litecanvas 0.400.0 → 0.401.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 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.400.0";
118
+ var version = "0.401.0";
119
119
  function litecanvas(settings = {}) {
120
120
  const root = window,
121
121
  math = Math,
@@ -990,77 +990,56 @@
990
990
  },
991
991
  _checkTapped = (tap) => tap && perf.now() - tap.t <= 300;
992
992
  let _pressingMouse = false;
993
- on(_canvas, "mousedown", (ev) => {
994
- if (!ev.button) {
995
- preventDefault(ev);
996
- const [x, y] = _getXY(ev);
997
- instance.emit("tap", x, y, 0);
998
- _registerTap(0, x, y);
993
+ on(_canvas, "pointerdown", (ev) => {
994
+ const [x, y] = _getXY(ev);
995
+ if ("mouse" === ev.pointerType) {
996
+ if (ev.button) return;
999
997
  _pressingMouse = true;
1000
998
  }
999
+ const id = ev.pointerId;
1000
+ _registerTap(id, x, y);
1001
+ instance.emit("tap", x, y, id);
1002
+ _canvas.setPointerCapture(id);
1001
1003
  });
1002
- on(_canvas, "mouseup", (ev) => {
1003
- if (!ev.button) {
1004
- preventDefault(ev);
1005
- const tap = _taps.get(0);
1006
- const [x, y] = _getXY(ev);
1007
- if (_checkTapped(tap)) {
1008
- instance.emit("tapped", tap.xi, tap.yi, 0);
1009
- }
1010
- instance.emit("untap", x, y, 0);
1011
- _taps.delete(0);
1012
- _pressingMouse = false;
1013
- }
1014
- });
1015
- on(root, "mousemove", (ev) => {
1016
- preventDefault(ev);
1004
+ on(_canvas, "pointermove", (ev) => {
1017
1005
  const [x, y] = _getXY(ev);
1018
- instance.def("MX", x);
1019
- instance.def("MY", y);
1020
- if (!_pressingMouse) return;
1021
- instance.emit("tapping", x, y, 0);
1022
- _updateTap(0, x, y);
1023
- });
1024
- on(_canvas, "touchstart", (ev) => {
1025
- preventDefault(ev);
1026
- const touches = ev.changedTouches;
1027
- for (const touch of touches) {
1028
- const [x, y] = _getXY(touch);
1029
- instance.emit("tap", x, y, touch.identifier + 1);
1030
- _registerTap(touch.identifier + 1, x, y);
1006
+ if ("mouse" === ev.pointerType) {
1007
+ instance.def("MX", x);
1008
+ instance.def("MY", y);
1009
+ if (!_pressingMouse) return;
1031
1010
  }
1032
- });
1033
- on(_canvas, "touchmove", (ev) => {
1034
- preventDefault(ev);
1035
- const touches = ev.changedTouches;
1036
- for (const touch of touches) {
1037
- const [x, y] = _getXY(touch);
1038
- instance.emit("tapping", x, y, touch.identifier + 1);
1039
- _updateTap(touch.identifier + 1, x, y);
1011
+ const id = ev.pointerId;
1012
+ if (_taps.get(id)) {
1013
+ instance.emit("tapping", x, y, id);
1014
+ _updateTap(id, x, y);
1040
1015
  }
1041
1016
  });
1042
- const _touchEndHandler = (ev) => {
1043
- preventDefault(ev);
1044
- const existing = [];
1045
- for (const touch of ev.targetTouches) {
1046
- existing.push(touch.identifier + 1);
1017
+ const _pointerUpHandler = (ev) => {
1018
+ const id = ev.pointerId;
1019
+ const tap = _taps.get(id);
1020
+ const [x, y] = _getXY(ev);
1021
+ if (!tap) return;
1022
+ if ("mouse" === ev.pointerType) {
1023
+ if (ev.button) return;
1024
+ _pressingMouse = false;
1047
1025
  }
1048
- for (const [id, tap] of _taps) {
1049
- if (existing.includes(id)) continue;
1050
- if (_checkTapped(tap)) {
1051
- instance.emit("tapped", tap.xi, tap.yi, id);
1052
- }
1053
- instance.emit("untap", tap.x, tap.y, id);
1054
- _taps.delete(id);
1026
+ if (_checkTapped(tap)) {
1027
+ instance.emit("tapped", tap.xi, tap.yi, id);
1055
1028
  }
1029
+ instance.emit("untap", x, y, id);
1030
+ _taps.delete(id);
1031
+ _canvas.releasePointerCapture(id);
1056
1032
  };
1057
- on(_canvas, "touchend", _touchEndHandler);
1058
- on(_canvas, "touchcancel", _touchEndHandler);
1033
+ on(_canvas, "pointerup", _pointerUpHandler);
1034
+ on(_canvas, "pointercancel", _pointerUpHandler);
1059
1035
  on(root, "blur", () => {
1060
1036
  _pressingMouse = false;
1061
1037
  for (const [id, tap] of _taps) {
1062
1038
  instance.emit("untap", tap.x, tap.y, id);
1063
1039
  _taps.delete(id);
1040
+ try {
1041
+ _canvas.releasePointerCapture(id);
1042
+ } catch (_) {}
1064
1043
  }
1065
1044
  });
1066
1045
  }
@@ -1180,7 +1159,7 @@
1180
1159
  instance.def("H", height);
1181
1160
  _canvas.width = width;
1182
1161
  _canvas.height = height;
1183
- _canvas.style = "image-rendering:pixelated";
1162
+ _canvas.style = "image-rendering:pixelated;touch-action:none";
1184
1163
  if (settings.autoscale) {
1185
1164
  let maxScale = +settings.autoscale;
1186
1165
  if (!_canvas.style.display) {
package/dist/dist.js CHANGED
@@ -564,77 +564,56 @@
564
564
  },
565
565
  _checkTapped = (tap) => tap && perf.now() - tap.t <= 300;
566
566
  let _pressingMouse = false;
567
- on(_canvas, "mousedown", (ev) => {
568
- if (!ev.button) {
569
- preventDefault(ev);
570
- const [x, y] = _getXY(ev);
571
- instance.emit("tap", x, y, 0);
572
- _registerTap(0, x, y);
567
+ on(_canvas, "pointerdown", (ev) => {
568
+ const [x, y] = _getXY(ev);
569
+ if ("mouse" === ev.pointerType) {
570
+ if (ev.button) return;
573
571
  _pressingMouse = true;
574
572
  }
573
+ const id = ev.pointerId;
574
+ _registerTap(id, x, y);
575
+ instance.emit("tap", x, y, id);
576
+ _canvas.setPointerCapture(id);
575
577
  });
576
- on(_canvas, "mouseup", (ev) => {
577
- if (!ev.button) {
578
- preventDefault(ev);
579
- const tap = _taps.get(0);
580
- const [x, y] = _getXY(ev);
581
- if (_checkTapped(tap)) {
582
- instance.emit("tapped", tap.xi, tap.yi, 0);
583
- }
584
- instance.emit("untap", x, y, 0);
585
- _taps.delete(0);
586
- _pressingMouse = false;
587
- }
588
- });
589
- on(root, "mousemove", (ev) => {
590
- preventDefault(ev);
578
+ on(_canvas, "pointermove", (ev) => {
591
579
  const [x, y] = _getXY(ev);
592
- instance.def("MX", x);
593
- instance.def("MY", y);
594
- if (!_pressingMouse) return;
595
- instance.emit("tapping", x, y, 0);
596
- _updateTap(0, x, y);
597
- });
598
- on(_canvas, "touchstart", (ev) => {
599
- preventDefault(ev);
600
- const touches = ev.changedTouches;
601
- for (const touch of touches) {
602
- const [x, y] = _getXY(touch);
603
- instance.emit("tap", x, y, touch.identifier + 1);
604
- _registerTap(touch.identifier + 1, x, y);
580
+ if ("mouse" === ev.pointerType) {
581
+ instance.def("MX", x);
582
+ instance.def("MY", y);
583
+ if (!_pressingMouse) return;
605
584
  }
606
- });
607
- on(_canvas, "touchmove", (ev) => {
608
- preventDefault(ev);
609
- const touches = ev.changedTouches;
610
- for (const touch of touches) {
611
- const [x, y] = _getXY(touch);
612
- instance.emit("tapping", x, y, touch.identifier + 1);
613
- _updateTap(touch.identifier + 1, x, y);
585
+ const id = ev.pointerId;
586
+ if (_taps.get(id)) {
587
+ instance.emit("tapping", x, y, id);
588
+ _updateTap(id, x, y);
614
589
  }
615
590
  });
616
- const _touchEndHandler = (ev) => {
617
- preventDefault(ev);
618
- const existing = [];
619
- for (const touch of ev.targetTouches) {
620
- existing.push(touch.identifier + 1);
591
+ const _pointerUpHandler = (ev) => {
592
+ const id = ev.pointerId;
593
+ const tap = _taps.get(id);
594
+ const [x, y] = _getXY(ev);
595
+ if (!tap) return;
596
+ if ("mouse" === ev.pointerType) {
597
+ if (ev.button) return;
598
+ _pressingMouse = false;
621
599
  }
622
- for (const [id, tap] of _taps) {
623
- if (existing.includes(id)) continue;
624
- if (_checkTapped(tap)) {
625
- instance.emit("tapped", tap.xi, tap.yi, id);
626
- }
627
- instance.emit("untap", tap.x, tap.y, id);
628
- _taps.delete(id);
600
+ if (_checkTapped(tap)) {
601
+ instance.emit("tapped", tap.xi, tap.yi, id);
629
602
  }
603
+ instance.emit("untap", x, y, id);
604
+ _taps.delete(id);
605
+ _canvas.releasePointerCapture(id);
630
606
  };
631
- on(_canvas, "touchend", _touchEndHandler);
632
- on(_canvas, "touchcancel", _touchEndHandler);
607
+ on(_canvas, "pointerup", _pointerUpHandler);
608
+ on(_canvas, "pointercancel", _pointerUpHandler);
633
609
  on(root, "blur", () => {
634
610
  _pressingMouse = false;
635
611
  for (const [id, tap] of _taps) {
636
612
  instance.emit("untap", tap.x, tap.y, id);
637
613
  _taps.delete(id);
614
+ try {
615
+ _canvas.releasePointerCapture(id);
616
+ } catch (_) {}
638
617
  }
639
618
  });
640
619
  }
@@ -719,7 +698,7 @@
719
698
  instance.def("H", height);
720
699
  _canvas.width = width;
721
700
  _canvas.height = height;
722
- _canvas.style = "image-rendering:pixelated";
701
+ _canvas.style = "image-rendering:pixelated;touch-action:none";
723
702
  if (settings.autoscale) {
724
703
  let maxScale = +settings.autoscale;
725
704
  if (!_canvas.style.display) {
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
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,w=1,v=0,x=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,C=0,P=0,I=1,D=0,L=0,S=0,A=y<0?-1:1,M=z*A*y*2/44100,N=b.cos(M),W=b.sin,X=W(M)/4,H=1+X,q=-2*N/H,B=(1-X)/H,V=(1+A*N)/2/H,O=-(A+N)/H,G=0,R=0,Y=0,$=0;for(l=44100*l+9,v*=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,A=l+v+n+i+g|0;P<A;t[P++]=S*e)++L%(100*m|0)||(S=o?1<o?2<o?3<o?W(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):W(T),S=(u?1-x+x*W(z*P/u):1)*(S<0?-1:1)*b.abs(S)**r*(P<l?P/l:P<l+v?1-(P-l)/v*(1-w):P<l+v+n?w:P<A-g?(A-P-g)/i*w:0),S=g?S/2+(g>P?0:(P<A-g?1:(A-P)/g)*t[P-g|0]/2/e):S,y&&(S=$=V*G+O*(G=R)+V*(R=S)-B*Y-q*(Y=$))),T+=(M=(a+=s+=f)*b.cos(h*C++))+M*p*W(P**5),I&&++I>c&&(a+=d,E+=d,I=0),!u||++D%u||(a=E,s=k,I=I||1);(e=zzfxX.createBuffer(1,A,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,p,h,m=1,g,w=.5,v=1,x,y=1e3/60,b,z=0,k=3,E="sans-serif",T=20,C=1.2,P=Date.now(),I=e,D=e,L=[],S=[.5,0,1750,,,.3,1,,,,600,.1],A={},M={W:0,H:0,T:0,MX:-1,MY:-1,TAU:o,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,mod:(e,t)=>(e%t+t)%t||0,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?M.clamp(o,l,n):o},norm:(e,t,a)=>M.map(e,t,a,0,1),rand:(e=0,t=1)=>(P=(1664525*P+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>~~M.rand(e,t+1),rseed(e){P=~~e},cls(e){null==e?g.clearRect(0,0,M.W,M.H):M.rectfill(0,0,M.W,M.H,e)},rect(e,t,a,l,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e-w,~~t-w,~~a+2*w,~~l+2*w,i),M.stroke(n)},rectfill(e,t,a,l,n,i){g.beginPath(),g[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),M.fill(n)},oval(e,t,a,l,n){g.beginPath(),g.ellipse(~~e,~~t,~~a,~~l,0,0,o),M.stroke(n)},ovalfill(e,t,a,l,n){g.beginPath(),g.ellipse(~~e,~~t,~~a,~~l,0,0,o),M.fill(n)},circ(e,t,a,l){M.oval(e,t,a,a,l)},circfill(e,t,a,l){M.ovalfill(e,t,a,a,l)},shape(e){g.beginPath();for(let t=0;t<e.length;t+=2)t?g.lineTo(~~e[t],~~e[t+1]):g.moveTo(~~e[t],~~e[t+1]);g.lineTo(~~e[0],~~e[1])},line(e,t,a,l,n){g.beginPath();let i=w&&~~e==~~a?.5:0,o=w&&~~t==~~l?.5:0;g.moveTo(~~e+i,~~t+o),g.lineTo(~~a+i,~~l+o),M.stroke(n)},linewidth(e){g.lineWidth=~~e,w=~~e%2?.5:0},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=q(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)g.fillText(i[a],~~e,~~t+T*C*a)},textgap(e){C=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.replace(/[^\w.\n]/g,"").split("\n").filter(e=>e);for(let a=0;a<l.length;a++)for(let n=0;n<l[a].length;n++)"."!==l[a][n]&&M.rectfill(e+n,t+a,1,1,parseInt(l[a][n],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(e=0,t=e,a=0,l=1,n=l){g.save(),M.translate(e,t),M.rotate(a),M.scale(l,n)},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=M.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,a)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e||=S,(t||a>=0)&&((e=e.slice())[0]=a*(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(M,l);for(let e in n)M.def(e,n[e])},resize(e,a=e,l){t.width=e,t.height=a,t.autoscale=null==l?t.autoscale:l,X()},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&&(H("before:"+(e=e.toLowerCase()),t,a,n,i),c||l[e]===M[e]||"function"!=typeof l[e]||l[e](t,a,n,i),H(e,t,a,n,i),H("after:"+e,t,a,n,i)),t),pal(e,t=3){null==e?I=D:(D=I,I=e),L=[],k=t,M.emit("pal",I,k)},palc(e,t){null==e?L=[]:L[e]=t},def(e,a){M[e]=a,t.global&&(l[e]=a)},timescale(e){v=e},framerate(e){y=1e3/~~e},stat:e=>[t,u,y/1e3,m,A,I,S,v,l.zzfxV,P,T,E,L,C][e],ispaused:()=>p,pause(){p||(p=!0,z=~~cancelAnimationFrame(z),M.emit("paused"))},resume(){u&&p&&(N(),p=!1,M.emit("resumed"))},quit(){for(let e of(M.emit("quit"),M.pause(),u=!1,A={},s))e();if(t.global){for(let e in M)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,min,max,pow,sqrt,sign".split(","))M[e]=n[e];function N(){z||(b=0,x=i.now(),z=r(W))}function W(){z=r(W);let e=i.now(),t=0,a=e-x;for(x=e,b+=a<100?a:y;b>=y;){t++,b-=y;let e=y/1e3*v;M.emit("update",e,t),M.def("T",M.T+e)}t&&(M.emit("draw",g),t>1&&(b=0))}function X(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(M.def("W",e),M.def("H",a),h.width=e,h.height=a,h.style="image-rendering:pixelated",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,M.textalign("start","top"),M.emit("resized",m)}function H(e,t,a,l,n){if(A[e])for(let i of A[e])i(t,a,l,n)}function q(e){return e>=0?I[~~(L[e]??e)%I.length]:e}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,M),l.ENGINE=M}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()),h.parentNode||a.body.appendChild(h),h.oncontextmenu=()=>!1,X(),c)for(let e in c)c[e]&&M.listen(e,c[e]);return r(function(){if(t.autoscale&&f(l,"resize",X),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(!t.button){t.preventDefault();let[l,n]=e(t);M.emit("tap",l,n,0),a(0,l,n),r=!0}}),f(h,"mouseup",a=>{if(!a.button){a.preventDefault();let l=t.get(0),[n,i]=e(a);o(l)&&M.emit("tapped",l.xi,l.yi,0),M.emit("untap",n,i,0),t.delete(0),r=!1}}),f(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);M.def("MX",a),M.def("MY",l),r&&(M.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);M.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);M.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{e.preventDefault();let a=[];for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(o(l)&&M.emit("tapped",l.xi,l.yi,e),M.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))M.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()),M.listen("after:update",()=>t.clear()),M.def("iskeydown",t=>a(e,t)),M.def("iskeypressed",e=>a(t,e)),M.def("lastkey",()=>n)}u=!0,M.emit("init",M),p||N()}),M}})();
1
+ (()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,n=window,l=Math,i=performance,o=2*l.PI,r=requestAnimationFrame,s=[],f=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))},c=(n.zzfxX=new AudioContext,n.zzfxV=1,(e=1,t=.05,a=220,n=0,l=0,i=.1,o=0,r=1,s=0,f=0,c=0,d=0,p=0,u=0,h=0,g=0,m=0,w=1,x=0,y=0,v=0)=>{let b=Math,z=2*b.PI,k=s*=500*z/44100/44100,C=a*=(1-t+2*t*b.random(t=[]))*z/44100,E=0,P=0,I=0,T=1,L=0,S=0,A=0,M=v<0?-1:1,N=z*M*v*2/44100,W=b.cos(N),X=b.sin,H=X(N)/4,q=1+H,B=-2*W/q,V=(1-H)/q,D=(1+M*W)/2/q,O=-(M+W)/q,G=0,R=0,Y=0,$=0;for(n=44100*n+9,x*=44100,l*=44100,i*=44100,m*=44100,f*=500*z/85766121e6,h*=z/44100,c*=z/44100,d*=44100,p=44100*p|0,e*=.3*zzfxV,M=n+x+l+i+m|0;I<M;t[I++]=A*e)++S%(100*g|0)||(A=o?1<o?2<o?3<o?X(E*E):b.max(b.min(b.tan(E),1),-1):1-(2*E/z%2+2)%2:1-4*b.abs(b.round(E/z)-E/z):X(E),A=(p?1-y+y*X(z*I/p):1)*(A<0?-1:1)*b.abs(A)**r*(I<n?I/n:I<n+x?1-(I-n)/x*(1-w):I<n+x+l?w:I<M-m?(M-I-m)/i*w:0),A=m?A/2+(m>I?0:(I<M-m?1:(M-I)/m)*t[I-m|0]/2/e):A,v&&(A=$=D*G+O*(G=R)+D*(R=A)-V*Y-B*(Y=$))),E+=(N=(a+=s+=f)*b.cos(h*P++))+N*u*X(I**5),T&&++T>d&&(a+=c,C+=c,T=0),!p||++L%p||(a=C,s=k,T=T||1);(e=zzfxX.createBuffer(1,M,44100)).getChannelData(0).set(t),(a=zzfxX.createBufferSource()).buffer=e,a.connect(zzfxX.destination),a.start()}),d=(t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t)).loop,p,u,h,g=1,m,w=.5,x=1,y,v=1e3/60,b,z=0,k=3,C="sans-serif",E=20,P=1.2,I=Date.now(),T=e,L=e,S=[],A=[.5,0,1750,,,.3,1,,,,600,.1],M={},N={W:0,H:0,T:0,MX:-1,MY:-1,TAU:o,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>l.PI/180*e,rad2deg:e=>180/l.PI*e,mod:(e,t)=>(e%t+t)%t||0,round:(e,t=0)=>{if(!t)return l.round(e);let a=10**t;return l.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,dist:(e,t,a,n)=>l.hypot(a-e,n-t),wrap:(e,t,a)=>e-(a-t)*l.floor((e-t)/(a-t)),map(e,t,a,n,l,i){let o=(e-t)/(a-t)*(l-n)+n;return i?N.clamp(o,n,l):o},norm:(e,t,a)=>N.map(e,t,a,0,1),rand:(e=0,t=1)=>(I=(1664525*I+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>~~N.rand(e,t+1),rseed(e){I=~~e},cls(e){null==e?m.clearRect(0,0,N.W,N.H):N.rectfill(0,0,N.W,N.H,e)},rect(e,t,a,n,l,i){m.beginPath(),m[i?"roundRect":"rect"](~~e-w,~~t-w,~~a+2*w,~~n+2*w,i),N.stroke(l)},rectfill(e,t,a,n,l,i){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,~~a,~~n,i),N.fill(l)},oval(e,t,a,n,l){m.beginPath(),m.ellipse(~~e,~~t,~~a,~~n,0,0,o),N.stroke(l)},ovalfill(e,t,a,n,l){m.beginPath(),m.ellipse(~~e,~~t,~~a,~~n,0,0,o),N.fill(l)},circ(e,t,a,n){N.oval(e,t,a,a,n)},circfill(e,t,a,n){N.ovalfill(e,t,a,a,n)},shape(e){m.beginPath();for(let t=0;t<e.length;t+=2)t?m.lineTo(~~e[t],~~e[t+1]):m.moveTo(~~e[t],~~e[t+1]);m.lineTo(~~e[0],~~e[1])},line(e,t,a,n,l){m.beginPath();let i=w&&~~e==~~a?.5:0,o=w&&~~t==~~n?.5:0;m.moveTo(~~e+i,~~t+o),m.lineTo(~~a+i,~~n+o),N.stroke(l)},linewidth(e){m.lineWidth=~~e,w=~~e%2?.5:0},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,n=k,l="normal"){m.font=`${l} ${E}px ${C}`,m.fillStyle=B(n);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)m.fillText(i[a],~~e,~~t+E*P*a)},textgap(e){P=e},textfont(e){C=e},textsize(e){E=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},image(e,t,a){m.drawImage(a,~~e,~~t)},spr(e,t,a){let n=a.replace(/[^\w.\n]/g,"").split("\n").filter(e=>e);for(let a=0;a<n.length;a++)for(let l=0;l<n[a].length;l++)"."!==n[a][l]&&N.rectfill(e+l,t+a,1,1,parseInt(n[a][l],36)||0)},paint(e,t,a,n={}){let l=n.canvas||new OffscreenCanvas(1,1),i=n.scale||1,o=m;return l.width=e*i,l.height=t*i,(m=l.getContext("2d")).scale(i,i),a(m),m=o,l.transferToImageBitmap()},ctx:e=>(e&&(m=e),m),push(e=0,t=e,a=0,n=1,l=n){m.save(),N.translate(e,t),N.rotate(a),N.scale(n,l)},pop(){m.restore()},translate(e,t){m.translate(~~e,~~t)},scale(e,t=e){m.scale(e,t)},rotate(e){m.rotate(e)},alpha(e){m.globalAlpha=N.clamp(e,0,1)},fill(e){m.fillStyle=B(e),m.fill()},stroke(e){m.strokeStyle=B(e),m.stroke()},clip(e){m.beginPath(),e(m),m.clip()},sfx:(e,t,a)=>!!n.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e||=A,(t||a>=0)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),c.apply(0,e),e),volume(e){n.zzfxV=e},canvas:()=>h,use(e,t={}){var a=e,n=t;let l=a(N,n);for(let e in l)N.def(e,l[e])},resize(e,a=e,n){t.width=e,t.height=a,t.autoscale=null==n?t.autoscale:n,H()},listen:(e,t)=>{M[e=e.toLowerCase()]=M[e]||new Set,M[e].add(t)},unlisten:(e,t)=>{M[e=e.toLowerCase()]&&M[e].delete(t)},emit:(e,t,a,l,i)=>(p&&(q("before:"+(e=e.toLowerCase()),t,a,l,i),d||n[e]===N[e]||"function"!=typeof n[e]||n[e](t,a,l,i),q(e,t,a,l,i),q("after:"+e,t,a,l,i)),t),pal(e,t=3){null==e?T=L:(L=T,T=e),S=[],k=t,N.emit("pal",T,k)},palc(e,t){null==e?S=[]:S[e]=t},def(e,a){N[e]=a,t.global&&(n[e]=a)},timescale(e){x=e},framerate(e){v=1e3/~~e},stat:e=>[t,p,v/1e3,g,M,T,A,x,n.zzfxV,I,E,C,S,P][e],ispaused:()=>u,pause(){u||(u=!0,z=~~cancelAnimationFrame(z),N.emit("paused"))},resume(){p&&u&&(W(),u=!1,N.emit("resumed"))},quit(){for(let e of(N.emit("quit"),N.pause(),p=!1,M={},s))e();if(t.global){for(let e in N)delete n[e];delete n.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,min,max,pow,sqrt,sign".split(","))N[e]=l[e];function W(){z||(b=0,y=i.now(),z=r(X))}function X(){z=r(X);let e=i.now(),t=0,a=e-y;for(y=e,b+=a<100?a:v;b>=v;){t++,b-=v;let e=v/1e3*x;N.emit("update",e,t),N.def("T",N.T+e)}t&&(N.emit("draw",m),t>1&&(b=0))}function H(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(N.def("W",e),N.def("H",a),h.width=e,h.height=a,h.style="image-rendering:pixelated;touch-action:none",t.autoscale){let n=+t.autoscale;h.style.display||(h.style.display="block",h.style.margin="auto"),g=l.min(innerWidth/e,innerHeight/a),g=n>1&&g>n?n:g,h.style.width=e*g+"px",h.style.height=a*g+"px"}m.imageSmoothingEnabled=!1,N.textalign("start","top"),N.emit("resized",g)}function q(e,t,a,n,l){if(M[e])for(let i of M[e])i(t,a,n,l)}function B(e){return e>=0?T[~~(S[e]??e)%T.length]:e}if(t.global){if(n.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(n,N),n.ENGINE=N}if(a=document,m=(h=(h="string"==typeof t.canvas?a.querySelector(t.canvas):t.canvas)||a.createElement("canvas")).getContext("2d"),f(h,"click",()=>focus()),h.parentNode||a.body.appendChild(h),h.oncontextmenu=()=>!1,H(),d)for(let e in d)d[e]&&N.listen(e,d[e]);return r(function(){if(t.autoscale&&f(n,"resize",H),t.tapEvents){let e=e=>[(e.pageX-h.offsetLeft)/g,(e.pageY-h.offsetTop)/g],t=new Map,a=(e,a,n)=>{let l={x:a,y:n,xi:a,yi:n,t:i.now()};return t.set(e,l),l},l=!1;f(h,"pointerdown",t=>{let[n,i]=e(t);if("mouse"===t.pointerType){if(t.button)return;l=!0}let o=t.pointerId;a(o,n,i),N.emit("tap",n,i,o),h.setPointerCapture(o)}),f(h,"pointermove",n=>{let[i,o]=e(n);if("mouse"===n.pointerType&&(N.def("MX",i),N.def("MY",o),!l))return;let r=n.pointerId;if(t.get(r)){let e;N.emit("tapping",i,o,r),(e=t.get(r)||a(r)).x=i,e.y=o}});let o=a=>{let n=a.pointerId,o=t.get(n),[r,s]=e(a);if(o){if("mouse"===a.pointerType){if(a.button)return;l=!1}o&&i.now()-o.t<=300&&N.emit("tapped",o.xi,o.yi,n),N.emit("untap",r,s,n),t.delete(n),h.releasePointerCapture(n)}};f(h,"pointerup",o),f(h,"pointercancel",o),f(n,"blur",()=>{for(let[e,a]of(l=!1,t)){N.emit("untap",a.x,a.y,e),t.delete(e);try{h.releasePointerCapture(e)}catch(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,l="";f(n,"keydown",a=>{let n=a.key.toLowerCase();e.has(n)||(e.add(n),t.add(n),l=" "===n?"space":n)}),f(n,"keyup",t=>{e.delete(t.key.toLowerCase())}),f(n,"blur",()=>e.clear()),N.listen("after:update",()=>t.clear()),N.def("iskeydown",t=>a(e,t)),N.def("iskeypressed",e=>a(t,e)),N.def("lastkey",()=>l)}p=!0,N.emit("init",N),u||W()}),N}})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.400.0",
3
+ "version": "0.401.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
@@ -1502,128 +1502,70 @@ export default function litecanvas(settings = {}) {
1502
1502
 
1503
1503
  let _pressingMouse = false
1504
1504
 
1505
- on(
1506
- _canvas,
1507
- 'mousedown',
1508
- /**
1509
- * @param {MouseEvent} ev
1510
- */
1511
- (ev) => {
1512
- if (!ev.button) {
1513
- preventDefault(ev)
1514
- const [x, y] = _getXY(ev)
1515
- instance.emit('tap', x, y, 0)
1516
- _registerTap(0, x, y)
1517
- _pressingMouse = true
1518
- }
1519
- }
1520
- )
1505
+ on(_canvas, 'pointerdown', (ev) => {
1506
+ const [x, y] = _getXY(ev)
1521
1507
 
1522
- on(
1523
- _canvas,
1524
- 'mouseup',
1525
- /**
1526
- * @param {MouseEvent} ev
1527
- */
1528
- (ev) => {
1529
- if (!ev.button) {
1530
- preventDefault(ev)
1531
- const tap = _taps.get(0)
1532
- const [x, y] = _getXY(ev)
1533
- if (_checkTapped(tap)) {
1534
- instance.emit('tapped', tap.xi, tap.yi, 0)
1535
- }
1536
- instance.emit('untap', x, y, 0)
1537
- _taps.delete(0)
1538
- _pressingMouse = false
1539
- }
1508
+ if ('mouse' === ev.pointerType) {
1509
+ if (ev.button) return
1510
+ _pressingMouse = true
1540
1511
  }
1541
- )
1542
1512
 
1543
- on(
1544
- root,
1545
- 'mousemove',
1546
- /**
1547
- * @param {MouseEvent} ev
1548
- */
1549
- (ev) => {
1550
- preventDefault(ev)
1513
+ const id = ev.pointerId
1514
+ _registerTap(id, x, y)
1515
+ instance.emit('tap', x, y, id)
1516
+
1517
+ _canvas.setPointerCapture(id)
1518
+ })
1551
1519
 
1552
- const [x, y] = _getXY(ev)
1520
+ on(_canvas, 'pointermove', (ev) => {
1521
+ const [x, y] = _getXY(ev)
1522
+
1523
+ if ('mouse' === ev.pointerType) {
1553
1524
  instance.def('MX', x)
1554
1525
  instance.def('MY', y)
1555
-
1556
1526
  if (!_pressingMouse) return
1557
-
1558
- instance.emit('tapping', x, y, 0)
1559
- _updateTap(0, x, y)
1560
1527
  }
1561
- )
1562
1528
 
1563
- on(
1564
- _canvas,
1565
- 'touchstart',
1566
- /**
1567
- * @param {TouchEvent} ev
1568
- */
1569
- (ev) => {
1570
- preventDefault(ev)
1571
- /** @type {TouchList} touches */
1572
- const touches = ev.changedTouches
1573
- for (const touch of touches) {
1574
- const [x, y] = _getXY(touch)
1575
- instance.emit('tap', x, y, touch.identifier + 1)
1576
- _registerTap(touch.identifier + 1, x, y)
1577
- }
1529
+ const id = ev.pointerId
1530
+ if (_taps.get(id)) {
1531
+ instance.emit('tapping', x, y, id)
1532
+ _updateTap(id, x, y)
1578
1533
  }
1579
- )
1534
+ })
1580
1535
 
1581
- on(
1582
- _canvas,
1583
- 'touchmove',
1584
- /**
1585
- * @param {TouchEvent} ev
1586
- */
1587
- (ev) => {
1588
- preventDefault(ev)
1589
- const touches = ev.changedTouches
1590
- for (const touch of touches) {
1591
- const [x, y] = _getXY(touch)
1592
- instance.emit('tapping', x, y, touch.identifier + 1)
1593
- _updateTap(touch.identifier + 1, x, y)
1594
- }
1595
- }
1596
- )
1536
+ const _pointerUpHandler = (ev) => {
1537
+ const id = ev.pointerId
1538
+ const tap = _taps.get(id)
1539
+ const [x, y] = _getXY(ev)
1597
1540
 
1598
- /**
1599
- * @param {TouchEvent} ev
1600
- */
1601
- const _touchEndHandler = (ev) => {
1602
- preventDefault(ev)
1603
- const existing = []
1541
+ if (!tap) return
1604
1542
 
1605
- for (const touch of ev.targetTouches) {
1606
- existing.push(touch.identifier + 1)
1543
+ if ('mouse' === ev.pointerType) {
1544
+ if (ev.button) return
1545
+ _pressingMouse = false
1607
1546
  }
1608
1547
 
1609
- for (const [id, tap] of _taps) {
1610
- if (existing.includes(id)) continue
1611
- if (_checkTapped(tap)) {
1612
- instance.emit('tapped', tap.xi, tap.yi, id)
1613
- }
1614
- instance.emit('untap', tap.x, tap.y, id)
1615
- _taps.delete(id)
1548
+ if (_checkTapped(tap)) {
1549
+ instance.emit('tapped', tap.xi, tap.yi, id)
1616
1550
  }
1551
+
1552
+ instance.emit('untap', x, y, id)
1553
+
1554
+ _taps.delete(id)
1555
+ _canvas.releasePointerCapture(id)
1617
1556
  }
1618
1557
 
1619
- on(_canvas, 'touchend', _touchEndHandler)
1620
- on(_canvas, 'touchcancel', _touchEndHandler)
1558
+ on(_canvas, 'pointerup', _pointerUpHandler)
1559
+ on(_canvas, 'pointercancel', _pointerUpHandler)
1621
1560
 
1622
1561
  on(root, 'blur', () => {
1623
1562
  _pressingMouse = false
1624
1563
  for (const [id, tap] of _taps) {
1625
1564
  instance.emit('untap', tap.x, tap.y, id)
1626
1565
  _taps.delete(id)
1566
+ try {
1567
+ _canvas.releasePointerCapture(id)
1568
+ } catch (_) {}
1627
1569
  }
1628
1570
  })
1629
1571
  }
@@ -1806,8 +1748,7 @@ export default function litecanvas(settings = {}) {
1806
1748
  _canvas.width = width
1807
1749
  _canvas.height = height
1808
1750
 
1809
- /** @ts-ignore */
1810
- _canvas.style = 'image-rendering:pixelated'
1751
+ _canvas.style = 'image-rendering:pixelated;touch-action:none'
1811
1752
 
1812
1753
  if (settings.autoscale) {
1813
1754
  let maxScale = +settings.autoscale
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.400.0'
2
+ export const version = '0.401.0'