litecanvas 0.84.2 → 0.85.1
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 +20 -27
- package/dist/dist.js +13 -20
- package/dist/dist.min.js +1 -1
- package/package.json +3 -3
- package/src/index.js +28 -32
- package/types/types.d.ts +1 -2
package/dist/dist.dev.js
CHANGED
|
@@ -50,16 +50,7 @@
|
|
|
50
50
|
animate: true
|
|
51
51
|
};
|
|
52
52
|
settings = Object.assign(defaults, settings);
|
|
53
|
-
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _colors = defaultPalette, _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
54
|
-
init: null,
|
|
55
|
-
update: null,
|
|
56
|
-
draw: null,
|
|
57
|
-
resized: null,
|
|
58
|
-
tap: null,
|
|
59
|
-
untap: null,
|
|
60
|
-
tapping: null,
|
|
61
|
-
tapped: null
|
|
62
|
-
};
|
|
53
|
+
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _colors = defaultPalette, _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
|
|
63
54
|
const instance = {
|
|
64
55
|
/** @type {number} */
|
|
65
56
|
W: 0,
|
|
@@ -566,11 +557,11 @@
|
|
|
566
557
|
"paint: 3rd param must be a function or array"
|
|
567
558
|
);
|
|
568
559
|
DEV: assert(
|
|
569
|
-
options &&
|
|
560
|
+
options && null == options.scale || isNumber(options.scale),
|
|
570
561
|
"paint: 4th param (options.scale) must be a number"
|
|
571
562
|
);
|
|
572
563
|
DEV: assert(
|
|
573
|
-
options &&
|
|
564
|
+
options && null == options.canvas || options.canvas instanceof OffscreenCanvas,
|
|
574
565
|
"paint: 4th param (options.canvas) must be an OffscreenCanvas"
|
|
575
566
|
);
|
|
576
567
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
@@ -812,9 +803,9 @@
|
|
|
812
803
|
DEV: assert("string" === typeof eventName, "listen: 1st param must be a string");
|
|
813
804
|
DEV: assert("function" === typeof callback, "listen: 2nd param must be a function");
|
|
814
805
|
eventName = eventName.toLowerCase();
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
return () =>
|
|
806
|
+
_eventListeners[eventName] = _eventListeners[eventName] || /* @__PURE__ */ new Set();
|
|
807
|
+
_eventListeners[eventName].add(callback);
|
|
808
|
+
return () => _eventListeners && _eventListeners[eventName].delete(callback);
|
|
818
809
|
},
|
|
819
810
|
/**
|
|
820
811
|
* Call all listeners attached to a game event
|
|
@@ -906,7 +897,7 @@
|
|
|
906
897
|
// 3
|
|
907
898
|
_scale,
|
|
908
899
|
// 4
|
|
909
|
-
|
|
900
|
+
_eventListeners,
|
|
910
901
|
// 5
|
|
911
902
|
_colors,
|
|
912
903
|
// 6
|
|
@@ -934,10 +925,10 @@
|
|
|
934
925
|
cancelAnimationFrame(_rafid);
|
|
935
926
|
_rafid = 0;
|
|
936
927
|
instance.emit("quit");
|
|
928
|
+
_eventListeners = {};
|
|
937
929
|
for (const removeListener of _browserEventListeners) {
|
|
938
930
|
removeListener();
|
|
939
931
|
}
|
|
940
|
-
_events = {};
|
|
941
932
|
if (settings.global) {
|
|
942
933
|
for (const key in instance) {
|
|
943
934
|
delete root[key];
|
|
@@ -947,12 +938,12 @@
|
|
|
947
938
|
_initialized = false;
|
|
948
939
|
}
|
|
949
940
|
};
|
|
950
|
-
for (const k of
|
|
941
|
+
for (const k of _mathFunctions.split(",")) {
|
|
951
942
|
instance[k] = math[k];
|
|
952
943
|
}
|
|
953
944
|
function init() {
|
|
954
945
|
const source = settings.loop ? settings.loop : root;
|
|
955
|
-
for (const event
|
|
946
|
+
for (const event of _coreEvents.split(",")) {
|
|
956
947
|
if (source[event]) instance.listen(event, source[event]);
|
|
957
948
|
}
|
|
958
949
|
for (const [callback, config] of _plugins) {
|
|
@@ -1200,15 +1191,17 @@
|
|
|
1200
1191
|
}
|
|
1201
1192
|
}
|
|
1202
1193
|
function setupCanvas() {
|
|
1203
|
-
if (settings.canvas) {
|
|
1204
|
-
DEV: assert(
|
|
1205
|
-
"string" === typeof settings.canvas,
|
|
1206
|
-
`Litecanvas' option "canvas" should be a string (a selector)`
|
|
1207
|
-
);
|
|
1194
|
+
if ("string" === typeof settings.canvas) {
|
|
1208
1195
|
_canvas = document.querySelector(settings.canvas);
|
|
1196
|
+
DEV: assert(null != _canvas, `Litecanvas' option "canvas" is an invalid CSS selector`);
|
|
1197
|
+
} else {
|
|
1198
|
+
_canvas = settings.canvas;
|
|
1209
1199
|
}
|
|
1210
1200
|
_canvas = _canvas || document.createElement("canvas");
|
|
1211
|
-
DEV: assert(
|
|
1201
|
+
DEV: assert(
|
|
1202
|
+
"CANVAS" === _canvas.tagName,
|
|
1203
|
+
`Litecanvas' option "canvas" should be a canvas element or string (CSS selector)`
|
|
1204
|
+
);
|
|
1212
1205
|
_ctx = _canvas.getContext("2d");
|
|
1213
1206
|
on(_canvas, "click", () => root.focus());
|
|
1214
1207
|
_canvas.style = "";
|
|
@@ -1254,8 +1247,8 @@
|
|
|
1254
1247
|
}
|
|
1255
1248
|
}
|
|
1256
1249
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1257
|
-
if (!
|
|
1258
|
-
for (const callback of
|
|
1250
|
+
if (!_eventListeners[eventName]) return;
|
|
1251
|
+
for (const callback of _eventListeners[eventName]) {
|
|
1259
1252
|
callback(arg1, arg2, arg3, arg4);
|
|
1260
1253
|
}
|
|
1261
1254
|
}
|
package/dist/dist.js
CHANGED
|
@@ -45,16 +45,7 @@
|
|
|
45
45
|
animate: true
|
|
46
46
|
};
|
|
47
47
|
settings = Object.assign(defaults, settings);
|
|
48
|
-
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _colors = defaultPalette, _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
49
|
-
init: null,
|
|
50
|
-
update: null,
|
|
51
|
-
draw: null,
|
|
52
|
-
resized: null,
|
|
53
|
-
tap: null,
|
|
54
|
-
untap: null,
|
|
55
|
-
tapping: null,
|
|
56
|
-
tapped: null
|
|
57
|
-
};
|
|
48
|
+
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _colors = defaultPalette, _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
|
|
58
49
|
const instance = {
|
|
59
50
|
/** @type {number} */
|
|
60
51
|
W: 0,
|
|
@@ -613,9 +604,9 @@
|
|
|
613
604
|
*/
|
|
614
605
|
listen(eventName, callback) {
|
|
615
606
|
eventName = eventName.toLowerCase();
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
return () =>
|
|
607
|
+
_eventListeners[eventName] = _eventListeners[eventName] || /* @__PURE__ */ new Set();
|
|
608
|
+
_eventListeners[eventName].add(callback);
|
|
609
|
+
return () => _eventListeners && _eventListeners[eventName].delete(callback);
|
|
619
610
|
},
|
|
620
611
|
/**
|
|
621
612
|
* Call all listeners attached to a game event
|
|
@@ -689,7 +680,7 @@
|
|
|
689
680
|
// 3
|
|
690
681
|
_scale,
|
|
691
682
|
// 4
|
|
692
|
-
|
|
683
|
+
_eventListeners,
|
|
693
684
|
// 5
|
|
694
685
|
_colors,
|
|
695
686
|
// 6
|
|
@@ -717,10 +708,10 @@
|
|
|
717
708
|
cancelAnimationFrame(_rafid);
|
|
718
709
|
_rafid = 0;
|
|
719
710
|
instance.emit("quit");
|
|
711
|
+
_eventListeners = {};
|
|
720
712
|
for (const removeListener of _browserEventListeners) {
|
|
721
713
|
removeListener();
|
|
722
714
|
}
|
|
723
|
-
_events = {};
|
|
724
715
|
if (settings.global) {
|
|
725
716
|
for (const key in instance) {
|
|
726
717
|
delete root[key];
|
|
@@ -730,12 +721,12 @@
|
|
|
730
721
|
_initialized = false;
|
|
731
722
|
}
|
|
732
723
|
};
|
|
733
|
-
for (const k of
|
|
724
|
+
for (const k of _mathFunctions.split(",")) {
|
|
734
725
|
instance[k] = math[k];
|
|
735
726
|
}
|
|
736
727
|
function init() {
|
|
737
728
|
const source = settings.loop ? settings.loop : root;
|
|
738
|
-
for (const event
|
|
729
|
+
for (const event of _coreEvents.split(",")) {
|
|
739
730
|
if (source[event]) instance.listen(event, source[event]);
|
|
740
731
|
}
|
|
741
732
|
for (const [callback, config] of _plugins) {
|
|
@@ -975,8 +966,10 @@
|
|
|
975
966
|
}
|
|
976
967
|
}
|
|
977
968
|
function setupCanvas() {
|
|
978
|
-
if (settings.canvas) {
|
|
969
|
+
if ("string" === typeof settings.canvas) {
|
|
979
970
|
_canvas = document.querySelector(settings.canvas);
|
|
971
|
+
} else {
|
|
972
|
+
_canvas = settings.canvas;
|
|
980
973
|
}
|
|
981
974
|
_canvas = _canvas || document.createElement("canvas");
|
|
982
975
|
_ctx = _canvas.getContext("2d");
|
|
@@ -1012,8 +1005,8 @@
|
|
|
1012
1005
|
}
|
|
1013
1006
|
}
|
|
1014
1007
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1015
|
-
if (!
|
|
1016
|
-
for (const callback of
|
|
1008
|
+
if (!_eventListeners[eventName]) return;
|
|
1009
|
+
for (const callback of _eventListeners[eventName]) {
|
|
1017
1010
|
callback(arg1, arg2, arg3, arg4);
|
|
1018
1011
|
}
|
|
1019
1012
|
}
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,n=Math,
|
|
1
|
+
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,n=Math,i=2*n.PI,l=requestAnimationFrame,r=[],o=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},s=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,n=.05,i=220,l=0,r=0,o=.1,s=0,f=1,c=0,d=0,p=0,u=0,h=0,g=0,m=0,w=0,v=0,x=1,b=0,y=0,k=0)=>{let E=Math,z=2*E.PI,T=c*=500*z/44100/44100,C=i*=(1-n+2*n*E.random(n=[]))*z/44100,I=0,P=0,A=0,L=1,S=0,X=0,Y=0,M=k<0?-1:1,D=z*M*k*2/44100,H=E.cos(D),N=E.sin,W=N(D)/4,F=1+W,q=-2*H/F,B=(1-W)/F,O=(1+M*H)/2/F,V=-(M+H)/F,R=0,G=0,$=0,j=0;for(l=44100*l+9,b*=44100,r*=44100,o*=44100,v*=44100,d*=500*z/85766121e6,m*=z/44100,p*=z/44100,u*=44100,h=44100*h|0,a*=.3*e.zzfxV,M=l+b+r+o+v|0;A<M;n[A++]=Y*a)++X%(100*w|0)||(Y=s?1<s?2<s?3<s?N(I*I):E.max(E.min(E.tan(I),1),-1):1-(2*I/z%2+2)%2:1-4*E.abs(E.round(I/z)-I/z):N(I),Y=(h?1-y+y*N(z*A/h):1)*(Y<0?-1:1)*E.abs(Y)**f*(A<l?A/l:A<l+b?1-(A-l)/b*(1-x):A<l+b+r?x:A<M-v?(M-A-v)/o*x:0),Y=v?Y/2+(v>A?0:(A<M-v?1:(M-A)/v)*n[A-v|0]/2/a):Y,k&&(Y=j=O*R+V*(R=G)+O*(G=Y)-B*$-q*($=j))),I+=(D=(i+=c+=d)*E.cos(m*P++))+D*g*N(A**5),L&&++L>u&&(i+=p,C+=p,L=0),!h||++S%h||(i=C,c=T,L=L||1);(a=t.createBuffer(1,M,44100)).getChannelData(0).set(n),(i=t.createBufferSource()).buffer=a,i.connect(t.destination),i.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0,animate:!0},t);let f=!1,c=[],d,p=1,u,h=.5,g=1,m,w=1/60,v=0,x,b="sans-serif",y=20,k=Date.now(),E=e,z=[.5,0,1750,,,.3,1,,,,600,.1],T={},C={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>a*(t-e)+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,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,n,i,l){let r=(e-t)/(a-t)*(i-n)+n;return l?C.clamp(r,n,i):r},norm:(e,t,a)=>C.map(e,t,a,0,1),wave:(e,t,a,n=Math.sin)=>e+(n(a)+1)/2*(t-e),rand:(e=0,t=1)=>(k=(1664525*k+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(C.rand(e,t+1)),rseed(e){k=~~e},cls(e){null==e?u.clearRect(0,0,u.canvas.width,u.canvas.height):C.rectfill(0,0,u.canvas.width,u.canvas.height,e)},rect(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e-h,~~t-h,~~a+2*h,~~n+2*h,l),C.stroke(i)},rectfill(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e,~~t,~~a,~~n,l),C.fill(i)},circ(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,i),C.stroke(n)},circfill(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,i),C.fill(n)},line(e,t,a,n,i){u.beginPath();let l=.5*(0!==h&&~~e==~~a),r=.5*(0!==h&&~~t==~~n);u.moveTo(~~e+l,~~t+r),u.lineTo(~~a+l,~~n+r),C.stroke(i)},linewidth(e){u.lineWidth=~~e,h=.5*(0!=~~e%2)},linedash(e,t=0){u.setLineDash(e),u.lineDashOffset=t},text(e,t,a,n=3,i="normal"){u.font=`${i} ${y}px ${b}`,u.fillStyle=E[~~n%E.length],u.fillText(a,~~e,~~t)},textfont(e){b=e},textsize(e){y=e},textalign(e,t){e&&(u.textAlign=e),t&&(u.textBaseline=t)},image(e,t,a){u.drawImage(a,~~e,~~t)},paint(e,t,a,n={}){let i=n.canvas||new OffscreenCanvas(1,1),l=n.scale||1,r=u;if(i.width=e*l,i.height=t*l,(u=i.getContext("2d")).scale(l,l),Array.isArray(a)){let e=0,t=0;for(let n of(u.imageSmoothingEnabled=!1,a)){for(let a of n)" "!==a&&"."!==a&&C.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(u);return u=r,i.transferToImageBitmap()},ctx:e=>(e&&(u=e),u),push:()=>u.save(),pop:()=>u.restore(),translate:(e,t)=>u.translate(~~e,~~t),scale:(e,t)=>u.scale(e,t||e),rotate:e=>u.rotate(e),alpha(e){u.globalAlpha=C.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){u.fillStyle=E[~~e%E.length],t?u.fill(t):u.fill()},stroke(e,t){u.strokeStyle=E[~~e%E.length],t?u.stroke(t):u.stroke()},clip(e){u.clip(e)},sfx:(e,t=0,n=1)=>!(a.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||z,(0!==t||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+t),s.apply(0,e),e),volume(e){a.zzfxV=e},canvas:()=>d,use(e,t={}){f?S(e,t):c.push([e,t])},listen:(e,t)=>(T[e=e.toLowerCase()]=T[e]||new Set,T[e].add(t),()=>T&&T[e].delete(t)),emit(e,t,a,n,i){f&&(L("before:"+(e=e.toLowerCase()),t,a,n,i),L(e,t,a,n,i),L("after:"+e,t,a,n,i))},pal(t=e){E=t},def(e,n){C[e]=n,t.global&&(a[e]=n)},timescale(e){g=e},framerate(e){w=1/~~e},stat(e){let n={index:e,value:[t,f,x,p,T,E,z,g,a.zzfxV||1,k,y,b][e]};return C.emit("stat",n),n.value},quit(){for(let e of(cancelAnimationFrame(x),x=0,C.emit("quit"),T={},r))e();if(t.global){for(let e in C)delete a[e];delete a.ENGINE}f=!1}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))C[e]=n[e];function I(){let e=t.loop?t.loop:a;for(let t of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))e[t]&&C.listen(t,e[t]);for(let[e,t]of c)S(e,t);if(t.autoscale&&o(a,"resize",A),t.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/p,(t-d.offsetTop)/p],t=new Map,n=(e,a,n)=>{let i={x:a,y:n,startX:a,startY:n,ts:performance.now()};return t.set(e,i),i},i=(e,a,i)=>{let l=t.get(e)||n(e);l.x=a,l.y=i},l=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),s=!1;o(d,"mousedown",t=>{if(0===t.button){r(t);let[a,i]=e(t.pageX,t.pageY);C.emit("tap",a,i,0),n(0,a,i),s=!0}}),o(d,"mouseup",a=>{if(0===a.button){r(a);let n=t.get(0),[i,o]=e(a.pageX,a.pageY);l(n)&&C.emit("tapped",n.startX,n.startY,0),C.emit("untap",i,o,0),t.delete(0),s=!1}}),o(d,"mousemove",t=>{r(t);let[a,n]=e(t.pageX,t.pageY);C.def("MX",a),C.def("MY",n),s&&(C.emit("tapping",a,n,0),i(0,a,n))}),o(d,"touchstart",t=>{for(let a of(r(t),t.changedTouches)){let[t,i]=e(a.pageX,a.pageY);C.emit("tap",t,i,a.identifier+1),n(a.identifier+1,t,i)}}),o(d,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,n]=e(a.pageX,a.pageY);C.emit("tapping",t,n,a.identifier+1),i(a.identifier+1,t,n)}});let f=e=>{r(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,n]of t)a.includes(e)||(l(n)&&C.emit("tapped",n.startX,n.startY,e),C.emit("untap",n.x,n.y,e),t.delete(e))};o(d,"touchend",f),o(d,"touchcancel",f),o(a,"blur",()=>{for(let[e,a]of(s=!1,t))C.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,n=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0;o(a,"keydown",a=>{let n=a.key.toLowerCase();e.has(n)||(e.add(n),t.add(n))}),o(a,"keyup",t=>{e.delete(t.key.toLowerCase())}),o(a,"blur",()=>e.clear()),C.listen("after:update",()=>t.clear()),C.def("iskeydown",t=>n(e,t)),C.def("iskeypressed",e=>n(t,e))}f=!0,C.emit("init",C),m=performance.now(),x=l(P)}function P(e){let a=0;if(t.animate){for(v+=n.min(.1,(e-m)/1e3),m=e;v>=w;)a++,C.emit("update",w*g,a),C.def("T",C.T+w*g),v-=w;x&&(x=l(P))}else a=1;a&&(C.textalign("start","top"),C.emit("draw"))}function A(){let e=t.width||a.innerWidth,i=t.height||t.width||a.innerHeight;C.def("W",d.width=e),C.def("H",d.height=i),t.autoscale&&(d.style.display||(d.style.display="block",d.style.margin="auto"),p=n.min(a.innerWidth/C.W,a.innerHeight/C.H),p=(t.pixelart?~~p:p)||1,d.style.width=C.W*p+"px",d.style.height=C.H*p+"px"),(!t.antialias||t.pixelart)&&(u.imageSmoothingEnabled=!1,d.style.imageRendering="pixelated"),C.emit("resized",p),C.cls(0),t.animate||l(P)}function L(e,t,a,n,i){if(T[e])for(let l of T[e])l(t,a,n,i)}function S(e,t){let a=e(C,t);for(let e in a)C.def(e,a[e])}if(t.global){if(a.ENGINE)throw Error("two global litecanvas detected");Object.assign(a,C),a.ENGINE=C}return u=(d=(d="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),o(d,"click",()=>a.focus()),d.style="",A(),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?o(a,"DOMContentLoaded",()=>l(I)):l(I),C}})();
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.85.1",
|
|
4
4
|
"description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and P5/Processing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Luiz Bills <luizbills@pm.me>",
|
|
7
7
|
"contributors": [],
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@litecanvas/jsdom-extras": "^1.1.0",
|
|
10
|
-
"@swc/core": "^1.12.
|
|
10
|
+
"@swc/core": "^1.12.7",
|
|
11
11
|
"@types/jsdom": "^21.1.7",
|
|
12
12
|
"ava": "^6.4.0",
|
|
13
13
|
"esbuild": "^0.25.5",
|
|
14
14
|
"gzip-size": "^7.0.0",
|
|
15
15
|
"jsdom": "^26.1.0",
|
|
16
|
-
"prettier": "^3.6.
|
|
16
|
+
"prettier": "^3.6.2",
|
|
17
17
|
"tap-min": "^3.0.0"
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://litecanvas.github.io/about.html",
|
package/src/index.js
CHANGED
|
@@ -74,21 +74,15 @@ export default function litecanvas(settings = {}) {
|
|
|
74
74
|
_colors = defaultPalette,
|
|
75
75
|
/** @type {number[]} */
|
|
76
76
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
77
|
+
/** @type {string} */
|
|
78
|
+
_coreEvents = 'init,update,draw,tap,untap,tapping,tapped,resized',
|
|
79
|
+
/** @type {string} list of functions copied from `Math` module*/
|
|
80
|
+
_mathFunctions =
|
|
81
|
+
'PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp',
|
|
77
82
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* @type {Object<string,Set<Function>>}
|
|
83
|
+
* @type {Object<string,Set<Function>>} game event listeners
|
|
81
84
|
*/
|
|
82
|
-
|
|
83
|
-
init: null,
|
|
84
|
-
update: null,
|
|
85
|
-
draw: null,
|
|
86
|
-
resized: null,
|
|
87
|
-
tap: null,
|
|
88
|
-
untap: null,
|
|
89
|
-
tapping: null,
|
|
90
|
-
tapped: null,
|
|
91
|
-
}
|
|
85
|
+
_eventListeners = {}
|
|
92
86
|
|
|
93
87
|
/** @type {Omit<LitecanvasInstance,'PI'|'sin'|'cos'|'atan2'|'hypot'|'tan'|'abs'|'ceil'|'floor'|'trunc'|'min'|'max'|'pow'|'sqrt'|'sign'|'exp'|'iskeydown'|'iskeypressed'>} */
|
|
94
88
|
const instance = {
|
|
@@ -659,11 +653,11 @@ export default function litecanvas(settings = {}) {
|
|
|
659
653
|
'paint: 3rd param must be a function or array'
|
|
660
654
|
)
|
|
661
655
|
DEV: assert(
|
|
662
|
-
(options &&
|
|
656
|
+
(options && null == options.scale) || isNumber(options.scale),
|
|
663
657
|
'paint: 4th param (options.scale) must be a number'
|
|
664
658
|
)
|
|
665
659
|
DEV: assert(
|
|
666
|
-
(options &&
|
|
660
|
+
(options && null == options.canvas) || options.canvas instanceof OffscreenCanvas,
|
|
667
661
|
'paint: 4th param (options.canvas) must be an OffscreenCanvas'
|
|
668
662
|
)
|
|
669
663
|
|
|
@@ -956,11 +950,11 @@ export default function litecanvas(settings = {}) {
|
|
|
956
950
|
|
|
957
951
|
eventName = eventName.toLowerCase()
|
|
958
952
|
|
|
959
|
-
|
|
960
|
-
|
|
953
|
+
_eventListeners[eventName] = _eventListeners[eventName] || new Set()
|
|
954
|
+
_eventListeners[eventName].add(callback)
|
|
961
955
|
|
|
962
956
|
// return a function to remove this event listener
|
|
963
|
-
return () =>
|
|
957
|
+
return () => _eventListeners && _eventListeners[eventName].delete(callback)
|
|
964
958
|
},
|
|
965
959
|
|
|
966
960
|
/**
|
|
@@ -1063,7 +1057,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1063
1057
|
// 3
|
|
1064
1058
|
_scale,
|
|
1065
1059
|
// 4
|
|
1066
|
-
|
|
1060
|
+
_eventListeners,
|
|
1067
1061
|
// 5
|
|
1068
1062
|
_colors,
|
|
1069
1063
|
// 6
|
|
@@ -1101,14 +1095,14 @@ export default function litecanvas(settings = {}) {
|
|
|
1101
1095
|
// emit "quit" event to manual clean ups
|
|
1102
1096
|
instance.emit('quit')
|
|
1103
1097
|
|
|
1098
|
+
// clear all engine event listeners
|
|
1099
|
+
_eventListeners = {}
|
|
1100
|
+
|
|
1104
1101
|
// clear all browser event listeners
|
|
1105
1102
|
for (const removeListener of _browserEventListeners) {
|
|
1106
1103
|
removeListener()
|
|
1107
1104
|
}
|
|
1108
1105
|
|
|
1109
|
-
// clear all engine event listeners
|
|
1110
|
-
_events = {}
|
|
1111
|
-
|
|
1112
1106
|
// maybe clear global context
|
|
1113
1107
|
if (settings.global) {
|
|
1114
1108
|
for (const key in instance) {
|
|
@@ -1124,7 +1118,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1124
1118
|
}
|
|
1125
1119
|
|
|
1126
1120
|
// prettier-ignore
|
|
1127
|
-
for (const k of
|
|
1121
|
+
for (const k of _mathFunctions.split(',')) {
|
|
1128
1122
|
// import native Math functions
|
|
1129
1123
|
instance[k] = math[k]
|
|
1130
1124
|
}
|
|
@@ -1132,7 +1126,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1132
1126
|
function init() {
|
|
1133
1127
|
// setup default event listeners
|
|
1134
1128
|
const source = settings.loop ? settings.loop : root
|
|
1135
|
-
for (const event
|
|
1129
|
+
for (const event of _coreEvents.split(',')) {
|
|
1136
1130
|
if (source[event]) instance.listen(event, source[event])
|
|
1137
1131
|
}
|
|
1138
1132
|
|
|
@@ -1441,17 +1435,19 @@ export default function litecanvas(settings = {}) {
|
|
|
1441
1435
|
}
|
|
1442
1436
|
|
|
1443
1437
|
function setupCanvas() {
|
|
1444
|
-
if (settings.canvas) {
|
|
1445
|
-
DEV: assert(
|
|
1446
|
-
'string' === typeof settings.canvas,
|
|
1447
|
-
'Litecanvas\' option "canvas" should be a string (a selector)'
|
|
1448
|
-
)
|
|
1438
|
+
if ('string' === typeof settings.canvas) {
|
|
1449
1439
|
_canvas = document.querySelector(settings.canvas)
|
|
1440
|
+
DEV: assert(null != _canvas, 'Litecanvas\' option "canvas" is an invalid CSS selector')
|
|
1441
|
+
} else {
|
|
1442
|
+
_canvas = settings.canvas
|
|
1450
1443
|
}
|
|
1451
1444
|
|
|
1452
1445
|
_canvas = _canvas || document.createElement('canvas')
|
|
1453
1446
|
|
|
1454
|
-
DEV: assert(
|
|
1447
|
+
DEV: assert(
|
|
1448
|
+
'CANVAS' === _canvas.tagName,
|
|
1449
|
+
'Litecanvas\' option "canvas" should be a canvas element or string (CSS selector)'
|
|
1450
|
+
)
|
|
1455
1451
|
|
|
1456
1452
|
_ctx = _canvas.getContext('2d')
|
|
1457
1453
|
|
|
@@ -1525,8 +1521,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1525
1521
|
* @param {*} arg4
|
|
1526
1522
|
*/
|
|
1527
1523
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1528
|
-
if (!
|
|
1529
|
-
for (const callback of
|
|
1524
|
+
if (!_eventListeners[eventName]) return
|
|
1525
|
+
for (const callback of _eventListeners[eventName]) {
|
|
1530
1526
|
callback(arg1, arg2, arg3, arg4)
|
|
1531
1527
|
}
|
|
1532
1528
|
}
|
package/types/types.d.ts
CHANGED
|
@@ -578,7 +578,7 @@ type LitecanvasOptions = {
|
|
|
578
578
|
/**
|
|
579
579
|
* Used to specify the selector of a custom canvas element
|
|
580
580
|
*/
|
|
581
|
-
canvas?: string
|
|
581
|
+
canvas?: HTMLCanvasElement | string
|
|
582
582
|
/**
|
|
583
583
|
* If `true` (default) scales the canvas to fill the screen, but preserving the aspect ratio.
|
|
584
584
|
* Only works if a game screen width was specified.
|
|
@@ -592,7 +592,6 @@ type LitecanvasOptions = {
|
|
|
592
592
|
* If `false` (default), disable the canvas antialias.
|
|
593
593
|
*/
|
|
594
594
|
antialias?: boolean
|
|
595
|
-
|
|
596
595
|
/**
|
|
597
596
|
* If `true` (default), all methods and properties of the engine will be exposed to the global scope (window).
|
|
598
597
|
*/
|