litecanvas 0.205.0 → 0.206.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 +23 -21
- package/dist/dist.js +22 -14
- package/dist/dist.min.js +1 -1
- package/package.json +3 -3
- package/src/index.js +31 -22
- package/src/version.js +1 -1
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.206.0";
|
|
119
119
|
function litecanvas(settings = {}) {
|
|
120
120
|
const root = window,
|
|
121
121
|
math = Math,
|
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
};
|
|
148
148
|
settings = Object.assign(defaults, settings);
|
|
149
149
|
let _initialized = false,
|
|
150
|
-
_paused
|
|
150
|
+
_paused,
|
|
151
151
|
_canvas,
|
|
152
152
|
_canvasScale = 1,
|
|
153
153
|
_ctx,
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
_lastFrameTime,
|
|
157
157
|
_fpsInterval = 1e3 / 60,
|
|
158
158
|
_accumulated,
|
|
159
|
-
_rafid,
|
|
159
|
+
_rafid = 0,
|
|
160
160
|
_defaultTextColor = 3,
|
|
161
161
|
_fontFamily = "sans-serif",
|
|
162
162
|
_fontSize = 20,
|
|
@@ -165,8 +165,6 @@
|
|
|
165
165
|
_colorPalette = defaultPalette,
|
|
166
166
|
_colorPaletteState = [],
|
|
167
167
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
168
|
-
_mathFunctions =
|
|
169
|
-
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp",
|
|
170
168
|
_eventListeners = {};
|
|
171
169
|
const instance = {
|
|
172
170
|
W: 0,
|
|
@@ -1033,7 +1031,7 @@
|
|
|
1033
1031
|
pause() {
|
|
1034
1032
|
if (!_paused) {
|
|
1035
1033
|
_paused = true;
|
|
1036
|
-
cancelAnimationFrame(_rafid);
|
|
1034
|
+
_rafid = ~~cancelAnimationFrame(_rafid);
|
|
1037
1035
|
instance.emit("paused");
|
|
1038
1036
|
}
|
|
1039
1037
|
},
|
|
@@ -1044,10 +1042,8 @@
|
|
|
1044
1042
|
'resume() cannot be called before the "init" event and neither after the quit() function',
|
|
1045
1043
|
);
|
|
1046
1044
|
if (_initialized && _paused) {
|
|
1045
|
+
startGameLoop();
|
|
1047
1046
|
_paused = false;
|
|
1048
|
-
_accumulated = _fpsInterval;
|
|
1049
|
-
_lastFrameTime = perf.now();
|
|
1050
|
-
_rafid = raf(drawFrame);
|
|
1051
1047
|
instance.emit("resumed");
|
|
1052
1048
|
}
|
|
1053
1049
|
},
|
|
@@ -1073,9 +1069,18 @@
|
|
|
1073
1069
|
);
|
|
1074
1070
|
},
|
|
1075
1071
|
};
|
|
1076
|
-
|
|
1072
|
+
const mathProps =
|
|
1073
|
+
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp";
|
|
1074
|
+
for (const k of mathProps.split(",")) {
|
|
1077
1075
|
instance[k] = math[k];
|
|
1078
1076
|
}
|
|
1077
|
+
function startGameLoop() {
|
|
1078
|
+
if (!_rafid) {
|
|
1079
|
+
_accumulated = 0;
|
|
1080
|
+
_lastFrameTime = perf.now();
|
|
1081
|
+
_rafid = raf(drawFrame);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1079
1084
|
function init() {
|
|
1080
1085
|
if (settings.autoscale) {
|
|
1081
1086
|
on(root, "resize", resizeCanvas);
|
|
@@ -1216,8 +1221,10 @@
|
|
|
1216
1221
|
instance.def("lastkey", () => _lastKey);
|
|
1217
1222
|
}
|
|
1218
1223
|
_initialized = true;
|
|
1219
|
-
instance.resume();
|
|
1220
1224
|
instance.emit("init", instance);
|
|
1225
|
+
if (!_paused) {
|
|
1226
|
+
startGameLoop();
|
|
1227
|
+
}
|
|
1221
1228
|
}
|
|
1222
1229
|
function drawFrame() {
|
|
1223
1230
|
_rafid = raf(drawFrame);
|
|
@@ -1237,18 +1244,13 @@
|
|
|
1237
1244
|
instance.emit("draw", _ctx);
|
|
1238
1245
|
if (updated > 1) {
|
|
1239
1246
|
_accumulated = 0;
|
|
1240
|
-
DEV: console.warn(
|
|
1241
|
-
loggerPrefix +
|
|
1242
|
-
"the last frame updated " +
|
|
1243
|
-
updated +
|
|
1244
|
-
" times. This can drop the FPS if it keeps happening.",
|
|
1245
|
-
);
|
|
1246
1247
|
}
|
|
1247
1248
|
}
|
|
1248
1249
|
}
|
|
1249
1250
|
function setupCanvas() {
|
|
1251
|
+
const d = document;
|
|
1250
1252
|
if ("string" === typeof settings.canvas) {
|
|
1251
|
-
_canvas =
|
|
1253
|
+
_canvas = d.querySelector(settings.canvas);
|
|
1252
1254
|
DEV: assert(
|
|
1253
1255
|
null != _canvas,
|
|
1254
1256
|
loggerPrefix +
|
|
@@ -1257,7 +1259,7 @@
|
|
|
1257
1259
|
} else {
|
|
1258
1260
|
_canvas = settings.canvas;
|
|
1259
1261
|
}
|
|
1260
|
-
_canvas = _canvas ||
|
|
1262
|
+
_canvas = _canvas || d.createElement("canvas");
|
|
1261
1263
|
DEV: assert(
|
|
1262
1264
|
_canvas instanceof HTMLElement && "CANVAS" === _canvas.tagName,
|
|
1263
1265
|
loggerPrefix +
|
|
@@ -1267,7 +1269,7 @@
|
|
|
1267
1269
|
on(_canvas, "click", () => focus());
|
|
1268
1270
|
resizeCanvas();
|
|
1269
1271
|
if (!_canvas.parentNode) {
|
|
1270
|
-
|
|
1272
|
+
d.body.appendChild(_canvas);
|
|
1271
1273
|
}
|
|
1272
1274
|
_canvas.style.imageRendering = "pixelated";
|
|
1273
1275
|
_canvas.oncontextmenu = () => false;
|
|
@@ -1351,7 +1353,7 @@
|
|
|
1351
1353
|
instance.listen(eventName, settings.loop[eventName]);
|
|
1352
1354
|
}
|
|
1353
1355
|
}
|
|
1354
|
-
|
|
1356
|
+
raf(init);
|
|
1355
1357
|
return instance;
|
|
1356
1358
|
}
|
|
1357
1359
|
window.litecanvas = litecanvas;
|
package/dist/dist.js
CHANGED
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
};
|
|
144
144
|
settings = Object.assign(defaults, settings);
|
|
145
145
|
let _initialized = false,
|
|
146
|
-
_paused
|
|
146
|
+
_paused,
|
|
147
147
|
_canvas,
|
|
148
148
|
_canvasScale = 1,
|
|
149
149
|
_ctx,
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
_lastFrameTime,
|
|
153
153
|
_fpsInterval = 1e3 / 60,
|
|
154
154
|
_accumulated,
|
|
155
|
-
_rafid,
|
|
155
|
+
_rafid = 0,
|
|
156
156
|
_defaultTextColor = 3,
|
|
157
157
|
_fontFamily = "sans-serif",
|
|
158
158
|
_fontSize = 20,
|
|
@@ -161,8 +161,6 @@
|
|
|
161
161
|
_colorPalette = defaultPalette,
|
|
162
162
|
_colorPaletteState = [],
|
|
163
163
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
164
|
-
_mathFunctions =
|
|
165
|
-
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp",
|
|
166
164
|
_eventListeners = {};
|
|
167
165
|
const instance = {
|
|
168
166
|
W: 0,
|
|
@@ -482,16 +480,14 @@
|
|
|
482
480
|
pause() {
|
|
483
481
|
if (!_paused) {
|
|
484
482
|
_paused = true;
|
|
485
|
-
cancelAnimationFrame(_rafid);
|
|
483
|
+
_rafid = ~~cancelAnimationFrame(_rafid);
|
|
486
484
|
instance.emit("paused");
|
|
487
485
|
}
|
|
488
486
|
},
|
|
489
487
|
resume() {
|
|
490
488
|
if (_initialized && _paused) {
|
|
489
|
+
startGameLoop();
|
|
491
490
|
_paused = false;
|
|
492
|
-
_accumulated = _fpsInterval;
|
|
493
|
-
_lastFrameTime = perf.now();
|
|
494
|
-
_rafid = raf(drawFrame);
|
|
495
491
|
instance.emit("resumed");
|
|
496
492
|
}
|
|
497
493
|
},
|
|
@@ -514,9 +510,18 @@
|
|
|
514
510
|
}
|
|
515
511
|
},
|
|
516
512
|
};
|
|
517
|
-
|
|
513
|
+
const mathProps =
|
|
514
|
+
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp";
|
|
515
|
+
for (const k of mathProps.split(",")) {
|
|
518
516
|
instance[k] = math[k];
|
|
519
517
|
}
|
|
518
|
+
function startGameLoop() {
|
|
519
|
+
if (!_rafid) {
|
|
520
|
+
_accumulated = 0;
|
|
521
|
+
_lastFrameTime = perf.now();
|
|
522
|
+
_rafid = raf(drawFrame);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
520
525
|
function init() {
|
|
521
526
|
if (settings.autoscale) {
|
|
522
527
|
on(root, "resize", resizeCanvas);
|
|
@@ -647,8 +652,10 @@
|
|
|
647
652
|
instance.def("lastkey", () => _lastKey);
|
|
648
653
|
}
|
|
649
654
|
_initialized = true;
|
|
650
|
-
instance.resume();
|
|
651
655
|
instance.emit("init", instance);
|
|
656
|
+
if (!_paused) {
|
|
657
|
+
startGameLoop();
|
|
658
|
+
}
|
|
652
659
|
}
|
|
653
660
|
function drawFrame() {
|
|
654
661
|
_rafid = raf(drawFrame);
|
|
@@ -672,17 +679,18 @@
|
|
|
672
679
|
}
|
|
673
680
|
}
|
|
674
681
|
function setupCanvas() {
|
|
682
|
+
const d = document;
|
|
675
683
|
if ("string" === typeof settings.canvas) {
|
|
676
|
-
_canvas =
|
|
684
|
+
_canvas = d.querySelector(settings.canvas);
|
|
677
685
|
} else {
|
|
678
686
|
_canvas = settings.canvas;
|
|
679
687
|
}
|
|
680
|
-
_canvas = _canvas ||
|
|
688
|
+
_canvas = _canvas || d.createElement("canvas");
|
|
681
689
|
_ctx = _canvas.getContext("2d");
|
|
682
690
|
on(_canvas, "click", () => focus());
|
|
683
691
|
resizeCanvas();
|
|
684
692
|
if (!_canvas.parentNode) {
|
|
685
|
-
|
|
693
|
+
d.body.appendChild(_canvas);
|
|
686
694
|
}
|
|
687
695
|
_canvas.style.imageRendering = "pixelated";
|
|
688
696
|
_canvas.oncontextmenu = () => false;
|
|
@@ -742,7 +750,7 @@
|
|
|
742
750
|
instance.listen(eventName, settings.loop[eventName]);
|
|
743
751
|
}
|
|
744
752
|
}
|
|
745
|
-
|
|
753
|
+
raf(init);
|
|
746
754
|
return instance;
|
|
747
755
|
}
|
|
748
756
|
window.litecanvas = litecanvas;
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let l,a=window,
|
|
1
|
+
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let l,a,n=window,i=Math,o=performance,r=2*i.PI,s=requestAnimationFrame,f=[],c=(e,t,l)=>{e.addEventListener(t,l,!1),f.push(()=>e.removeEventListener(t,l,!1))},d=(l=new AudioContext,n.zzfxV=1,(e=1,t=.05,a=220,i=0,o=0,r=.1,s=0,f=1,c=0,d=0,p=0,u=0,h=0,m=0,g=0,w=0,v=0,x=1,y=0,b=0,k=0)=>{let E=Math,P=2*E.PI,T=c*=500*P/44100/44100,z=a*=(1-t+2*t*E.random(t=[]))*P/44100,C=0,I=0,L=0,D=1,A=0,S=0,H=0,M=k<0?-1:1,N=P*M*k*2/44100,W=E.cos(N),q=E.sin,B=q(N)/4,V=1+B,O=-2*W/V,R=(1-B)/V,F=(1+M*W)/2/V,G=-(M+W)/V,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,v*=44100,d*=500*P/85766121e6,g*=P/44100,p*=P/44100,u*=44100,h=44100*h|0,e*=.3*n.zzfxV,M=i+y+o+r+v|0;L<M;t[L++]=H*e)++S%(100*w|0)||(H=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),H=(h?1-b+b*q(P*L/h):1)*(H<0?-1:1)*E.abs(H)**f*(L<i?L/i:L<i+y?1-(L-i)/y*(1-x):L<i+y+o?x:L<M-v?(M-L-v)/r*x:0),H=v?H/2+(v>L?0:(L<M-v?1:(M-L)/v)*t[L-v|0]/2/e):H,k&&(H=j=F*X+G*(X=Y)+F*(Y=H)-R*$-O*($=j))),C+=(N=(a+=c+=d)*E.cos(g*I++))+N*m*q(L**5),D&&++D>u&&(a+=p,z+=p,D=0),!h||++A%h||(a=z,c=T,D=D||1);(e=l.createBuffer(1,M,44100)).getChannelData(0).set(t),(a=l.createBufferSource()).buffer=e,a.connect(l.destination),a.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let p=!1,u,h,m=1,g,w=.5,v=1,x,y=1e3/60,b,k=0,E=3,P="sans-serif",T=20,z=1.2,C=Date.now(),I=e,L=[],D=[.5,0,1750,,,.3,1,,,,600,.1],A={},S={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:r,HALF_PI:r/4,lerp:(e,t,l)=>e+l*(t-e),deg2rad:e=>i.PI/180*e,rad2deg:e=>180/i.PI*e,round:(e,t=0)=>{if(!t)return i.round(e);let l=10**t;return i.round(e*l)/l},clamp:(e,t,l)=>e<t?t:e>l?l:e,dist:(e,t,l,a)=>i.hypot(l-e,a-t),wrap:(e,t,l)=>e-(l-t)*i.floor((e-t)/(l-t)),map(e,t,l,a,n,i){let o=(e-t)/(l-t)*(n-a)+a;return i?S.clamp(o,a,n):o},norm:(e,t,l)=>S.map(e,t,l,0,1),rand:(e=0,t=1)=>(C=(1664525*C+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>~~S.rand(e,t+1),rseed(e){C=~~e},cls(e){null==e?g.clearRect(0,0,S.W,S.H):S.rectfill(0,0,S.W,S.H,e)},rect(e,t,l,a,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e-w,~~t-w,~~l+2*w,~~a+2*w,i),S.stroke(n)},rectfill(e,t,l,a,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e,~~t,~~l,~~a,i),S.fill(n)},circ(e,t,l,a){g.beginPath(),g.arc(~~e,~~t,~~l,0,r),S.stroke(a)},circfill(e,t,l,a){g.beginPath(),g.arc(~~e,~~t,~~l,0,r),S.fill(a)},oval(e,t,l,a,n){g.beginPath(),g.ellipse(~~e,~~t,~~l,~~a,0,0,r),S.stroke(n)},ovalfill(e,t,l,a,n){g.beginPath(),g.ellipse(~~e,~~t,~~l,~~a,0,0,r),S.fill(n)},shape(e){g.beginPath();for(let t=0;t<e.length;t+=2)0===t?g.moveTo(~~e[t],~~e[t+1]):g.lineTo(~~e[t],~~e[t+1]);g.lineTo(~~e[0],~~e[1])},line(e,t,l,a,n){g.beginPath();let i=.5*(0!==w&&~~e==~~l),o=.5*(0!==w&&~~t==~~a);g.moveTo(~~e+i,~~t+o),g.lineTo(~~l+i,~~a+o),S.stroke(n)},linewidth(e){g.lineWidth=~~e,w=.5*(0!=~~e%2)},linedash(e,t=0){g.setLineDash(e),g.lineDashOffset=t},text(e,t,l,a=E,n="normal"){g.font=`${n} ${T}px ${P}`,g.fillStyle=q(a);let i=(""+l).split("\n");for(let l=0;l<i.length;l++)g.fillText(i[l],~~e,~~t+T*z*l)},textgap(e){z=e},textfont(e){P=e},textsize(e){T=e},textalign(e,t){e&&(g.textAlign=e),t&&(g.textBaseline=t)},image(e,t,l){g.drawImage(l,~~e,~~t)},spr(e,t,l){let a=l.trim().split("\n");for(let l=0;l<a.length;l++){let n=a[l].trim();for(let a=0;a<n.length;a++){let i=n[a];"."!==i&&" "!==i&&S.rectfill(e+a,t+l,1,1,parseInt(i,36)||0)}}},paint(e,t,l,a={}){let n=a.canvas||new OffscreenCanvas(1,1),i=a.scale||1,o=g;return n.width=e*i,n.height=t*i,(g=n.getContext("2d")).scale(i,i),l(g),g=o,n.transferToImageBitmap()},ctx:e=>(e&&(g=e),g),push(){g.save()},pop(){g.restore()},translate(e,t){g.translate(~~e,~~t)},scale(e,t=e){g.scale(e,t)},rotate(e){g.rotate(e)},alpha(e){g.globalAlpha=S.clamp(e,0,1)},fill(e){g.fillStyle=q(e),g.fill()},stroke(e){g.strokeStyle=q(e),g.stroke()},clip(e){g.beginPath(),e(g),g.clip()},sfx:(e,t=0,l=1)=>!!n.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||D,(0!==t||1!==l)&&((e=e.slice())[0]=l*(e[0]||1),e[10]=~~e[10]+t),d.apply(0,e),e),volume(e){n.zzfxV=e},canvas:()=>h,use(e,t={}){var l=e,a=t;let n=l(S,a);for(let e in n)S.def(e,n[e])},listen:(e,t)=>{A[e=e.toLowerCase()]=A[e]||new Set,A[e].add(t)},unlisten:(e,t)=>{A[e=e.toLowerCase()]&&A[e].delete(t)},emit:(e,l,a,i,o)=>(p&&(W("before:"+(e=e.toLowerCase()),l,a,i,o),t.loop||n[e]===S[e]||"function"!=typeof n[e]||n[e](l,a,i,o),W(e,l,a,i,o),W("after:"+e,l,a,i,o)),l),pal(t,l=3){I=t||e,L=[],E=l,S.emit("pal",I,E)},palc(e,t){null==e?L=[]:L[e]=t},def(e,l){S[e]=l,t.global&&(n[e]=l)},timescale(e){v=e},framerate(e){y=1e3/~~e},stat:e=>[t,p,y/1e3,m,A,I,D,v,n.zzfxV,C,T,P,L,z][e],pause(){u||(u=!0,k=~~cancelAnimationFrame(k),S.emit("paused"))},resume(){p&&u&&(H(),u=!1,S.emit("resumed"))},ispaused:()=>u,quit(){for(let e of(S.emit("quit"),S.pause(),p=!1,A={},f))e();if(t.global){for(let e in S)delete n[e];delete n.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))S[e]=i[e];function H(){k||(b=0,x=o.now(),k=s(M))}function M(){k=s(M);let e=o.now(),t=0,l=e-x;for(x=e,b+=l<100?l:y;b>=y;){t++,b-=y;let e=y/1e3*v;S.emit("update",e,t),S.def("T",S.T+e)}t&&(S.emit("draw",g),t>1&&(b=0))}function N(){let e=t.width>0?t.width:innerWidth,l=t.width>0?t.height||t.width:innerHeight;if(S.def("W",e),S.def("H",l),h.width=e,h.height=l,t.autoscale){let a=+t.autoscale;h.style.display||(h.style.display="block",h.style.margin="auto"),m=i.min(innerWidth/e,innerHeight/l),m=a>1&&m>a?a:m,h.style.width=e*m+"px",h.style.height=l*m+"px"}g.imageSmoothingEnabled=!1,S.textalign("start","top"),S.emit("resized",m)}function W(e,t,l,a,n){if(A[e])for(let i of A[e])i(t,l,a,n)}function q(e){return I[~~(L[e]??e)%I.length]}if(t.global){if(n.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(n,S),n.ENGINE=S}if(a=document,g=(h=(h="string"==typeof t.canvas?a.querySelector(t.canvas):t.canvas)||a.createElement("canvas")).getContext("2d"),c(h,"click",()=>focus()),N(),h.parentNode||a.body.appendChild(h),h.style.imageRendering="pixelated",h.oncontextmenu=()=>!1,t.loop)for(let e in t.loop)t.loop[e]&&S.listen(e,t.loop[e]);return s(function(){if(t.autoscale&&c(n,"resize",N),t.tapEvents){let e=e=>[(e.pageX-h.offsetLeft)/m,(e.pageY-h.offsetTop)/m],t=new Map,l=(e,l,a)=>{let n={x:l,y:a,xi:l,yi:a,t:o.now()};return t.set(e,n),n},a=(e,a,n)=>{let i=t.get(e)||l(e);i.x=a,i.y=n},i=e=>e&&o.now()-e.t<=300,r=!1;c(h,"mousedown",t=>{if(0===t.button){t.preventDefault();let[a,n]=e(t);S.emit("tap",a,n,0),l(0,a,n),r=!0}}),c(h,"mouseup",l=>{if(0===l.button){l.preventDefault();let a=t.get(0),[n,o]=e(l);i(a)&&S.emit("tapped",a.xi,a.yi,0),S.emit("untap",n,o,0),t.delete(0),r=!1}}),c(n,"mousemove",t=>{t.preventDefault();let[l,n]=e(t);S.def("MX",l),S.def("MY",n),r&&(S.emit("tapping",l,n,0),a(0,l,n))}),c(h,"touchstart",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,n]=e(a);S.emit("tap",t,n,a.identifier+1),l(a.identifier+1,t,n)}}),c(h,"touchmove",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);S.emit("tapping",t,n,l.identifier+1),a(l.identifier+1,t,n)}});let s=e=>{e.preventDefault();let l=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)l.push(t.identifier+1);for(let[e,a]of t)l.includes(e)||(i(a)&&S.emit("tapped",a.xi,a.yi,e),S.emit("untap",a.x,a.y,e),t.delete(e))};c(h,"touchend",s),c(h,"touchcancel",s),c(n,"blur",()=>{for(let[e,l]of(r=!1,t))S.emit("untap",l.x,l.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,l=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,a="";c(n,"keydown",l=>{let n=l.key.toLowerCase();e.has(n)||(e.add(n),t.add(n),a=" "===n?"space":n)}),c(n,"keyup",t=>{e.delete(t.key.toLowerCase())}),c(n,"blur",()=>e.clear()),S.listen("after:update",()=>t.clear()),S.def("iskeydown",t=>l(e,t)),S.def("iskeypressed",e=>l(t,e)),S.def("lastkey",()=>a)}p=!0,S.emit("init",S),u||H()}),S}})();
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.206.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>",
|
|
7
7
|
"contributors": [],
|
|
8
|
-
"homepage": "https://litecanvas.
|
|
8
|
+
"homepage": "https://litecanvas.js.org",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "git+https://github.com/litecanvas/game-engine.git"
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@happy-dom/global-registrator": "^20.9.0",
|
|
36
36
|
"@size-limit/preset-small-lib": "^12.1.0",
|
|
37
|
-
"@swc/core": "^1.15.
|
|
37
|
+
"@swc/core": "^1.15.32",
|
|
38
38
|
"ava": "^7.0.0",
|
|
39
39
|
"esbuild": "^0.27.7",
|
|
40
40
|
"genversion": "^3.2.0",
|
package/src/index.js
CHANGED
|
@@ -51,7 +51,7 @@ export default function litecanvas(settings = {}) {
|
|
|
51
51
|
let /** @type {boolean} */
|
|
52
52
|
_initialized = false,
|
|
53
53
|
/** @type {boolean} */
|
|
54
|
-
_paused
|
|
54
|
+
_paused,
|
|
55
55
|
/** @type {HTMLCanvasElement} _canvas */
|
|
56
56
|
_canvas,
|
|
57
57
|
/** @type {number} */
|
|
@@ -68,8 +68,8 @@ export default function litecanvas(settings = {}) {
|
|
|
68
68
|
_fpsInterval = 1000 / 60,
|
|
69
69
|
/** @type {number} */
|
|
70
70
|
_accumulated,
|
|
71
|
-
/** @type {number
|
|
72
|
-
_rafid,
|
|
71
|
+
/** @type {number} */
|
|
72
|
+
_rafid = 0,
|
|
73
73
|
/** @type {number} */
|
|
74
74
|
_defaultTextColor = 3,
|
|
75
75
|
/** @type {string} */
|
|
@@ -86,9 +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} list of functions copied from `Math` module */
|
|
90
|
-
_mathFunctions =
|
|
91
|
-
'PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp',
|
|
92
89
|
/**
|
|
93
90
|
* @type {Object<string,Set<Function>>} game event listeners
|
|
94
91
|
*/
|
|
@@ -1343,7 +1340,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1343
1340
|
pause() {
|
|
1344
1341
|
if (!_paused) {
|
|
1345
1342
|
_paused = true
|
|
1346
|
-
cancelAnimationFrame(_rafid)
|
|
1343
|
+
_rafid = ~~cancelAnimationFrame(_rafid)
|
|
1347
1344
|
instance.emit('paused')
|
|
1348
1345
|
}
|
|
1349
1346
|
},
|
|
@@ -1358,10 +1355,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1358
1355
|
'resume() cannot be called before the "init" event and neither after the quit() function'
|
|
1359
1356
|
)
|
|
1360
1357
|
if (_initialized && _paused) {
|
|
1358
|
+
startGameLoop()
|
|
1361
1359
|
_paused = false
|
|
1362
|
-
_accumulated = _fpsInterval
|
|
1363
|
-
_lastFrameTime = perf.now()
|
|
1364
|
-
_rafid = raf(drawFrame)
|
|
1365
1360
|
instance.emit('resumed')
|
|
1366
1361
|
}
|
|
1367
1362
|
},
|
|
@@ -1409,11 +1404,20 @@ export default function litecanvas(settings = {}) {
|
|
|
1409
1404
|
}
|
|
1410
1405
|
|
|
1411
1406
|
// prettier-ignore
|
|
1412
|
-
|
|
1407
|
+
const mathProps = 'PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp'
|
|
1408
|
+
for (const k of mathProps.split(',')) {
|
|
1413
1409
|
// import native Math functions
|
|
1414
1410
|
instance[k] = math[k]
|
|
1415
1411
|
}
|
|
1416
1412
|
|
|
1413
|
+
function startGameLoop() {
|
|
1414
|
+
if (!_rafid) {
|
|
1415
|
+
_accumulated = 0
|
|
1416
|
+
_lastFrameTime = perf.now()
|
|
1417
|
+
_rafid = raf(drawFrame)
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1417
1421
|
function init() {
|
|
1418
1422
|
// listen window resize event when "autoscale" is enabled
|
|
1419
1423
|
if (settings.autoscale) {
|
|
@@ -1600,6 +1604,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1600
1604
|
})
|
|
1601
1605
|
}
|
|
1602
1606
|
|
|
1607
|
+
// default keyboard handler
|
|
1603
1608
|
if (settings.keyboardEvents) {
|
|
1604
1609
|
/** @type {Set<string>} */
|
|
1605
1610
|
const _keysDown = new Set()
|
|
@@ -1677,8 +1682,10 @@ export default function litecanvas(settings = {}) {
|
|
|
1677
1682
|
|
|
1678
1683
|
// start the engine
|
|
1679
1684
|
_initialized = true
|
|
1680
|
-
instance.resume()
|
|
1681
1685
|
instance.emit('init', instance)
|
|
1686
|
+
if (!_paused) {
|
|
1687
|
+
startGameLoop()
|
|
1688
|
+
}
|
|
1682
1689
|
}
|
|
1683
1690
|
|
|
1684
1691
|
function drawFrame() {
|
|
@@ -1703,22 +1710,24 @@ export default function litecanvas(settings = {}) {
|
|
|
1703
1710
|
}
|
|
1704
1711
|
|
|
1705
1712
|
if (updated) {
|
|
1713
|
+
// draws only when an update happens.
|
|
1706
1714
|
instance.emit('draw', _ctx)
|
|
1715
|
+
|
|
1716
|
+
// sometimes the FPS locks at a value below 60
|
|
1717
|
+
// and does not go back up, even with a very simple logic.
|
|
1718
|
+
// One solution I found was to reset the variable that
|
|
1719
|
+
// accumulates time between frames, when multiple updates occur.
|
|
1707
1720
|
if (updated > 1) {
|
|
1708
1721
|
_accumulated = 0
|
|
1709
|
-
DEV: console.warn(
|
|
1710
|
-
loggerPrefix +
|
|
1711
|
-
'the last frame updated ' +
|
|
1712
|
-
updated +
|
|
1713
|
-
' times. This can drop the FPS if it keeps happening.'
|
|
1714
|
-
)
|
|
1715
1722
|
}
|
|
1716
1723
|
}
|
|
1717
1724
|
}
|
|
1718
1725
|
|
|
1719
1726
|
function setupCanvas() {
|
|
1727
|
+
const d = document
|
|
1728
|
+
|
|
1720
1729
|
if ('string' === typeof settings.canvas) {
|
|
1721
|
-
_canvas =
|
|
1730
|
+
_canvas = d.querySelector(settings.canvas)
|
|
1722
1731
|
DEV: assert(
|
|
1723
1732
|
null != _canvas,
|
|
1724
1733
|
loggerPrefix + 'litecanvas() option "canvas" is an invalid CSS selector'
|
|
@@ -1727,7 +1736,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1727
1736
|
_canvas = settings.canvas
|
|
1728
1737
|
}
|
|
1729
1738
|
|
|
1730
|
-
_canvas = _canvas ||
|
|
1739
|
+
_canvas = _canvas || d.createElement('canvas')
|
|
1731
1740
|
|
|
1732
1741
|
DEV: assert(
|
|
1733
1742
|
_canvas instanceof HTMLElement && 'CANVAS' === _canvas.tagName,
|
|
@@ -1742,7 +1751,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1742
1751
|
resizeCanvas()
|
|
1743
1752
|
|
|
1744
1753
|
if (!_canvas.parentNode) {
|
|
1745
|
-
|
|
1754
|
+
d.body.appendChild(_canvas)
|
|
1746
1755
|
}
|
|
1747
1756
|
|
|
1748
1757
|
_canvas.style.imageRendering = 'pixelated'
|
|
@@ -1863,7 +1872,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1863
1872
|
}
|
|
1864
1873
|
|
|
1865
1874
|
// init the engine (async)
|
|
1866
|
-
|
|
1875
|
+
raf(init)
|
|
1867
1876
|
|
|
1868
1877
|
return instance
|
|
1869
1878
|
}
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.206.0'
|