litecanvas 0.78.0 → 0.78.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -136,7 +136,9 @@
136
136
  return 180 / PI * rads;
137
137
  },
138
138
  /**
139
- * Calculates the integer closest to a number and optional precision.
139
+ * Returns the rounded value of an number to optional precision (number of digits after the decimal point).
140
+ *
141
+ * Note: precision is optional but must be >= 0
140
142
  *
141
143
  * @param {number} n number to round.
142
144
  * @param {number} [precision] number of decimal digits to round to, default is 0.
@@ -1152,28 +1154,27 @@
1152
1154
  _rafid = raf(drawFrame);
1153
1155
  }
1154
1156
  function drawFrame(now) {
1155
- if (_animated) {
1156
- _rafid = raf(drawFrame);
1157
- }
1158
1157
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
1159
1158
  _lastFrameTime = now;
1160
- if (frameTime > _deltaTime * 30) {
1161
- console.warn("skipping too long frame");
1162
- } else {
1163
- _accumulated += frameTime;
1164
- if (!_animated) {
1165
- _accumulated = _deltaTime;
1159
+ if (_animated) {
1160
+ _rafid = raf(drawFrame);
1161
+ if (frameTime > 0.3) {
1162
+ return console.warn("skipping too long frame");
1166
1163
  }
1167
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1164
+ _accumulated += frameTime;
1165
+ while (_accumulated >= _deltaTime) {
1168
1166
  instance.emit("update", _deltaTime * _timeScale);
1169
1167
  instance.setvar(
1170
1168
  "ELAPSED",
1171
1169
  instance.ELAPSED + _deltaTime * _timeScale
1172
1170
  );
1173
1171
  updated++;
1172
+ _accumulated -= _deltaTime;
1174
1173
  }
1174
+ } else {
1175
+ updated = 1;
1175
1176
  }
1176
- if (updated || !_animated) {
1177
+ if (updated) {
1177
1178
  instance.textalign("start", "top");
1178
1179
  instance.emit("draw");
1179
1180
  }
package/dist/dist.js CHANGED
@@ -126,7 +126,9 @@
126
126
  return 180 / PI * rads;
127
127
  },
128
128
  /**
129
- * Calculates the integer closest to a number and optional precision.
129
+ * Returns the rounded value of an number to optional precision (number of digits after the decimal point).
130
+ *
131
+ * Note: precision is optional but must be >= 0
130
132
  *
131
133
  * @param {number} n number to round.
132
134
  * @param {number} [precision] number of decimal digits to round to, default is 0.
@@ -871,27 +873,27 @@
871
873
  _rafid = raf(drawFrame);
872
874
  }
873
875
  function drawFrame(now) {
874
- if (_animated) {
875
- _rafid = raf(drawFrame);
876
- }
877
876
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
878
877
  _lastFrameTime = now;
879
- if (frameTime > _deltaTime * 30) {
880
- } else {
881
- _accumulated += frameTime;
882
- if (!_animated) {
883
- _accumulated = _deltaTime;
878
+ if (_animated) {
879
+ _rafid = raf(drawFrame);
880
+ if (frameTime > 0.3) {
881
+ return void 0;
884
882
  }
885
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
883
+ _accumulated += frameTime;
884
+ while (_accumulated >= _deltaTime) {
886
885
  instance.emit("update", _deltaTime * _timeScale);
887
886
  instance.setvar(
888
887
  "ELAPSED",
889
888
  instance.ELAPSED + _deltaTime * _timeScale
890
889
  );
891
890
  updated++;
891
+ _accumulated -= _deltaTime;
892
892
  }
893
+ } else {
894
+ updated = 1;
893
895
  }
894
- if (updated || !_animated) {
896
+ if (updated) {
895
897
  instance.textalign("start", "top");
896
898
  instance.emit("draw");
897
899
  }
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,d=0,u=0,p=0,g=0,h=0,m=0,E=0,v=1,b=0,w=0,x=0)=>{let T=Math,y=2*T.PI,H=c*=500*y/44100/44100,I=l*=(1-a+2*a*T.random(a=[]))*y/44100,S=0,D=0,k=0,A=1,C=0,X=0,z=0,N=x<0?-1:1,P=y*N*x*2/44100,L=T.cos(P),O=T.sin,Y=O(P)/4,F=1+Y,W=-2*L/F,G=(1-Y)/F,M=(1+N*L)/2/F,R=-(N+L)/F,B=0,U=0,q=0,V=0;for(n=44100*n+9,b*=44100,i*=44100,r*=44100,E*=44100,f*=500*y/85766121e6,h*=y/44100,d*=y/44100,u*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),N=n+b+i+r+E|0;k<N;a[k++]=z*t)++X%(100*m|0)||(z=o?1<o?2<o?3<o?O(S*S):T.max(T.min(T.tan(S),1),-1):1-(2*S/y%2+2)%2:1-4*T.abs(T.round(S/y)-S/y):O(S),z=(p?1-w+w*O(y*k/p):1)*(z<0?-1:1)*T.abs(z)**s*(k<n?k/n:k<n+b?1-(k-n)/b*(1-v):k<n+b+i?v:k<N-E?(N-k-E)/r*v:0),z=E?z/2+(E>k?0:(k<N-E?1:(N-k)/E)*a[k-E|0]/2/t):z,x&&(z=V=M*B+R*(B=U)+M*(U=z)-G*q-W*(q=V))),S+=(P=(l+=c+=f)*T.cos(h*D++))+P*g*O(k**5),A&&++A>u&&(l+=d,I+=d,A=0),!p||++C%p||(l=I,c=H,A=A||1);(t=e.createBuffer(1,N,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math,i=n.PI,r=2*i,o=requestAnimationFrame,s=[],c=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,pauseOnBlur:!0,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,d=[],u=e.canvas||document.createElement("canvas"),p=e.animate,g=1,h,m=.5,E=1,v,b=1/60,w=0,x,T="sans-serif",y=18,H=Date.now(),I=e.global,S={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},D={settings:Object.assign({},e),colors:a},k={WIDTH:e.width,HEIGHT:e.height||e.width,CANVAS:null,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,,1675,,.06,.2,1,1.8,,,637,.06],TWO_PI:r,HALF_PI:i/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i/180*e,rad2deg:e=>180/i*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let r=(e-t)/(a-t)*(n-l)+l;return i?k.clamp(r,l,n):r},norm:(e,t,a)=>k.map(e,t,a,0,1),rand:(e=0,t=1)=>(H=(1664525*H+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(k.rand(e,t+1)),seed:e=>null==e?H:H=~~e,cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):k.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~l+2*m,i),k.stroke(n)},rectfill(e,t,a,l,n,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),k.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.fill(l)},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==m&&~~e==~~a),r=.5*(0!==m&&~~t==~~l);h.moveTo(~~e+i,~~t+r),h.lineTo(~~a+i,~~l+r),k.stroke(n)},linewidth(e){h.lineWidth=~~e,m=.5*(~~e%2!=0)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=3,n="normal"){h.font=`${n} ${y}px ${T}`,h.fillStyle=k.getcolor(l),h.fillText(a,~~e,~~t)},textfont(e){T=e},textsize(e){y=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,r=h;if(n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(h.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&k.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(h);return h=r,n},ctx:e=>(e&&(h=e),h),push:()=>h.save(),pop:()=>h.restore(),translate:(e,t)=>h.translate(~~e,~~t),scale:(e,t)=>h.scale(e,t||e),rotate:e=>h.rotate(e),alpha(e){h.globalAlpha=k.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){h.fillStyle=k.getcolor(e),t?h.fill(t):h.fill()},stroke(e,t){h.strokeStyle=k.getcolor(e),t?h.stroke(t):h.stroke()},clip(e){h.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||k.DEFAULT_SFX,(0!==a||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){l.zzfxV=e},use(e,t={}){f?N(e,t):d.push([e,t])},listen:(e,t)=>(S[e]=S[e]||new Set,S[e].add(t),()=>S[e].delete(t)),emit(e,t,a,l,n){f&&(z("before:"+e,t,a,l,n),z(e,t,a,l,n),z("after:"+e,t,a,l,n))},getcolor:e=>a[~~e%a.length],setvar(e,t){k[e]=t,I&&(l[e]=t)},resize(e,t){k.setvar("WIDTH",u.width=e),k.setvar("HEIGHT",u.height=t),k.setvar("CENTERX",k.WIDTH/2),k.setvar("CENTERY",k.HEIGHT/2),X()},timescale(e){E=e},setfps(e){b=1/~~e},quit(){for(let e of(cancelAnimationFrame(x),k.emit("quit"),S=[],s))e();if(I){for(let e in k)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))k[e]=n[e];function A(){f=!0;let t=e.loop?e.loop:l;for(let e in S)t[e]&&k.listen(e,t[e]);for(let[e,t]of d)N(e,t);if(e.autoscale&&c(l,"resize",X),e.tapEvents){let e=(e,t)=>[(e-u.offsetLeft)/g,(t-u.offsetTop)/g],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,startX:a,startY:l,ts:performance.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),o=!1;c(u,"mousedown",t=>{if(0===t.button){r(t);let[l,n]=e(t.pageX,t.pageY);k.emit("tap",l,n,0),a(0,l,n),o=!0}}),c(u,"mouseup",a=>{if(0===a.button){r(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&k.emit("tapped",l.startX,l.startY,0),k.emit("untap",n,s,0),t.delete(0),o=!1}}),c(u,"mousemove",t=>{r(t);let[a,l]=e(t.pageX,t.pageY);k.setvar("MOUSEX",a),k.setvar("MOUSEY",l),o&&(k.emit("tapping",a,l,0),n(0,a,l))}),c(u,"touchstart",t=>{for(let l of(r(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);k.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),c(u,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);k.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{r(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&k.emit("tapped",l.startX,l.startY,e),k.emit("untap",l.x,l.y,e),t.delete(e))};c(u,"touchend",s),c(u,"touchcancel",s),c(l,"blur",()=>{for(let[e,a]of(o=!1,t))k.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,n=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;c(l,"keydown",l=>{t.has(e(l.key))||(t.add(e(l.key)),a.add(e(l.key)))}),c(l,"keyup",a=>{t.delete(e(a.key))}),c(l,"blur",()=>t.clear()),k.listen("after:draw",()=>a.clear()),k.setvar("iskeydown",e=>n(t,e)),k.setvar("iskeypressed",e=>n(a,e))}e.pauseOnBlur&&(c(l,"blur",()=>{x=cancelAnimationFrame(x)}),c(l,"focus",()=>{x||(x=o(C))})),k.emit("init",k),v=performance.now(),x=o(C)}function C(e){p&&(x=o(C));let t=0,a=(e-v)/1e3;if(v=e,a>30*b);else for(w+=a,p||(w=b);w>=b;w-=b)k.emit("update",b*E),k.setvar("ELAPSED",k.ELAPSED+b*E),t++;(t||!p)&&(k.textalign("start","top"),k.emit("draw"))}function X(){let t=u.style;e.autoscale&&(t.display||(t.display="block",t.margin="auto"),g=n.min(l.innerWidth/k.WIDTH,l.innerHeight/k.HEIGHT),g=(e.pixelart?~~g:g)||1,t.width=k.WIDTH*g+"px",t.height=k.HEIGHT*g+"px"),(!e.antialias||e.pixelart)&&(h.imageSmoothingEnabled=!1,t.imageRendering="pixelated"),k.emit("resized",g),p||o(C)}function z(e,t,a,l,n){if(S[e])for(let i of S[e])i(t,a,l,n)}function N(e,t){let a=e(k,D,t);for(let e in a)k.setvar(e,a[e])}if(I){if(l.ENGINE)throw"two global litecanvas detected";Object.assign(l,k),l.ENGINE=k}return u="string"==typeof u?document.querySelector(u):u,k.setvar("CANVAS",u),h=u.getContext("2d"),c(u,"click",()=>l.focus()),u.style="",k.WIDTH||(k.WIDTH=l.innerWidth,k.HEIGHT=l.innerHeight),k.resize(k.WIDTH,k.HEIGHT,!1),u.parentNode||document.body.appendChild(u),"loading"===document.readyState?c(l,"DOMContentLoaded",()=>o(A)):o(A),k}})();
1
+ (()=>{var e=new AudioContext,t=(t=1,a=.05,n=220,l=0,i=0,r=.1,o=0,s=1,c=0,f=0,d=0,u=0,p=0,g=0,h=0,m=0,E=0,v=1,b=0,w=0,x=0)=>{let T=Math,y=2*T.PI,H=c*=500*y/44100/44100,I=n*=(1-a+2*a*T.random(a=[]))*y/44100,S=0,D=0,k=0,A=1,C=0,X=0,z=0,N=x<0?-1:1,P=y*N*x*2/44100,L=T.cos(P),O=T.sin,Y=O(P)/4,F=1+Y,W=-2*L/F,G=(1-Y)/F,M=(1+N*L)/2/F,R=-(N+L)/F,B=0,U=0,q=0,V=0;for(l=44100*l+9,b*=44100,i*=44100,r*=44100,E*=44100,f*=500*y/85766121e6,h*=y/44100,d*=y/44100,u*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),N=l+b+i+r+E|0;k<N;a[k++]=z*t)++X%(100*m|0)||(z=o?1<o?2<o?3<o?O(S*S):T.max(T.min(T.tan(S),1),-1):1-(2*S/y%2+2)%2:1-4*T.abs(T.round(S/y)-S/y):O(S),z=(p?1-w+w*O(y*k/p):1)*(z<0?-1:1)*T.abs(z)**s*(k<l?k/l:k<l+b?1-(k-l)/b*(1-v):k<l+b+i?v:k<N-E?(N-k-E)/r*v:0),z=E?z/2+(E>k?0:(k<N-E?1:(N-k)/E)*a[k-E|0]/2/t):z,x&&(z=V=M*B+R*(B=U)+M*(U=z)-G*q-W*(q=V))),S+=(P=(n+=c+=f)*T.cos(h*D++))+P*g*O(k**5),A&&++A>u&&(n+=d,I+=d,A=0),!p||++C%p||(n=I,c=H,A=A||1);(t=e.createBuffer(1,N,44100)).getChannelData(0).set(a),(n=e.createBufferSource()).buffer=t,n.connect(e.destination),n.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let n=globalThis,l=Math,i=l.PI,r=2*i,o=requestAnimationFrame,s=[],c=(e,t,a)=>{e.addEventListener(t,a,!1),s.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,pauseOnBlur:!0,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,d=[],u=e.canvas||document.createElement("canvas"),p=e.animate,g=1,h,m=.5,E=1,v,b=1/60,w=0,x,T="sans-serif",y=18,H=Date.now(),I=e.global,S={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},D={settings:Object.assign({},e),colors:a},k={WIDTH:e.width,HEIGHT:e.height||e.width,CANVAS:null,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,,1675,,.06,.2,1,1.8,,,637,.06],TWO_PI:r,HALF_PI:i/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i/180*e,rad2deg:e=>180/i*e,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,wrap:(e,t,a)=>e-(a-t)*l.floor((e-t)/(a-t)),map(e,t,a,n,l,i){let r=(e-t)/(a-t)*(l-n)+n;return i?k.clamp(r,n,l):r},norm:(e,t,a)=>k.map(e,t,a,0,1),rand:(e=0,t=1)=>(H=(1664525*H+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>l.floor(k.rand(e,t+1)),seed:e=>null==e?H:H=~~e,cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):k.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,n,l,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~n+2*m,i),k.stroke(l)},rectfill(e,t,a,n,l,i=null){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~n,i),k.fill(l)},circ(e,t,a,n){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.stroke(n)},circfill(e,t,a,n){h.beginPath(),h.arc(~~e,~~t,~~a,0,r),k.fill(n)},line(e,t,a,n,l){h.beginPath();let i=.5*(0!==m&&~~e==~~a),r=.5*(0!==m&&~~t==~~n);h.moveTo(~~e+i,~~t+r),h.lineTo(~~a+i,~~n+r),k.stroke(l)},linewidth(e){h.lineWidth=~~e,m=.5*(~~e%2!=0)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,n=3,l="normal"){h.font=`${l} ${y}px ${T}`,h.fillStyle=k.getcolor(n),h.fillText(a,~~e,~~t)},textfont(e){T=e},textsize(e){y=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},paint(e,t,a,n={}){let l=n.canvas||new OffscreenCanvas(1,1),i=n.scale||1,r=h;if(l.width=e*i,l.height=t*i,(h=l.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let n of(h.imageSmoothingEnabled=!1,a)){for(let a of n)" "!==a&&"."!==a&&k.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(h);return h=r,l},ctx:e=>(e&&(h=e),h),push:()=>h.save(),pop:()=>h.restore(),translate:(e,t)=>h.translate(~~e,~~t),scale:(e,t)=>h.scale(e,t||e),rotate:e=>h.rotate(e),alpha(e){h.globalAlpha=k.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){h.fillStyle=k.getcolor(e),t?h.fill(t):h.fill()},stroke(e,t){h.strokeStyle=k.getcolor(e),t?h.stroke(t):h.stroke()},clip(e){h.clip(e)},sfx:(e,a=0,l=1)=>!(n.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||k.DEFAULT_SFX,(0!==a||1!==l)&&((e=e.slice())[0]=l*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){n.zzfxV=e},use(e,t={}){f?N(e,t):d.push([e,t])},listen:(e,t)=>(S[e]=S[e]||new Set,S[e].add(t),()=>S[e].delete(t)),emit(e,t,a,n,l){f&&(z("before:"+e,t,a,n,l),z(e,t,a,n,l),z("after:"+e,t,a,n,l))},getcolor:e=>a[~~e%a.length],setvar(e,t){k[e]=t,I&&(n[e]=t)},resize(e,t){k.setvar("WIDTH",u.width=e),k.setvar("HEIGHT",u.height=t),k.setvar("CENTERX",k.WIDTH/2),k.setvar("CENTERY",k.HEIGHT/2),X()},timescale(e){E=e},setfps(e){b=1/~~e},quit(){for(let e of(cancelAnimationFrame(x),k.emit("quit"),S=[],s))e();if(I){for(let e in k)delete n[e];delete n.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))k[e]=l[e];function A(){f=!0;let t=e.loop?e.loop:n;for(let e in S)t[e]&&k.listen(e,t[e]);for(let[e,t]of d)N(e,t);if(e.autoscale&&c(n,"resize",X),e.tapEvents){let e=(e,t)=>[(e-u.offsetLeft)/g,(t-u.offsetTop)/g],t=new Map,a=(e,a,n)=>{let l={x:a,y:n,startX:a,startY:n,ts:performance.now()};return t.set(e,l),l},l=(e,n,l)=>{let i=t.get(e)||a(e);i.x=n,i.y=l},i=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),o=!1;c(u,"mousedown",t=>{if(0===t.button){r(t);let[n,l]=e(t.pageX,t.pageY);k.emit("tap",n,l,0),a(0,n,l),o=!0}}),c(u,"mouseup",a=>{if(0===a.button){r(a);let n=t.get(0),[l,s]=e(a.pageX,a.pageY);i(n)&&k.emit("tapped",n.startX,n.startY,0),k.emit("untap",l,s,0),t.delete(0),o=!1}}),c(u,"mousemove",t=>{r(t);let[a,n]=e(t.pageX,t.pageY);k.setvar("MOUSEX",a),k.setvar("MOUSEY",n),o&&(k.emit("tapping",a,n,0),l(0,a,n))}),c(u,"touchstart",t=>{for(let n of(r(t),t.changedTouches)){let[t,l]=e(n.pageX,n.pageY);k.emit("tap",t,l,n.identifier+1),a(n.identifier+1,t,l)}}),c(u,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,n]=e(a.pageX,a.pageY);k.emit("tapping",t,n,a.identifier+1),l(a.identifier+1,t,n)}});let s=e=>{r(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,n]of t)a.includes(e)||(i(n)&&k.emit("tapped",n.startX,n.startY,e),k.emit("untap",n.x,n.y,e),t.delete(e))};c(u,"touchend",s),c(u,"touchcancel",s),c(n,"blur",()=>{for(let[e,a]of(o=!1,t))k.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,l=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;c(n,"keydown",n=>{t.has(e(n.key))||(t.add(e(n.key)),a.add(e(n.key)))}),c(n,"keyup",a=>{t.delete(e(a.key))}),c(n,"blur",()=>t.clear()),k.listen("after:draw",()=>a.clear()),k.setvar("iskeydown",e=>l(t,e)),k.setvar("iskeypressed",e=>l(a,e))}e.pauseOnBlur&&(c(n,"blur",()=>{x=cancelAnimationFrame(x)}),c(n,"focus",()=>{x||(x=o(C))})),k.emit("init",k),v=performance.now(),x=o(C)}function C(e){let t=0,a=(e-v)/1e3;if(v=e,p){if(x=o(C),a>.3)return;for(w+=a;w>=b;)k.emit("update",b*E),k.setvar("ELAPSED",k.ELAPSED+b*E),t++,w-=b}else t=1;t&&(k.textalign("start","top"),k.emit("draw"))}function X(){let t=u.style;e.autoscale&&(t.display||(t.display="block",t.margin="auto"),g=l.min(n.innerWidth/k.WIDTH,n.innerHeight/k.HEIGHT),g=(e.pixelart?~~g:g)||1,t.width=k.WIDTH*g+"px",t.height=k.HEIGHT*g+"px"),(!e.antialias||e.pixelart)&&(h.imageSmoothingEnabled=!1,t.imageRendering="pixelated"),k.emit("resized",g),p||o(C)}function z(e,t,a,n,l){if(S[e])for(let i of S[e])i(t,a,n,l)}function N(e,t){let a=e(k,D,t);for(let e in a)k.setvar(e,a[e])}if(I){if(n.ENGINE)throw"two global litecanvas detected";Object.assign(n,k),n.ENGINE=k}return u="string"==typeof u?document.querySelector(u):u,k.setvar("CANVAS",u),h=u.getContext("2d"),c(u,"click",()=>n.focus()),u.style="",k.WIDTH||(k.WIDTH=n.innerWidth,k.HEIGHT=n.innerHeight),k.resize(k.WIDTH,k.HEIGHT,!1),u.parentNode||document.body.appendChild(u),"loading"===document.readyState?c(n,"DOMContentLoaded",()=>o(A)):o(A),k}})();
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.78.0",
3
+ "version": "0.78.2",
4
4
  "description": "Lightweight HTML5 canvas game engine suitable for small projects and creative coding. Inspired by PICO-8 and P5/Processing.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
7
7
  "contributors": [],
8
8
  "devDependencies": {
9
- "@swc/core": "^1.11.9",
9
+ "@swc/core": "^1.11.11",
10
10
  "ava": "^6.2.0",
11
11
  "esbuild": "^0.25.1",
12
12
  "gzip-size": "^7.0.0",
package/src/index.js CHANGED
@@ -191,7 +191,9 @@ export default function litecanvas(settings = {}) {
191
191
  },
192
192
 
193
193
  /**
194
- * Calculates the integer closest to a number and optional precision.
194
+ * Returns the rounded value of an number to optional precision (number of digits after the decimal point).
195
+ *
196
+ * Note: precision is optional but must be >= 0
195
197
  *
196
198
  * @param {number} n number to round.
197
199
  * @param {number} [precision] number of decimal digits to round to, default is 0.
@@ -1402,36 +1404,41 @@ export default function litecanvas(settings = {}) {
1402
1404
  * @param {DOMHighResTimeStamp} now
1403
1405
  */
