litecanvas 0.81.2 → 0.83.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 -35
- package/dist/dist.js +26 -35
- package/dist/dist.min.js +1 -1
- package/package.json +2 -2
- package/src/index.js +45 -48
- package/types/types.d.ts +3 -7
package/dist/dist.dev.js
CHANGED
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
canvas: null,
|
|
45
45
|
global: true,
|
|
46
46
|
loop: null,
|
|
47
|
-
pauseOnBlur: true,
|
|
48
47
|
tapEvents: true,
|
|
49
48
|
keyboardEvents: true,
|
|
50
49
|
animate: true
|
|
@@ -855,6 +854,7 @@
|
|
|
855
854
|
"function" === typeof callback,
|
|
856
855
|
"listen: 2nd param must be a function"
|
|
857
856
|
);
|
|
857
|
+
eventName = eventName.toLowerCase();
|
|
858
858
|
_events[eventName] = _events[eventName] || /* @__PURE__ */ new Set();
|
|
859
859
|
_events[eventName].add(callback);
|
|
860
860
|
return () => _events[eventName].delete(callback);
|
|
@@ -874,6 +874,7 @@
|
|
|
874
874
|
"emit: 1st param must be a string"
|
|
875
875
|
);
|
|
876
876
|
if (_initialized) {
|
|
877
|
+
eventName = eventName.toLowerCase();
|
|
877
878
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
878
879
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
879
880
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
@@ -975,13 +976,16 @@
|
|
|
975
976
|
// 11
|
|
976
977
|
_fontFamily
|
|
977
978
|
];
|
|
978
|
-
|
|
979
|
+
const data = { index: n, value: list[n] };
|
|
980
|
+
instance.emit("stat", data);
|
|
981
|
+
return data.value;
|
|
979
982
|
},
|
|
980
983
|
/**
|
|
981
984
|
* Stops the litecanvas instance and remove all event listeners.
|
|
982
985
|
*/
|
|
983
986
|
quit() {
|
|
984
987
|
cancelAnimationFrame(_rafid);
|
|
988
|
+
_rafid = 0;
|
|
985
989
|
instance.emit("quit");
|
|
986
990
|
for (const removeListener of _browserEventListeners) {
|
|
987
991
|
removeListener();
|
|
@@ -1142,25 +1146,24 @@
|
|
|
1142
1146
|
});
|
|
1143
1147
|
}
|
|
1144
1148
|
if (settings.keyboardEvents) {
|
|
1145
|
-
const toLowerCase = (s) => s.toLowerCase();
|
|
1146
1149
|
const _keysDown = /* @__PURE__ */ new Set();
|
|
1147
1150
|
const _keysPress = /* @__PURE__ */ new Set();
|
|
1148
|
-
const keyCheck = (
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
);
|
|
1151
|
+
const keyCheck = (keySet, key = "") => {
|
|
1152
|
+
key = key.toLowerCase();
|
|
1153
|
+
return !key ? keySet.size > 0 : keySet.has("space" === key ? " " : key);
|
|
1152
1154
|
};
|
|
1153
1155
|
on(root, "keydown", (event) => {
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1156
|
+
const key = event.key.toLowerCase();
|
|
1157
|
+
if (!_keysDown.has(key)) {
|
|
1158
|
+
_keysDown.add(key);
|
|
1159
|
+
_keysPress.add(key);
|
|
1157
1160
|
}
|
|
1158
1161
|
});
|
|
1159
1162
|
on(root, "keyup", (event) => {
|
|
1160
|
-
_keysDown.delete(
|
|
1163
|
+
_keysDown.delete(event.key.toLowerCase());
|
|
1161
1164
|
});
|
|
1162
1165
|
on(root, "blur", () => _keysDown.clear());
|
|
1163
|
-
instance.listen("after:
|
|
1166
|
+
instance.listen("after:update", () => _keysPress.clear());
|
|
1164
1167
|
instance.def(
|
|
1165
1168
|
"iskeydown",
|
|
1166
1169
|
/**
|
|
@@ -1196,17 +1199,6 @@
|
|
|
1196
1199
|
}
|
|
1197
1200
|
);
|
|
1198
1201
|
}
|
|
1199
|
-
if (settings.pauseOnBlur) {
|
|
1200
|
-
on(root, "blur", () => {
|
|
1201
|
-
_rafid = cancelAnimationFrame(_rafid);
|
|
1202
|
-
});
|
|
1203
|
-
on(root, "focus", () => {
|
|
1204
|
-
if (!_rafid) {
|
|
1205
|
-
_accumulated = 0;
|
|
1206
|
-
_rafid = raf(drawFrame);
|
|
1207
|
-
}
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
1202
|
_initialized = true;
|
|
1211
1203
|
instance.emit("init", instance);
|
|
1212
1204
|
_lastFrameTime = performance.now();
|
|
@@ -1216,17 +1208,18 @@
|
|
|
1216
1208
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1217
1209
|
_lastFrameTime = now;
|
|
1218
1210
|
if (settings.animate) {
|
|
1219
|
-
_rafid = raf(drawFrame);
|
|
1220
1211
|
if (frameTime > 0.3) {
|
|
1221
|
-
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1212
|
+
console.warn("skipping too long frame");
|
|
1213
|
+
} else {
|
|
1214
|
+
_accumulated += frameTime;
|
|
1215
|
+
while (_accumulated >= _deltaTime) {
|
|
1216
|
+
updated++;
|
|
1217
|
+
instance.emit("update", _deltaTime * _timeScale, updated);
|
|
1218
|
+
instance.def("T", instance.T + _deltaTime * _timeScale);
|
|
1219
|
+
_accumulated -= _deltaTime;
|
|
1220
|
+
}
|
|
1229
1221
|
}
|
|
1222
|
+
if (_rafid) _rafid = raf(drawFrame);
|
|
1230
1223
|
} else {
|
|
1231
1224
|
updated = 1;
|
|
1232
1225
|
}
|
|
@@ -1236,11 +1229,14 @@
|
|
|
1236
1229
|
}
|
|
1237
1230
|
}
|
|
1238
1231
|
function setupCanvas() {
|
|
1239
|
-
if (
|
|
1232
|
+
if (settings.canvas) {
|
|
1233
|
+
DEV: assert(
|
|
1234
|
+
"string" === typeof settings.canvas,
|
|
1235
|
+
`Litecanvas' option "canvas" should be a string (a selector)`
|
|
1236
|
+
);
|
|
1240
1237
|
_canvas = document.querySelector(settings.canvas);
|
|
1241
|
-
} else {
|
|
1242
|
-
_canvas = settings.canvas || document.createElement("canvas");
|
|
1243
1238
|
}
|
|
1239
|
+
_canvas = _canvas || document.createElement("canvas");
|
|
1244
1240
|
DEV: assert(
|
|
1245
1241
|
_canvas && _canvas.tagName === "CANVAS",
|
|
1246
1242
|
"Invalid canvas element"
|
package/dist/dist.js
CHANGED
|
@@ -39,7 +39,6 @@
|
|
|
39
39
|
canvas: null,
|
|
40
40
|
global: true,
|
|
41
41
|
loop: null,
|
|
42
|
-
pauseOnBlur: true,
|
|
43
42
|
tapEvents: true,
|
|
44
43
|
keyboardEvents: true,
|
|
45
44
|
animate: true
|
|
@@ -611,6 +610,7 @@
|
|
|
611
610
|
* @returns {Function} a function to remove the listener
|
|
612
611
|
*/
|
|
613
612
|
listen(eventName, callback) {
|
|
613
|
+
eventName = eventName.toLowerCase();
|
|
614
614
|
_events[eventName] = _events[eventName] || /* @__PURE__ */ new Set();
|
|
615
615
|
_events[eventName].add(callback);
|
|
616
616
|
return () => _events[eventName].delete(callback);
|
|
@@ -626,6 +626,7 @@
|
|
|
626
626
|
*/
|
|
627
627
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
628
628
|
if (_initialized) {
|
|
629
|
+
eventName = eventName.toLowerCase();
|
|
629
630
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
630
631
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
631
632
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
@@ -702,13 +703,16 @@
|
|
|
702
703
|
// 11
|
|
703
704
|
_fontFamily
|
|
704
705
|
];
|
|
705
|
-
|
|
706
|
+
const data = { index: n, value: list[n] };
|
|
707
|
+
instance.emit("stat", data);
|
|
708
|
+
return data.value;
|
|
706
709
|
},
|
|
707
710
|
/**
|
|
708
711
|
* Stops the litecanvas instance and remove all event listeners.
|
|
709
712
|
*/
|
|
710
713
|
quit() {
|
|
711
714
|
cancelAnimationFrame(_rafid);
|
|
715
|
+
_rafid = 0;
|
|
712
716
|
instance.emit("quit");
|
|
713
717
|
for (const removeListener of _browserEventListeners) {
|
|
714
718
|
removeListener();
|
|
@@ -869,25 +873,24 @@
|
|
|
869
873
|
});
|
|
870
874
|
}
|
|
871
875
|
if (settings.keyboardEvents) {
|
|
872
|
-
const toLowerCase = (s) => s.toLowerCase();
|
|
873
876
|
const _keysDown = /* @__PURE__ */ new Set();
|
|
874
877
|
const _keysPress = /* @__PURE__ */ new Set();
|
|
875
|
-
const keyCheck = (
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
);
|
|
878
|
+
const keyCheck = (keySet, key = "") => {
|
|
879
|
+
key = key.toLowerCase();
|
|
880
|
+
return !key ? keySet.size > 0 : keySet.has("space" === key ? " " : key);
|
|
879
881
|
};
|
|
880
882
|
on(root, "keydown", (event) => {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
883
|
+
const key = event.key.toLowerCase();
|
|
884
|
+
if (!_keysDown.has(key)) {
|
|
885
|
+
_keysDown.add(key);
|
|
886
|
+
_keysPress.add(key);
|
|
884
887
|
}
|
|
885
888
|
});
|
|
886
889
|
on(root, "keyup", (event) => {
|
|
887
|
-
_keysDown.delete(
|
|
890
|
+
_keysDown.delete(event.key.toLowerCase());
|
|
888
891
|
});
|
|
889
892
|
on(root, "blur", () => _keysDown.clear());
|
|
890
|
-
instance.listen("after:
|
|
893
|
+
instance.listen("after:update", () => _keysPress.clear());
|
|
891
894
|
instance.def(
|
|
892
895
|
"iskeydown",
|
|
893
896
|
/**
|
|
@@ -915,17 +918,6 @@
|
|
|
915
918
|
}
|
|
916
919
|
);
|
|
917
920
|
}
|
|
918
|
-
if (settings.pauseOnBlur) {
|
|
919
|
-
on(root, "blur", () => {
|
|
920
|
-
_rafid = cancelAnimationFrame(_rafid);
|
|
921
|
-
});
|
|
922
|
-
on(root, "focus", () => {
|
|
923
|
-
if (!_rafid) {
|
|
924
|
-
_accumulated = 0;
|
|
925
|
-
_rafid = raf(drawFrame);
|
|
926
|
-
}
|
|
927
|
-
});
|
|
928
|
-
}
|
|
929
921
|
_initialized = true;
|
|
930
922
|
instance.emit("init", instance);
|
|
931
923
|
_lastFrameTime = performance.now();
|
|
@@ -935,17 +927,17 @@
|
|
|
935
927
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
936
928
|
_lastFrameTime = now;
|
|
937
929
|
if (settings.animate) {
|
|
938
|
-
_rafid = raf(drawFrame);
|
|
939
930
|
if (frameTime > 0.3) {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
931
|
+
} else {
|
|
932
|
+
_accumulated += frameTime;
|
|
933
|
+
while (_accumulated >= _deltaTime) {
|
|
934
|
+
updated++;
|
|
935
|
+
instance.emit("update", _deltaTime * _timeScale, updated);
|
|
936
|
+
instance.def("T", instance.T + _deltaTime * _timeScale);
|
|
937
|
+
_accumulated -= _deltaTime;
|
|
938
|
+
}
|
|
948
939
|
}
|
|
940
|
+
if (_rafid) _rafid = raf(drawFrame);
|
|
949
941
|
} else {
|
|
950
942
|
updated = 1;
|
|
951
943
|
}
|
|
@@ -955,11 +947,10 @@
|
|
|
955
947
|
}
|
|
956
948
|
}
|
|
957
949
|
function setupCanvas() {
|
|
958
|
-
if (
|
|
950
|
+
if (settings.canvas) {
|
|
959
951
|
_canvas = document.querySelector(settings.canvas);
|
|
960
|
-
} else {
|
|
961
|
-
_canvas = settings.canvas || document.createElement("canvas");
|
|
962
952
|
}
|
|
953
|
+
_canvas = _canvas || document.createElement("canvas");
|
|
963
954
|
instance.def("CANVAS", _canvas);
|
|
964
955
|
_ctx = _canvas.getContext("2d");
|
|
965
956
|
on(_canvas, "click", () => root.focus());
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,
|
|
1
|
+
(()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,o=.1,r=0,s=1,f=0,c=0,d=0,p=0,u=0,h=0,g=0,m=0,w=0,b=1,v=0,x=0,y=0)=>{let C=Math,k=2*C.PI,E=f*=500*k/44100/44100,T=l*=(1-a+2*a*C.random(a=[]))*k/44100,z=0,A=0,I=0,P=1,S=0,X=0,Y=0,L=y<0?-1:1,M=k*L*y*2/44100,N=C.cos(M),H=C.sin,W=H(M)/4,D=1+W,F=-2*N/D,V=(1-W)/D,q=(1+L*N)/2/D,B=-(L+N)/D,O=0,R=0,G=0,$=0;for(n=44100*n+9,v*=44100,i*=44100,o*=44100,w*=44100,c*=500*k/85766121e6,g*=k/44100,d*=k/44100,p*=44100,u=44100*u|0,t*=.3*(globalThis.zzfxV||1),L=n+v+i+o+w|0;I<L;a[I++]=Y*t)++X%(100*m|0)||(Y=r?1<r?2<r?3<r?H(z*z):C.max(C.min(C.tan(z),1),-1):1-(2*z/k%2+2)%2:1-4*C.abs(C.round(z/k)-z/k):H(z),Y=(u?1-x+x*H(k*I/u):1)*(Y<0?-1:1)*C.abs(Y)**s*(I<n?I/n:I<n+v?1-(I-n)/v*(1-b):I<n+v+i?b:I<L-w?(L-I-w)/o*b:0),Y=w?Y/2+(w>I?0:(I<L-w?1:(L-I)/w)*a[I-w|0]/2/t):Y,y&&(Y=$=q*O+B*(O=R)+q*(R=Y)-V*G-F*(G=$))),z+=(M=(l+=f+=c)*C.cos(g*A++))+M*h*H(I**5),P&&++P>p&&(l+=d,T+=d,P=0),!u||++S%u||(l=T,f=E,P=P||1);(t=e.createBuffer(1,L,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,c=[],d,p=1,u,h=.5,g=1,m,w=1/60,b=0,v,x="sans-serif",y=20,C=Date.now(),k=a,E=[.5,0,1750,,,.3,1,,,,600,.1],T={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},z={CANVAS:null,W:0,H:0,T:0,CX:0,CY:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:n.PI/2,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,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?z.clamp(o,l,n):o},norm:(e,t,a)=>z.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(C=(1664525*C+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(z.rand(e,t+1)),rseed(e){C=~~e},cls(e){null==e?u.clearRect(0,0,u.canvas.width,u.canvas.height):z.rectfill(0,0,u.canvas.width,u.canvas.height,e)},rect(e,t,a,l,n,i){u.beginPath(),u[i?"roundRect":"rect"](~~e-h,~~t-h,~~a+2*h,~~l+2*h,i),z.stroke(n)},rectfill(e,t,a,l,n,i){u.beginPath(),u[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),z.fill(n)},circ(e,t,a,l){u.beginPath(),u.arc(~~e,~~t,~~a,0,i),z.stroke(l)},circfill(e,t,a,l){u.beginPath(),u.arc(~~e,~~t,~~a,0,i),z.fill(l)},line(e,t,a,l,n){u.beginPath();let i=.5*(0!==h&&~~e==~~a),o=.5*(0!==h&&~~t==~~l);u.moveTo(~~e+i,~~t+o),u.lineTo(~~a+i,~~l+o),z.stroke(n)},linewidth(e){u.lineWidth=~~e,h=.5*(0!=~~e%2)},linedash(e,t=0){u.setLineDash(e),u.lineDashOffset=t},text(e,t,a,l=3,n="normal"){u.font=`${n} ${y}px ${x}`,u.fillStyle=k[~~l%k.length],u.fillText(a,~~e,~~t)},textfont(e){x=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,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=u;if(n.width=e*i,n.height=t*i,(u=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(u.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&z.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(u);return u=o,n.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=z.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){u.fillStyle=k[~~e%k.length],t?u.fill(t):u.fill()},stroke(e,t){u.strokeStyle=k[~~e%k.length],t?u.stroke(t):u.stroke()},clip(e){u.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||E,(0!==a||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){l.zzfxV=e},use(e,t={}){f?X(e,t):c.push([e,t])},listen:(e,t)=>(T[e=e.toLowerCase()]=T[e]||new Set,T[e].add(t),()=>T[e].delete(t)),emit(e,t,a,l,n){f&&(S("before:"+(e=e.toLowerCase()),t,a,l,n),S(e,t,a,l,n),S("after:"+e,t,a,l,n))},pal(e=a){k=e},def(t,a){z[t]=a,e.global&&(l[t]=a)},timescale(e){g=e},framerate(e){w=1/~~e},stat(t){let a={index:t,value:[e,f,v,p,T,k,E,g,l.zzfxV||1,C,y,x][t]};return z.emit("stat",a),a.value},quit(){for(let e of(cancelAnimationFrame(v),v=0,z.emit("quit"),r))e();if(T={},e.global){for(let e in z)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(","))z[e]=n[e];function A(){let t=e.loop?e.loop:l;for(let e in T)t[e]&&z.listen(e,t[e]);for(let[e,t]of c)X(e,t);if(e.autoscale&&s(l,"resize",P),e.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/p,(t-d.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,startX:a,startY:l,ts:performance.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&performance.now()-e.ts<=300,o=e=>e.preventDefault(),r=!1;s(d,"mousedown",t=>{if(0===t.button){o(t);let[l,n]=e(t.pageX,t.pageY);z.emit("tap",l,n,0),a(0,l,n),r=!0}}),s(d,"mouseup",a=>{if(0===a.button){o(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&z.emit("tapped",l.startX,l.startY,0),z.emit("untap",n,s,0),t.delete(0),r=!1}}),s(d,"mousemove",t=>{o(t);let[a,l]=e(t.pageX,t.pageY);z.def("MX",a),z.def("MY",l),r&&(z.emit("tapping",a,l,0),n(0,a,l))}),s(d,"touchstart",t=>{for(let l of(o(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);z.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(d,"touchmove",t=>{for(let a of(o(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);z.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let f=e=>{o(e);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)||(i(l)&&z.emit("tapped",l.startX,l.startY,e),z.emit("untap",l.x,l.y,e),t.delete(e))};s(d,"touchend",f),s(d,"touchcancel",f),s(l,"blur",()=>{for(let[e,a]of(r=!1,t))z.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0;s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l))}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),z.listen("after:update",()=>t.clear()),z.def("iskeydown",t=>a(e,t)),z.def("iskeypressed",e=>a(t,e))}f=!0,z.emit("init",z),m=performance.now(),v=o(I)}function I(t){let a=0,l=(t-m)/1e3;if(m=t,e.animate){if(l>.3);else for(b+=l;b>=w;)a++,z.emit("update",w*g,a),z.def("T",z.T+w*g),b-=w;v&&(v=o(I))}else a=1;a&&(z.textalign("start","top"),z.emit("draw"))}function P(){let t=e.width||l.innerWidth,a=e.height||e.width||l.innerHeight;z.def("W",d.width=t),z.def("H",d.height=a),z.def("CX",z.W/2),z.def("CY",z.H/2),e.autoscale&&(d.style.display||(d.style.display="block",d.style.margin="auto"),p=n.min(l.innerWidth/z.W,l.innerHeight/z.H),p=(e.pixelart?~~p:p)||1,d.style.width=z.W*p+"px",d.style.height=z.H*p+"px"),(!e.antialias||e.pixelart)&&(u.imageSmoothingEnabled=!1,d.style.imageRendering="pixelated"),z.emit("resized",p),z.cls(0),e.animate||o(I)}function S(e,t,a,l,n){if(T[e])for(let i of T[e])i(t,a,l,n)}function X(e,t){let a=e(z,t);for(let e in a)z.def(e,a[e])}if(e.global){if(l.ENGINE)throw Error("two global litecanvas detected");Object.assign(l,z),l.ENGINE=z}return e.canvas&&(d=document.querySelector(e.canvas)),d=d||document.createElement("canvas"),z.def("CANVAS",d),u=d.getContext("2d"),s(d,"click",()=>l.focus()),d.style="",P(),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(A)):o(A),z}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.83.0",
|
|
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>",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"main": "src/index.js",
|
|
25
25
|
"types": "types/index.d.ts",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"test": "
|
|
27
|
+
"test": "ava",
|
|
28
28
|
"dev:test": "ava --watch",
|
|
29
29
|
"dev": "esbuild src/web.js --bundle --watch --outfile=dist/dist.dev.js --servedir=.",
|
|
30
30
|
"build": "node script/build.js",
|
package/src/index.js
CHANGED
|
@@ -35,7 +35,6 @@ export default function litecanvas(settings = {}) {
|
|
|
35
35
|
canvas: null,
|
|
36
36
|
global: true,
|
|
37
37
|
loop: null,
|
|
38
|
-
pauseOnBlur: true,
|
|
39
38
|
tapEvents: true,
|
|
40
39
|
keyboardEvents: true,
|
|
41
40
|
animate: true,
|
|
@@ -1014,6 +1013,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1014
1013
|
'listen: 2nd param must be a function'
|
|
1015
1014
|
)
|
|
1016
1015
|
|
|
1016
|
+
eventName = eventName.toLowerCase()
|
|
1017
|
+
|
|
1017
1018
|
_events[eventName] = _events[eventName] || new Set()
|
|
1018
1019
|
_events[eventName].add(callback)
|
|
1019
1020
|
|
|
@@ -1036,6 +1037,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1036
1037
|
'emit: 1st param must be a string'
|
|
1037
1038
|
)
|
|
1038
1039
|
if (_initialized) {
|
|
1040
|
+
eventName = eventName.toLowerCase()
|
|
1041
|
+
|
|
1039
1042
|
triggerEvent('before:' + eventName, arg1, arg2, arg3, arg4)
|
|
1040
1043
|
triggerEvent(eventName, arg1, arg2, arg3, arg4)
|
|
1041
1044
|
triggerEvent('after:' + eventName, arg1, arg2, arg3, arg4)
|
|
@@ -1146,7 +1149,13 @@ export default function litecanvas(settings = {}) {
|
|
|
1146
1149
|
// 11
|
|
1147
1150
|
_fontFamily,
|
|
1148
1151
|
]
|
|
1149
|
-
|
|
1152
|
+
|
|
1153
|
+
const data = { index: n, value: list[n] }
|
|
1154
|
+
|
|
1155
|
+
// plugins can modify or create stat values
|
|
1156
|
+
instance.emit('stat', data)
|
|
1157
|
+
|
|
1158
|
+
return data.value
|
|
1150
1159
|
},
|
|
1151
1160
|
|
|
1152
1161
|
/**
|
|
@@ -1155,6 +1164,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1155
1164
|
quit() {
|
|
1156
1165
|
// stop the game loop (update & draw)
|
|
1157
1166
|
cancelAnimationFrame(_rafid)
|
|
1167
|
+
_rafid = 0
|
|
1158
1168
|
|
|
1159
1169
|
// emit "quit" event to manual clean ups
|
|
1160
1170
|
instance.emit('quit')
|
|
@@ -1361,8 +1371,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1361
1371
|
}
|
|
1362
1372
|
|
|
1363
1373
|
if (settings.keyboardEvents) {
|
|
1364
|
-
const toLowerCase = (/** @type {string} */ s) => s.toLowerCase()
|
|
1365
|
-
|
|
1366
1374
|
/** @type {Set<string>} */
|
|
1367
1375
|
const _keysDown = new Set()
|
|
1368
1376
|
|
|
@@ -1370,34 +1378,34 @@ export default function litecanvas(settings = {}) {
|
|
|
1370
1378
|
const _keysPress = new Set()
|
|
1371
1379
|
|
|
1372
1380
|
/**
|
|
1373
|
-
* @param {Set<string>}
|
|
1381
|
+
* @param {Set<string>} keySet
|
|
1374
1382
|
* @param {string} [key]
|
|
1375
1383
|
* @returns {boolean}
|
|
1376
1384
|
*/
|
|
1377
|
-
const keyCheck = (
|
|
1385
|
+
const keyCheck = (keySet, key = '') => {
|
|
1386
|
+
key = key.toLowerCase()
|
|
1378
1387
|
return !key
|
|
1379
|
-
?
|
|
1380
|
-
:
|
|
1381
|
-
'space' === toLowerCase(key) ? ' ' : toLowerCase(key)
|
|
1382
|
-
)
|
|
1388
|
+
? keySet.size > 0
|
|
1389
|
+
: keySet.has('space' === key ? ' ' : key)
|
|
1383
1390
|
}
|
|
1384
1391
|
|
|
1385
1392
|
// @ts-ignore
|
|
1386
1393
|
on(root, 'keydown', (/** @type {KeyboardEvent} */ event) => {
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1394
|
+
const key = event.key.toLowerCase()
|
|
1395
|
+
if (!_keysDown.has(key)) {
|
|
1396
|
+
_keysDown.add(key)
|
|
1397
|
+
_keysPress.add(key)
|
|
1390
1398
|
}
|
|
1391
1399
|
})
|
|
1392
1400
|
|
|
1393
1401
|
// @ts-ignore
|
|
1394
1402
|
on(root, 'keyup', (/** @type {KeyboardEvent} */ event) => {
|
|
1395
|
-
_keysDown.delete(
|
|
1403
|
+
_keysDown.delete(event.key.toLowerCase())
|
|
1396
1404
|
})
|
|
1397
1405
|
|
|
1398
1406
|
// @ts-ignore
|
|
1399
1407
|
on(root, 'blur', () => _keysDown.clear())
|
|
1400
|
-
instance.listen('after:
|
|
1408
|
+
instance.listen('after:update', () => _keysPress.clear())
|
|
1401
1409
|
|
|
1402
1410
|
instance.def(
|
|
1403
1411
|
'iskeydown',
|
|
@@ -1436,23 +1444,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1436
1444
|
)
|
|
1437
1445
|
}
|
|
1438
1446
|
|
|
1439
|
-
// listen browser focus/blur events and pause the update/draw loop
|
|
1440
|
-
if (settings.pauseOnBlur) {
|
|
1441
|
-
// @ts-ignore
|
|
1442
|
-
on(root, 'blur', () => {
|
|
1443
|
-
// @ts-ignore
|
|
1444
|
-
_rafid = cancelAnimationFrame(_rafid)
|
|
1445
|
-
})
|
|
1446
|
-
|
|
1447
|
-
// @ts-ignore
|
|
1448
|
-
on(root, 'focus', () => {
|
|
1449
|
-
if (!_rafid) {
|
|
1450
|
-
_accumulated = 0
|
|
1451
|
-
_rafid = raf(drawFrame)
|
|
1452
|
-
}
|
|
1453
|
-
})
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
1447
|
_initialized = true
|
|
1457
1448
|
|
|
1458
1449
|
// start the game loop
|
|
@@ -1472,24 +1463,26 @@ export default function litecanvas(settings = {}) {
|
|
|
1472
1463
|
_lastFrameTime = now
|
|
1473
1464
|
|
|
1474
1465
|
if (settings.animate) {
|
|
1475
|
-
// request the next frame
|
|
1476
|
-
_rafid = raf(drawFrame)
|
|
1477
|
-
|
|
1478
1466
|
if (frameTime > 0.3) {
|
|
1479
|
-
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
_accumulated += frameTime
|
|
1467
|
+
console.warn('skipping too long frame')
|
|
1468
|
+
} else {
|
|
1469
|
+
_accumulated += frameTime
|
|
1483
1470
|
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1471
|
+
while (_accumulated >= _deltaTime) {
|
|
1472
|
+
updated++
|
|
1473
|
+
instance.emit('update', _deltaTime * _timeScale, updated)
|
|
1474
|
+
instance.def('T', instance.T + _deltaTime * _timeScale)
|
|
1475
|
+
_accumulated -= _deltaTime
|
|
1476
|
+
}
|
|
1489
1477
|
}
|
|
1478
|
+
|
|
1479
|
+
// request the next frame
|
|
1480
|
+
// check if the last ID exists, because
|
|
1481
|
+
// quit() delete it (sets to zero)
|
|
1482
|
+
if (_rafid) _rafid = raf(drawFrame)
|
|
1490
1483
|
} else {
|
|
1491
1484
|
// when the canvas is not animated
|
|
1492
|
-
// we
|
|
1485
|
+
// we force one frame when redraws are triggered
|
|
1493
1486
|
updated = 1
|
|
1494
1487
|
}
|
|
1495
1488
|
|
|
@@ -1502,12 +1495,16 @@ export default function litecanvas(settings = {}) {
|
|
|
1502
1495
|
}
|
|
1503
1496
|
|
|
1504
1497
|
function setupCanvas() {
|
|
1505
|
-
if (
|
|
1498
|
+
if (settings.canvas) {
|
|
1499
|
+
DEV: assert(
|
|
1500
|
+
'string' === typeof settings.canvas,
|
|
1501
|
+
'Litecanvas\' option "canvas" should be a string (a selector)'
|
|
1502
|
+
)
|
|
1506
1503
|
_canvas = document.querySelector(settings.canvas)
|
|
1507
|
-
} else {
|
|
1508
|
-
_canvas = settings.canvas || document.createElement('canvas')
|
|
1509
1504
|
}
|
|
1510
1505
|
|
|
1506
|
+
_canvas = _canvas || document.createElement('canvas')
|
|
1507
|
+
|
|
1511
1508
|
DEV: assert(
|
|
1512
1509
|
_canvas && _canvas.tagName === 'CANVAS',
|
|
1513
1510
|
'Invalid canvas element'
|
package/types/types.d.ts
CHANGED
|
@@ -591,10 +591,9 @@ type LitecanvasOptions = {
|
|
|
591
591
|
*/
|
|
592
592
|
height?: number
|
|
593
593
|
/**
|
|
594
|
-
*
|
|
595
|
-
* Default: `true`
|
|
594
|
+
* Used to specify the selector of a custom canvas element
|
|
596
595
|
*/
|
|
597
|
-
|
|
596
|
+
canvas?: string
|
|
598
597
|
/**
|
|
599
598
|
* If `true` (default) scales the canvas to fill the screen, but preserving the aspect ratio.
|
|
600
599
|
* Only works if a game screen width was specified.
|
|
@@ -608,10 +607,7 @@ type LitecanvasOptions = {
|
|
|
608
607
|
* If `false` (default), disable the canvas antialias.
|
|
609
608
|
*/
|
|
610
609
|
antialias?: boolean
|
|
611
|
-
|
|
612
|
-
* Used to specify the selector of a custom canvas element
|
|
613
|
-
*/
|
|
614
|
-
canvas?: string
|
|
610
|
+
|
|
615
611
|
/**
|
|
616
612
|
* If `true` (default), all methods and properties of the engine will be exposed to the global scope (window).
|
|
617
613
|
*/
|