litecanvas 0.41.3 → 0.42.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.js CHANGED
@@ -61,6 +61,7 @@
61
61
  fullscreen: true,
62
62
  width: null,
63
63
  height: null,
64
+ pauseOnBlur: true,
64
65
  autoscale: true,
65
66
  pixelart: false,
66
67
  antialias: true,
@@ -70,7 +71,7 @@
70
71
  loop: null
71
72
  };
72
73
  settings = Object.assign(defaults, settings);
73
- let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _fullscreen = settings.fullscreen, _autoscale = settings.autoscale, _scale = 1, _mouseX, _mouseY, _ctx, _lastFrame, _step = 1 / settings.fps, _stepMs = _step * 1e3, _accumulated = 0, _rafid, _drawCount = 0, _drawTime = 0, _fontFamily = "sans-serif", _fontStyle = "", _fontSize = 32, _textAlign = "start", _textBaseline = "top", _events = {
74
+ let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _fullscreen = settings.fullscreen, _autoscale = settings.autoscale, _scale = 1, _mouseX, _mouseY, _ctx, _timeScale = 1, _lastFrame, _step = 1 / settings.fps, _stepMs = _step * 1e3, _accumulated = 0, _rafid, _drawCount = 0, _drawTime = 0, _fontFamily = "sans-serif", _fontStyle = "", _fontSize = 32, _textAlign = "start", _textBaseline = "top", _events = {
74
75
  init: [],
75
76
  update: [],
76
77
  draw: [],
@@ -211,7 +212,7 @@
211
212
  /**
212
213
  * Clear the game screen
213
214
  *
214
- * @param {number|null} color The background color (from 0 to 7) or null
215
+ * @param {number|null} color The background color (from 0 to 7) or null (for transparent)
215
216
  */
216
217
  cls(color) {
217
218
  if (null == color) {
@@ -626,6 +627,16 @@
626
627
  * @returns number[]
627
628
  */
628
629
  mousepos: () => [_mouseX, _mouseY],
630
+ /**
631
+ * The scale of the game's time delta (dt).
632
+ * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
633
+ * A value of 0 freezes time and is effectively equivalent to pausing.
634
+ *
635
+ * @param {number} value
636
+ */
637
+ timescale(value) {
638
+ _timeScale = value;
639
+ },
629
640
  /** PLUGINS API */
630
641
  /**
631
642
  * Prepares a plugin to be loaded
@@ -667,10 +678,10 @@
667
678
  }
668
679
  },
669
680
  /**
670
- * Get the color value
681
+ * Get a color by index
671
682
  *
672
683
  * @param {number} index The color number
673
- * @returns {string} the color value
684
+ * @returns {string} the color code
674
685
  */
675
686
  getcolor: (index) => colors[~~index % colors.length],
676
687
  /**
@@ -720,16 +731,6 @@
720
731
  function init() {
721
732
  _initialized = true;
722
733
  setupCanvas();
723
- on(root, "blur", () => {
724
- cancelAnimationFrame(_rafid);
725
- _rafid = 0;
726
- });
727
- on(root, "focus", () => {
728
- if (!_rafid) {
729
- _lastFrame = performance.now();
730
- _rafid = requestAnimationFrame(drawFrame);
731
- }
732
- });
733
734
  const source = settings.loop ? settings.loop : root;
734
735
  for (const event in _events) {
735
736
  if (source[event])
@@ -740,9 +741,6 @@
740
741
  }
741
742
  on(root, "resize", pageResized);
742
743
  pageResized();
743
- instance.emit("init");
744
- _lastFrame = performance.now();
745
- _rafid = requestAnimationFrame(drawFrame);
746
744
  if (settings.tapEvents) {
747
745
  const _getXY = (pageX, pageY) => [
748
746
  (pageX - _canvas.offsetLeft) / _scale,
@@ -840,20 +838,34 @@
840
838
  }
841
839
  });
842
840
  }
841
+ if (settings.pauseOnBlur) {
842
+ on(root, "blur", () => {
843
+ _rafid = null;
844
+ });
845
+ on(root, "focus", () => {
846
+ if (!_rafid) {
847
+ _lastFrame = performance.now();
848
+ _rafid = requestAnimationFrame(drawFrame);
849
+ }
850
+ });
851
+ }
852
+ instance.emit("init");
853
+ _lastFrame = performance.now();
854
+ _rafid = requestAnimationFrame(drawFrame);
843
855
  }
844
856
  function drawFrame(now) {
845
857
  let ticks = 0, t = now - _lastFrame;
846
858
  _lastFrame = now;
847
859
  _accumulated += t;
848
860
  while (_accumulated >= _stepMs) {
849
- instance.emit("update", _step);
850
- instance.setvar("ELAPSED", instance.ELAPSED + _step);
861
+ instance.emit("update", _step * _timeScale);
862
+ instance.setvar("ELAPSED", instance.ELAPSED + _step * _timeScale);
851
863
  _accumulated -= _stepMs;
852
864
  ticks++;
853
865
  }
854
866
  if (ticks) {
855
- _drawCount++;
856
867
  instance.emit("draw");
868
+ _drawCount++;
857
869
  _drawTime += _stepMs * ticks;
858
870
  if (_drawTime + _accumulated >= 1e3) {
859
871
  instance.setvar("FPS", _drawCount);
package/dist/dist.min.js CHANGED
@@ -1,2 +1,2 @@
1
- (()=>{zzfxX=new AudioContext;zzfxV=.3;zzfx=(u=1,A=.05,y=220,h=0,V=0,G=.1,b=0,c=1,M=0,R=0,E=0,L=0,P=0,r=0,Y=0,B=0,I=0,C=1,D=0,O=0,F=0)=>{let T=Math,_=2*T.PI,g=44100,j=M*=500*_/g/g,N=y*=(1-A+2*A*T.random(A=[]))*_/g,m=0,J=0,a=0,S=1,$=0,K=0,H=0,z=F<0?-1:1,e=_*z*F*2/g,t=T.cos(e),n=T.sin,o=n(e)/4,l=1+o,d=-2*t/l,x=(1-o)/l,w=(1+z*t)/2/l,i=-(z+t)/l,f=w,s=0,p=0,W=0,X=0;for(h=g*h+9,D*=g,V*=g,G*=g,I*=g,R*=500*_/g**3,Y*=_/g,E*=_/g,L*=g,P=g*P|0,u*=zzfxV,z=h+D+V+G+I|0;a<z;A[a++]=H*u)++K%(100*B|0)||(H=b?1<b?2<b?3<b?n(m*m):T.max(T.min(T.tan(m),1),-1):1-(2*m/_%2+2)%2:1-4*T.abs(T.round(m/_)-m/_):n(m),H=(P?1-O+O*n(_*a/P):1)*(H<0?-1:1)*T.abs(H)**c*(a<h?a/h:a<h+D?1-(a-h)/D*(1-C):a<h+D+V?C:a<z-I?(z-a-I)/G*C:0),H=I?H/2+(I>a?0:(a<z-I?1:(z-a)/I)*A[a-I|0]/2/u):H,F&&(H=X=f*s+i*(s=p)+w*(p=H)-x*W-d*(W=X))),e=(y+=M+=R)*T.cos(Y*J++),m+=e+e*r*n(a**5),S&&++S>L&&(y+=E,N+=E,S=0),!P||++$%P||(y=N,M=j,S=S||1);u=zzfxX.createBuffer(1,z,g),u.getChannelData(0).set(A),y=zzfxX.createBufferSource(),y.buffer=u,y.connect(zzfxX.destination),y.start()};var k=["#18161c","#6a7799","#aec2c2","#f3eade","#f04f78","#fcf660","#2f328f","#4b80ca","#327345","#63c64d","#703075","#a56243"];var q=[[.8,0,2e3,.01,.05,,1,2,,,-600,.05,,,,,,.5,.05],[.5,0,375,.02,.01,.2,1,,,,,,,.4,,.1,,.6,.1],[,0,360,.01,,.08,1,1.7,12,32,,,,,,,,.63,.02,,99],[1.2,0,240,.02,.15,.15,1,4,,,,,.05,,,,,.6,.15]];var v=globalThis;function Q(u={}){let A=Math.PI,y=A*2,h=(e,t,n)=>e.addEventListener(t,n);u=Object.assign({fps:60,fullscreen:!0,width:null,height:null,autoscale:!0,pixelart:!1,antialias:!0,canvas:null,global:!0,tapEvents:!0,loop:null},u);let G=!1,b=[],c=u.canvas||document.createElement("canvas"),M=u.fullscreen,R=u.autoscale,E=1,L,P,r,Y,B=1/u.fps,I=B*1e3,C=0,D,O=0,F=0,T="sans-serif",_="",g=32,j="start",N="top",m={init:[],update:[],draw:[],resized:[],tap:[],untap:[],tapping:[],tapped:[]},J={settings:Object.assign({},u),colors:k,sounds:q},a={WIDTH:u.width,HEIGHT:u.height||u.width,CANVAS:null,ELAPSED:0,FPS:u.fps,CENTERX:null,CENTERY:null,PI:A,TWO_PI:y,HALF_PI:A*.5,lerp:(e,t,n)=>e+n*(t-e),deg2rad:e=>A/180*e,rad2deg:e=>180/A*e,clamp:(e,t,n)=>Math.min(Math.max(e,t),n),wrap:(e,t,n)=>e-(n-t)*Math.floor((e-t)/(n-t)),map(e,t,n,o,l,d=!1){let x=(e-t)/(n-t)*(l-o)+o;return d?a.clamp(x,o,l):x},norm:(e,t,n)=>a.map(e,t,n,0,1),rand:(e=0,t=1)=>Math.random()*(t-e)+e,randi:(e=0,t=1)=>a.floor(a.rand()*(t-e+1)+e),cls(e){e==null?r.clearRect(0,0,a.WIDTH,a.HEIGHT):a.rectfill(0,0,a.WIDTH,a.HEIGHT,e)},rect(e,t,n,o,l=0,d=null){r.beginPath(),r[d?"roundRect":"rect"](~~e,~~t,~~n,~~o,d),a.stroke(l)},rectfill(e,t,n,o,l=0,d=null){r.beginPath(),r[d?"roundRect":"rect"](~~e,~~t,~~n,~~o,d),a.fill(l)},circ(e,t,n,o=0){r.beginPath(),r.arc(~~e,~~t,~~n,0,y),r.closePath(),a.stroke(o)},circfill(e,t,n,o=0){r.beginPath(),r.arc(~~e,~~t,~~n,0,y),r.closePath(),a.fill(o)},line(e,t,n,o,l=0){r.beginPath(),r.moveTo(~~e,~~t),r.lineTo(~~n,~~o),a.stroke(l)},linewidth(e){r.lineWidth=e},linedash(e,t=0){r.setLineDash(Array.isArray(e)?e:[e]),r.lineDashOffset=t},text(e,t,n,o=3){r.font=`${_||""} ${~~g}px ${T}`,r.fillStyle=a.getcolor(o),r.fillText(n,~~e,~~t)},textfont(e){T=e},textsize(e){g=e},textstyle(e){_=e},textalign(e,t){r.textAlign=j=e,r.textBaseline=N=t},textmetrics(e,t){return r.font=`${_||""} ${~~(t||g)}px ${T}`,metrics=r.measureText(e),metrics.height=metrics.actualBoundingBoxAscent+metrics.actualBoundingBoxDescent,metrics},image(e,t,n){r.drawImage(n,~~e,~~t)},paint(e,t,n,o={}){let l=new OffscreenCanvas(e,t),d=r,x=o.scale||1;if(l.width=e*x,l.height=t*x,r=l.getContext("2d"),r.scale(x,x),Array.isArray(n)){let w=0,i=0;r.imageSmoothingEnabled=!1;for(let f of n){for(let s of f)s!==" "&&s!=="."&&a.rectfill(w,i,1,1,parseInt(s,16)),w++;i++,w=0}}else n(l,r);return r=d,l},ctx:()=>r,push:()=>r.save(),pop:()=>r.restore(),translate:(e,t)=>r.translate(e,t),scale:(e,t)=>r.scale(e,t||e),rotate:e=>r.rotate(e),transform:(e,t,n,o,l,d,x=!0)=>r[x?"setTransform":"transform"](e,t,n,o,l,d),alpha(e){r.globalAlpha=e},path:e=>new Path2D(e),fill(e,t){r.fillStyle=a.getcolor(e),r.fill(t)},stroke(e,t){r.strokeStyle=a.getcolor(e),t?r.stroke(t):r.stroke()},cliprect(e,t,n,o){r.beginPath(),r.rect(e,t,n,o),r.clip()},clipcirc(e,t,n){r.beginPath(),r.arc(e,t,n,0,y),r.clip()},blendmode(e){r.globalCompositeOperation=e},sfx(e=0,t=1,n=0,o=0){if(navigator.userActivation&&!navigator.userActivation.hasBeenActive)return;let l=Array.isArray(e)?e:q[~~e%q.length];return(t!==1||n||o)&&(l=[...l],l[0]=(Number(t)||1)*(l[0]||1),l[1]=o>0?o:0,l[10]=~~l[10]+~~n),zzfx(...l)},colrect:(e,t,n,o,l,d,x,w)=>e<l+x&&e+n>l&&t<d+w&&t+o>d,colcirc:(e,t,n,o,l,d)=>(o-e)**2+(l-t)**2<=(n+d)**2,mousepos:()=>[L,P],use:(e,t={})=>{e.__config=t,G?z(e):b.push(e)},listen(e,t,n=!1){return m[e]=m[e]||[],m[e][n?"unshift":"push"](t),()=>{m[e]=m[e].filter(o=>o!==t)}},emit(e,...t){if(m[e])for(let n=0;n<m[e].length;++n)m[e][n](...t)},getcolor:e=>k[~~e%k.length],setvar(e,t){a[e]=t,u.global&&(v[e]=t)},resize(e,t){a.setvar("WIDTH",c.width=~~e),a.setvar("HEIGHT",c.height=~~(t||e)),H()}};for(let e of["sin","cos","atan2","hypot","tan","abs","ceil","round","floor","trunc","min","max","pow","sqrt","sign","exp"])a[e]=Math[e];function S(){G=!0,K(),h(v,"blur",()=>{cancelAnimationFrame(D),D=0}),h(v,"focus",()=>{D||(Y=performance.now(),D=requestAnimationFrame($))});let e=u.loop?u.loop:v;for(let t in m)e[t]&&a.listen(t,e[t]);for(let t=0;t<b.length;t++)z(b[t]);if(h(v,"resize",H),H(),a.emit("init"),Y=performance.now(),D=requestAnimationFrame($),u.tapEvents){let t=(i,f)=>[(i-c.offsetLeft)/E,(f-c.offsetTop)/E],n=new Map,o=(i,f,s)=>{let p={x:f,y:s,startX:f,startY:s,ts:performance.now()};return n.set(i,p),p},l=(i,f,s)=>{let p=n.get(i)||o(i);p.x=f,p.y=s},d=i=>i&&performance.now()-i.ts<=200,x=!1;h(c,"mousedown",i=>{i.preventDefault();let[f,s]=t(i.pageX,i.pageY);a.emit("tap",f,s,0),o(0,f,s),x=!0}),h(c,"mousemove",i=>{i.preventDefault();let[f,s]=[L,P]=t(i.pageX,i.pageY);x&&(a.emit("tapping",f,s,0),l(0,f,s))}),h(c,"mouseup",i=>{i.preventDefault();let f=n.get(0),[s,p]=t(i.pageX,i.pageY);d(f)&&a.emit("tapped",f.startX,f.startY,0),a.emit("untap",s,p,0),n.delete(0),x=!1}),h(c,"touchstart",i=>{i.preventDefault();let f=i.changedTouches;for(let s=0;s<f.length;s++){let p=f[s],[W,X]=t(p.pageX,p.pageY);a.emit("tap",W,X,p.identifier+1),o(p.identifier+1,W,X)}}),h(c,"touchmove",i=>{i.preventDefault();let f=i.changedTouches;for(let s=0;s<f.length;s++){let p=f[s],[W,X]=t(p.pageX,p.pageY);a.emit("tapping",W,X,p.identifier+1),l(p.identifier+1,W,X)}});let w=i=>{i.preventDefault();let f=[];if(i.targetTouches.length>0)for(let s of i.targetTouches)f.push(s.identifier+1);for(let[s,p]of n)f.includes(s)||(d(p)&&a.emit("tapped",p.startX,p.startY,s),a.emit("untap",p.x,p.y,s),n.delete(s))};h(c,"touchend",w),h(c,"touchcancel",w),h(v,"blur",()=>{if(x=!1,n.size!==0)for(let[i,f]of n)a.emit("untap",f.x,f.y,i),n.delete(i)})}}function $(e){let t=0,n=e-Y;for(Y=e,C+=n;C>=I;)a.emit("update",B),a.setvar("ELAPSED",a.ELAPSED+B),C-=I,t++;t&&(O++,a.emit("draw"),F+=I*t,F+C>=1e3&&(a.setvar("FPS",O),O=0,F-=1e3)),D&&(D=requestAnimationFrame($))}function K(){c=typeof c=="string"?document.querySelector(c):c,a.setvar("CANVAS",c),r=c.getContext("2d"),a.WIDTH>0&&(M=!1),c.width=a.WIDTH,c.height=a.HEIGHT||a.WIDTH,c.parentNode||document.body.appendChild(c),(!u.antialias||u.pixelart)&&(r.imageSmoothingEnabled=!1,c.style.imageRendering="pixelated"),c.style.display="block",M?(c.style.position="absolute",c.style.inset=0):R&&(c.style.margin="auto")}function H(){M?(c.width=innerWidth,c.height=innerHeight,a.setvar("WIDTH",innerWidth),a.setvar("HEIGHT",innerHeight)):R&&(E=Math.min(innerWidth/a.WIDTH,innerHeight/a.HEIGHT),E=u.pixelart?Math.floor(E):E,c.style.width=a.WIDTH*E+"px",c.style.height=a.HEIGHT*E+"px"),a.setvar("CENTERX",a.WIDTH/2),a.setvar("CENTERY",a.HEIGHT/2),a.textalign(j,N),a.emit("resized",E)}function z(e){let t=e(a,J,e.__config);if(typeof t=="object")for(let n in t)a.setvar(n,t[n])}if(u.global){if(v.__litecanvas)throw new Error("Cannot instantiate litecanvas globally twice");Object.assign(v,a),v.__litecanvas=!0}return document.readyState==="loading"?h(v,"DOMContentLoaded",S):S(),a}v.litecanvas=Q;})();
1
+ (()=>{zzfxX=new AudioContext;zzfxV=.3;zzfx=(u=1,D=.05,y=220,h=0,q=0,G=.1,W=0,f=1,Y=0,L=0,E=0,N=0,C=0,r=0,R=0,F=0,I=0,O=1,P=0,S=0,B=0)=>{let T=Math,_=2*T.PI,g=44100,$=Y*=500*_/g/g,V=y*=(1-D+2*D*T.random(D=[]))*_/g,A=0,w=0,x=0,n=1,J=0,j=0,z=0,H=B<0?-1:1,X=_*H*B*2/g,e=T.cos(X),t=T.sin,a=t(X)/4,i=1+a,l=-2*e/i,d=(1-a)/i,m=(1+H*e)/2/i,b=-(H+e)/i,o=m,c=0,s=0,p=0,M=0;for(h=g*h+9,P*=g,q*=g,G*=g,I*=g,L*=500*_/g**3,R*=_/g,E*=_/g,N*=g,C=g*C|0,u*=zzfxV,H=h+P+q+G+I|0;x<H;D[x++]=z*u)++j%(100*F|0)||(z=W?1<W?2<W?3<W?t(A*A):T.max(T.min(T.tan(A),1),-1):1-(2*A/_%2+2)%2:1-4*T.abs(T.round(A/_)-A/_):t(A),z=(C?1-S+S*t(_*x/C):1)*(z<0?-1:1)*T.abs(z)**f*(x<h?x/h:x<h+P?1-(x-h)/P*(1-O):x<h+P+q?O:x<H-I?(H-x-I)/G*O:0),z=I?z/2+(I>x?0:(x<H-I?1:(H-x)/I)*D[x-I|0]/2/u):z,B&&(z=M=o*c+b*(c=s)+m*(s=z)-d*p-l*(p=M))),X=(y+=Y+=L)*T.cos(R*w++),A+=X+X*r*t(x**5),n&&++n>N&&(y+=E,V+=E,n=0),!C||++J%C||(y=V,Y=$,n=n||1);u=zzfxX.createBuffer(1,H,g),u.getChannelData(0).set(D),y=zzfxX.createBufferSource(),y.buffer=u,y.connect(zzfxX.destination),y.start()};var K=["#18161c","#6a7799","#aec2c2","#f3eade","#f04f78","#fcf660","#2f328f","#4b80ca","#327345","#63c64d","#703075","#a56243"];var Q=[[.8,0,2e3,.01,.05,,1,2,,,-600,.05,,,,,,.5,.05],[.5,0,375,.02,.01,.2,1,,,,,,,.4,,.1,,.6,.1],[,0,360,.01,,.08,1,1.7,12,32,,,,,,,,.63,.02,,99],[1.2,0,240,.02,.15,.15,1,4,,,,,.05,,,,,.6,.15]];var v=globalThis;function U(u={}){let D=Math.PI,y=D*2,h=(e,t,a)=>e.addEventListener(t,a);u=Object.assign({fps:60,fullscreen:!0,width:null,height:null,pauseOnBlur:!0,autoscale:!0,pixelart:!1,antialias:!0,canvas:null,global:!0,tapEvents:!0,loop:null},u);let G=!1,W=[],f=u.canvas||document.createElement("canvas"),Y=u.fullscreen,L=u.autoscale,E=1,N,C,r,R=1,F,I=1/u.fps,O=I*1e3,P=0,S,B=0,T=0,_="sans-serif",g="",$=32,V="start",A="top",w={init:[],update:[],draw:[],resized:[],tap:[],untap:[],tapping:[],tapped:[]},x={settings:Object.assign({},u),colors:K,sounds:Q},n={WIDTH:u.width,HEIGHT:u.height||u.width,CANVAS:null,ELAPSED:0,FPS:u.fps,CENTERX:null,CENTERY:null,PI:D,TWO_PI:y,HALF_PI:D*.5,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>D/180*e,rad2deg:e=>180/D*e,clamp:(e,t,a)=>Math.min(Math.max(e,t),a),wrap:(e,t,a)=>e-(a-t)*Math.floor((e-t)/(a-t)),map(e,t,a,i,l,d=!1){let m=(e-t)/(a-t)*(l-i)+i;return d?n.clamp(m,i,l):m},norm:(e,t,a)=>n.map(e,t,a,0,1),rand:(e=0,t=1)=>Math.random()*(t-e)+e,randi:(e=0,t=1)=>n.floor(n.rand()*(t-e+1)+e),cls(e){e==null?r.clearRect(0,0,n.WIDTH,n.HEIGHT):n.rectfill(0,0,n.WIDTH,n.HEIGHT,e)},rect(e,t,a,i,l=0,d=null){r.beginPath(),r[d?"roundRect":"rect"](~~e,~~t,~~a,~~i,d),n.stroke(l)},rectfill(e,t,a,i,l=0,d=null){r.beginPath(),r[d?"roundRect":"rect"](~~e,~~t,~~a,~~i,d),n.fill(l)},circ(e,t,a,i=0){r.beginPath(),r.arc(~~e,~~t,~~a,0,y),r.closePath(),n.stroke(i)},circfill(e,t,a,i=0){r.beginPath(),r.arc(~~e,~~t,~~a,0,y),r.closePath(),n.fill(i)},line(e,t,a,i,l=0){r.beginPath(),r.moveTo(~~e,~~t),r.lineTo(~~a,~~i),n.stroke(l)},linewidth(e){r.lineWidth=e},linedash(e,t=0){r.setLineDash(Array.isArray(e)?e:[e]),r.lineDashOffset=t},text(e,t,a,i=3){r.font=`${g||""} ${~~$}px ${_}`,r.fillStyle=n.getcolor(i),r.fillText(a,~~e,~~t)},textfont(e){_=e},textsize(e){$=e},textstyle(e){g=e},textalign(e,t){r.textAlign=V=e,r.textBaseline=A=t},textmetrics(e,t){return r.font=`${g||""} ${~~(t||$)}px ${_}`,metrics=r.measureText(e),metrics.height=metrics.actualBoundingBoxAscent+metrics.actualBoundingBoxDescent,metrics},image(e,t,a){r.drawImage(a,~~e,~~t)},paint(e,t,a,i={}){let l=new OffscreenCanvas(e,t),d=r,m=i.scale||1;if(l.width=e*m,l.height=t*m,r=l.getContext("2d"),r.scale(m,m),Array.isArray(a)){let b=0,o=0;r.imageSmoothingEnabled=!1;for(let c of a){for(let s of c)s!==" "&&s!=="."&&n.rectfill(b,o,1,1,parseInt(s,16)),b++;o++,b=0}}else a(l,r);return r=d,l},ctx:()=>r,push:()=>r.save(),pop:()=>r.restore(),translate:(e,t)=>r.translate(e,t),scale:(e,t)=>r.scale(e,t||e),rotate:e=>r.rotate(e),transform:(e,t,a,i,l,d,m=!0)=>r[m?"setTransform":"transform"](e,t,a,i,l,d),alpha(e){r.globalAlpha=e},path:e=>new Path2D(e),fill(e,t){r.fillStyle=n.getcolor(e),r.fill(t)},stroke(e,t){r.strokeStyle=n.getcolor(e),t?r.stroke(t):r.stroke()},cliprect(e,t,a,i){r.beginPath(),r.rect(e,t,a,i),r.clip()},clipcirc(e,t,a){r.beginPath(),r.arc(e,t,a,0,y),r.clip()},blendmode(e){r.globalCompositeOperation=e},sfx(e=0,t=1,a=0,i=0){if(navigator.userActivation&&!navigator.userActivation.hasBeenActive)return;let l=Array.isArray(e)?e:Q[~~e%Q.length];return(t!==1||a||i)&&(l=[...l],l[0]=(Number(t)||1)*(l[0]||1),l[1]=i>0?i:0,l[10]=~~l[10]+~~a),zzfx(...l)},colrect:(e,t,a,i,l,d,m,b)=>e<l+m&&e+a>l&&t<d+b&&t+i>d,colcirc:(e,t,a,i,l,d)=>(i-e)**2+(l-t)**2<=(a+d)**2,mousepos:()=>[N,C],timescale(e){R=e},use:(e,t={})=>{e.__config=t,G?X(e):W.push(e)},listen(e,t,a=!1){return w[e]=w[e]||[],w[e][a?"unshift":"push"](t),()=>{w[e]=w[e].filter(i=>i!==t)}},emit(e,...t){if(w[e])for(let a=0;a<w[e].length;++a)w[e][a](...t)},getcolor:e=>K[~~e%K.length],setvar(e,t){n[e]=t,u.global&&(v[e]=t)},resize(e,t){n.setvar("WIDTH",f.width=~~e),n.setvar("HEIGHT",f.height=~~(t||e)),H()}};for(let e of["sin","cos","atan2","hypot","tan","abs","ceil","round","floor","trunc","min","max","pow","sqrt","sign","exp"])n[e]=Math[e];function J(){G=!0,z();let e=u.loop?u.loop:v;for(let t in w)e[t]&&n.listen(t,e[t]);for(let t=0;t<W.length;t++)X(W[t]);if(h(v,"resize",H),H(),u.tapEvents){let t=(o,c)=>[(o-f.offsetLeft)/E,(c-f.offsetTop)/E],a=new Map,i=(o,c,s)=>{let p={x:c,y:s,startX:c,startY:s,ts:performance.now()};return a.set(o,p),p},l=(o,c,s)=>{let p=a.get(o)||i(o);p.x=c,p.y=s},d=o=>o&&performance.now()-o.ts<=200,m=!1;h(f,"mousedown",o=>{o.preventDefault();let[c,s]=t(o.pageX,o.pageY);n.emit("tap",c,s,0),i(0,c,s),m=!0}),h(f,"mousemove",o=>{o.preventDefault();let[c,s]=[N,C]=t(o.pageX,o.pageY);m&&(n.emit("tapping",c,s,0),l(0,c,s))}),h(f,"mouseup",o=>{o.preventDefault();let c=a.get(0),[s,p]=t(o.pageX,o.pageY);d(c)&&n.emit("tapped",c.startX,c.startY,0),n.emit("untap",s,p,0),a.delete(0),m=!1}),h(f,"touchstart",o=>{o.preventDefault();let c=o.changedTouches;for(let s=0;s<c.length;s++){let p=c[s],[M,k]=t(p.pageX,p.pageY);n.emit("tap",M,k,p.identifier+1),i(p.identifier+1,M,k)}}),h(f,"touchmove",o=>{o.preventDefault();let c=o.changedTouches;for(let s=0;s<c.length;s++){let p=c[s],[M,k]=t(p.pageX,p.pageY);n.emit("tapping",M,k,p.identifier+1),l(p.identifier+1,M,k)}});let b=o=>{o.preventDefault();let c=[];if(o.targetTouches.length>0)for(let s of o.targetTouches)c.push(s.identifier+1);for(let[s,p]of a)c.includes(s)||(d(p)&&n.emit("tapped",p.startX,p.startY,s),n.emit("untap",p.x,p.y,s),a.delete(s))};h(f,"touchend",b),h(f,"touchcancel",b),h(v,"blur",()=>{if(m=!1,a.size!==0)for(let[o,c]of a)n.emit("untap",c.x,c.y,o),a.delete(o)})}u.pauseOnBlur&&(h(v,"blur",()=>{S=null}),h(v,"focus",()=>{S||(F=performance.now(),S=requestAnimationFrame(j))})),n.emit("init"),F=performance.now(),S=requestAnimationFrame(j)}function j(e){let t=0,a=e-F;for(F=e,P+=a;P>=O;)n.emit("update",I*R),n.setvar("ELAPSED",n.ELAPSED+I*R),P-=O,t++;t&&(n.emit("draw"),B++,T+=O*t,T+P>=1e3&&(n.setvar("FPS",B),B=0,T-=1e3)),S&&(S=requestAnimationFrame(j))}function z(){f=typeof f=="string"?document.querySelector(f):f,n.setvar("CANVAS",f),r=f.getContext("2d"),n.WIDTH>0&&(Y=!1),f.width=n.WIDTH,f.height=n.HEIGHT||n.WIDTH,f.parentNode||document.body.appendChild(f),(!u.antialias||u.pixelart)&&(r.imageSmoothingEnabled=!1,f.style.imageRendering="pixelated"),f.style.display="block",Y?(f.style.position="absolute",f.style.inset=0):L&&(f.style.margin="auto")}function H(){Y?(f.width=innerWidth,f.height=innerHeight,n.setvar("WIDTH",innerWidth),n.setvar("HEIGHT",innerHeight)):L&&(E=Math.min(innerWidth/n.WIDTH,innerHeight/n.HEIGHT),E=u.pixelart?Math.floor(E):E,f.style.width=n.WIDTH*E+"px",f.style.height=n.HEIGHT*E+"px"),n.setvar("CENTERX",n.WIDTH/2),n.setvar("CENTERY",n.HEIGHT/2),n.textalign(V,A),n.emit("resized",E)}function X(e){let t=e(n,x,e.__config);if(typeof t=="object")for(let a in t)n.setvar(a,t[a])}if(u.global){if(v.__litecanvas)throw new Error("Cannot instantiate litecanvas globally twice");Object.assign(v,n),v.__litecanvas=!0}return document.readyState==="loading"?h(v,"DOMContentLoaded",J):J(),n}v.litecanvas=U;})();
2
2
  //# sourceMappingURL=dist.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/zzfx.js", "../src/palette.js", "../src/sounds.js", "../src/index.js"],
4
- "sourcesContent": ["// ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX\nzzfxX = new AudioContext() // audio context\nzzfxV = 0.3 // global volume\nzzfx = (\n p = 1,\n k = 0.05,\n b = 220,\n e = 0,\n r = 0,\n t = 0.1,\n q = 0,\n D = 1,\n u = 0,\n y = 0,\n v = 0,\n z = 0,\n l = 0,\n E = 0,\n A = 0,\n F = 0,\n c = 0,\n w = 1,\n m = 0,\n B = 0,\n N = 0\n) => {\n let M = Math,\n d = 2 * M.PI,\n R = 44100,\n G = (u *= (500 * d) / R / R),\n C = (b *= ((1 - k + 2 * k * M.random((k = []))) * d) / R),\n g = 0,\n H = 0,\n a = 0,\n n = 1,\n I = 0,\n J = 0,\n f = 0,\n h = N < 0 ? -1 : 1,\n x = (d * h * N * 2) / R,\n L = M.cos(x),\n Z = M.sin,\n K = Z(x) / 4,\n O = 1 + K,\n X = (-2 * L) / O,\n Y = (1 - K) / O,\n P = (1 + h * L) / 2 / O,\n Q = -(h + L) / O,\n S = P,\n T = 0,\n U = 0,\n V = 0,\n W = 0\n e = R * e + 9\n m *= R\n r *= R\n t *= R\n c *= R\n y *= (500 * d) / R ** 3\n A *= d / R\n v *= d / R\n z *= R\n l = (R * l) | 0\n p *= zzfxV\n for (h = (e + m + r + t + c) | 0; a < h; k[a++] = f * p)\n ++J % ((100 * F) | 0) ||\n ((f = q\n ? 1 < q\n ? 2 < q\n ? 3 < q\n ? Z(g * g)\n : M.max(M.min(M.tan(g), 1), -1)\n : 1 - (((((2 * g) / d) % 2) + 2) % 2)\n : 1 - 4 * M.abs(M.round(g / d) - g / d)\n : Z(g)),\n (f =\n (l ? 1 - B + B * Z((d * a) / l) : 1) *\n (f < 0 ? -1 : 1) *\n M.abs(f) ** D *\n (a < e\n ? a / e\n : a < e + m\n ? 1 - ((a - e) / m) * (1 - w)\n : a < e + m + r\n ? w\n : a < h - c\n ? ((h - a - c) / t) * w\n : 0)),\n (f = c\n ? f / 2 +\n (c > a\n ? 0\n : ((a < h - c ? 1 : (h - a) / c) * k[(a - c) | 0]) /\n 2 /\n p)\n : f),\n N\n ? (f = W =\n S * T + Q * (T = U) + P * (U = f) - Y * V - X * (V = W))\n : 0),\n (x = (b += u += y) * M.cos(A * H++)),\n (g += x + x * E * Z(a ** 5)),\n n && ++n > z && ((b += v), (C += v), (n = 0)),\n !l || ++I % l || ((b = C), (u = G), (n = n || 1))\n p = zzfxX.createBuffer(1, h, R)\n p.getChannelData(0).set(k)\n b = zzfxX.createBufferSource()\n b.buffer = p\n b.connect(zzfxX.destination)\n b.start()\n}\n", "// Default colors inspired by https://lospec.com/palette-list/trirampo\nexport const colors = [\n '#18161c',\n '#6a7799',\n '#aec2c2',\n '#f3eade',\n\n '#f04f78',\n '#fcf660',\n '#2f328f',\n '#4b80ca',\n\n '#327345',\n '#63c64d',\n '#703075',\n '#a56243',\n]\n", "// prettier-ignore\nexport const sounds = [\n // 0 - pickup\n [0.8, 0, 2e3, 0.01, 0.05, , 1, 2, , , -600, 0.05, , , , , , 0.5, 0.05],\n // 1 - hit\n [0.5, 0, 375, 0.02, 0.01, 0.2, 1, , , , , , , 0.4, , 0.1, , 0.6, 0.1],\n // 2 - jump\n [, 0, 360, 0.01, , 0.08, 1, 1.7, 12, 32, , , , , , , , 0.63, 0.02, , 99],\n // 3 - warning\n [1.2, 0, 240, 0.02, 0.15, 0.15, 1, 4, , , , , 0.05, , , , , 0.6, 0.15],\n]\n", "/* litecanvas v0.41.3 | https://github.com/litecanvas/game-engine */\nimport './zzfx'\nimport { colors } from './palette'\nimport { sounds } from './sounds'\n\nconst root = globalThis\n\n/**\n * The litecanvas constructor\n *\n * @param {LitecanvasOptions} [settings]\n * @returns {LitecanvasInstance}\n */\nexport default function litecanvas(settings = {}) {\n // helpers\n const PI = Math.PI,\n TWO_PI = PI * 2,\n /** @type {(elem:HTMLElement, evt:string, callback:Function)=>void} */\n on = (elem, evt, callback) => elem.addEventListener(evt, callback),\n /** @type {LitecanvasOptions} */\n defaults = {\n fps: 60,\n fullscreen: true,\n width: null,\n height: null,\n autoscale: true,\n pixelart: false,\n antialias: true,\n canvas: null,\n global: true,\n tapEvents: true,\n loop: null,\n }\n\n // setup the settings default values\n settings = Object.assign(defaults, settings)\n\n let /** @type {boolean} */\n _initialized = false,\n /** @type {function[]} */\n _plugins = [],\n /** @type {HTMLCanvasElement|string} _canvas */\n _canvas = settings.canvas || document.createElement('canvas'),\n /** @type {boolean} */\n _fullscreen = settings.fullscreen,\n /** @type {boolean} */\n _autoscale = settings.autoscale,\n /** @type {number} */\n _scale = 1,\n /** @type {number?} */\n _mouseX,\n /** @type {number?} */\n _mouseY,\n /** @type {CanvasRenderingContext2D} */\n _ctx,\n /** @type {number} */\n _lastFrame,\n /** @type {number} */\n _step = 1 / settings.fps,\n /** @type {number} */\n _stepMs = _step * 1000,\n /** @type {number} */\n _accumulated = 0,\n /** @type {number} */\n _rafid,\n /** @type {number} */\n _drawCount = 0,\n /** @type {number} */\n _drawTime = 0,\n /** @type {string} */\n _fontFamily = 'sans-serif',\n /** @type {string} */\n _fontStyle = '',\n /** @type {number} */\n _fontSize = 32,\n /** @type {string} */\n _textAlign = 'start',\n /** @type {string} */\n _textBaseline = 'top',\n /**\n * default game events\n */\n _events = {\n init: [],\n update: [],\n draw: [],\n resized: [],\n tap: [],\n untap: [],\n tapping: [],\n tapped: [],\n },\n /**\n * Helpers to be used by plugins\n *\n * @type {LitecanvasPluginHelpers}\n */\n _helpers = {\n settings: Object.assign({}, settings),\n colors,\n sounds,\n }\n\n /** @type {LitecanvasInstance} */\n const instance = {\n /** @type {number} */\n WIDTH: settings.width,\n /** @type {number} */\n HEIGHT: settings.height || settings.width,\n /** @type {HTMLCanvasElement} */\n CANVAS: null,\n /** @type {number} */\n ELAPSED: 0,\n /** @type {number} */\n FPS: settings.fps,\n /** @type {number} */\n CENTERX: null,\n /** @type {number} */\n CENTERY: null,\n\n /** MATH API */\n /**\n * The value of the mathematical constant PI (\u03C0).\n * Approximately 3.14159\n *\n * @type {number}\n */\n PI,\n\n /**\n * Twice the value of the mathematical constant PI (\u03C0).\n * Approximately 6.28318\n *\n * Note: TWO_PI radians equals 360\u00B0, PI radians equals 180\u00B0,\n * HALF_PI radians equals 90\u00B0, and HALF_PI/2 radians equals 45\u00B0.\n *\n * @type {number}\n */\n TWO_PI,\n\n /**\n * Half the value of the mathematical constant PI (\u03C0).\n * Approximately 1.57079\n *\n * @type {number}\n */\n HALF_PI: PI * 0.5,\n\n /**\n * Calculates a linear (interpolation) value over t%.\n *\n * @param {number} start\n * @param {number} end\n * @param {number} t The progress in percentage, where 0 = 0% and 1 = 100%.\n * @returns {number} The unterpolated value\n * @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/\n */\n lerp: (start, end, t) => start + t * (end - start),\n\n /**\n * Convert degrees to radians\n *\n * @param {number} degs\n * @returns {number} the value in radians\n */\n deg2rad: (degs) => (PI / 180) * degs,\n\n /**\n * Convert radians to degrees\n *\n * @param {number} rads\n * @returns {number} the value in degrees\n */\n rad2deg: (rads) => (180 / PI) * rads,\n\n /**\n * Constrains a number between `min` and `max`.\n *\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\n clamp: (value, min, max) => Math.min(Math.max(value, min), max),\n\n /**\n * Wraps a number between `min` (inclusive) and `max` (exclusive).\n *\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\n wrap: (value, min, max) =>\n value - (max - min) * Math.floor((value - min) / (max - min)),\n\n /**\n * Re-maps a number from one range to another.\n *\n * @param {number} value the value to be remapped.\n * @param {number} min1 lower bound of the value's current range.\n * @param {number} max1 upper bound of the value's current range.\n * @param {number} min2 lower bound of the value's target range.\n * @param {number} max2 upper bound of the value's target range.\n * @param {boolean} [withinBounds=false] constrain the value to the newly mapped range\n * @returns {number} the remapped number\n */\n map(value, min1, max1, min2, max2, withinBounds = false) {\n // prettier-ignore\n const result = ((value - min1) / (max1 - min1)) * (max2 - min2) + min2\n return !withinBounds ? result : instance.clamp(result, min2, max2)\n },\n\n /**\n * Maps a number from one range to a value between 0 and 1.\n *\n * @param {number} value\n * @param {number} min\n * @param {number} min\n * @returns {number} the normalized number.\n */\n norm: (value, min, max) => instance.map(value, min, max, 0, 1),\n\n /** RNG API */\n /**\n * Generates a pseudorandom float between min (inclusive) and max (exclusive)\n *\n * @param {number} [min=0.0]\n * @param {number} [max=1.0]\n * @returns {number} the random number\n */\n rand: (min = 0.0, max = 1.0) => Math.random() * (max - min) + min,\n\n /**\n * Generates a pseudorandom integer between min (inclusive) and max (inclusive)\n *\n * @param {number} [min=0]\n * @param {number} [max=1]\n * @returns {number} the random number\n */\n randi: (min = 0, max = 1) =>\n instance.floor(instance.rand() * (max - min + 1) + min),\n\n /** BASIC GRAPHICS API */\n /**\n * Clear the game screen\n *\n * @param {number|null} color The background color (from 0 to 7) or null\n */\n cls(color) {\n if (null == color) {\n _ctx.clearRect(0, 0, instance.WIDTH, instance.HEIGHT)\n } else {\n instance.rectfill(0, 0, instance.WIDTH, instance.HEIGHT, color)\n }\n },\n\n /**\n * Draw a rectangle outline\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @param {number} [color=0] the color index (generally from 0 to 7)\n * @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle\n */\n rect(x, y, width, height, color = 0, radii = null) {\n _ctx.beginPath()\n _ctx[radii ? 'roundRect' : 'rect'](\n ~~x,\n ~~y,\n ~~width,\n ~~height,\n radii\n )\n instance.stroke(color)\n },\n\n /**\n * Draw a color-filled rectangle\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @param {number} [color=0] the color index (generally from 0 to 7)\n * @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle\n */\n rectfill(x, y, width, height, color = 0, radii = null) {\n _ctx.beginPath()\n _ctx[radii ? 'roundRect' : 'rect'](\n ~~x,\n ~~y,\n ~~width,\n ~~height,\n radii\n )\n instance.fill(color)\n },\n\n /**\n * Draw a circle outline\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n circ(x, y, radius, color = 0) {\n _ctx.beginPath()\n _ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)\n _ctx.closePath()\n instance.stroke(color)\n },\n\n /**\n * Draw a color-filled circle\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n circfill(x, y, radius, color = 0) {\n _ctx.beginPath()\n _ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)\n _ctx.closePath()\n instance.fill(color)\n },\n\n /**\n * Draw a line\n *\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n line(x1, y1, x2, y2, color = 0) {\n _ctx.beginPath()\n _ctx.moveTo(~~x1, ~~y1)\n _ctx.lineTo(~~x2, ~~y2)\n instance.stroke(color)\n },\n\n /**\n * Sets the thickness of lines\n *\n * @param {number} value\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth\n */\n linewidth(value) {\n _ctx.lineWidth = value\n },\n\n /**\n * Sets the line dash pattern used when drawing lines\n *\n * @param {number|number[]} segments the line dash pattern\n * @param {number} [offset=0] the line dash offset, or \"phase\".\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset\n */\n linedash(segments, offset = 0) {\n _ctx.setLineDash(Array.isArray(segments) ? segments : [segments])\n _ctx.lineDashOffset = offset\n },\n\n /** TEXT RENDERING API */\n /**\n * Draw text\n *\n * @param {number} x\n * @param {number} y\n * @param {string} text the text message\n * @param {number} [color=3] the color index (generally from 0 to 7)\n */\n text(x, y, text, color = 3) {\n _ctx.font = `${_fontStyle || ''} ${~~_fontSize}px ${_fontFamily}`\n _ctx.fillStyle = instance.getcolor(color)\n _ctx.fillText(text, ~~x, ~~y)\n },\n\n /**\n * Set the font family\n *\n * @param {string} fontFamily\n */\n textfont(fontFamily) {\n _fontFamily = fontFamily\n },\n\n /**\n * Set the font size\n *\n * @param {string} size\n */\n textsize(size) {\n _fontSize = size\n },\n\n /**\n * Sets whether a font should be styled with a normal, italic, or bold.\n *\n * @param {string} style\n */\n textstyle(style) {\n _fontStyle = style\n },\n\n /**\n * Sets the alignment used when drawing texts\n *\n * @param {string} align the horizontal alignment. Possible values: \"left\", \"right\", \"center\", \"start\" or \"end\"\n * @param {string} baseline the vertical alignment. Possible values: \"top\", \"bottom\", \"middle\", \"hanging\" or \"ideographic\"\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign\n */\n textalign(align, baseline) {\n _ctx.textAlign = _textAlign = align\n _ctx.textBaseline = _textBaseline = baseline\n },\n\n /**\n * Returns a TextMetrics object that contains information about the measured text (such as its width, for example)\n *\n * @param {string} text\n * @param {number} [size]\n * @returns {TextMetrics}\n * @see https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics\n */\n textmetrics(text, size) {\n // prettier-ignore\n _ctx.font = `${_fontStyle || ''} ${~~(size || _fontSize)}px ${_fontFamily}`\n metrics = _ctx.measureText(text)\n metrics.height =\n metrics.actualBoundingBoxAscent +\n metrics.actualBoundingBoxDescent\n return metrics\n },\n\n /** IMAGE GRAPHICS API */\n /**\n * Draw an image\n *\n * @param {number} x\n * @param {number} y\n * @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} image\n */\n image(x, y, image) {\n _ctx.drawImage(image, ~~x, ~~y)\n },\n\n /**\n * Creates a offscreen canvas to draw on it\n *\n * @param {number} width\n * @param {number} height\n * @param {string[]|drawCallback} draw\n * @param {{scale?:number}} [options]\n * @returns {OffscreenCanvas}\n * @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas\n */\n paint(width, height, draw, options = {}) {\n const offscreenCanvas = new OffscreenCanvas(width, height),\n ctxOriginal = _ctx,\n scale = options.scale || 1\n\n offscreenCanvas.width = width * scale\n offscreenCanvas.height = height * scale\n _ctx = offscreenCanvas.getContext('2d')\n\n _ctx.scale(scale, scale)\n\n // is pixelart?\n if (Array.isArray(draw)) {\n let x = 0,\n y = 0\n\n _ctx.imageSmoothingEnabled = false\n\n for (const str of draw) {\n for (const color of str) {\n if (' ' !== color && '.' !== color) {\n // support for 16-color palettes using hex (from 0 to f)\n instance.rectfill(x, y, 1, 1, parseInt(color, 16))\n }\n x++\n }\n y++\n x = 0\n }\n } else {\n draw(offscreenCanvas, _ctx)\n }\n\n _ctx = ctxOriginal // restore the context\n\n return offscreenCanvas\n },\n\n /** ADVANCED GRAPHICS API */\n /**\n * Get the canvas context\n *\n * @returns {CanvasRenderingContext2D}\n */\n ctx: () => _ctx,\n\n /**\n * saves the current drawing style settings and transformations\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save\n */\n push: () => _ctx.save(),\n\n /**\n * restores the drawing style settings and transformations\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore\n */\n pop: () => _ctx.restore(),\n\n /**\n * Adds a translation transformation to the current matrix\n *\n * @param {number} x\n * @param {number} y\n */\n translate: (x, y) => _ctx.translate(x, y),\n\n /**\n * Adds a scaling transformation to the canvas units horizontally and/or vertically.\n *\n * @param {number} x\n * @param {number} [y]\n */\n scale: (x, y) => _ctx.scale(x, y || x),\n\n /**\n * Adds a rotation to the transformation matrix\n *\n * @param {number} radians\n */\n rotate: (radians) => _ctx.rotate(radians),\n\n /**\n * Adds a transformation that skews to the transformation matrix\n *\n * @param {number} a\n * @param {number} b\n * @param {number} c\n * @param {number} d\n * @param {number} e\n * @param {number} f\n * @param {boolean} [resetFirst=true] `false` to use _ctx.transform(); by default use _ctx.setTransform()\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform\n */\n transform: (a, b, c, d, e, f, resetFirst = true) =>\n _ctx[resetFirst ? 'setTransform' : 'transform'](a, b, c, d, e, f),\n\n /**\n * Sets the alpha (transparency) value to apply when drawing new shapes and images\n *\n * @param {number} alpha float from 0 to 1 (e.g: 0.5 = 50% transparent)\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha\n */\n alpha(alpha) {\n _ctx.globalAlpha = alpha\n },\n\n /**\n * Returns a newly instantiated Path2D object, optionally with another\n * path as an argument (creates a copy), or optionally with a string\n * consisting of SVG path data.\n *\n * @param {Path2D|string} [arg]\n * @returns Path2D\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D\n */\n path: (arg) => new Path2D(arg),\n\n /**\n * Fills the current or given path with a given color.\n *\n * @param {number} color\n * @param {Path2D} [path]\n */\n fill(color, path) {\n _ctx.fillStyle = instance.getcolor(color)\n _ctx.fill(path)\n },\n\n /**\n * Outlines the current or given path with a given color.\n *\n * @param {number} color\n * @param {Path2D} [path]\n */\n stroke(color, path) {\n _ctx.strokeStyle = instance.getcolor(color)\n path ? _ctx.stroke(path) : _ctx.stroke()\n },\n\n /**\n * Create a retangular clipping region.\n *\n * Note: Clip paths cannot be reverted directly. You must save your\n * canvas state using push() before calling cliprect(), and restore it\n * once you have finished drawing in the clipped area using pop().\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip\n */\n cliprect(x, y, width, height) {\n _ctx.beginPath()\n _ctx.rect(x, y, width, height)\n _ctx.clip()\n },\n\n /**\n * Create a circular clipping region.\n *\n * Note: Clip paths cannot be reverted directly. You must save your\n * canvas state using push() before calling clipcirc(), and restore it\n * once you have finished drawing in the clipped area using pop().\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip\n */\n clipcirc(x, y, radius) {\n _ctx.beginPath()\n _ctx.arc(x, y, radius, 0, TWO_PI)\n _ctx.clip()\n },\n\n /**\n * Sets the type of compositing operation to apply when drawing new shapes.\n * Default value = 'source-over'.\n *\n * @param {string} value\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation\n */\n blendmode(value) {\n _ctx.globalCompositeOperation = value\n },\n\n /** SOUND API */\n /**\n * Play a defined sound or a ZzFX array of params\n *\n * @param {number|number[]} [sound=0] the sound index (from 0 to 7) or a ZzFX array of params\n * @param {number} [volume=1]\n * @param {number} [pitch=0]\n * @param {number} [randomness=0]\n * @returns {AudioBufferSourceNode}\n * @see https://github.com/KilledByAPixel/ZzFX\n */\n sfx(sound = 0, volume = 1, pitch = 0, randomness = 0) {\n if (\n navigator.userActivation &&\n !navigator.userActivation.hasBeenActive\n ) {\n return\n }\n\n let z = Array.isArray(sound)\n ? sound\n : sounds[~~sound % sounds.length]\n if (volume !== 1 || pitch || randomness) {\n z = [...z] // clone the sound to not modify the original\n z[0] = (Number(volume) || 1) * (z[0] || 1)\n z[1] = randomness > 0 ? randomness : 0\n z[10] = ~~z[10] + ~~pitch\n }\n\n return zzfx(...z)\n },\n\n /** UTILS API */\n /**\n * Check a collision between two rectangles\n *\n * @param {number} x1 first rectangle position X\n * @param {number} y1 first rectangle position Y\n * @param {number} w1 first rectangle width\n * @param {number} h1 first rectangle height\n * @param {number} x2 second rectangle position X\n * @param {number} y2 second rectangle position Y\n * @param {number} w2 second rectangle width\n * @param {number} h2 second rectangle height\n * @returns {boolean}\n */\n colrect: (x1, y1, w1, h1, x2, y2, w2, h2) =>\n x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2,\n\n /**\n * Check a collision between two circles\n *\n * @param {number} x1 first circle position X\n * @param {number} y1 first circle position Y\n * @param {number} r1 first circle position radius\n * @param {number} x2 second circle position X\n * @param {number} y2 second circle position Y\n * @param {number} r2 second circle position radius\n * @returns {boolean}\n */\n colcirc: (x1, y1, r1, x2, y2, r2) =>\n (x2 - x1) ** 2 + (y2 - y1) ** 2 <= (r1 + r2) ** 2,\n\n /**\n * Get the mouse position\n * @returns number[]\n */\n mousepos: () => [_mouseX, _mouseY],\n\n /** PLUGINS API */\n /**\n * Prepares a plugin to be loaded\n *\n * @param {pluginCallback} callback\n */\n use: (callback, config = {}) => {\n callback.__config = config\n _initialized ? loadPlugin(callback) : _plugins.push(callback)\n },\n\n /**\n * Add a game event listener\n *\n * @param {string} event the event type name\n * @param {function} callback the function that is called when the event occurs\n * @param {boolean} [highPriority=false] determines whether the callback will be called before or after the others\n * @returns {function} a function to remove the listener\n */\n listen(event, callback, highPriority = false) {\n _events[event] = _events[event] || []\n _events[event][highPriority ? 'unshift' : 'push'](callback)\n\n // return a function to remove this event listener\n return () => {\n _events[event] = _events[event].filter(\n (item) => item !== callback\n )\n }\n },\n\n /**\n * Call all listeners attached to a game event\n *\n * @param {string} event The game event type\n * @param {...any} args Arguments passed to all listeners\n */\n emit(event, ...args) {\n if (!_events[event]) return\n for (let i = 0; i < _events[event].length; ++i) {\n _events[event][i](...args)\n }\n },\n\n /**\n * Get the color value\n *\n * @param {number} index The color number\n * @returns {string} the color value\n */\n getcolor: (index) => colors[~~index % colors.length],\n\n /**\n * Create or update a instance variable\n *\n * @param {string} key\n * @param {any} value\n */\n setvar(key, value) {\n instance[key] = value\n if (settings.global) {\n root[key] = value\n }\n },\n\n /**\n * Resizes the game canvas and emit the \"resized\" event\n *\n * @param {number} width\n * @param {number} height\n */\n resize(width, height) {\n instance.setvar('WIDTH', (_canvas.width = ~~width))\n instance.setvar('HEIGHT', (_canvas.height = ~~(height || width)))\n pageResized()\n },\n }\n\n /** Copy some functions from native `Math` object */\n for (const k of [\n 'sin',\n 'cos',\n 'atan2',\n 'hypot',\n 'tan',\n 'abs',\n 'ceil',\n 'round',\n 'floor',\n 'trunc',\n 'min',\n 'max',\n 'pow',\n 'sqrt',\n 'sign',\n 'exp',\n ]) {\n // import some native Math functions\n instance[k] = Math[k]\n }\n\n function init() {\n _initialized = true\n setupCanvas()\n\n // pause on page blur\n on(root, 'blur', () => {\n cancelAnimationFrame(_rafid)\n _rafid = 0\n })\n\n // resume on page focus if paused\n on(root, 'focus', () => {\n if (!_rafid) {\n _lastFrame = performance.now()\n _rafid = requestAnimationFrame(drawFrame)\n }\n })\n\n // listen the default events\n const source = settings.loop ? settings.loop : root\n for (const event in _events) {\n if (source[event]) instance.listen(event, source[event])\n }\n\n // load plugins\n for (let i = 0; i < _plugins.length; i++) {\n loadPlugin(_plugins[i])\n }\n\n // listen window resize event\n on(root, 'resize', pageResized)\n pageResized()\n\n // start the game loop\n instance.emit('init')\n _lastFrame = performance.now()\n _rafid = requestAnimationFrame(drawFrame)\n\n // default mouse/touch handlers\n if (settings.tapEvents) {\n const _getXY = (pageX, pageY) => [\n (pageX - _canvas.offsetLeft) / _scale,\n (pageY - _canvas.offsetTop) / _scale,\n ],\n _taps = new Map(),\n _registerTap = (id, x, y) => {\n const tap = {\n x,\n y,\n startX: x,\n startY: y,\n // timestamp\n ts: performance.now(),\n }\n _taps.set(id, tap)\n return tap\n },\n _updateTap = (id, x, y) => {\n const tap = _taps.get(id) || _registerTap(id)\n tap.x = x\n tap.y = y\n },\n _checkTapped = (tap) => tap && performance.now() - tap.ts <= 200\n\n let _pressingMouse = false\n\n on(_canvas, 'mousedown', (ev) => {\n ev.preventDefault()\n const [x, y] = _getXY(ev.pageX, ev.pageY)\n instance.emit('tap', x, y, 0)\n _registerTap(0, x, y)\n _pressingMouse = true\n })\n\n on(_canvas, 'mousemove', (ev) => {\n ev.preventDefault()\n const [x, y] = ([_mouseX, _mouseY] = _getXY(ev.pageX, ev.pageY))\n if (!_pressingMouse) return\n instance.emit('tapping', x, y, 0)\n _updateTap(0, x, y)\n })\n\n on(_canvas, 'mouseup', (ev) => {\n ev.preventDefault()\n const tap = _taps.get(0)\n const [x, y] = _getXY(ev.pageX, ev.pageY)\n if (_checkTapped(tap)) {\n instance.emit('tapped', tap.startX, tap.startY, 0)\n }\n instance.emit('untap', x, y, 0)\n _taps.delete(0)\n _pressingMouse = false\n })\n\n on(_canvas, 'touchstart', (ev) => {\n ev.preventDefault()\n /** @type {TouchList} touches */\n const touches = ev.changedTouches\n for (let i = 0; i < touches.length; i++) {\n const touch = touches[i]\n const [x, y] = _getXY(touch.pageX, touch.pageY)\n instance.emit('tap', x, y, touch.identifier + 1)\n _registerTap(touch.identifier + 1, x, y)\n }\n })\n\n on(_canvas, 'touchmove', (ev) => {\n ev.preventDefault()\n /** @type {TouchList} touches */\n const touches = ev.changedTouches\n for (let i = 0; i < touches.length; i++) {\n const touch = touches[i]\n const [x, y] = _getXY(touch.pageX, touch.pageY)\n instance.emit('tapping', x, y, touch.identifier + 1)\n _updateTap(touch.identifier + 1, x, y)\n }\n })\n\n const _touchEndHandler = (ev) => {\n ev.preventDefault()\n const existing = []\n\n if (ev.targetTouches.length > 0) {\n for (const touch of ev.targetTouches) {\n existing.push(touch.identifier + 1)\n }\n }\n\n for (const [id, tap] of _taps) {\n if (existing.includes(id)) continue\n if (_checkTapped(tap)) {\n instance.emit('tapped', tap.startX, tap.startY, id)\n }\n instance.emit('untap', tap.x, tap.y, id)\n _taps.delete(id)\n }\n }\n\n on(_canvas, 'touchend', _touchEndHandler)\n on(_canvas, 'touchcancel', _touchEndHandler)\n\n on(root, 'blur', () => {\n _pressingMouse = false\n\n if (_taps.size === 0) return\n\n for (const [id, tap] of _taps) {\n instance.emit('untap', tap.x, tap.y, id)\n _taps.delete(id)\n }\n })\n }\n }\n\n /**\n * @param {number} now\n */\n function drawFrame(now) {\n let ticks = 0,\n t = now - _lastFrame\n\n _lastFrame = now\n _accumulated += t\n\n while (_accumulated >= _stepMs) {\n instance.emit('update', _step)\n instance.setvar('ELAPSED', instance.ELAPSED + _step)\n _accumulated -= _stepMs\n ticks++\n }\n\n if (ticks) {\n _drawCount++\n instance.emit('draw')\n _drawTime += _stepMs * ticks\n if (_drawTime + _accumulated >= 1000) {\n instance.setvar('FPS', _drawCount)\n _drawCount = 0\n _drawTime -= 1000\n }\n }\n\n if (_rafid) _rafid = requestAnimationFrame(drawFrame)\n }\n\n function setupCanvas() {\n _canvas =\n 'string' === typeof _canvas\n ? document.querySelector(_canvas)\n : _canvas\n\n instance.setvar('CANVAS', _canvas)\n _ctx = _canvas.getContext('2d')\n\n // disable fullscreen if a width is specified\n if (instance.WIDTH > 0) _fullscreen = false\n\n _canvas.width = instance.WIDTH\n _canvas.height = instance.HEIGHT || instance.WIDTH\n\n if (!_canvas.parentNode) document.body.appendChild(_canvas)\n\n if (!settings.antialias || settings.pixelart) {\n _ctx.imageSmoothingEnabled = false\n _canvas.style.imageRendering = 'pixelated'\n }\n\n // canvas CSS tweaks\n _canvas.style.display = 'block'\n if (_fullscreen) {\n _canvas.style.position = 'absolute'\n _canvas.style.inset = 0\n } else if (_autoscale) {\n _canvas.style.margin = 'auto'\n }\n }\n\n function pageResized() {\n if (_fullscreen) {\n _canvas.width = innerWidth\n _canvas.height = innerHeight\n instance.setvar('WIDTH', innerWidth)\n instance.setvar('HEIGHT', innerHeight)\n } else if (_autoscale) {\n _scale = Math.min(\n innerWidth / instance.WIDTH,\n innerHeight / instance.HEIGHT\n )\n _scale = settings.pixelart ? Math.floor(_scale) : _scale\n _canvas.style.width = instance.WIDTH * _scale + 'px'\n _canvas.style.height = instance.HEIGHT * _scale + 'px'\n }\n\n instance.setvar('CENTERX', instance.WIDTH / 2)\n instance.setvar('CENTERY', instance.HEIGHT / 2)\n\n // fix the font align and baseline\n instance.textalign(_textAlign, _textBaseline)\n\n instance.emit('resized', _scale)\n }\n\n /**\n * @param {pluginCallback} callback\n */\n function loadPlugin(callback) {\n const pluginData = callback(instance, _helpers, callback.__config)\n if ('object' === typeof pluginData) {\n for (const key in pluginData) {\n instance.setvar(key, pluginData[key])\n }\n }\n }\n\n if (settings.global) {\n if (root.__litecanvas) {\n throw new Error('Cannot instantiate litecanvas globally twice')\n }\n Object.assign(root, instance)\n root.__litecanvas = true\n }\n\n if ('loading' === document.readyState) {\n on(root, 'DOMContentLoaded', init)\n } else {\n init()\n }\n\n return instance\n}\n\nroot.litecanvas = litecanvas\n"],
5
- "mappings": "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",
6
- "names": ["p", "k", "b", "e", "r", "t", "q", "D", "u", "y", "v", "z", "l", "E", "A", "F", "c", "w", "m", "B", "N", "M", "d", "R", "G", "C", "g", "H", "n", "I", "J", "f", "h", "x", "L", "Z", "K", "O", "X", "Y", "P", "Q", "S", "T", "U", "V", "W", "colors", "sounds", "root", "litecanvas", "settings", "PI", "TWO_PI", "on", "elem", "evt", "callback", "_initialized", "_plugins", "_canvas", "_fullscreen", "_autoscale", "_scale", "_mouseX", "_mouseY", "_ctx", "_lastFrame", "_step", "_stepMs", "_accumulated", "_rafid", "_drawCount", "_drawTime", "_fontFamily", "_fontStyle", "_fontSize", "_textAlign", "_textBaseline", "_events", "_helpers", "colors", "sounds", "instance", "start", "end", "t", "degs", "rads", "value", "min", "max", "min1", "max1", "min2", "max2", "withinBounds", "result", "color", "x", "y", "width", "height", "radii", "radius", "x1", "y1", "x2", "y2", "segments", "offset", "text", "fontFamily", "size", "style", "align", "baseline", "image", "draw", "options", "offscreenCanvas", "ctxOriginal", "scale", "str", "radians", "a", "b", "c", "d", "e", "f", "resetFirst", "alpha", "arg", "path", "sound", "volume", "pitch", "randomness", "z", "w1", "h1", "w2", "h2", "r1", "r2", "config", "loadPlugin", "event", "highPriority", "item", "args", "i", "index", "key", "pageResized", "k", "init", "setupCanvas", "drawFrame", "source", "_getXY", "pageX", "pageY", "_taps", "_registerTap", "id", "tap", "_updateTap", "_checkTapped", "_pressingMouse", "ev", "touches", "touch", "_touchEndHandler", "existing", "now", "ticks", "pluginData"]
4
+ "sourcesContent": ["// ZzFXMicro - Zuper Zmall Zound Zynth - v1.3.0 by Frank Force | https://github.com/KilledByAPixel/ZzFX\nzzfxX = new AudioContext() // audio context\nzzfxV = 0.3 // global volume\nzzfx = (\n p = 1,\n k = 0.05,\n b = 220,\n e = 0,\n r = 0,\n t = 0.1,\n q = 0,\n D = 1,\n u = 0,\n y = 0,\n v = 0,\n z = 0,\n l = 0,\n E = 0,\n A = 0,\n F = 0,\n c = 0,\n w = 1,\n m = 0,\n B = 0,\n N = 0\n) => {\n let M = Math,\n d = 2 * M.PI,\n R = 44100,\n G = (u *= (500 * d) / R / R),\n C = (b *= ((1 - k + 2 * k * M.random((k = []))) * d) / R),\n g = 0,\n H = 0,\n a = 0,\n n = 1,\n I = 0,\n J = 0,\n f = 0,\n h = N < 0 ? -1 : 1,\n x = (d * h * N * 2) / R,\n L = M.cos(x),\n Z = M.sin,\n K = Z(x) / 4,\n O = 1 + K,\n X = (-2 * L) / O,\n Y = (1 - K) / O,\n P = (1 + h * L) / 2 / O,\n Q = -(h + L) / O,\n S = P,\n T = 0,\n U = 0,\n V = 0,\n W = 0\n e = R * e + 9\n m *= R\n r *= R\n t *= R\n c *= R\n y *= (500 * d) / R ** 3\n A *= d / R\n v *= d / R\n z *= R\n l = (R * l) | 0\n p *= zzfxV\n for (h = (e + m + r + t + c) | 0; a < h; k[a++] = f * p)\n ++J % ((100 * F) | 0) ||\n ((f = q\n ? 1 < q\n ? 2 < q\n ? 3 < q\n ? Z(g * g)\n : M.max(M.min(M.tan(g), 1), -1)\n : 1 - (((((2 * g) / d) % 2) + 2) % 2)\n : 1 - 4 * M.abs(M.round(g / d) - g / d)\n : Z(g)),\n (f =\n (l ? 1 - B + B * Z((d * a) / l) : 1) *\n (f < 0 ? -1 : 1) *\n M.abs(f) ** D *\n (a < e\n ? a / e\n : a < e + m\n ? 1 - ((a - e) / m) * (1 - w)\n : a < e + m + r\n ? w\n : a < h - c\n ? ((h - a - c) / t) * w\n : 0)),\n (f = c\n ? f / 2 +\n (c > a\n ? 0\n : ((a < h - c ? 1 : (h - a) / c) * k[(a - c) | 0]) /\n 2 /\n p)\n : f),\n N\n ? (f = W =\n S * T + Q * (T = U) + P * (U = f) - Y * V - X * (V = W))\n : 0),\n (x = (b += u += y) * M.cos(A * H++)),\n (g += x + x * E * Z(a ** 5)),\n n && ++n > z && ((b += v), (C += v), (n = 0)),\n !l || ++I % l || ((b = C), (u = G), (n = n || 1))\n p = zzfxX.createBuffer(1, h, R)\n p.getChannelData(0).set(k)\n b = zzfxX.createBufferSource()\n b.buffer = p\n b.connect(zzfxX.destination)\n b.start()\n}\n", "// Default colors inspired by https://lospec.com/palette-list/trirampo\nexport const colors = [\n '#18161c',\n '#6a7799',\n '#aec2c2',\n '#f3eade',\n\n '#f04f78',\n '#fcf660',\n '#2f328f',\n '#4b80ca',\n\n '#327345',\n '#63c64d',\n '#703075',\n '#a56243',\n]\n", "// prettier-ignore\nexport const sounds = [\n // 0 - pickup\n [0.8, 0, 2e3, 0.01, 0.05, , 1, 2, , , -600, 0.05, , , , , , 0.5, 0.05],\n // 1 - hit\n [0.5, 0, 375, 0.02, 0.01, 0.2, 1, , , , , , , 0.4, , 0.1, , 0.6, 0.1],\n // 2 - jump\n [, 0, 360, 0.01, , 0.08, 1, 1.7, 12, 32, , , , , , , , 0.63, 0.02, , 99],\n // 3 - warning\n [1.2, 0, 240, 0.02, 0.15, 0.15, 1, 4, , , , , 0.05, , , , , 0.6, 0.15],\n]\n", "/* litecanvas v0.42.0 | https://github.com/litecanvas/game-engine */\nimport './zzfx'\nimport { colors } from './palette'\nimport { sounds } from './sounds'\n\nconst root = globalThis\n\n/**\n * The litecanvas constructor\n *\n * @param {LitecanvasOptions} [settings]\n * @returns {LitecanvasInstance}\n */\nexport default function litecanvas(settings = {}) {\n // helpers\n const PI = Math.PI,\n TWO_PI = PI * 2,\n /** @type {(elem:HTMLElement, evt:string, callback:Function)=>void} */\n on = (elem, evt, callback) => elem.addEventListener(evt, callback),\n /** @type {LitecanvasOptions} */\n defaults = {\n fps: 60,\n fullscreen: true,\n width: null,\n height: null,\n pauseOnBlur: true,\n autoscale: true,\n pixelart: false,\n antialias: true,\n canvas: null,\n global: true,\n tapEvents: true,\n loop: null,\n }\n\n // setup the settings default values\n settings = Object.assign(defaults, settings)\n\n let /** @type {boolean} */\n _initialized = false,\n /** @type {function[]} */\n _plugins = [],\n /** @type {HTMLCanvasElement|string} _canvas */\n _canvas = settings.canvas || document.createElement('canvas'),\n /** @type {boolean} */\n _fullscreen = settings.fullscreen,\n /** @type {boolean} */\n _autoscale = settings.autoscale,\n /** @type {number} */\n _scale = 1,\n /** @type {number?} */\n _mouseX,\n /** @type {number?} */\n _mouseY,\n /** @type {CanvasRenderingContext2D} */\n _ctx,\n /** @type {number} */\n _timeScale = 1,\n /** @type {number} */\n _lastFrame,\n /** @type {number} */\n _step = 1 / settings.fps,\n /** @type {number} */\n _stepMs = _step * 1000,\n /** @type {number} */\n _accumulated = 0,\n /** @type {number} */\n _rafid,\n /** @type {number} */\n _drawCount = 0,\n /** @type {number} */\n _drawTime = 0,\n /** @type {string} */\n _fontFamily = 'sans-serif',\n /** @type {string} */\n _fontStyle = '',\n /** @type {number} */\n _fontSize = 32,\n /** @type {string} */\n _textAlign = 'start',\n /** @type {string} */\n _textBaseline = 'top',\n /**\n * default game events\n */\n _events = {\n init: [],\n update: [],\n draw: [],\n resized: [],\n tap: [],\n untap: [],\n tapping: [],\n tapped: [],\n },\n /**\n * Helpers to be used by plugins\n *\n * @type {LitecanvasPluginHelpers}\n */\n _helpers = {\n settings: Object.assign({}, settings),\n colors,\n sounds,\n }\n\n /** @type {LitecanvasInstance} */\n const instance = {\n /** @type {number} */\n WIDTH: settings.width,\n /** @type {number} */\n HEIGHT: settings.height || settings.width,\n /** @type {HTMLCanvasElement} */\n CANVAS: null,\n /** @type {number} */\n ELAPSED: 0,\n /** @type {number} */\n FPS: settings.fps,\n /** @type {number} */\n CENTERX: null,\n /** @type {number} */\n CENTERY: null,\n\n /** MATH API */\n /**\n * The value of the mathematical constant PI (\u03C0).\n * Approximately 3.14159\n *\n * @type {number}\n */\n PI,\n\n /**\n * Twice the value of the mathematical constant PI (\u03C0).\n * Approximately 6.28318\n *\n * Note: TWO_PI radians equals 360\u00B0, PI radians equals 180\u00B0,\n * HALF_PI radians equals 90\u00B0, and HALF_PI/2 radians equals 45\u00B0.\n *\n * @type {number}\n */\n TWO_PI,\n\n /**\n * Half the value of the mathematical constant PI (\u03C0).\n * Approximately 1.57079\n *\n * @type {number}\n */\n HALF_PI: PI * 0.5,\n\n /**\n * Calculates a linear (interpolation) value over t%.\n *\n * @param {number} start\n * @param {number} end\n * @param {number} t The progress in percentage, where 0 = 0% and 1 = 100%.\n * @returns {number} The unterpolated value\n * @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/\n */\n lerp: (start, end, t) => start + t * (end - start),\n\n /**\n * Convert degrees to radians\n *\n * @param {number} degs\n * @returns {number} the value in radians\n */\n deg2rad: (degs) => (PI / 180) * degs,\n\n /**\n * Convert radians to degrees\n *\n * @param {number} rads\n * @returns {number} the value in degrees\n */\n rad2deg: (rads) => (180 / PI) * rads,\n\n /**\n * Constrains a number between `min` and `max`.\n *\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\n clamp: (value, min, max) => Math.min(Math.max(value, min), max),\n\n /**\n * Wraps a number between `min` (inclusive) and `max` (exclusive).\n *\n * @param {number} value\n * @param {number} min\n * @param {number} max\n * @returns {number}\n */\n wrap: (value, min, max) =>\n value - (max - min) * Math.floor((value - min) / (max - min)),\n\n /**\n * Re-maps a number from one range to another.\n *\n * @param {number} value the value to be remapped.\n * @param {number} min1 lower bound of the value's current range.\n * @param {number} max1 upper bound of the value's current range.\n * @param {number} min2 lower bound of the value's target range.\n * @param {number} max2 upper bound of the value's target range.\n * @param {boolean} [withinBounds=false] constrain the value to the newly mapped range\n * @returns {number} the remapped number\n */\n map(value, min1, max1, min2, max2, withinBounds = false) {\n // prettier-ignore\n const result = ((value - min1) / (max1 - min1)) * (max2 - min2) + min2\n return !withinBounds ? result : instance.clamp(result, min2, max2)\n },\n\n /**\n * Maps a number from one range to a value between 0 and 1.\n *\n * @param {number} value\n * @param {number} min\n * @param {number} min\n * @returns {number} the normalized number.\n */\n norm: (value, min, max) => instance.map(value, min, max, 0, 1),\n\n /** RNG API */\n /**\n * Generates a pseudorandom float between min (inclusive) and max (exclusive)\n *\n * @param {number} [min=0.0]\n * @param {number} [max=1.0]\n * @returns {number} the random number\n */\n rand: (min = 0.0, max = 1.0) => Math.random() * (max - min) + min,\n\n /**\n * Generates a pseudorandom integer between min (inclusive) and max (inclusive)\n *\n * @param {number} [min=0]\n * @param {number} [max=1]\n * @returns {number} the random number\n */\n randi: (min = 0, max = 1) =>\n instance.floor(instance.rand() * (max - min + 1) + min),\n\n /** BASIC GRAPHICS API */\n /**\n * Clear the game screen\n *\n * @param {number|null} color The background color (from 0 to 7) or null (for transparent)\n */\n cls(color) {\n if (null == color) {\n _ctx.clearRect(0, 0, instance.WIDTH, instance.HEIGHT)\n } else {\n instance.rectfill(0, 0, instance.WIDTH, instance.HEIGHT, color)\n }\n },\n\n /**\n * Draw a rectangle outline\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @param {number} [color=0] the color index (generally from 0 to 7)\n * @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle\n */\n rect(x, y, width, height, color = 0, radii = null) {\n _ctx.beginPath()\n _ctx[radii ? 'roundRect' : 'rect'](\n ~~x,\n ~~y,\n ~~width,\n ~~height,\n radii\n )\n instance.stroke(color)\n },\n\n /**\n * Draw a color-filled rectangle\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @param {number} [color=0] the color index (generally from 0 to 7)\n * @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle\n */\n rectfill(x, y, width, height, color = 0, radii = null) {\n _ctx.beginPath()\n _ctx[radii ? 'roundRect' : 'rect'](\n ~~x,\n ~~y,\n ~~width,\n ~~height,\n radii\n )\n instance.fill(color)\n },\n\n /**\n * Draw a circle outline\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n circ(x, y, radius, color = 0) {\n _ctx.beginPath()\n _ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)\n _ctx.closePath()\n instance.stroke(color)\n },\n\n /**\n * Draw a color-filled circle\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n circfill(x, y, radius, color = 0) {\n _ctx.beginPath()\n _ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)\n _ctx.closePath()\n instance.fill(color)\n },\n\n /**\n * Draw a line\n *\n * @param {number} x1\n * @param {number} y1\n * @param {number} x2\n * @param {number} y2\n * @param {number} [color=0] the color index (generally from 0 to 7)\n */\n line(x1, y1, x2, y2, color = 0) {\n _ctx.beginPath()\n _ctx.moveTo(~~x1, ~~y1)\n _ctx.lineTo(~~x2, ~~y2)\n instance.stroke(color)\n },\n\n /**\n * Sets the thickness of lines\n *\n * @param {number} value\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth\n */\n linewidth(value) {\n _ctx.lineWidth = value\n },\n\n /**\n * Sets the line dash pattern used when drawing lines\n *\n * @param {number|number[]} segments the line dash pattern\n * @param {number} [offset=0] the line dash offset, or \"phase\".\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset\n */\n linedash(segments, offset = 0) {\n _ctx.setLineDash(Array.isArray(segments) ? segments : [segments])\n _ctx.lineDashOffset = offset\n },\n\n /** TEXT RENDERING API */\n /**\n * Draw text\n *\n * @param {number} x\n * @param {number} y\n * @param {string} text the text message\n * @param {number} [color=3] the color index (generally from 0 to 7)\n */\n text(x, y, text, color = 3) {\n _ctx.font = `${_fontStyle || ''} ${~~_fontSize}px ${_fontFamily}`\n _ctx.fillStyle = instance.getcolor(color)\n _ctx.fillText(text, ~~x, ~~y)\n },\n\n /**\n * Set the font family\n *\n * @param {string} fontFamily\n */\n textfont(fontFamily) {\n _fontFamily = fontFamily\n },\n\n /**\n * Set the font size\n *\n * @param {string} size\n */\n textsize(size) {\n _fontSize = size\n },\n\n /**\n * Sets whether a font should be styled with a normal, italic, or bold.\n *\n * @param {string} style\n */\n textstyle(style) {\n _fontStyle = style\n },\n\n /**\n * Sets the alignment used when drawing texts\n *\n * @param {string} align the horizontal alignment. Possible values: \"left\", \"right\", \"center\", \"start\" or \"end\"\n * @param {string} baseline the vertical alignment. Possible values: \"top\", \"bottom\", \"middle\", \"hanging\" or \"ideographic\"\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign\n */\n textalign(align, baseline) {\n _ctx.textAlign = _textAlign = align\n _ctx.textBaseline = _textBaseline = baseline\n },\n\n /**\n * Returns a TextMetrics object that contains information about the measured text (such as its width, for example)\n *\n * @param {string} text\n * @param {number} [size]\n * @returns {TextMetrics}\n * @see https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics\n */\n textmetrics(text, size) {\n // prettier-ignore\n _ctx.font = `${_fontStyle || ''} ${~~(size || _fontSize)}px ${_fontFamily}`\n metrics = _ctx.measureText(text)\n metrics.height =\n metrics.actualBoundingBoxAscent +\n metrics.actualBoundingBoxDescent\n return metrics\n },\n\n /** IMAGE GRAPHICS API */\n /**\n * Draw an image\n *\n * @param {number} x\n * @param {number} y\n * @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} image\n */\n image(x, y, image) {\n _ctx.drawImage(image, ~~x, ~~y)\n },\n\n /**\n * Creates a offscreen canvas to draw on it\n *\n * @param {number} width\n * @param {number} height\n * @param {string[]|drawCallback} draw\n * @param {{scale?:number}} [options]\n * @returns {OffscreenCanvas}\n * @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas\n */\n paint(width, height, draw, options = {}) {\n const offscreenCanvas = new OffscreenCanvas(width, height),\n ctxOriginal = _ctx,\n scale = options.scale || 1\n\n offscreenCanvas.width = width * scale\n offscreenCanvas.height = height * scale\n _ctx = offscreenCanvas.getContext('2d')\n\n _ctx.scale(scale, scale)\n\n // is pixelart?\n if (Array.isArray(draw)) {\n let x = 0,\n y = 0\n\n _ctx.imageSmoothingEnabled = false\n\n for (const str of draw) {\n for (const color of str) {\n if (' ' !== color && '.' !== color) {\n // support for 16-color palettes using hex (from 0 to f)\n instance.rectfill(x, y, 1, 1, parseInt(color, 16))\n }\n x++\n }\n y++\n x = 0\n }\n } else {\n draw(offscreenCanvas, _ctx)\n }\n\n _ctx = ctxOriginal // restore the context\n\n return offscreenCanvas\n },\n\n /** ADVANCED GRAPHICS API */\n /**\n * Get the canvas context\n *\n * @returns {CanvasRenderingContext2D}\n */\n ctx: () => _ctx,\n\n /**\n * saves the current drawing style settings and transformations\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save\n */\n push: () => _ctx.save(),\n\n /**\n * restores the drawing style settings and transformations\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore\n */\n pop: () => _ctx.restore(),\n\n /**\n * Adds a translation transformation to the current matrix\n *\n * @param {number} x\n * @param {number} y\n */\n translate: (x, y) => _ctx.translate(x, y),\n\n /**\n * Adds a scaling transformation to the canvas units horizontally and/or vertically.\n *\n * @param {number} x\n * @param {number} [y]\n */\n scale: (x, y) => _ctx.scale(x, y || x),\n\n /**\n * Adds a rotation to the transformation matrix\n *\n * @param {number} radians\n */\n rotate: (radians) => _ctx.rotate(radians),\n\n /**\n * Adds a transformation that skews to the transformation matrix\n *\n * @param {number} a\n * @param {number} b\n * @param {number} c\n * @param {number} d\n * @param {number} e\n * @param {number} f\n * @param {boolean} [resetFirst=true] `false` to use _ctx.transform(); by default use _ctx.setTransform()\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform\n */\n transform: (a, b, c, d, e, f, resetFirst = true) =>\n _ctx[resetFirst ? 'setTransform' : 'transform'](a, b, c, d, e, f),\n\n /**\n * Sets the alpha (transparency) value to apply when drawing new shapes and images\n *\n * @param {number} alpha float from 0 to 1 (e.g: 0.5 = 50% transparent)\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha\n */\n alpha(alpha) {\n _ctx.globalAlpha = alpha\n },\n\n /**\n * Returns a newly instantiated Path2D object, optionally with another\n * path as an argument (creates a copy), or optionally with a string\n * consisting of SVG path data.\n *\n * @param {Path2D|string} [arg]\n * @returns Path2D\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D\n */\n path: (arg) => new Path2D(arg),\n\n /**\n * Fills the current or given path with a given color.\n *\n * @param {number} color\n * @param {Path2D} [path]\n */\n fill(color, path) {\n _ctx.fillStyle = instance.getcolor(color)\n _ctx.fill(path)\n },\n\n /**\n * Outlines the current or given path with a given color.\n *\n * @param {number} color\n * @param {Path2D} [path]\n */\n stroke(color, path) {\n _ctx.strokeStyle = instance.getcolor(color)\n path ? _ctx.stroke(path) : _ctx.stroke()\n },\n\n /**\n * Create a retangular clipping region.\n *\n * Note: Clip paths cannot be reverted directly. You must save your\n * canvas state using push() before calling cliprect(), and restore it\n * once you have finished drawing in the clipped area using pop().\n *\n * @param {number} x\n * @param {number} y\n * @param {number} width\n * @param {number} height\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip\n */\n cliprect(x, y, width, height) {\n _ctx.beginPath()\n _ctx.rect(x, y, width, height)\n _ctx.clip()\n },\n\n /**\n * Create a circular clipping region.\n *\n * Note: Clip paths cannot be reverted directly. You must save your\n * canvas state using push() before calling clipcirc(), and restore it\n * once you have finished drawing in the clipped area using pop().\n *\n * @param {number} x\n * @param {number} y\n * @param {number} radius\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip\n */\n clipcirc(x, y, radius) {\n _ctx.beginPath()\n _ctx.arc(x, y, radius, 0, TWO_PI)\n _ctx.clip()\n },\n\n /**\n * Sets the type of compositing operation to apply when drawing new shapes.\n * Default value = 'source-over'.\n *\n * @param {string} value\n * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation\n */\n blendmode(value) {\n _ctx.globalCompositeOperation = value\n },\n\n /** SOUND API */\n /**\n * Play a defined sound or a ZzFX array of params\n *\n * @param {number|number[]} [sound=0] the sound index (from 0 to 7) or a ZzFX array of params\n * @param {number} [volume=1]\n * @param {number} [pitch=0]\n * @param {number} [randomness=0]\n * @returns {AudioBufferSourceNode}\n * @see https://github.com/KilledByAPixel/ZzFX\n */\n sfx(sound = 0, volume = 1, pitch = 0, randomness = 0) {\n if (\n navigator.userActivation &&\n !navigator.userActivation.hasBeenActive\n ) {\n return\n }\n\n let z = Array.isArray(sound)\n ? sound\n : sounds[~~sound % sounds.length]\n if (volume !== 1 || pitch || randomness) {\n z = [...z] // clone the sound to not modify the original\n z[0] = (Number(volume) || 1) * (z[0] || 1)\n z[1] = randomness > 0 ? randomness : 0\n z[10] = ~~z[10] + ~~pitch\n }\n\n return zzfx(...z)\n },\n\n /** UTILS API */\n /**\n * Check a collision between two rectangles\n *\n * @param {number} x1 first rectangle position X\n * @param {number} y1 first rectangle position Y\n * @param {number} w1 first rectangle width\n * @param {number} h1 first rectangle height\n * @param {number} x2 second rectangle position X\n * @param {number} y2 second rectangle position Y\n * @param {number} w2 second rectangle width\n * @param {number} h2 second rectangle height\n * @returns {boolean}\n */\n colrect: (x1, y1, w1, h1, x2, y2, w2, h2) =>\n x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2,\n\n /**\n * Check a collision between two circles\n *\n * @param {number} x1 first circle position X\n * @param {number} y1 first circle position Y\n * @param {number} r1 first circle position radius\n * @param {number} x2 second circle position X\n * @param {number} y2 second circle position Y\n * @param {number} r2 second circle position radius\n * @returns {boolean}\n */\n colcirc: (x1, y1, r1, x2, y2, r2) =>\n (x2 - x1) ** 2 + (y2 - y1) ** 2 <= (r1 + r2) ** 2,\n\n /**\n * Get the mouse position\n * @returns number[]\n */\n mousepos: () => [_mouseX, _mouseY],\n\n /**\n * The scale of the game's time delta (dt).\n * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.\n * A value of 0 freezes time and is effectively equivalent to pausing.\n *\n * @param {number} value\n */\n timescale(value) {\n _timeScale = value\n },\n\n /** PLUGINS API */\n /**\n * Prepares a plugin to be loaded\n *\n * @param {pluginCallback} callback\n */\n use: (callback, config = {}) => {\n callback.__config = config\n _initialized ? loadPlugin(callback) : _plugins.push(callback)\n },\n\n /**\n * Add a game event listener\n *\n * @param {string} event the event type name\n * @param {function} callback the function that is called when the event occurs\n * @param {boolean} [highPriority=false] determines whether the callback will be called before or after the others\n * @returns {function} a function to remove the listener\n */\n listen(event, callback, highPriority = false) {\n _events[event] = _events[event] || []\n _events[event][highPriority ? 'unshift' : 'push'](callback)\n\n // return a function to remove this event listener\n return () => {\n _events[event] = _events[event].filter(\n (item) => item !== callback\n )\n }\n },\n\n /**\n * Call all listeners attached to a game event\n *\n * @param {string} event The game event type\n * @param {...any} args Arguments passed to all listeners\n */\n emit(event, ...args) {\n if (!_events[event]) return\n for (let i = 0; i < _events[event].length; ++i) {\n _events[event][i](...args)\n }\n },\n\n /**\n * Get a color by index\n *\n * @param {number} index The color number\n * @returns {string} the color code\n */\n getcolor: (index) => colors[~~index % colors.length],\n\n /**\n * Create or update a instance variable\n *\n * @param {string} key\n * @param {any} value\n */\n setvar(key, value) {\n instance[key] = value\n if (settings.global) {\n root[key] = value\n }\n },\n\n /**\n * Resizes the game canvas and emit the \"resized\" event\n *\n * @param {number} width\n * @param {number} height\n */\n resize(width, height) {\n instance.setvar('WIDTH', (_canvas.width = ~~width))\n instance.setvar('HEIGHT', (_canvas.height = ~~(height || width)))\n pageResized()\n },\n }\n\n /** Copy some functions from native `Math` object */\n for (const k of [\n 'sin',\n 'cos',\n 'atan2',\n 'hypot',\n 'tan',\n 'abs',\n 'ceil',\n 'round',\n 'floor',\n 'trunc',\n 'min',\n 'max',\n 'pow',\n 'sqrt',\n 'sign',\n 'exp',\n ]) {\n // import some native Math functions\n instance[k] = Math[k]\n }\n\n function init() {\n _initialized = true\n setupCanvas()\n\n // listen the default events\n const source = settings.loop ? settings.loop : root\n for (const event in _events) {\n if (source[event]) instance.listen(event, source[event])\n }\n\n // load plugins\n for (let i = 0; i < _plugins.length; i++) {\n loadPlugin(_plugins[i])\n }\n\n // listen window resize event\n on(root, 'resize', pageResized)\n pageResized()\n\n // default mouse/touch handlers\n if (settings.tapEvents) {\n const _getXY = (pageX, pageY) => [\n (pageX - _canvas.offsetLeft) / _scale,\n (pageY - _canvas.offsetTop) / _scale,\n ],\n _taps = new Map(),\n _registerTap = (id, x, y) => {\n const tap = {\n x,\n y,\n startX: x,\n startY: y,\n // timestamp\n ts: performance.now(),\n }\n _taps.set(id, tap)\n return tap\n },\n _updateTap = (id, x, y) => {\n const tap = _taps.get(id) || _registerTap(id)\n tap.x = x\n tap.y = y\n },\n _checkTapped = (tap) => tap && performance.now() - tap.ts <= 200\n\n let _pressingMouse = false\n\n on(_canvas, 'mousedown', (ev) => {\n ev.preventDefault()\n const [x, y] = _getXY(ev.pageX, ev.pageY)\n instance.emit('tap', x, y, 0)\n _registerTap(0, x, y)\n _pressingMouse = true\n })\n\n on(_canvas, 'mousemove', (ev) => {\n ev.preventDefault()\n const [x, y] = ([_mouseX, _mouseY] = _getXY(ev.pageX, ev.pageY))\n if (!_pressingMouse) return\n instance.emit('tapping', x, y, 0)\n _updateTap(0, x, y)\n })\n\n on(_canvas, 'mouseup', (ev) => {\n ev.preventDefault()\n const tap = _taps.get(0)\n const [x, y] = _getXY(ev.pageX, ev.pageY)\n if (_checkTapped(tap)) {\n instance.emit('tapped', tap.startX, tap.startY, 0)\n }\n instance.emit('untap', x, y, 0)\n _taps.delete(0)\n _pressingMouse = false\n })\n\n on(_canvas, 'touchstart', (ev) => {\n ev.preventDefault()\n /** @type {TouchList} touches */\n const touches = ev.changedTouches\n for (let i = 0; i < touches.length; i++) {\n const touch = touches[i]\n const [x, y] = _getXY(touch.pageX, touch.pageY)\n instance.emit('tap', x, y, touch.identifier + 1)\n _registerTap(touch.identifier + 1, x, y)\n }\n })\n\n on(_canvas, 'touchmove', (ev) => {\n ev.preventDefault()\n /** @type {TouchList} touches */\n const touches = ev.changedTouches\n for (let i = 0; i < touches.length; i++) {\n const touch = touches[i]\n const [x, y] = _getXY(touch.pageX, touch.pageY)\n instance.emit('tapping', x, y, touch.identifier + 1)\n _updateTap(touch.identifier + 1, x, y)\n }\n })\n\n const _touchEndHandler = (ev) => {\n ev.preventDefault()\n const existing = []\n\n if (ev.targetTouches.length > 0) {\n for (const touch of ev.targetTouches) {\n existing.push(touch.identifier + 1)\n }\n }\n\n for (const [id, tap] of _taps) {\n if (existing.includes(id)) continue\n if (_checkTapped(tap)) {\n instance.emit('tapped', tap.startX, tap.startY, id)\n }\n instance.emit('untap', tap.x, tap.y, id)\n _taps.delete(id)\n }\n }\n\n on(_canvas, 'touchend', _touchEndHandler)\n on(_canvas, 'touchcancel', _touchEndHandler)\n\n on(root, 'blur', () => {\n _pressingMouse = false\n\n if (_taps.size === 0) return\n\n for (const [id, tap] of _taps) {\n instance.emit('untap', tap.x, tap.y, id)\n _taps.delete(id)\n }\n })\n }\n\n // listen browser focus/blur events and pause the update/draw loop\n if (settings.pauseOnBlur) {\n on(root, 'blur', () => {\n _rafid = null\n })\n on(root, 'focus', () => {\n if (!_rafid) {\n _lastFrame = performance.now()\n _rafid = requestAnimationFrame(drawFrame)\n }\n })\n }\n\n // start the game loop\n instance.emit('init')\n _lastFrame = performance.now()\n _rafid = requestAnimationFrame(drawFrame)\n }\n\n /**\n * @param {number} now\n */\n function drawFrame(now) {\n let ticks = 0,\n t = now - _lastFrame\n\n _lastFrame = now\n _accumulated += t\n\n while (_accumulated >= _stepMs) {\n instance.emit('update', _step * _timeScale)\n instance.setvar('ELAPSED', instance.ELAPSED + _step * _timeScale)\n _accumulated -= _stepMs\n ticks++\n }\n\n if (ticks) {\n instance.emit('draw')\n _drawCount++\n _drawTime += _stepMs * ticks\n if (_drawTime + _accumulated >= 1000) {\n instance.setvar('FPS', _drawCount)\n _drawCount = 0\n _drawTime -= 1000\n }\n }\n\n if (_rafid) _rafid = requestAnimationFrame(drawFrame)\n }\n\n function setupCanvas() {\n _canvas =\n 'string' === typeof _canvas\n ? document.querySelector(_canvas)\n : _canvas\n\n instance.setvar('CANVAS', _canvas)\n _ctx = _canvas.getContext('2d')\n\n // disable fullscreen if a width is specified\n if (instance.WIDTH > 0) _fullscreen = false\n\n _canvas.width = instance.WIDTH\n _canvas.height = instance.HEIGHT || instance.WIDTH\n\n if (!_canvas.parentNode) document.body.appendChild(_canvas)\n\n if (!settings.antialias || settings.pixelart) {\n _ctx.imageSmoothingEnabled = false\n _canvas.style.imageRendering = 'pixelated'\n }\n\n // canvas CSS tweaks\n _canvas.style.display = 'block'\n if (_fullscreen) {\n _canvas.style.position = 'absolute'\n _canvas.style.inset = 0\n } else if (_autoscale) {\n _canvas.style.margin = 'auto'\n }\n }\n\n function pageResized() {\n if (_fullscreen) {\n _canvas.width = innerWidth\n _canvas.height = innerHeight\n instance.setvar('WIDTH', innerWidth)\n instance.setvar('HEIGHT', innerHeight)\n } else if (_autoscale) {\n _scale = Math.min(\n innerWidth / instance.WIDTH,\n innerHeight / instance.HEIGHT\n )\n _scale = settings.pixelart ? Math.floor(_scale) : _scale\n _canvas.style.width = instance.WIDTH * _scale + 'px'\n _canvas.style.height = instance.HEIGHT * _scale + 'px'\n }\n\n instance.setvar('CENTERX', instance.WIDTH / 2)\n instance.setvar('CENTERY', instance.HEIGHT / 2)\n\n // fix the font align and baseline\n instance.textalign(_textAlign, _textBaseline)\n\n instance.emit('resized', _scale)\n }\n\n /**\n * @param {pluginCallback} callback\n */\n function loadPlugin(callback) {\n const pluginData = callback(instance, _helpers, callback.__config)\n if ('object' === typeof pluginData) {\n for (const key in pluginData) {\n instance.setvar(key, pluginData[key])\n }\n }\n }\n\n if (settings.global) {\n if (root.__litecanvas) {\n throw new Error('Cannot instantiate litecanvas globally twice')\n }\n Object.assign(root, instance)\n root.__litecanvas = true\n }\n\n if ('loading' === document.readyState) {\n on(root, 'DOMContentLoaded', init)\n } else {\n init()\n }\n\n return instance\n}\n\nroot.litecanvas = litecanvas\n"],
5
+ "mappings": "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",
6
+ "names": ["p", "k", "b", "e", "r", "t", "q", "D", "u", "y", "v", "z", "l", "E", "A", "c", "w", "m", "B", "N", "M", "d", "R", "G", "C", "g", "H", "a", "I", "J", "f", "h", "x", "L", "Z", "K", "O", "X", "Y", "P", "Q", "S", "T", "U", "V", "W", "colors", "sounds", "root", "litecanvas", "settings", "PI", "TWO_PI", "on", "elem", "evt", "callback", "_initialized", "_plugins", "_canvas", "_fullscreen", "_autoscale", "_scale", "_mouseX", "_mouseY", "_ctx", "_timeScale", "_lastFrame", "_step", "_stepMs", "_accumulated", "_rafid", "_drawCount", "_drawTime", "_fontFamily", "_fontStyle", "_fontSize", "_textAlign", "_textBaseline", "_events", "_helpers", "colors", "sounds", "instance", "start", "end", "t", "degs", "rads", "value", "min", "max", "min1", "max1", "min2", "max2", "withinBounds", "result", "color", "x", "y", "width", "height", "radii", "radius", "x1", "y1", "x2", "y2", "segments", "offset", "text", "fontFamily", "size", "style", "align", "baseline", "image", "draw", "options", "offscreenCanvas", "ctxOriginal", "scale", "str", "radians", "a", "b", "c", "d", "e", "f", "resetFirst", "alpha", "arg", "path", "sound", "volume", "pitch", "randomness", "z", "w1", "h1", "w2", "h2", "r1", "r2", "config", "loadPlugin", "event", "highPriority", "item", "args", "i", "index", "key", "pageResized", "k", "init", "setupCanvas", "source", "_getXY", "pageX", "pageY", "_taps", "_registerTap", "id", "tap", "_updateTap", "_checkTapped", "_pressingMouse", "ev", "touches", "touch", "_touchEndHandler", "existing", "drawFrame", "now", "ticks", "pluginData"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.41.3",
3
+ "version": "0.42.0",
4
4
  "description": "Lightweight HTML5 canvas engine suitable for small games and animations.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
package/src/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /* litecanvas v0.41.3 | https://github.com/litecanvas/game-engine */
1
+ /* litecanvas v0.42.0 | https://github.com/litecanvas/game-engine */
2
2
  import './zzfx'
3
3
  import { colors } from './palette'
4
4
  import { sounds } from './sounds'
@@ -23,6 +23,7 @@ export default function litecanvas(settings = {}) {
23
23
  fullscreen: true,
24
24
  width: null,
25
25
  height: null,
26
+ pauseOnBlur: true,
26
27
  autoscale: true,
27
28
  pixelart: false,
28
29
  antialias: true,
@@ -54,6 +55,8 @@ export default function litecanvas(settings = {}) {
54
55
  /** @type {CanvasRenderingContext2D} */
55
56
  _ctx,
56
57
  /** @type {number} */
58
+ _timeScale = 1,
59
+ /** @type {number} */
57
60
  _lastFrame,
58
61
  /** @type {number} */
59
62
  _step = 1 / settings.fps,
@@ -245,7 +248,7 @@ export default function litecanvas(settings = {}) {
245
248
  /**
246
249
  * Clear the game screen
247
250
  *
248
- * @param {number|null} color The background color (from 0 to 7) or null
251
+ * @param {number|null} color The background color (from 0 to 7) or null (for transparent)
249
252
  */
250
253
  cls(color) {
251
254
  if (null == color) {
@@ -719,6 +722,17 @@ export default function litecanvas(settings = {}) {
719
722
  */
720
723
  mousepos: () => [_mouseX, _mouseY],
721
724
 
725
+ /**
726
+ * The scale of the game's time delta (dt).
727
+ * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
728
+ * A value of 0 freezes time and is effectively equivalent to pausing.
729
+ *
730
+ * @param {number} value
731
+ */
732
+ timescale(value) {
733
+ _timeScale = value
734
+ },
735
+
722
736
  /** PLUGINS API */
723
737
  /**
724
738
  * Prepares a plugin to be loaded
@@ -764,10 +778,10 @@ export default function litecanvas(settings = {}) {
764
778
  },
765
779
 
766
780
  /**
767
- * Get the color value
781
+ * Get a color by index
768
782
  *
769
783
  * @param {number} index The color number
770
- * @returns {string} the color value
784
+ * @returns {string} the color code
771
785
  */
772
786
  getcolor: (index) => colors[~~index % colors.length],
773
787
 
@@ -824,20 +838,6 @@ export default function litecanvas(settings = {}) {
824
838
  _initialized = true
825
839
  setupCanvas()
826
840
 
827
- // pause on page blur
828
- on(root, 'blur', () => {
829
- cancelAnimationFrame(_rafid)
830
- _rafid = 0
831
- })
832
-
833
- // resume on page focus if paused
834
- on(root, 'focus', () => {
835
- if (!_rafid) {
836
- _lastFrame = performance.now()
837
- _rafid = requestAnimationFrame(drawFrame)
838
- }
839
- })
840
-
841
841
  // listen the default events
842
842
  const source = settings.loop ? settings.loop : root
843
843
  for (const event in _events) {
@@ -853,11 +853,6 @@ export default function litecanvas(settings = {}) {
853
853
  on(root, 'resize', pageResized)
854
854
  pageResized()
855
855
 
856
- // start the game loop
857
- instance.emit('init')
858
- _lastFrame = performance.now()
859
- _rafid = requestAnimationFrame(drawFrame)
860
-
861
856
  // default mouse/touch handlers
862
857
  if (settings.tapEvents) {
863
858
  const _getXY = (pageX, pageY) => [
@@ -972,6 +967,24 @@ export default function litecanvas(settings = {}) {
972
967
  }
973
968
  })
974
969
  }
970
+
971
+ // listen browser focus/blur events and pause the update/draw loop
972
+ if (settings.pauseOnBlur) {
973
+ on(root, 'blur', () => {
974
+ _rafid = null
975
+ })
976
+ on(root, 'focus', () => {
977
+ if (!_rafid) {
978
+ _lastFrame = performance.now()
979
+ _rafid = requestAnimationFrame(drawFrame)
980
+ }
981
+ })
982
+ }
983
+
984
+ // start the game loop
985
+ instance.emit('init')
986
+ _lastFrame = performance.now()
987
+ _rafid = requestAnimationFrame(drawFrame)
975
988
  }
976
989
 
977
990
  /**
@@ -985,15 +998,15 @@ export default function litecanvas(settings = {}) {
985
998
  _accumulated += t
986
999
 
987
1000
  while (_accumulated >= _stepMs) {
988
- instance.emit('update', _step)
989
- instance.setvar('ELAPSED', instance.ELAPSED + _step)
1001
+ instance.emit('update', _step * _timeScale)
1002
+ instance.setvar('ELAPSED', instance.ELAPSED + _step * _timeScale)
990
1003
  _accumulated -= _stepMs
991
1004
  ticks++
992
1005
  }
993
1006
 
994
1007
  if (ticks) {
995
- _drawCount++
996
1008
  instance.emit('draw')
1009
+ _drawCount++
997
1010
  _drawTime += _stepMs * ticks
998
1011
  if (_drawTime + _accumulated >= 1000) {
999
1012
  instance.setvar('FPS', _drawCount)
package/src/types.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * @property {boolean} [fullscreen=true]
6
6
  * @property {number} [width]
7
7
  * @property {number} [height]
8
+ * @property {boolean} [pauseOnBlur=true]
8
9
  * @property {boolean} [autoscale=true]
9
10
  * @property {boolean} [pixelart=false]
10
11
  * @property {boolean} [antialias=true]
package/types/index.d.ts CHANGED
@@ -565,6 +565,14 @@ declare global {
565
565
  * @returns number[]
566
566
  */
567
567
  function mousepos(): number[]
568
+ /**
569
+ * The scale of the game's time delta (dt).
570
+ * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
571
+ * A value of 0 freezes time and is effectively equivalent to pausing.
572
+ *
573
+ * @param {number} value
574
+ */
575
+ function timescale(value: number): void
568
576
 
569
577
  /** PLUGINS API */
570
578
  /**
package/types/types.d.ts CHANGED
@@ -552,6 +552,14 @@ type LitecanvasInstance = {
552
552
  * @returns number[]
553
553
  */
554
554
  mousepos(): number[]
555
+ /**
556
+ * The scale of the game's time delta (dt).
557
+ * Values higher than 1 increase the speed of time, while values smaller than 1 decrease it.
558
+ * A value of 0 freezes time and is effectively equivalent to pausing.
559
+ *
560
+ * @param {number} value
561
+ */
562
+ timescale(value: number): void
555
563
 
556
564
  /** PLUGINS API */
557
565
  /**
@@ -620,6 +628,11 @@ type LitecanvasOptions = {
620
628
  * The game screen height.
621
629
  */
622
630
  height?: number
631
+ /**
632
+ * Determines whether the game loop should be paused when the "blur" event happens.
633
+ * Default: `true`
634
+ */
635
+ pauseOnBlur?: boolean
623
636
  /**
624
637
  * If `true` (default) scales the canvas to fill the screen, but preserving the aspect ratio.
625
638
  * Only works if a game screen width was specified.