litecanvas 0.84.1 → 0.84.2
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 -10
- package/dist/dist.js +10 -7
- package/dist/dist.min.js +1 -1
- package/package.json +12 -9
- package/src/index.js +27 -22
- package/src/zzfx.js +1 -1
- package/types/index.d.ts +1 -1
- package/types/types.d.ts +2 -2
package/dist/dist.dev.js
CHANGED
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
|
|
34
34
|
// src/index.js
|
|
35
35
|
function litecanvas(settings = {}) {
|
|
36
|
-
const root =
|
|
36
|
+
const root = window, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
|
|
37
37
|
elem.addEventListener(evt, callback, false);
|
|
38
38
|
_browserEventListeners.push(() => elem.removeEventListener(evt, callback, false));
|
|
39
|
-
}, zzfx = setupZzFX(root),
|
|
39
|
+
}, isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
|
|
40
40
|
width: null,
|
|
41
41
|
height: null,
|
|
42
42
|
autoscale: true,
|
|
@@ -556,8 +556,11 @@
|
|
|
556
556
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
557
557
|
*/
|
|
558
558
|
paint(width, height, drawing, options = {}) {
|
|
559
|
-
DEV: assert(isNumber(width), "paint: 1st param must be a number");
|
|
560
|
-
DEV: assert(
|
|
559
|
+
DEV: assert(isNumber(width) && width >= 1, "paint: 1st param must be a positive number");
|
|
560
|
+
DEV: assert(
|
|
561
|
+
isNumber(height) && height >= 1,
|
|
562
|
+
"paint: 2nd param must be a positive number"
|
|
563
|
+
);
|
|
561
564
|
DEV: assert(
|
|
562
565
|
"function" === typeof drawing || Array.isArray(drawing),
|
|
563
566
|
"paint: 3rd param must be a function or array"
|
|
@@ -566,12 +569,16 @@
|
|
|
566
569
|
options && !options.scale || isNumber(options.scale),
|
|
567
570
|
"paint: 4th param (options.scale) must be a number"
|
|
568
571
|
);
|
|
572
|
+
DEV: assert(
|
|
573
|
+
options && !options.canvas || options.canvas instanceof OffscreenCanvas,
|
|
574
|
+
"paint: 4th param (options.canvas) must be an OffscreenCanvas"
|
|
575
|
+
);
|
|
569
576
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
570
577
|
canvas.width = width * scale;
|
|
571
578
|
canvas.height = height * scale;
|
|
572
579
|
_ctx = canvas.getContext("2d");
|
|
573
580
|
_ctx.scale(scale, scale);
|
|
574
|
-
if (drawing
|
|
581
|
+
if (Array.isArray(drawing)) {
|
|
575
582
|
let x = 0, y = 0;
|
|
576
583
|
_ctx.imageSmoothingEnabled = false;
|
|
577
584
|
for (const str of drawing) {
|
|
@@ -748,7 +755,10 @@
|
|
|
748
755
|
);
|
|
749
756
|
DEV: assert(isNumber(pitchSlide), "sfx: 2nd param must be a number");
|
|
750
757
|
DEV: assert(isNumber(volumeFactor), "sfx: 3rd param must be a number");
|
|
751
|
-
if (
|
|
758
|
+
if (
|
|
759
|
+
// @ts-ignore
|
|
760
|
+
root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive
|
|
761
|
+
) {
|
|
752
762
|
return false;
|
|
753
763
|
}
|
|
754
764
|
zzfxParams = zzfxParams || _defaultSound;
|
|
@@ -776,9 +786,7 @@
|
|
|
776
786
|
*
|
|
777
787
|
* @returns {HTMLCanvasElement}
|
|
778
788
|
*/
|
|
779
|
-
canvas()
|
|
780
|
-
return _canvas;
|
|
781
|
-
},
|
|
789
|
+
canvas: () => _canvas,
|
|
782
790
|
/**
|
|
783
791
|
* Prepares a plugin to be loaded
|
|
784
792
|
*
|
|
@@ -887,7 +895,7 @@
|
|
|
887
895
|
* @returns {any}
|
|
888
896
|
*/
|
|
889
897
|
stat(n) {
|
|
890
|
-
DEV: assert(isNumber(n) && n >= 0, "stat: 1st param must be a
|
|
898
|
+
DEV: assert(isNumber(n) && n >= 0, "stat: 1st param must be a number");
|
|
891
899
|
const list = [
|
|
892
900
|
// 0
|
|
893
901
|
settings,
|
|
@@ -906,6 +914,7 @@
|
|
|
906
914
|
// 7
|
|
907
915
|
_timeScale,
|
|
908
916
|
// 8
|
|
917
|
+
// @ts-ignore
|
|
909
918
|
root.zzfxV || 1,
|
|
910
919
|
// 9
|
|
911
920
|
_rngSeed,
|
|
@@ -935,6 +944,7 @@
|
|
|
935
944
|
}
|
|
936
945
|
delete root.ENGINE;
|
|
937
946
|
}
|
|
947
|
+
_initialized = false;
|
|
938
948
|
}
|
|
939
949
|
};
|
|
940
950
|
for (const k of "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(",")) {
|
package/dist/dist.js
CHANGED
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
|
|
29
29
|
// src/index.js
|
|
30
30
|
function litecanvas(settings = {}) {
|
|
31
|
-
const root =
|
|
31
|
+
const root = window, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
|
|
32
32
|
elem.addEventListener(evt, callback, false);
|
|
33
33
|
_browserEventListeners.push(() => elem.removeEventListener(evt, callback, false));
|
|
34
|
-
}, zzfx = setupZzFX(root),
|
|
34
|
+
}, isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
|
|
35
35
|
width: null,
|
|
36
36
|
height: null,
|
|
37
37
|
autoscale: true,
|
|
@@ -417,7 +417,7 @@
|
|
|
417
417
|
canvas.height = height * scale;
|
|
418
418
|
_ctx = canvas.getContext("2d");
|
|
419
419
|
_ctx.scale(scale, scale);
|
|
420
|
-
if (drawing
|
|
420
|
+
if (Array.isArray(drawing)) {
|
|
421
421
|
let x = 0, y = 0;
|
|
422
422
|
_ctx.imageSmoothingEnabled = false;
|
|
423
423
|
for (const str of drawing) {
|
|
@@ -561,7 +561,10 @@
|
|
|
561
561
|
* @see https://github.com/KilledByAPixel/ZzFX
|
|
562
562
|
*/
|
|
563
563
|
sfx(zzfxParams, pitchSlide = 0, volumeFactor = 1) {
|
|
564
|
-
if (
|
|
564
|
+
if (
|
|
565
|
+
// @ts-ignore
|
|
566
|
+
root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive
|
|
567
|
+
) {
|
|
565
568
|
return false;
|
|
566
569
|
}
|
|
567
570
|
zzfxParams = zzfxParams || _defaultSound;
|
|
@@ -588,9 +591,7 @@
|
|
|
588
591
|
*
|
|
589
592
|
* @returns {HTMLCanvasElement}
|
|
590
593
|
*/
|
|
591
|
-
canvas()
|
|
592
|
-
return _canvas;
|
|
593
|
-
},
|
|
594
|
+
canvas: () => _canvas,
|
|
594
595
|
/**
|
|
595
596
|
* Prepares a plugin to be loaded
|
|
596
597
|
*
|
|
@@ -696,6 +697,7 @@
|
|
|
696
697
|
// 7
|
|
697
698
|
_timeScale,
|
|
698
699
|
// 8
|
|
700
|
+
// @ts-ignore
|
|
699
701
|
root.zzfxV || 1,
|
|
700
702
|
// 9
|
|
701
703
|
_rngSeed,
|
|
@@ -725,6 +727,7 @@
|
|
|
725
727
|
}
|
|
726
728
|
delete root.ENGINE;
|
|
727
729
|
}
|
|
730
|
+
_initialized = false;
|
|
728
731
|
}
|
|
729
732
|
};
|
|
730
733
|
for (const k of "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(",")) {
|
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=
|
|
1
|
+
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,n=Math,l=2*n.PI,i=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,l=220,i=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=l*=(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(i=44100*i+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=i+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<i?A/i:A<i+b?1-(A-i)/b*(1-x):A<i+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=(l+=c+=d)*E.cos(m*P++))+D*g*N(A**5),L&&++L>u&&(l+=p,C+=p,L=0),!h||++S%h||(l=C,c=T,L=L||1);(a=t.createBuffer(1,M,44100)).getChannelData(0).set(n),(l=t.createBufferSource()).buffer=a,l.connect(t.destination),l.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={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},C={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:l,HALF_PI:l/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,l,i){let r=(e-t)/(a-t)*(l-n)+n;return i?C.clamp(r,n,l):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,l,i){u.beginPath(),u[i?"roundRect":"rect"](~~e-h,~~t-h,~~a+2*h,~~n+2*h,i),C.stroke(l)},rectfill(e,t,a,n,l,i){u.beginPath(),u[i?"roundRect":"rect"](~~e,~~t,~~a,~~n,i),C.fill(l)},circ(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),C.stroke(n)},circfill(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),C.fill(n)},line(e,t,a,n,l){u.beginPath();let i=.5*(0!==h&&~~e==~~a),r=.5*(0!==h&&~~t==~~n);u.moveTo(~~e+i,~~t+r),u.lineTo(~~a+i,~~n+r),C.stroke(l)},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,l="normal"){u.font=`${l} ${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 l=n.canvas||new OffscreenCanvas(1,1),i=n.scale||1,r=u;if(l.width=e*i,l.height=t*i,(u=l.getContext("2d")).scale(i,i),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,l.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[e].delete(t)),emit(e,t,a,n,l){f&&(L("before:"+(e=e.toLowerCase()),t,a,n,l),L(e,t,a,n,l),L("after:"+e,t,a,n,l))},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"),r))e();if(T={},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 in T)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 l={x:a,y:n,startX:a,startY:n,ts:performance.now()};return t.set(e,l),l},l=(e,a,l)=>{let i=t.get(e)||n(e);i.x=a,i.y=l},i=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,l]=e(t.pageX,t.pageY);C.emit("tap",a,l,0),n(0,a,l),s=!0}}),o(d,"mouseup",a=>{if(0===a.button){r(a);let n=t.get(0),[l,o]=e(a.pageX,a.pageY);i(n)&&C.emit("tapped",n.startX,n.startY,0),C.emit("untap",l,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),l(0,a,n))}),o(d,"touchstart",t=>{for(let a of(r(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);C.emit("tap",t,l,a.identifier+1),n(a.identifier+1,t,l)}}),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),l(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)||(i(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=i(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=i(P))}else a=1;a&&(C.textalign("start","top"),C.emit("draw"))}function A(){let e=t.width||a.innerWidth,l=t.height||t.width||a.innerHeight;C.def("W",d.width=e),C.def("H",d.height=l),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||i(P)}function L(e,t,a,n,l){if(T[e])for(let i of T[e])i(t,a,n,l)}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 t.canvas&&(d=document.querySelector(t.canvas)),u=(d=d||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",()=>i(I)):i(I),C}})();
|
package/package.json
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.84.
|
|
3
|
+
"version": "0.84.2",
|
|
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.6",
|
|
11
|
+
"@types/jsdom": "^21.1.7",
|
|
10
12
|
"ava": "^6.4.0",
|
|
11
13
|
"esbuild": "^0.25.5",
|
|
12
14
|
"gzip-size": "^7.0.0",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"jsdom": "^26.1.0"
|
|
15
|
+
"jsdom": "^26.1.0",
|
|
16
|
+
"prettier": "^3.6.0",
|
|
17
|
+
"tap-min": "^3.0.0"
|
|
17
18
|
},
|
|
18
19
|
"homepage": "https://litecanvas.github.io/about.html",
|
|
19
20
|
"repository": {
|
|
@@ -56,8 +57,10 @@
|
|
|
56
57
|
],
|
|
57
58
|
"ava": {
|
|
58
59
|
"files": [
|
|
59
|
-
"tests
|
|
60
|
-
"!tests/_mocks"
|
|
60
|
+
"tests/**/*.js"
|
|
61
61
|
]
|
|
62
|
-
}
|
|
62
|
+
},
|
|
63
|
+
"trustedDependencies": [
|
|
64
|
+
"@swc/core"
|
|
65
|
+
]
|
|
63
66
|
}
|
package/src/index.js
CHANGED
|
@@ -10,20 +10,20 @@ import { assert } from './dev.js'
|
|
|
10
10
|
* @returns {LitecanvasInstance}
|
|
11
11
|
*/
|
|
12
12
|
export default function litecanvas(settings = {}) {
|
|
13
|
-
const /** @type {
|
|
14
|
-
root =
|
|
13
|
+
const /** @type {Window} */
|
|
14
|
+
root = window,
|
|
15
15
|
math = Math,
|
|
16
16
|
TWO_PI = math.PI * 2,
|
|
17
17
|
raf = requestAnimationFrame,
|
|
18
18
|
/** @type {Function[]} */
|
|
19
19
|
_browserEventListeners = [],
|
|
20
|
-
/** @type {(elem:
|
|
20
|
+
/** @type {(elem: EventTarget, evt: string, callback: (event: Event) => void) => void} */
|
|
21
21
|
on = (elem, evt, callback) => {
|
|
22
22
|
elem.addEventListener(evt, callback, false)
|
|
23
23
|
_browserEventListeners.push(() => elem.removeEventListener(evt, callback, false))
|
|
24
24
|
},
|
|
25
|
-
zzfx = setupZzFX(root),
|
|
26
25
|
isNumber = Number.isFinite,
|
|
26
|
+
zzfx = setupZzFX(root),
|
|
27
27
|
/** @type {LitecanvasOptions} */
|
|
28
28
|
defaults = {
|
|
29
29
|
width: null,
|
|
@@ -649,8 +649,11 @@ export default function litecanvas(settings = {}) {
|
|
|
649
649
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
650
650
|
*/
|
|
651
651
|
paint(width, height, drawing, options = {}) {
|
|
652
|
-
DEV: assert(isNumber(width), 'paint: 1st param must be a number')
|
|
653
|
-
DEV: assert(
|
|
652
|
+
DEV: assert(isNumber(width) && width >= 1, 'paint: 1st param must be a positive number')
|
|
653
|
+
DEV: assert(
|
|
654
|
+
isNumber(height) && height >= 1,
|
|
655
|
+
'paint: 2nd param must be a positive number'
|
|
656
|
+
)
|
|
654
657
|
DEV: assert(
|
|
655
658
|
'function' === typeof drawing || Array.isArray(drawing),
|
|
656
659
|
'paint: 3rd param must be a function or array'
|
|
@@ -659,6 +662,10 @@ export default function litecanvas(settings = {}) {
|
|
|
659
662
|
(options && !options.scale) || isNumber(options.scale),
|
|
660
663
|
'paint: 4th param (options.scale) must be a number'
|
|
661
664
|
)
|
|
665
|
+
DEV: assert(
|
|
666
|
+
(options && !options.canvas) || options.canvas instanceof OffscreenCanvas,
|
|
667
|
+
'paint: 4th param (options.canvas) must be an OffscreenCanvas'
|
|
668
|
+
)
|
|
662
669
|
|
|
663
670
|
const /** @type {OffscreenCanvas} */
|
|
664
671
|
canvas = options.canvas || new OffscreenCanvas(1, 1),
|
|
@@ -667,19 +674,17 @@ export default function litecanvas(settings = {}) {
|
|
|
667
674
|
|
|
668
675
|
canvas.width = width * scale
|
|
669
676
|
canvas.height = height * scale
|
|
670
|
-
_ctx = canvas.getContext('2d')
|
|
671
677
|
|
|
678
|
+
_ctx = canvas.getContext('2d')
|
|
672
679
|
_ctx.scale(scale, scale)
|
|
673
680
|
|
|
674
681
|
// draw pixel art if `draw` is a array
|
|
675
|
-
|
|
676
|
-
if (drawing.push) {
|
|
682
|
+
if (Array.isArray(drawing)) {
|
|
677
683
|
let x = 0,
|
|
678
684
|
y = 0
|
|
679
685
|
|
|
680
686
|
_ctx.imageSmoothingEnabled = false
|
|
681
687
|
|
|
682
|
-
// @ts-ignore
|
|
683
688
|
for (const str of drawing) {
|
|
684
689
|
for (const color of str) {
|
|
685
690
|
if (' ' !== color && '.' !== color) {
|
|
@@ -692,7 +697,6 @@ export default function litecanvas(settings = {}) {
|
|
|
692
697
|
x = 0
|
|
693
698
|
}
|
|
694
699
|
} else {
|
|
695
|
-
// @ts-ignore
|
|
696
700
|
drawing(_ctx)
|
|
697
701
|
}
|
|
698
702
|
|
|
@@ -880,6 +884,7 @@ export default function litecanvas(settings = {}) {
|
|
|
880
884
|
DEV: assert(isNumber(volumeFactor), 'sfx: 3rd param must be a number')
|
|
881
885
|
|
|
882
886
|
if (
|
|
887
|
+
// @ts-ignore
|
|
883
888
|
root.zzfxV <= 0 ||
|
|
884
889
|
(navigator.userActivation && !navigator.userActivation.hasBeenActive)
|
|
885
890
|
) {
|
|
@@ -909,6 +914,7 @@ export default function litecanvas(settings = {}) {
|
|
|
909
914
|
volume(value) {
|
|
910
915
|
DEV: assert(isNumber(value), 'volume: 1st param must be a number')
|
|
911
916
|
|
|
917
|
+
// @ts-ignore
|
|
912
918
|
root.zzfxV = value
|
|
913
919
|
},
|
|
914
920
|
|
|
@@ -918,9 +924,7 @@ export default function litecanvas(settings = {}) {
|
|
|
918
924
|
*
|
|
919
925
|
* @returns {HTMLCanvasElement}
|
|
920
926
|
*/
|
|
921
|
-
canvas()
|
|
922
|
-
return _canvas
|
|
923
|
-
},
|
|
927
|
+
canvas: () => _canvas,
|
|
924
928
|
/**
|
|
925
929
|
* Prepares a plugin to be loaded
|
|
926
930
|
*
|
|
@@ -1047,7 +1051,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1047
1051
|
* @returns {any}
|
|
1048
1052
|
*/
|
|
1049
1053
|
stat(n) {
|
|
1050
|
-
DEV: assert(isNumber(n) && n >= 0, 'stat: 1st param must be a
|
|
1054
|
+
DEV: assert(isNumber(n) && n >= 0, 'stat: 1st param must be a number')
|
|
1051
1055
|
|
|
1052
1056
|
const list = [
|
|
1053
1057
|
// 0
|
|
@@ -1067,6 +1071,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1067
1071
|
// 7
|
|
1068
1072
|
_timeScale,
|
|
1069
1073
|
// 8
|
|
1074
|
+
// @ts-ignore
|
|
1070
1075
|
root.zzfxV || 1,
|
|
1071
1076
|
// 9
|
|
1072
1077
|
_rngSeed,
|
|
@@ -1090,6 +1095,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1090
1095
|
quit() {
|
|
1091
1096
|
// stop the game loop (update & draw)
|
|
1092
1097
|
cancelAnimationFrame(_rafid)
|
|
1098
|
+
|
|
1093
1099
|
_rafid = 0
|
|
1094
1100
|
|
|
1095
1101
|
// emit "quit" event to manual clean ups
|
|
@@ -1108,8 +1114,12 @@ export default function litecanvas(settings = {}) {
|
|
|
1108
1114
|
for (const key in instance) {
|
|
1109
1115
|
delete root[key]
|
|
1110
1116
|
}
|
|
1117
|
+
// @ts-ignore
|
|
1111
1118
|
delete root.ENGINE
|
|
1112
1119
|
}
|
|
1120
|
+
|
|
1121
|
+
// unset that flag
|
|
1122
|
+
_initialized = false
|
|
1113
1123
|
},
|
|
1114
1124
|
}
|
|
1115
1125
|
|
|
@@ -1133,7 +1143,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1133
1143
|
|
|
1134
1144
|
// listen window resize event when "autoscale" is enabled
|
|
1135
1145
|
if (settings.autoscale) {
|
|
1136
|
-
// @ts-ignore
|
|
1137
1146
|
on(root, 'resize', resizeCanvas)
|
|
1138
1147
|
}
|
|
1139
1148
|
|
|
@@ -1306,7 +1315,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1306
1315
|
on(_canvas, 'touchend', _touchEndHandler)
|
|
1307
1316
|
on(_canvas, 'touchcancel', _touchEndHandler)
|
|
1308
1317
|
|
|
1309
|
-
// @ts-ignore
|
|
1310
1318
|
on(root, 'blur', () => {
|
|
1311
1319
|
_pressingMouse = false
|
|
1312
1320
|
for (const [id, tap] of _taps) {
|
|
@@ -1333,7 +1341,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1333
1341
|
return !key ? keySet.size > 0 : keySet.has('space' === key ? ' ' : key)
|
|
1334
1342
|
}
|
|
1335
1343
|
|
|
1336
|
-
// @ts-ignore
|
|
1337
1344
|
on(root, 'keydown', (/** @type {KeyboardEvent} */ event) => {
|
|
1338
1345
|
const key = event.key.toLowerCase()
|
|
1339
1346
|
if (!_keysDown.has(key)) {
|
|
@@ -1342,12 +1349,10 @@ export default function litecanvas(settings = {}) {
|
|
|
1342
1349
|
}
|
|
1343
1350
|
})
|
|
1344
1351
|
|
|
1345
|
-
// @ts-ignore
|
|
1346
1352
|
on(root, 'keyup', (/** @type {KeyboardEvent} */ event) => {
|
|
1347
1353
|
_keysDown.delete(event.key.toLowerCase())
|
|
1348
1354
|
})
|
|
1349
1355
|
|
|
1350
|
-
// @ts-ignore
|
|
1351
1356
|
on(root, 'blur', () => _keysDown.clear())
|
|
1352
1357
|
instance.listen('after:update', () => _keysPress.clear())
|
|
1353
1358
|
|
|
@@ -1521,7 +1526,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1521
1526
|
*/
|
|
1522
1527
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1523
1528
|
if (!_events[eventName]) return
|
|
1524
|
-
// @ts-ignore
|
|
1525
1529
|
for (const callback of _events[eventName]) {
|
|
1526
1530
|
callback(arg1, arg2, arg3, arg4)
|
|
1527
1531
|
}
|
|
@@ -1546,17 +1550,18 @@ export default function litecanvas(settings = {}) {
|
|
|
1546
1550
|
}
|
|
1547
1551
|
|
|
1548
1552
|
if (settings.global) {
|
|
1553
|
+
// @ts-ignore
|
|
1549
1554
|
if (root.ENGINE) {
|
|
1550
1555
|
throw new Error('two global litecanvas detected')
|
|
1551
1556
|
}
|
|
1552
1557
|
Object.assign(root, instance)
|
|
1558
|
+
// @ts-ignore
|
|
1553
1559
|
root.ENGINE = instance
|
|
1554
1560
|
}
|
|
1555
1561
|
|
|
1556
1562
|
setupCanvas()
|
|
1557
1563
|
|
|
1558
1564
|
if ('loading' === document.readyState) {
|
|
1559
|
-
// @ts-ignore
|
|
1560
1565
|
on(root, 'DOMContentLoaded', () => raf(init))
|
|
1561
1566
|
} else {
|
|
1562
1567
|
raf(init)
|
package/src/zzfx.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX
|
|
2
2
|
// prettier-ignore
|
|
3
3
|
/**
|
|
4
|
-
* @param {
|
|
4
|
+
* @param {Window} global
|
|
5
5
|
* @returns {Function} the `zzfx()` function
|
|
6
6
|
*/
|
|
7
7
|
export const setupZzFX = (global) => {
|
package/types/index.d.ts
CHANGED
|
@@ -515,7 +515,7 @@ declare global {
|
|
|
515
515
|
* @param callback the function that is called when the event occurs
|
|
516
516
|
* @returns a function to remove the listener
|
|
517
517
|
*/
|
|
518
|
-
function listen(event: string, callback: Function): Function
|
|
518
|
+
function listen(event: string, callback: Function): Function
|
|
519
519
|
/**
|
|
520
520
|
* Call all listeners attached to a game event
|
|
521
521
|
*
|
package/types/types.d.ts
CHANGED
|
@@ -502,7 +502,7 @@ type LitecanvasInstance = {
|
|
|
502
502
|
* @param callback the function that is called when the event occurs
|
|
503
503
|
* @returns a function to remove the listener
|
|
504
504
|
*/
|
|
505
|
-
listen(event: string, callback: Function): Function
|
|
505
|
+
listen(event: string, callback: Function): Function
|
|
506
506
|
/**
|
|
507
507
|
* Call all listeners attached to a game event
|
|
508
508
|
*
|
|
@@ -645,6 +645,6 @@ type LitecanvasGameLoop = {
|
|
|
645
645
|
tapping?: (tapX: number, tapY: number, tapId: number) => void
|
|
646
646
|
}
|
|
647
647
|
|
|
648
|
-
type drawCallback = (context:
|
|
648
|
+
type drawCallback = (context: OffscreenCanvasRenderingContext2D) => void
|
|
649
649
|
|
|
650
650
|
type pluginCallback = (instance: LitecanvasInstance, config?: any) => any
|