litecanvas 0.206.1 → 0.207.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 +41 -45
- package/dist/dist.js +9 -13
- package/dist/dist.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +49 -52
- package/src/version.js +1 -1
- package/src/zzfx.js +106 -5
package/dist/dist.dev.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
var setupZzFX = (global) => {
|
|
3
|
-
|
|
3
|
+
global.zzfxX = new AudioContext();
|
|
4
4
|
global.zzfxV = 1;
|
|
5
5
|
return (
|
|
6
6
|
i = 1,
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
V *= t / a,
|
|
64
64
|
J *= a,
|
|
65
65
|
h = (a * h) | 0,
|
|
66
|
-
i *= 0.3 *
|
|
66
|
+
i *= 0.3 * zzfxV,
|
|
67
67
|
s = (e + X + P + S + r) | 0;
|
|
68
68
|
f < s;
|
|
69
69
|
d[f++] = o * i
|
|
@@ -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.207.0";
|
|
119
119
|
function litecanvas(settings = {}) {
|
|
120
120
|
const root = window,
|
|
121
121
|
math = Math,
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
TWO_PI = math.PI * 2,
|
|
124
124
|
loggerPrefix = "[Litecanvas] ",
|
|
125
125
|
raf = requestAnimationFrame,
|
|
126
|
+
isNumber = Number.isFinite,
|
|
126
127
|
_browserEventListeners = [],
|
|
127
128
|
on = (elem, evt, callback) => {
|
|
128
129
|
elem.addEventListener(evt, callback, false);
|
|
@@ -133,7 +134,6 @@
|
|
|
133
134
|
lowerCase = (str) => str.toLowerCase(),
|
|
134
135
|
preventDefault = (ev) => ev.preventDefault(),
|
|
135
136
|
beginPath = (c) => c.beginPath(),
|
|
136
|
-
isNumber = Number.isFinite,
|
|
137
137
|
zzfx = setupZzFX(root),
|
|
138
138
|
defaults = {
|
|
139
139
|
width: null,
|
|
@@ -450,102 +450,98 @@
|
|
|
450
450
|
_ctx[radii ? "roundRect" : "rect"](~~x, ~~y, ~~width, ~~height, radii);
|
|
451
451
|
instance.fill(color);
|
|
452
452
|
},
|
|
453
|
-
|
|
453
|
+
oval(x, y, radiusX, radiusY, color) {
|
|
454
454
|
DEV: assert(
|
|
455
455
|
isNumber(x),
|
|
456
|
-
loggerPrefix + "
|
|
456
|
+
loggerPrefix + "oval() 1st param must be a number",
|
|
457
457
|
);
|
|
458
458
|
DEV: assert(
|
|
459
459
|
isNumber(y),
|
|
460
|
-
loggerPrefix + "
|
|
460
|
+
loggerPrefix + "oval() 2nd param must be a number",
|
|
461
461
|
);
|
|
462
462
|
DEV: assert(
|
|
463
|
-
isNumber(
|
|
464
|
-
loggerPrefix + "
|
|
463
|
+
isNumber(radiusX) && radiusX >= 0,
|
|
464
|
+
loggerPrefix + "oval() 3rd param must be a positive number or zero",
|
|
465
|
+
);
|
|
466
|
+
DEV: assert(
|
|
467
|
+
isNumber(radiusY) && radiusY >= 0,
|
|
468
|
+
loggerPrefix + "oval() 4th param must be a positive number or zero",
|
|
465
469
|
);
|
|
466
470
|
DEV: assert(
|
|
467
471
|
null == color || (isNumber(color) && color >= 0),
|
|
468
|
-
loggerPrefix + "
|
|
472
|
+
loggerPrefix + "oval() 5th param must be a positive number or zero",
|
|
469
473
|
);
|
|
470
474
|
beginPath(_ctx);
|
|
471
|
-
_ctx.
|
|
475
|
+
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
472
476
|
instance.stroke(color);
|
|
473
477
|
},
|
|
474
|
-
|
|
478
|
+
ovalfill(x, y, radiusX, radiusY, color) {
|
|
475
479
|
DEV: assert(
|
|
476
480
|
isNumber(x),
|
|
477
|
-
loggerPrefix + "
|
|
481
|
+
loggerPrefix + "ovalfill() 1st param must be a number",
|
|
478
482
|
);
|
|
479
483
|
DEV: assert(
|
|
480
484
|
isNumber(y),
|
|
481
|
-
loggerPrefix + "
|
|
485
|
+
loggerPrefix + "ovalfill() 2nd param must be a number",
|
|
482
486
|
);
|
|
483
487
|
DEV: assert(
|
|
484
|
-
isNumber(
|
|
488
|
+
isNumber(radiusX) && radiusX >= 0,
|
|
485
489
|
loggerPrefix +
|
|
486
|
-
"
|
|
490
|
+
"ovalfill() 3rd param must be a positive number or zero",
|
|
491
|
+
);
|
|
492
|
+
DEV: assert(
|
|
493
|
+
isNumber(radiusY) && radiusY >= 0,
|
|
494
|
+
loggerPrefix +
|
|
495
|
+
"ovalfill() 4th param must be a positive number or zero",
|
|
487
496
|
);
|
|
488
497
|
DEV: assert(
|
|
489
498
|
null == color || (isNumber(color) && color >= 0),
|
|
490
499
|
loggerPrefix +
|
|
491
|
-
"
|
|
500
|
+
"ovalfill() 5th param must be a positive number or zero",
|
|
492
501
|
);
|
|
493
502
|
beginPath(_ctx);
|
|
494
|
-
_ctx.
|
|
503
|
+
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
495
504
|
instance.fill(color);
|
|
496
505
|
},
|
|
497
|
-
|
|
506
|
+
circ(x, y, radius, color) {
|
|
498
507
|
DEV: assert(
|
|
499
508
|
isNumber(x),
|
|
500
|
-
loggerPrefix + "
|
|
509
|
+
loggerPrefix + "circ() 1st param must be a number",
|
|
501
510
|
);
|
|
502
511
|
DEV: assert(
|
|
503
512
|
isNumber(y),
|
|
504
|
-
loggerPrefix + "
|
|
505
|
-
);
|
|
506
|
-
DEV: assert(
|
|
507
|
-
isNumber(radiusX) && radiusX >= 0,
|
|
508
|
-
loggerPrefix + "oval() 3rd param must be a positive number or zero",
|
|
513
|
+
loggerPrefix + "circ() 2nd param must be a number",
|
|
509
514
|
);
|
|
510
515
|
DEV: assert(
|
|
511
|
-
isNumber(
|
|
512
|
-
loggerPrefix + "
|
|
516
|
+
isNumber(radius) && radius >= 0,
|
|
517
|
+
loggerPrefix + "circ() 3rd param must be a positive number or zero",
|
|
513
518
|
);
|
|
514
519
|
DEV: assert(
|
|
515
520
|
null == color || (isNumber(color) && color >= 0),
|
|
516
|
-
loggerPrefix + "
|
|
521
|
+
loggerPrefix + "circ() 4th param must be a positive number or zero",
|
|
517
522
|
);
|
|
518
|
-
|
|
519
|
-
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
520
|
-
instance.stroke(color);
|
|
523
|
+
instance.oval(x, y, radius, radius, color);
|
|
521
524
|
},
|
|
522
|
-
|
|
525
|
+
circfill(x, y, radius, color) {
|
|
523
526
|
DEV: assert(
|
|
524
527
|
isNumber(x),
|
|
525
|
-
loggerPrefix + "
|
|
528
|
+
loggerPrefix + "circfill() 1st param must be a number",
|
|
526
529
|
);
|
|
527
530
|
DEV: assert(
|
|
528
531
|
isNumber(y),
|
|
529
|
-
loggerPrefix + "
|
|
530
|
-
);
|
|
531
|
-
DEV: assert(
|
|
532
|
-
isNumber(radiusX) && radiusX >= 0,
|
|
533
|
-
loggerPrefix +
|
|
534
|
-
"ovalfill() 3rd param must be a positive number or zero",
|
|
532
|
+
loggerPrefix + "circfill() 2nd param must be a number",
|
|
535
533
|
);
|
|
536
534
|
DEV: assert(
|
|
537
|
-
isNumber(
|
|
535
|
+
isNumber(radius) && radius >= 0,
|
|
538
536
|
loggerPrefix +
|
|
539
|
-
"
|
|
537
|
+
"circfill() 3rd param must be a positive number or zero",
|
|
540
538
|
);
|
|
541
539
|
DEV: assert(
|
|
542
540
|
null == color || (isNumber(color) && color >= 0),
|
|
543
541
|
loggerPrefix +
|
|
544
|
-
"
|
|
542
|
+
"circfill() 4th param must be a positive number or zero",
|
|
545
543
|
);
|
|
546
|
-
|
|
547
|
-
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
548
|
-
instance.fill(color);
|
|
544
|
+
instance.ovalfill(x, y, radius, radius, color);
|
|
549
545
|
},
|
|
550
546
|
shape(points) {
|
|
551
547
|
DEV: assert(
|
package/dist/dist.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
var setupZzFX = (global) => {
|
|
3
|
-
|
|
3
|
+
global.zzfxX = new AudioContext();
|
|
4
4
|
global.zzfxV = 1;
|
|
5
5
|
return (
|
|
6
6
|
i = 1,
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
V *= t / a,
|
|
64
64
|
J *= a,
|
|
65
65
|
h = (a * h) | 0,
|
|
66
|
-
i *= 0.3 *
|
|
66
|
+
i *= 0.3 * zzfxV,
|
|
67
67
|
s = (e + X + P + S + r) | 0;
|
|
68
68
|
f < s;
|
|
69
69
|
d[f++] = o * i
|
|
@@ -119,6 +119,7 @@
|
|
|
119
119
|
TWO_PI = math.PI * 2,
|
|
120
120
|
loggerPrefix = "[Litecanvas] ",
|
|
121
121
|
raf = requestAnimationFrame,
|
|
122
|
+
isNumber = Number.isFinite,
|
|
122
123
|
_browserEventListeners = [],
|
|
123
124
|
on = (elem, evt, callback) => {
|
|
124
125
|
elem.addEventListener(evt, callback, false);
|
|
@@ -129,7 +130,6 @@
|
|
|
129
130
|
lowerCase = (str) => str.toLowerCase(),
|
|
130
131
|
preventDefault = (ev) => ev.preventDefault(),
|
|
131
132
|
beginPath = (c) => c.beginPath(),
|
|
132
|
-
isNumber = Number.isFinite,
|
|
133
133
|
zzfx = setupZzFX(root),
|
|
134
134
|
defaults = {
|
|
135
135
|
width: null,
|
|
@@ -242,16 +242,6 @@
|
|
|
242
242
|
_ctx[radii ? "roundRect" : "rect"](~~x, ~~y, ~~width, ~~height, radii);
|
|
243
243
|
instance.fill(color);
|
|
244
244
|
},
|
|
245
|
-
circ(x, y, radius, color) {
|
|
246
|
-
beginPath(_ctx);
|
|
247
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
248
|
-
instance.stroke(color);
|
|
249
|
-
},
|
|
250
|
-
circfill(x, y, radius, color) {
|
|
251
|
-
beginPath(_ctx);
|
|
252
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
253
|
-
instance.fill(color);
|
|
254
|
-
},
|
|
255
245
|
oval(x, y, radiusX, radiusY, color) {
|
|
256
246
|
beginPath(_ctx);
|
|
257
247
|
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
@@ -262,6 +252,12 @@
|
|
|
262
252
|
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
263
253
|
instance.fill(color);
|
|
264
254
|
},
|
|
255
|
+
circ(x, y, radius, color) {
|
|
256
|
+
instance.oval(x, y, radius, radius, color);
|
|
257
|
+
},
|
|
258
|
+
circfill(x, y, radius, color) {
|
|
259
|
+
instance.ovalfill(x, y, radius, radius, color);
|
|
260
|
+
},
|
|
265
261
|
shape(points) {
|
|
266
262
|
beginPath(_ctx);
|
|
267
263
|
for (let i = 0; i < points.length; i += 2) {
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l
|
|
1
|
+
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=performance,o=2*n.PI,r=requestAnimationFrame,s=[],f=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))},d=(l.zzfxX=new AudioContext,l.zzfxV=1,(e=1,t=.05,a=220,l=0,n=0,i=.1,o=0,r=1,s=0,f=0,d=0,c=0,u=0,p=0,h=0,m=0,g=0,v=1,x=0,w=0,y=0)=>{let b=Math,z=2*b.PI,k=s*=500*z/44100/44100,E=a*=(1-t+2*t*b.random(t=[]))*z/44100,T=0,P=0,C=0,I=1,L=0,D=0,A=0,S=y<0?-1:1,H=z*S*y*2/44100,M=b.cos(H),N=b.sin,W=N(H)/4,X=1+W,q=-2*M/X,B=(1-W)/X,V=(1+S*M)/2/X,O=-(S+M)/X,R=0,F=0,G=0,Y=0;for(l=44100*l+9,x*=44100,n*=44100,i*=44100,g*=44100,f*=500*z/85766121e6,h*=z/44100,d*=z/44100,c*=44100,u=44100*u|0,e*=.3*zzfxV,S=l+x+n+i+g|0;C<S;t[C++]=A*e)++D%(100*m|0)||(A=o?1<o?2<o?3<o?N(T*T):b.max(b.min(b.tan(T),1),-1):1-(2*T/z%2+2)%2:1-4*b.abs(b.round(T/z)-T/z):N(T),A=(u?1-w+w*N(z*C/u):1)*(A<0?-1:1)*b.abs(A)**r*(C<l?C/l:C<l+x?1-(C-l)/x*(1-v):C<l+x+n?v:C<S-g?(S-C-g)/i*v:0),A=g?A/2+(g>C?0:(C<S-g?1:(S-C)/g)*t[C-g|0]/2/e):A,y&&(A=Y=V*R+O*(R=F)+V*(F=A)-B*G-q*(G=Y))),T+=(H=(a+=s+=f)*b.cos(h*P++))+H*p*N(C**5),I&&++I>c&&(a+=d,E+=d,I=0),!u||++L%u||(a=E,s=k,I=I||1);(e=zzfxX.createBuffer(1,S,44100)).getChannelData(0).set(t),(a=zzfxX.createBufferSource()).buffer=e,a.connect(zzfxX.destination),a.start()}),c=(t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t)).loop,u=!1,p,h,m=1,g,v=.5,x=1,w,y=1e3/60,b,z=0,k=3,E="sans-serif",T=20,P=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:o,HALF_PI:o/4,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,dist:(e,t,a,l)=>n.hypot(a-e,l-t),wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?S.clamp(o,l,n):o},norm:(e,t,a)=>S.map(e,t,a,0,1),rand:(e=0,t=1)=>(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,a,l,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e-v,~~t-v,~~a+2*v,~~l+2*v,i),S.stroke(n)},rectfill(e,t,a,l,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),S.fill(n)},oval(e,t,a,l,n){g.beginPath(),g.ellipse(~~e,~~t,~~a,~~l,0,0,o),S.stroke(n)},ovalfill(e,t,a,l,n){g.beginPath(),g.ellipse(~~e,~~t,~~a,~~l,0,0,o),S.fill(n)},circ(e,t,a,l){S.oval(e,t,a,a,l)},circfill(e,t,a,l){S.ovalfill(e,t,a,a,l)},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,a,l,n){g.beginPath();let i=.5*(0!==v&&~~e==~~a),o=.5*(0!==v&&~~t==~~l);g.moveTo(~~e+i,~~t+o),g.lineTo(~~a+i,~~l+o),S.stroke(n)},linewidth(e){g.lineWidth=~~e,v=.5*(0!=~~e%2)},linedash(e,t=0){g.setLineDash(e),g.lineDashOffset=t},text(e,t,a,l=k,n="normal"){g.font=`${n} ${T}px ${E}`,g.fillStyle=X(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)g.fillText(i[a],~~e,~~t+T*P*a)},textgap(e){P=e},textfont(e){E=e},textsize(e){T=e},textalign(e,t){e&&(g.textAlign=e),t&&(g.textBaseline=t)},image(e,t,a){g.drawImage(a,~~e,~~t)},spr(e,t,a){let l=a.trim().split("\n");for(let a=0;a<l.length;a++){let n=l[a].trim();for(let l=0;l<n.length;l++){let i=n[l];"."!==i&&" "!==i&&S.rectfill(e+l,t+a,1,1,parseInt(i,36)||0)}}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=g;return n.width=e*i,n.height=t*i,(g=n.getContext("2d")).scale(i,i),a(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=X(e),g.fill()},stroke(e){g.strokeStyle=X(e),g.stroke()},clip(e){g.beginPath(),e(g),g.clip()},sfx:(e,t,a)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e||=D,(t||a)&&((e=e.slice())[0]=(a||1)*(e[0]||1),e[10]=~~e[10]+t),d.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>h,use(e,t={}){var a=e,l=t;let n=a(S,l);for(let e in n)S.def(e,n[e])},listen:(e,t)=>{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,t,a,n,i)=>(u&&(W("before:"+(e=e.toLowerCase()),t,a,n,i),c||l[e]===S[e]||"function"!=typeof l[e]||l[e](t,a,n,i),W(e,t,a,n,i),W("after:"+e,t,a,n,i)),t),pal(t,a=3){I=t||e,L=[],k=a,S.emit("pal",I,k)},palc(e,t){null==e?L=[]:L[e]=t},def(e,a){S[e]=a,t.global&&(l[e]=a)},timescale(e){x=e},framerate(e){y=1e3/~~e},stat:e=>[t,u,y/1e3,m,A,I,D,x,l.zzfxV,C,T,E,L,P][e],pause(){p||(p=!0,z=~~cancelAnimationFrame(z),S.emit("paused"))},resume(){u&&p&&(H(),p=!1,S.emit("resumed"))},ispaused:()=>p,quit(){for(let e of(S.emit("quit"),S.pause(),u=!1,A={},s))e();if(t.global){for(let e in S)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))S[e]=n[e];function H(){z||(b=0,w=i.now(),z=r(M))}function M(){z=r(M);let e=i.now(),t=0,a=e-w;for(w=e,b+=a<100?a:y;b>=y;){t++,b-=y;let e=y/1e3*x;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,a=t.width>0?t.height||t.width:innerHeight;if(S.def("W",e),S.def("H",a),h.width=e,h.height=a,t.autoscale){let l=+t.autoscale;h.style.display||(h.style.display="block",h.style.margin="auto"),m=n.min(innerWidth/e,innerHeight/a),m=l>1&&m>l?l:m,h.style.width=e*m+"px",h.style.height=a*m+"px"}g.imageSmoothingEnabled=!1,S.textalign("start","top"),S.emit("resized",m)}function W(e,t,a,l,n){if(A[e])for(let i of A[e])i(t,a,l,n)}function X(e){return I[~~(L[e]??e)%I.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,S),l.ENGINE=S}if(a=document,g=(h=(h="string"==typeof t.canvas?a.querySelector(t.canvas):t.canvas)||a.createElement("canvas")).getContext("2d"),f(h,"click",()=>focus()),N(),h.parentNode||a.body.appendChild(h),h.style.imageRendering="pixelated",h.oncontextmenu=()=>!1,c)for(let e in c)c[e]&&S.listen(e,c[e]);return r(function(){if(t.autoscale&&f(l,"resize",N),t.tapEvents){let e=e=>[(e.pageX-h.offsetLeft)/m,(e.pageY-h.offsetTop)/m],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:i.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},o=e=>e&&i.now()-e.t<=300,r=!1;f(h,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);S.emit("tap",l,n,0),a(0,l,n),r=!0}}),f(h,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,i]=e(a);o(l)&&S.emit("tapped",l.xi,l.yi,0),S.emit("untap",n,i,0),t.delete(0),r=!1}}),f(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);S.def("MX",a),S.def("MY",l),r&&(S.emit("tapping",a,l,0),n(0,a,l))}),f(h,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);S.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),f(h,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);S.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(o(l)&&S.emit("tapped",l.xi,l.yi,e),S.emit("untap",l.x,l.y,e),t.delete(e))};f(h,"touchend",s),f(h,"touchcancel",s),f(l,"blur",()=>{for(let[e,a]of(r=!1,t))S.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";f(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),f(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),f(l,"blur",()=>e.clear()),S.listen("after:update",()=>t.clear()),S.def("iskeydown",t=>a(e,t)),S.def("iskeypressed",e=>a(t,e)),S.def("lastkey",()=>n)}u=!0,S.emit("init",S),p||H()}),S}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.207.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>",
|
package/src/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export default function litecanvas(settings = {}) {
|
|
|
17
17
|
TWO_PI = math.PI * 2,
|
|
18
18
|
loggerPrefix = '[Litecanvas] ',
|
|
19
19
|
raf = requestAnimationFrame,
|
|
20
|
+
isNumber = Number.isFinite,
|
|
20
21
|
/** @type {Function[]} */
|
|
21
22
|
_browserEventListeners = [],
|
|
22
23
|
/** @type {(elem: EventTarget, evt: string, callback: (event: Event) => void) => void} */
|
|
@@ -30,7 +31,6 @@ export default function litecanvas(settings = {}) {
|
|
|
30
31
|
preventDefault = (ev) => ev.preventDefault(),
|
|
31
32
|
/** @type {(c: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) => void} */
|
|
32
33
|
beginPath = (c) => c.beginPath(),
|
|
33
|
-
isNumber = Number.isFinite,
|
|
34
34
|
zzfx = setupZzFX(root),
|
|
35
35
|
/** @type {LitecanvasOptions} */
|
|
36
36
|
defaults = {
|
|
@@ -52,7 +52,7 @@ export default function litecanvas(settings = {}) {
|
|
|
52
52
|
_initialized = false,
|
|
53
53
|
/** @type {boolean} */
|
|
54
54
|
_paused,
|
|
55
|
-
/** @type {HTMLCanvasElement}
|
|
55
|
+
/** @type {HTMLCanvasElement} */
|
|
56
56
|
_canvas,
|
|
57
57
|
/** @type {number} */
|
|
58
58
|
_canvasScale = 1,
|
|
@@ -459,56 +459,6 @@ export default function litecanvas(settings = {}) {
|
|
|
459
459
|
instance.fill(color)
|
|
460
460
|
},
|
|
461
461
|
|
|
462
|
-
/**
|
|
463
|
-
* Draw a circle outline
|
|
464
|
-
*
|
|
465
|
-
* @param {number} x
|
|
466
|
-
* @param {number} y
|
|
467
|
-
* @param {number} radius
|
|
468
|
-
* @param {number} [color=0] the color index
|
|
469
|
-
*/
|
|
470
|
-
circ(x, y, radius, color) {
|
|
471
|
-
DEV: assert(isNumber(x), loggerPrefix + 'circ() 1st param must be a number')
|
|
472
|
-
DEV: assert(isNumber(y), loggerPrefix + 'circ() 2nd param must be a number')
|
|
473
|
-
DEV: assert(
|
|
474
|
-
isNumber(radius) && radius >= 0,
|
|
475
|
-
loggerPrefix + 'circ() 3rd param must be a positive number or zero'
|
|
476
|
-
)
|
|
477
|
-
DEV: assert(
|
|
478
|
-
null == color || (isNumber(color) && color >= 0),
|
|
479
|
-
loggerPrefix + 'circ() 4th param must be a positive number or zero'
|
|
480
|
-
)
|
|
481
|
-
|
|
482
|
-
beginPath(_ctx)
|
|
483
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)
|
|
484
|
-
instance.stroke(color)
|
|
485
|
-
},
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Draw a color-filled circle
|
|
489
|
-
*
|
|
490
|
-
* @param {number} x
|
|
491
|
-
* @param {number} y
|
|
492
|
-
* @param {number} radius
|
|
493
|
-
* @param {number} [color=0] the color index
|
|
494
|
-
*/
|
|
495
|
-
circfill(x, y, radius, color) {
|
|
496
|
-
DEV: assert(isNumber(x), loggerPrefix + 'circfill() 1st param must be a number')
|
|
497
|
-
DEV: assert(isNumber(y), loggerPrefix + 'circfill() 2nd param must be a number')
|
|
498
|
-
DEV: assert(
|
|
499
|
-
isNumber(radius) && radius >= 0,
|
|
500
|
-
loggerPrefix + 'circfill() 3rd param must be a positive number or zero'
|
|
501
|
-
)
|
|
502
|
-
DEV: assert(
|
|
503
|
-
null == color || (isNumber(color) && color >= 0),
|
|
504
|
-
loggerPrefix + 'circfill() 4th param must be a positive number or zero'
|
|
505
|
-
)
|
|
506
|
-
|
|
507
|
-
beginPath(_ctx)
|
|
508
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)
|
|
509
|
-
instance.fill(color)
|
|
510
|
-
},
|
|
511
|
-
|
|
512
462
|
/**
|
|
513
463
|
* Draw a ellipse outline
|
|
514
464
|
*
|
|
@@ -569,6 +519,52 @@ export default function litecanvas(settings = {}) {
|
|
|
569
519
|
instance.fill(color)
|
|
570
520
|
},
|
|
571
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Draw a circle outline
|
|
524
|
+
*
|
|
525
|
+
* @param {number} x
|
|
526
|
+
* @param {number} y
|
|
527
|
+
* @param {number} radius
|
|
528
|
+
* @param {number} [color=0] the color index
|
|
529
|
+
*/
|
|
530
|
+
circ(x, y, radius, color) {
|
|
531
|
+
DEV: assert(isNumber(x), loggerPrefix + 'circ() 1st param must be a number')
|
|
532
|
+
DEV: assert(isNumber(y), loggerPrefix + 'circ() 2nd param must be a number')
|
|
533
|
+
DEV: assert(
|
|
534
|
+
isNumber(radius) && radius >= 0,
|
|
535
|
+
loggerPrefix + 'circ() 3rd param must be a positive number or zero'
|
|
536
|
+
)
|
|
537
|
+
DEV: assert(
|
|
538
|
+
null == color || (isNumber(color) && color >= 0),
|
|
539
|
+
loggerPrefix + 'circ() 4th param must be a positive number or zero'
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
instance.oval(x, y, radius, radius, color)
|
|
543
|
+
},
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Draw a color-filled circle
|
|
547
|
+
*
|
|
548
|
+
* @param {number} x
|
|
549
|
+
* @param {number} y
|
|
550
|
+
* @param {number} radius
|
|
551
|
+
* @param {number} [color=0] the color index
|
|
552
|
+
*/
|
|
553
|
+
circfill(x, y, radius, color) {
|
|
554
|
+
DEV: assert(isNumber(x), loggerPrefix + 'circfill() 1st param must be a number')
|
|
555
|
+
DEV: assert(isNumber(y), loggerPrefix + 'circfill() 2nd param must be a number')
|
|
556
|
+
DEV: assert(
|
|
557
|
+
isNumber(radius) && radius >= 0,
|
|
558
|
+
loggerPrefix + 'circfill() 3rd param must be a positive number or zero'
|
|
559
|
+
)
|
|
560
|
+
DEV: assert(
|
|
561
|
+
null == color || (isNumber(color) && color >= 0),
|
|
562
|
+
loggerPrefix + 'circfill() 4th param must be a positive number or zero'
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
instance.ovalfill(x, y, radius, radius, color)
|
|
566
|
+
},
|
|
567
|
+
|
|
572
568
|
/**
|
|
573
569
|
* Make a custom shape in the canvas context.
|
|
574
570
|
* Then, just use `fill` or `stroke` to draw the shape.
|
|
@@ -707,6 +703,7 @@ export default function litecanvas(settings = {}) {
|
|
|
707
703
|
*/
|
|
708
704
|
textgap(value) {
|
|
709
705
|
DEV: assert(isNumber(value), loggerPrefix + 'textgap() 1st param must be a number')
|
|
706
|
+
|
|
710
707
|
_fontLineHeight = value
|
|
711
708
|
},
|
|
712
709
|
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.207.0'
|
package/src/zzfx.js
CHANGED
|
@@ -1,13 +1,114 @@
|
|
|
1
1
|
// ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX
|
|
2
|
-
// prettier-ignore
|
|
3
2
|
/**
|
|
4
3
|
* @param {Window} global
|
|
5
4
|
* @returns {Function} the `zzfx()` function
|
|
6
5
|
*/
|
|
7
6
|
export const setupZzFX = (global) => {
|
|
8
|
-
|
|
7
|
+
global.zzfxX = new AudioContext()
|
|
8
|
+
global.zzfxV = 1 // volume rate
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
return (
|
|
11
|
+
i = 1, // volume
|
|
12
|
+
d = 0.05, // randomness
|
|
13
|
+
z = 220, // frequency
|
|
14
|
+
e = 0, // attack
|
|
15
|
+
P = 0, // sustain
|
|
16
|
+
S = 0.1, // release
|
|
17
|
+
I = 0, // shape
|
|
18
|
+
c = 1, // shape curve
|
|
19
|
+
T = 0, // slide
|
|
20
|
+
H = 0, // delta slide
|
|
21
|
+
V = 0, // pitch jump
|
|
22
|
+
J = 0, // pitch jump time
|
|
23
|
+
h = 0, // repeat time
|
|
24
|
+
j = 0, // noise
|
|
25
|
+
K = 0, // modulation
|
|
26
|
+
E = 0, // bit crush
|
|
27
|
+
r = 0, // delay
|
|
28
|
+
B = 1, // sustain volume
|
|
29
|
+
X = 0, // decay
|
|
30
|
+
L = 0, // tremolo
|
|
31
|
+
D = 0 // filter
|
|
32
|
+
) => {
|
|
33
|
+
let n = Math,
|
|
34
|
+
t = 2 * n.PI,
|
|
35
|
+
a = 44100,
|
|
36
|
+
F = (T *= (500 * t) / a / a),
|
|
37
|
+
O = (z *= ((1 - d + 2 * d * n.random((d = []))) * t) / a),
|
|
38
|
+
x = 0,
|
|
39
|
+
_ = 0,
|
|
40
|
+
f = 0,
|
|
41
|
+
g = 1,
|
|
42
|
+
$ = 0,
|
|
43
|
+
l = 0,
|
|
44
|
+
o = 0,
|
|
45
|
+
s = D < 0 ? -1 : 1,
|
|
46
|
+
u = (t * s * D * 2) / a,
|
|
47
|
+
G = n.cos(u),
|
|
48
|
+
C = n.sin,
|
|
49
|
+
Q = C(u) / 4,
|
|
50
|
+
M = 1 + Q,
|
|
51
|
+
m = (-2 * G) / M,
|
|
52
|
+
y = (1 - Q) / M,
|
|
53
|
+
R = (1 + s * G) / 2 / M,
|
|
54
|
+
A = -(s + G) / M,
|
|
55
|
+
v = R,
|
|
56
|
+
U = 0,
|
|
57
|
+
W = 0,
|
|
58
|
+
Y = 0,
|
|
59
|
+
Z = 0
|
|
60
|
+
for (
|
|
61
|
+
e = a * e + 9,
|
|
62
|
+
X *= a,
|
|
63
|
+
P *= a,
|
|
64
|
+
S *= a,
|
|
65
|
+
r *= a,
|
|
66
|
+
H *= (500 * t) / a ** 3,
|
|
67
|
+
K *= t / a,
|
|
68
|
+
V *= t / a,
|
|
69
|
+
J *= a,
|
|
70
|
+
h = (a * h) | 0,
|
|
71
|
+
i *= 0.3 * zzfxV,
|
|
72
|
+
s = (e + X + P + S + r) | 0;
|
|
73
|
+
f < s;
|
|
74
|
+
d[f++] = o * i
|
|
75
|
+
)
|
|
76
|
+
(++l % ((100 * E) | 0) ||
|
|
77
|
+
((o = I
|
|
78
|
+
? 1 < I
|
|
79
|
+
? 2 < I
|
|
80
|
+
? 3 < I
|
|
81
|
+
? C(x * x)
|
|
82
|
+
: n.max(n.min(n.tan(x), 1), -1)
|
|
83
|
+
: 1 - (((((2 * x) / t) % 2) + 2) % 2)
|
|
84
|
+
: 1 - 4 * n.abs(n.round(x / t) - x / t)
|
|
85
|
+
: C(x)),
|
|
86
|
+
(o =
|
|
87
|
+
(h ? 1 - L + L * C((t * f) / h) : 1) *
|
|
88
|
+
(o < 0 ? -1 : 1) *
|
|
89
|
+
n.abs(o) ** c *
|
|
90
|
+
(f < e
|
|
91
|
+
? f / e
|
|
92
|
+
: f < e + X
|
|
93
|
+
? 1 - ((f - e) / X) * (1 - B)
|
|
94
|
+
: f < e + X + P
|
|
95
|
+
? B
|
|
96
|
+
: f < s - r
|
|
97
|
+
? ((s - f - r) / S) * B
|
|
98
|
+
: 0)),
|
|
99
|
+
(o = r
|
|
100
|
+
? o / 2 + (r > f ? 0 : ((f < s - r ? 1 : (s - f) / r) * d[(f - r) | 0]) / 2 / i)
|
|
101
|
+
: o),
|
|
102
|
+
D && (o = Z = v * U + A * (U = W) + R * (W = o) - y * Y - m * (Y = Z))),
|
|
103
|
+
(u = (z += T += H) * n.cos(K * _++)),
|
|
104
|
+
(x += u + u * j * C(f ** 5)),
|
|
105
|
+
g && ++g > J && ((z += V), (O += V), (g = 0)),
|
|
106
|
+
!h || ++$ % h || ((z = O), (T = F), (g = g || 1)))
|
|
107
|
+
;((i = zzfxX.createBuffer(1, s, a)),
|
|
108
|
+
i.getChannelData(0).set(d),
|
|
109
|
+
(z = zzfxX.createBufferSource()),
|
|
110
|
+
(z.buffer = i),
|
|
111
|
+
z.connect(zzfxX.destination),
|
|
112
|
+
z.start())
|
|
113
|
+
}
|
|
13
114
|
}
|