litecanvas 0.103.7 → 0.201.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dist.dev.js +31 -16
- package/dist/dist.js +21 -11
- package/dist/dist.min.js +1 -1
- package/package.json +2 -2
- package/src/index.js +61 -29
- package/src/version.js +1 -1
- package/types/global.d.ts +21 -7
- package/types/types.d.ts +26 -18
package/dist/dist.dev.js
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
var assert = (condition, message = "Assertion failed") => {
|
|
116
116
|
if (!condition) throw new Error("[litecanvas] " + message);
|
|
117
117
|
};
|
|
118
|
-
var version = "0.
|
|
118
|
+
var version = "0.201.0";
|
|
119
119
|
function litecanvas(settings = {}) {
|
|
120
120
|
const root = window,
|
|
121
121
|
math = Math,
|
|
@@ -165,7 +165,6 @@
|
|
|
165
165
|
_colorPalette = defaultPalette,
|
|
166
166
|
_colorPaletteState = [],
|
|
167
167
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
168
|
-
_coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized",
|
|
169
168
|
_mathFunctions =
|
|
170
169
|
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp",
|
|
171
170
|
_eventListeners = {};
|
|
@@ -686,7 +685,7 @@
|
|
|
686
685
|
if (align) _ctx.textAlign = align;
|
|
687
686
|
if (baseline) _ctx.textBaseline = baseline;
|
|
688
687
|
},
|
|
689
|
-
image(x, y,
|
|
688
|
+
image(x, y, source) {
|
|
690
689
|
DEV: assert(
|
|
691
690
|
isNumber(x),
|
|
692
691
|
loggerPrefix + "image() 1st param must be a number",
|
|
@@ -695,7 +694,7 @@
|
|
|
695
694
|
isNumber(y),
|
|
696
695
|
loggerPrefix + "image() 2nd param must be a number",
|
|
697
696
|
);
|
|
698
|
-
_ctx.drawImage(
|
|
697
|
+
_ctx.drawImage(source, ~~x, ~~y);
|
|
699
698
|
},
|
|
700
699
|
spr(x, y, pixels) {
|
|
701
700
|
DEV: assert(
|
|
@@ -881,7 +880,7 @@
|
|
|
881
880
|
);
|
|
882
881
|
loadPlugin(callback, config);
|
|
883
882
|
},
|
|
884
|
-
listen(eventName, callback) {
|
|
883
|
+
listen: (eventName, callback) => {
|
|
885
884
|
DEV: assert(
|
|
886
885
|
"string" === typeof eventName,
|
|
887
886
|
loggerPrefix + "listen() 1st param must be a string",
|
|
@@ -893,7 +892,20 @@
|
|
|
893
892
|
eventName = lowerCase(eventName);
|
|
894
893
|
_eventListeners[eventName] = _eventListeners[eventName] || new Set();
|
|
895
894
|
_eventListeners[eventName].add(callback);
|
|
896
|
-
|
|
895
|
+
},
|
|
896
|
+
unlisten: (eventName, callback) => {
|
|
897
|
+
DEV: assert(
|
|
898
|
+
"string" === typeof eventName,
|
|
899
|
+
loggerPrefix + "unlisten() 1st param must be a string",
|
|
900
|
+
);
|
|
901
|
+
DEV: assert(
|
|
902
|
+
"function" === typeof callback,
|
|
903
|
+
loggerPrefix + "unlisten() 2nd param must be a function",
|
|
904
|
+
);
|
|
905
|
+
eventName = lowerCase(eventName);
|
|
906
|
+
if (_eventListeners[eventName]) {
|
|
907
|
+
_eventListeners[eventName].delete(callback);
|
|
908
|
+
}
|
|
897
909
|
},
|
|
898
910
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
899
911
|
DEV: assert(
|
|
@@ -903,6 +915,9 @@
|
|
|
903
915
|
if (_initialized) {
|
|
904
916
|
eventName = lowerCase(eventName);
|
|
905
917
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
918
|
+
if (!settings.loop && "function" === typeof root[eventName]) {
|
|
919
|
+
root[eventName](arg1, arg2, arg3, arg4);
|
|
920
|
+
}
|
|
906
921
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
907
922
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
908
923
|
}
|
|
@@ -1216,9 +1231,9 @@
|
|
|
1216
1231
|
}
|
|
1217
1232
|
_canvas = _canvas || document.createElement("canvas");
|
|
1218
1233
|
DEV: assert(
|
|
1219
|
-
"CANVAS" === _canvas.tagName,
|
|
1234
|
+
_canvas instanceof HTMLElement && "CANVAS" === _canvas.tagName,
|
|
1220
1235
|
loggerPrefix +
|
|
1221
|
-
'litecanvas() option "canvas" should be a canvas element or string (CSS selector)',
|
|
1236
|
+
'litecanvas() option "canvas" should be a canvas element or string (CSS selector of a canvas)',
|
|
1222
1237
|
);
|
|
1223
1238
|
_ctx = _canvas.getContext("2d");
|
|
1224
1239
|
on(_canvas, "click", () => focus());
|
|
@@ -1271,9 +1286,10 @@
|
|
|
1271
1286
|
instance.emit("resized", _canvasScale);
|
|
1272
1287
|
}
|
|
1273
1288
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1274
|
-
if (
|
|
1275
|
-
|
|
1276
|
-
|
|
1289
|
+
if (_eventListeners[eventName]) {
|
|
1290
|
+
for (const callback of _eventListeners[eventName]) {
|
|
1291
|
+
callback(arg1, arg2, arg3, arg4);
|
|
1292
|
+
}
|
|
1277
1293
|
}
|
|
1278
1294
|
}
|
|
1279
1295
|
function loadPlugin(callback, config) {
|
|
@@ -1301,12 +1317,11 @@
|
|
|
1301
1317
|
DEV: console.info(loggerPrefix + `version ${version} started`);
|
|
1302
1318
|
DEV: console.debug(loggerPrefix + `litecanvas() options =`, settings);
|
|
1303
1319
|
setupCanvas();
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1320
|
+
if (settings.loop) {
|
|
1321
|
+
for (const eventName in settings.loop) {
|
|
1322
|
+
if (settings.loop[eventName])
|
|
1323
|
+
instance.listen(eventName, settings.loop[eventName]);
|
|
1308
1324
|
}
|
|
1309
|
-
if (source[event]) instance.listen(event, source[event]);
|
|
1310
1325
|
}
|
|
1311
1326
|
if ("loading" === document.readyState) {
|
|
1312
1327
|
on(root, "DOMContentLoaded", () => raf(init));
|
package/dist/dist.js
CHANGED
|
@@ -161,7 +161,6 @@
|
|
|
161
161
|
_colorPalette = defaultPalette,
|
|
162
162
|
_colorPaletteState = [],
|
|
163
163
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
164
|
-
_coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized",
|
|
165
164
|
_mathFunctions =
|
|
166
165
|
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp",
|
|
167
166
|
_eventListeners = {};
|
|
@@ -316,8 +315,8 @@
|
|
|
316
315
|
if (align) _ctx.textAlign = align;
|
|
317
316
|
if (baseline) _ctx.textBaseline = baseline;
|
|
318
317
|
},
|
|
319
|
-
image(x, y,
|
|
320
|
-
_ctx.drawImage(
|
|
318
|
+
image(x, y, source) {
|
|
319
|
+
_ctx.drawImage(source, ~~x, ~~y);
|
|
321
320
|
},
|
|
322
321
|
spr(x, y, pixels) {
|
|
323
322
|
const rows = pixels.trim().split("\n");
|
|
@@ -409,16 +408,24 @@
|
|
|
409
408
|
use(callback, config = {}) {
|
|
410
409
|
loadPlugin(callback, config);
|
|
411
410
|
},
|
|
412
|
-
listen(eventName, callback) {
|
|
411
|
+
listen: (eventName, callback) => {
|
|
413
412
|
eventName = lowerCase(eventName);
|
|
414
413
|
_eventListeners[eventName] = _eventListeners[eventName] || new Set();
|
|
415
414
|
_eventListeners[eventName].add(callback);
|
|
416
|
-
|
|
415
|
+
},
|
|
416
|
+
unlisten: (eventName, callback) => {
|
|
417
|
+
eventName = lowerCase(eventName);
|
|
418
|
+
if (_eventListeners[eventName]) {
|
|
419
|
+
_eventListeners[eventName].delete(callback);
|
|
420
|
+
}
|
|
417
421
|
},
|
|
418
422
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
419
423
|
if (_initialized) {
|
|
420
424
|
eventName = lowerCase(eventName);
|
|
421
425
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
426
|
+
if (!settings.loop && "function" === typeof root[eventName]) {
|
|
427
|
+
root[eventName](arg1, arg2, arg3, arg4);
|
|
428
|
+
}
|
|
422
429
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
423
430
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
424
431
|
}
|
|
@@ -697,9 +704,10 @@
|
|
|
697
704
|
instance.emit("resized", _canvasScale);
|
|
698
705
|
}
|
|
699
706
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
700
|
-
if (
|
|
701
|
-
|
|
702
|
-
|
|
707
|
+
if (_eventListeners[eventName]) {
|
|
708
|
+
for (const callback of _eventListeners[eventName]) {
|
|
709
|
+
callback(arg1, arg2, arg3, arg4);
|
|
710
|
+
}
|
|
703
711
|
}
|
|
704
712
|
}
|
|
705
713
|
function loadPlugin(callback, config) {
|
|
@@ -720,9 +728,11 @@
|
|
|
720
728
|
root.ENGINE = instance;
|
|
721
729
|
}
|
|
722
730
|
setupCanvas();
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
731
|
+
if (settings.loop) {
|
|
732
|
+
for (const eventName in settings.loop) {
|
|
733
|
+
if (settings.loop[eventName])
|
|
734
|
+
instance.listen(eventName, settings.loop[eventName]);
|
|
735
|
+
}
|
|
726
736
|
}
|
|
727
737
|
if ("loading" === document.readyState) {
|
|
728
738
|
on(root, "DOMContentLoaded", () => raf(init));
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=performance,o=2*n.PI,r=requestAnimationFrame,s=[],f=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))},d=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,d=0,c=0,
|
|
1
|
+
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=performance,o=2*n.PI,r=requestAnimationFrame,s=[],f=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))},d=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,d=0,c=0,u=0,p=0,h=0,m=0,g=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let E=Math,P=2*E.PI,T=d*=500*P/44100/44100,z=n*=(1-t+2*t*E.random(t=[]))*P/44100,C=0,I=0,L=0,D=1,S=0,A=0,M=0,H=k<0?-1:1,N=P*H*k*2/44100,W=E.cos(N),q=E.sin,B=q(N)/4,O=1+B,V=-2*W/O,R=(1-B)/O,F=(1+H*W)/2/O,G=-(H+W)/O,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,c*=500*P/85766121e6,g*=P/44100,u*=P/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,H=i+y+o+r+w|0;L<H;t[L++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?q(C*C):E.max(E.min(E.tan(C),1),-1):1-(2*C/P%2+2)%2:1-4*E.abs(E.round(C/P)-C/P):q(C),M=(h?1-b+b*q(P*L/h):1)*(M<0?-1:1)*E.abs(M)**f*(L<i?L/i:L<i+y?1-(L-i)/y*(1-x):L<i+y+o?x:L<H-w?(H-L-w)/r*x:0),M=w?M/2+(w>L?0:(L<H-w?1:(H-L)/w)*t[L-w|0]/2/e):M,k&&(M=j=F*X+G*(X=Y)+F*(Y=M)-R*$-V*($=j))),C+=(N=(n+=d+=c)*E.cos(g*I++))+N*m*q(L**5),D&&++D>p&&(n+=u,z+=u,D=0),!h||++S%h||(n=z,d=T,D=D||1);(e=a.createBuffer(1,H,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let c=!1,u=!0,p,h=1,m,g=.5,v=1,w,x=1e3/60,y,b,k=3,E="sans-serif",P=20,T=1.2,z=Date.now(),C=e,I=[],L=[.5,0,1750,,,.3,1,,,,600,.1],D={},S={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:o,HALF_PI:o/4,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,dist:(e,t,a,l)=>n.hypot(a-e,l-t),wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?S.clamp(o,l,n):o},norm:(e,t,a)=>S.map(e,t,a,0,1),rand:(e=0,t=1)=>(z=(1664525*z+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>~~S.rand(e,t+1),rseed(e){z=~~e},cls(e){null==e?m.clearRect(0,0,S.W,S.H):S.rectfill(0,0,S.W,S.H,e)},rect(e,t,a,l,n,i){m.beginPath(),m[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),S.stroke(n)},rectfill(e,t,a,l,n,i){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),S.fill(n)},circ(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,~~a,0,o),S.stroke(l)},circfill(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,~~a,0,o),S.fill(l)},oval(e,t,a,l,n){m.beginPath(),m.ellipse(~~e,~~t,~~a,~~l,0,0,o),S.stroke(n)},ovalfill(e,t,a,l,n){m.beginPath(),m.ellipse(~~e,~~t,~~a,~~l,0,0,o),S.fill(n)},shape(e){m.beginPath();for(let t=0;t<e.length;t+=2)0===t?m.moveTo(~~e[t],~~e[t+1]):m.lineTo(~~e[t],~~e[t+1]);m.lineTo(~~e[0],~~e[1])},line(e,t,a,l,n){m.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);m.moveTo(~~e+i,~~t+o),m.lineTo(~~a+i,~~l+o),S.stroke(n)},linewidth(e){m.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,l=k,n="normal"){m.font=`${n} ${P}px ${E}`,m.fillStyle=W(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)m.fillText(i[a],~~e,~~t+P*T*a)},textgap(e){T=e},textfont(e){E=e},textsize(e){P=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},image(e,t,a){m.drawImage(a,~~e,~~t)},spr(e,t,a){let l=a.trim().split("\n");for(let a=0;a<l.length;a++){let n=l[a].trim();for(let l=0;l<n.length;l++){let i=n[l];"."!==i&&" "!==i&&S.rectfill(e+l,t+a,1,1,parseInt(i,36)||0)}}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=m;return n.width=e*i,n.height=t*i,(m=n.getContext("2d")).scale(i,i),a(m),m=o,n.transferToImageBitmap()},ctx:e=>(e&&(m=e),m),push(){m.save()},pop(){m.restore()},translate(e,t){m.translate(~~e,~~t)},scale(e,t){m.scale(e,t||e)},rotate(e){m.rotate(e)},alpha(e){m.globalAlpha=S.clamp(e,0,1)},fill(e){m.fillStyle=W(e),m.fill()},stroke(e){m.strokeStyle=W(e),m.stroke()},clip(e){m.beginPath(),e(m),m.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||L,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),d.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>p,use(e,t={}){var a=e,l=t;let n=a(S,l);for(let e in n)S.def(e,n[e])},listen:(e,t)=>{D[e=e.toLowerCase()]=D[e]||new Set,D[e].add(t)},unlisten:(e,t)=>{D[e=e.toLowerCase()]&&D[e].delete(t)},emit(e,a,n,i,o){c&&(N("before:"+(e=e.toLowerCase()),a,n,i,o),t.loop||"function"!=typeof l[e]||l[e](a,n,i,o),N(e,a,n,i,o),N("after:"+e,a,n,i,o))},pal(t,a=3){C=t||e,I=[],k=a},palc(e,t){null==e?I=[]:I[e]=t},def(e,a){S[e]=a,t.global&&(l[e]=a)},timescale(e){v=e},framerate(e){x=1e3/~~e},stat(e){let a={index:e,value:[t,c,x/1e3,h,D,C,L,v,l.zzfxV,z,P,E,I,T][e]};return S.emit("stat",a),a.value},pause(){u=!0,cancelAnimationFrame(b)},resume(){c&&u&&(u=!1,y=x,w=i.now(),b=r(M))},paused:()=>u,quit(){for(let e of(S.emit("quit"),S.pause(),c=!1,D={},s))e();if(t.global){for(let e in S)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))S[e]=n[e];function A(){if(t.autoscale&&f(l,"resize",H),t.tapEvents){let e=e=>[(e.pageX-p.offsetLeft)/h,(e.pageY-p.offsetTop)/h],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:i.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},o=e=>e&&i.now()-e.t<=300,r=!1;f(p,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);S.emit("tap",l,n,0),a(0,l,n),r=!0}}),f(p,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,i]=e(a);o(l)&&S.emit("tapped",l.xi,l.yi,0),S.emit("untap",n,i,0),t.delete(0),r=!1}}),f(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);S.def("MX",a),S.def("MY",l),r&&(S.emit("tapping",a,l,0),n(0,a,l))}),f(p,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);S.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),f(p,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);S.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(o(l)&&S.emit("tapped",l.xi,l.yi,e),S.emit("untap",l.x,l.y,e),t.delete(e))};f(p,"touchend",s),f(p,"touchcancel",s),f(l,"blur",()=>{for(let[e,a]of(r=!1,t))S.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";f(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),f(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),f(l,"blur",()=>e.clear()),S.listen("after:update",()=>t.clear()),S.def("iskeydown",t=>a(e,t)),S.def("iskeypressed",e=>a(t,e)),S.def("lastkey",()=>n)}c=!0,S.resume(),S.emit("init",S)}function M(){b=r(M);let e=i.now(),t=0,a=e-w;for(w=e,y+=a<100?a:x;y>=x;){t++,y-=x;let e=x/1e3*v;S.emit("update",e,t),S.def("T",S.T+e)}t&&(S.emit("draw",m),t>1&&(y=0))}function H(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(S.def("W",e),S.def("H",a),p.width=e,p.height=a,t.autoscale){let l=+t.autoscale;p.style.display||(p.style.display="block",p.style.margin="auto"),h=n.min(innerWidth/e,innerHeight/a),h=l>1&&h>l?l:h,p.style.width=e*h+"px",p.style.height=a*h+"px"}m.imageSmoothingEnabled=!1,S.textalign("start","top"),S.emit("resized",h)}function N(e,t,a,l,n){if(D[e])for(let i of D[e])i(t,a,l,n)}function W(e){return C[~~(I[e]??e)%C.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,S),l.ENGINE=S}if(m=(p=(p="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),f(p,"click",()=>focus()),H(),p.parentNode||document.body.appendChild(p),p.style.imageRendering="pixelated",p.oncontextmenu=()=>!1,t.loop)for(let e in t.loop)t.loop[e]&&S.listen(e,t.loop[e]);return"loading"===document.readyState?f(l,"DOMContentLoaded",()=>r(A)):b=r(A),S}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.201.0",
|
|
4
4
|
"description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and p5.js/Processing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Luiz Bills <luizbills@pm.me>",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"creative coding"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@happy-dom/global-registrator": "^20.8.
|
|
35
|
+
"@happy-dom/global-registrator": "^20.8.4",
|
|
36
36
|
"@size-limit/preset-small-lib": "^12.0.1",
|
|
37
37
|
"@swc/core": "^1.15.18",
|
|
38
38
|
"ava": "^7.0.0",
|
package/src/index.js
CHANGED
|
@@ -86,8 +86,6 @@ export default function litecanvas(settings = {}) {
|
|
|
86
86
|
_colorPaletteState = [],
|
|
87
87
|
/** @type {number[]} */
|
|
88
88
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
89
|
-
/** @type {string} */
|
|
90
|
-
_coreEvents = 'init,update,draw,tap,untap,tapping,tapped,resized',
|
|
91
89
|
/** @type {string} list of functions copied from `Math` module*/
|
|
92
90
|
_mathFunctions =
|
|
93
91
|
'PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp',
|
|
@@ -1075,13 +1073,12 @@ export default function litecanvas(settings = {}) {
|
|
|
1075
1073
|
},
|
|
1076
1074
|
|
|
1077
1075
|
/**
|
|
1078
|
-
* Add a game event listener
|
|
1076
|
+
* Add a game event listener.
|
|
1079
1077
|
*
|
|
1080
1078
|
* @param {string} eventName the event type name
|
|
1081
1079
|
* @param {Function} callback the function that is called when the event occurs
|
|
1082
|
-
* @returns {Function} a function to remove the listener
|
|
1083
1080
|
*/
|
|
1084
|
-
listen(eventName, callback) {
|
|
1081
|
+
listen: (eventName, callback) => {
|
|
1085
1082
|
DEV: assert(
|
|
1086
1083
|
'string' === typeof eventName,
|
|
1087
1084
|
loggerPrefix + 'listen() 1st param must be a string'
|
|
@@ -1095,19 +1092,43 @@ export default function litecanvas(settings = {}) {
|
|
|
1095
1092
|
|
|
1096
1093
|
_eventListeners[eventName] = _eventListeners[eventName] || new Set()
|
|
1097
1094
|
_eventListeners[eventName].add(callback)
|
|
1095
|
+
},
|
|
1098
1096
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1097
|
+
/**
|
|
1098
|
+
* Remove a game event listener.
|
|
1099
|
+
*
|
|
1100
|
+
* @param {string} eventName the event type name
|
|
1101
|
+
* @param {Function} callback the function that is called when the event occurs
|
|
1102
|
+
*/
|
|
1103
|
+
unlisten: (eventName, callback) => {
|
|
1104
|
+
DEV: assert(
|
|
1105
|
+
'string' === typeof eventName,
|
|
1106
|
+
loggerPrefix + 'unlisten() 1st param must be a string'
|
|
1107
|
+
)
|
|
1108
|
+
DEV: assert(
|
|
1109
|
+
'function' === typeof callback,
|
|
1110
|
+
loggerPrefix + 'unlisten() 2nd param must be a function'
|
|
1111
|
+
)
|
|
1112
|
+
|
|
1113
|
+
eventName = lowerCase(eventName)
|
|
1114
|
+
|
|
1115
|
+
if (_eventListeners[eventName]) {
|
|
1116
|
+
_eventListeners[eventName].delete(callback)
|
|
1117
|
+
}
|
|
1101
1118
|
},
|
|
1102
1119
|
|
|
1103
1120
|
/**
|
|
1104
|
-
* Call all listeners attached to a game event
|
|
1121
|
+
* Call all listeners attached to a game event.
|
|
1122
|
+
*
|
|
1123
|
+
* Note: when the `litecanvas()` "loop" option is `null` (default),
|
|
1124
|
+
* `emit()` will first call a global function matching the event name (if it exists).
|
|
1125
|
+
* E.g: `emit("boom")` calls `window.boom()`.
|
|
1105
1126
|
*
|
|
1106
1127
|
* @param {string} eventName The event type name
|
|
1107
|
-
* @param {
|
|
1108
|
-
* @param {
|
|
1109
|
-
* @param {
|
|
1110
|
-
* @param {
|
|
1128
|
+
* @param {any} [arg1] any data to be passed over the listeners
|
|
1129
|
+
* @param {any} [arg2] any data to be passed over the listeners
|
|
1130
|
+
* @param {any} [arg3] any data to be passed over the listeners
|
|
1131
|
+
* @param {any} [arg4] any data to be passed over the listeners
|
|
1111
1132
|
*/
|
|
1112
1133
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
1113
1134
|
DEV: assert(
|
|
@@ -1119,7 +1140,12 @@ export default function litecanvas(settings = {}) {
|
|
|
1119
1140
|
eventName = lowerCase(eventName)
|
|
1120
1141
|
|
|
1121
1142
|
triggerEvent('before:' + eventName, arg1, arg2, arg3, arg4)
|
|
1143
|
+
|
|
1144
|
+
if (!settings.loop && 'function' === typeof root[eventName]) {
|
|
1145
|
+
root[eventName](arg1, arg2, arg3, arg4)
|
|
1146
|
+
}
|
|
1122
1147
|
triggerEvent(eventName, arg1, arg2, arg3, arg4)
|
|
1148
|
+
|
|
1123
1149
|
triggerEvent('after:' + eventName, arg1, arg2, arg3, arg4)
|
|
1124
1150
|
}
|
|
1125
1151
|
},
|
|
@@ -1175,8 +1201,13 @@ export default function litecanvas(settings = {}) {
|
|
|
1175
1201
|
/**
|
|
1176
1202
|
* Define or update a instance property.
|
|
1177
1203
|
*
|
|
1178
|
-
*
|
|
1179
|
-
*
|
|
1204
|
+
* Note: when the `litecanvas()` option "global" is `true` (default),
|
|
1205
|
+
* `def()` with set/update a global property.
|
|
1206
|
+
*
|
|
1207
|
+
* E.g: `def('ONE', 1)` do `window.ONE = 1`.
|
|
1208
|
+
*
|
|
1209
|
+
* @param {string} key the property name
|
|
1210
|
+
* @param {any} value the property value
|
|
1180
1211
|
*/
|
|
1181
1212
|
def(key, value) {
|
|
1182
1213
|
DEV: assert('string' === typeof key, loggerPrefix + 'def() 1st param must be a string')
|
|
@@ -1663,9 +1694,9 @@ export default function litecanvas(settings = {}) {
|
|
|
1663
1694
|
_canvas = _canvas || document.createElement('canvas')
|
|
1664
1695
|
|
|
1665
1696
|
DEV: assert(
|
|
1666
|
-
'CANVAS' === _canvas.tagName,
|
|
1697
|
+
_canvas instanceof HTMLElement && 'CANVAS' === _canvas.tagName,
|
|
1667
1698
|
loggerPrefix +
|
|
1668
|
-
'litecanvas() option "canvas" should be a canvas element or string (CSS selector)'
|
|
1699
|
+
'litecanvas() option "canvas" should be a canvas element or string (CSS selector of a canvas)'
|
|
1669
1700
|
)
|
|
1670
1701
|
|
|
1671
1702
|
_ctx = _canvas.getContext('2d')
|
|
@@ -1679,6 +1710,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1679
1710
|
}
|
|
1680
1711
|
|
|
1681
1712
|
_canvas.style.imageRendering = 'pixelated'
|
|
1713
|
+
|
|
1714
|
+
// disable default browser's right click in canvas
|
|
1682
1715
|
_canvas.oncontextmenu = () => false
|
|
1683
1716
|
}
|
|
1684
1717
|
|
|
@@ -1733,21 +1766,22 @@ export default function litecanvas(settings = {}) {
|
|
|
1733
1766
|
|
|
1734
1767
|
/**
|
|
1735
1768
|
* @param {string} eventName
|
|
1736
|
-
* @param {
|
|
1737
|
-
* @param {
|
|
1738
|
-
* @param {
|
|
1739
|
-
* @param {
|
|
1769
|
+
* @param {any} [arg1]
|
|
1770
|
+
* @param {any} [arg2]
|
|
1771
|
+
* @param {any} [arg3]
|
|
1772
|
+
* @param {any} [arg4]
|
|
1740
1773
|
*/
|
|
1741
1774
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1742
|
-
if (
|
|
1743
|
-
|
|
1744
|
-
|
|
1775
|
+
if (_eventListeners[eventName]) {
|
|
1776
|
+
for (const callback of _eventListeners[eventName]) {
|
|
1777
|
+
callback(arg1, arg2, arg3, arg4)
|
|
1778
|
+
}
|
|
1745
1779
|
}
|
|
1746
1780
|
}
|
|
1747
1781
|
|
|
1748
1782
|
/**
|
|
1749
1783
|
* @param {pluginCallback} callback
|
|
1750
|
-
* @param {
|
|
1784
|
+
* @param {any} config
|
|
1751
1785
|
*/
|
|
1752
1786
|
function loadPlugin(callback, config) {
|
|
1753
1787
|
const pluginData = callback(instance, config)
|
|
@@ -1786,12 +1820,10 @@ export default function litecanvas(settings = {}) {
|
|
|
1786
1820
|
setupCanvas()
|
|
1787
1821
|
|
|
1788
1822
|
// setup default event listeners
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
console.info(loggerPrefix + `using window.${event}()`)
|
|
1823
|
+
if (settings.loop) {
|
|
1824
|
+
for (const eventName in settings.loop) {
|
|
1825
|
+
if (settings.loop[eventName]) instance.listen(eventName, settings.loop[eventName])
|
|
1793
1826
|
}
|
|
1794
|
-
if (source[event]) instance.listen(event, source[event])
|
|
1795
1827
|
}
|
|
1796
1828
|
|
|
1797
1829
|
// init the engine (async)
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.201.0'
|
package/types/global.d.ts
CHANGED
|
@@ -547,15 +547,25 @@ declare global {
|
|
|
547
547
|
*/
|
|
548
548
|
function use(callback: pluginCallback): void
|
|
549
549
|
/**
|
|
550
|
-
* Add a game loop event listener
|
|
550
|
+
* Add a game loop event listener.
|
|
551
551
|
*
|
|
552
552
|
* @param event The game event type
|
|
553
553
|
* @param callback the function that is called when the event occurs
|
|
554
|
-
* @returns a function to remove the listener
|
|
555
554
|
*/
|
|
556
|
-
function listen(event: string, callback: Function):
|
|
555
|
+
function listen(event: string, callback: Function): void
|
|
557
556
|
/**
|
|
558
|
-
*
|
|
557
|
+
* Remove a game loop event listener.
|
|
558
|
+
*
|
|
559
|
+
* @param event The game event type
|
|
560
|
+
* @param callback the function that is called when the event occurs
|
|
561
|
+
*/
|
|
562
|
+
function unlisten(event: string, callback: Function): void
|
|
563
|
+
/**
|
|
564
|
+
* Call all listeners attached to a game event.
|
|
565
|
+
*
|
|
566
|
+
* Note: when the `litecanvas()` "loop" option is `null` (default),
|
|
567
|
+
* `emit()` will first call a global function matching the event name (if it exists).
|
|
568
|
+
* E.g: `emit("boom", 10)` calls `window.boom(10)`.
|
|
559
569
|
*
|
|
560
570
|
* @param event The game event type
|
|
561
571
|
* @param [arg1] any data to be passed over the listeners
|
|
@@ -583,10 +593,14 @@ declare global {
|
|
|
583
593
|
*/
|
|
584
594
|
function palc(a?: number, b?: number): void
|
|
585
595
|
/**
|
|
586
|
-
* Define or update a instance property
|
|
596
|
+
* Define or update a instance property.
|
|
587
597
|
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
598
|
+
* Note: when the `litecanvas()` option "global" is `true` (default),
|
|
599
|
+
* `def()` with set/update a global property.
|
|
600
|
+
* E.g: `def('ONE', 1)` also do `window.ONE = 1`.
|
|
601
|
+
*
|
|
602
|
+
* @param key the property name
|
|
603
|
+
* @param value the property value
|
|
590
604
|
*/
|
|
591
605
|
function def(key: string, value: any): void
|
|
592
606
|
/**
|
package/types/types.d.ts
CHANGED
|
@@ -531,15 +531,25 @@ type LitecanvasInstance = {
|
|
|
531
531
|
*/
|
|
532
532
|
use(callback: pluginCallback): void
|
|
533
533
|
/**
|
|
534
|
-
* Add a game loop event listener
|
|
534
|
+
* Add a game loop event listener.
|
|
535
535
|
*
|
|
536
536
|
* @param event The game event type
|
|
537
537
|
* @param callback the function that is called when the event occurs
|
|
538
|
-
* @returns a function to remove the listener
|
|
539
538
|
*/
|
|
540
|
-
listen(event: string, callback: Function):
|
|
539
|
+
listen(event: string, callback: Function): void
|
|
541
540
|
/**
|
|
542
|
-
*
|
|
541
|
+
* Remove a game loop event listener.
|
|
542
|
+
*
|
|
543
|
+
* @param event The game event type
|
|
544
|
+
* @param callback the function that is called when the event occurs
|
|
545
|
+
*/
|
|
546
|
+
unlisten(event: string, callback: Function): void
|
|
547
|
+
/**
|
|
548
|
+
* Call all listeners attached to a game event.
|
|
549
|
+
*
|
|
550
|
+
* Note: when the `litecanvas()` "loop" option is `null` (default),
|
|
551
|
+
* `emit()` will first call a global function matching the event name (if it exists).
|
|
552
|
+
* E.g: `emit("boom", 10)` calls `window.boom(10)`.
|
|
543
553
|
*
|
|
544
554
|
* @param event The game event type
|
|
545
555
|
* @param [arg1] any data to be passed over the listeners
|
|
@@ -549,10 +559,14 @@ type LitecanvasInstance = {
|
|
|
549
559
|
*/
|
|
550
560
|
emit(event: string, arg1?: any, arg2?: any, arg3?: any, arg4?: any): void
|
|
551
561
|
/**
|
|
552
|
-
* Define or update a instance property
|
|
562
|
+
* Define or update a instance property.
|
|
553
563
|
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
564
|
+
* Note: when the `litecanvas()` option "global" is `true` (default),
|
|
565
|
+
* `def()` with set/update a global property.
|
|
566
|
+
* E.g: `def('ONE', 1)` also do `window.ONE = 1`.
|
|
567
|
+
*
|
|
568
|
+
* @param key the property name
|
|
569
|
+
* @param value the property value
|
|
556
570
|
*/
|
|
557
571
|
def(key: string, value: any): void
|
|
558
572
|
/**
|
|
@@ -652,19 +666,13 @@ type LitecanvasOptions = {
|
|
|
652
666
|
*/
|
|
653
667
|
global?: boolean
|
|
654
668
|
/**
|
|
655
|
-
* Specify your game loop callbacks.
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
659
|
-
*
|
|
660
|
-
* - `window.resized(scale: number): void`
|
|
661
|
-
* - `window.tap(tapX: number, tapY: number, touchId: number): void`
|
|
662
|
-
* - `window.untap(tapX: number, tapY: number, touchId: number): void`
|
|
663
|
-
* - `window.tapped(tapX: number, tapY: number, touchId: number): void`
|
|
664
|
-
* - `window.tapping(tapX: number, tapY: number, touchId: number): void`
|
|
669
|
+
* Specify your game loop listener callbacks.
|
|
670
|
+
*
|
|
671
|
+
* By default, it uses global functions with the same name as the events (if they exist).
|
|
672
|
+
*
|
|
673
|
+
* Example: `window.init`, `window.update`, `window.draw`, etc
|
|
665
674
|
*/
|
|
666
675
|
loop?: LitecanvasGameLoop
|
|
667
|
-
|
|
668
676
|
/**
|
|
669
677
|
* default: `true`
|
|
670
678
|
*
|