1404
1406
  function drawFrame(now) {
1405
- if (_animated) {
1406
- _rafid = raf(drawFrame)
1407
- }
1408
-
1409
1407
  let updated = 0,
1410
1408
  frameTime = (now - _lastFrameTime) / 1000
1411
1409
 
1412
1410
  _lastFrameTime = now
1413
1411
 
1414
- if (frameTime > _deltaTime * 30) {
1415
- console.warn('skipping too long frame')
1416
- } else {
1417
- _accumulated += frameTime
1412
+ if (_animated) {
1413
+ // request the next frame
1414
+ _rafid = raf(drawFrame)
1418
1415
 
1419
- if (!_animated) {
1420
- _accumulated = _deltaTime
1416
+ if (frameTime > 0.3) {
1417
+ return console.warn('skipping too long frame')
1421
1418
  }
1422
1419
 
1423
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1420
+ _accumulated += frameTime
1421
+
1422
+ while (_accumulated >= _deltaTime) {
1424
1423
  instance.emit('update', _deltaTime * _timeScale)
1425
1424
  instance.setvar(
1426
1425
  'ELAPSED',
1427
1426
  instance.ELAPSED + _deltaTime * _timeScale
1428
1427
  )
1429
1428
  updated++
1429
+ _accumulated -= _deltaTime
1430
1430
  }
1431
+ } else {
1432
+ // when the canvas is not animated
1433
+ // we for one frame when a redraw is triggered
1434
+ updated = 1
1431
1435
  }
1432
1436
 
1433
- if (updated || !_animated) {
1434
- instance.textalign('start', 'top') // default values for textAlign & textBaseline
1437
+ if (updated) {
1438
+ // by default the text
1439
+ // always set default values for
1440
+ // _ctx.textAlign and _ctx.textBaseline before draw
1441
+ instance.textalign('start', 'top')
1435
1442
  instance.emit('draw')
1436
1443
  }
1437
1444
  }
package/types/index.d.ts CHANGED
@@ -72,6 +72,14 @@ declare global {
72
72
  * @returns the value in degrees
73
73
  */
74
74
  function rad2deg(rads: number): number
75
+ /**
76
+ * Returns the rounded value of an number to optional precision (number of digits after the decimal point).
77
+ *
78
+ * @param n number to round.
79
+ * @param [precision] number of decimal digits to round to, default is 0.
80
+ * @returns the rounded number.
81
+ */
82
+ function round(n: number, precision?: number): number
75
83
  /**
76
84
  * Constrains a number between `min` and `max`.
77
85
  *
package/types/types.d.ts CHANGED
@@ -61,6 +61,14 @@ type LitecanvasInstance = {
61
61
  * @returns the value in degrees
62
62
  */
63
63
  rad2deg(rads: number): number
64
+ /**
65
+ * Returns the rounded value of an number to optional precision (number of digits after the decimal point).
66
+ *
67
+ * @param n number to round.
68
+ * @param [precision] number of decimal digits to round to, default is 0.
69
+ * @returns the rounded number.
70
+ */
71
+ round(n: number, precision?: number): number
64
72
  /**
65
73
  * Constrains a number between `min` and `max`.
66
74
  *