litecanvas 0.102.2 → 0.102.3

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
@@ -19,7 +19,7 @@
19
19
  };
20
20
 
21
21
  // src/version.js
22
- var version = "0.102.2";
22
+ var version = "0.102.3";
23
23
 
24
24
  // src/index.js
25
25
  function litecanvas(settings = {}) {
@@ -37,7 +37,7 @@
37
37
  keyboardEvents: true
38
38
  };
39
39
  settings = Object.assign(defaults, settings);
40
- let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
40
+ let _initialized = false, _paused = true, _canvas, _canvasScale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
41
41
  const instance = {
42
42
  /** @type {number} */
43
43
  W: 0,
@@ -80,7 +80,7 @@
80
80
  DEV: assert(isNumber(start), "[litecanvas] lerp() 1st param must be a number");
81
81
  DEV: assert(isNumber(end), "[litecanvas] lerp() 2nd param must be a number");
82
82
  DEV: assert(isNumber(t), "[litecanvas] lerp() 3rd param must be a number");
83
- return t * (end - start) + start;
83
+ return start + t * (end - start);
84
84
  },
85
85
  /**
86
86
  * Convert degrees to radians
@@ -256,7 +256,7 @@
256
256
  DEV: assert(isNumber(min), "[litecanvas] randi() 1st param must be a number");
257
257
  DEV: assert(isNumber(max), "[litecanvas] randi() 2nd param must be a number");
258
258
  DEV: assert(
259
- max > min,
259
+ min <= max,
260
260
  "[litecanvas] randi() the 1st param must be less than the 2nd param"
261
261
  );
262
262
  return math.floor(instance.rand(min, max + 1));
@@ -911,7 +911,7 @@
911
911
  eventName = lowerCase(eventName);
912
912
  _eventListeners[eventName] = _eventListeners[eventName] || /* @__PURE__ */ new Set();
913
913
  _eventListeners[eventName].add(callback);
914
- return () => _eventListeners && _eventListeners[eventName].delete(callback);
914
+ return () => _eventListeners[eventName]?.delete(callback);
915
915
  },
916
916
  /**
917
917
  * Call all listeners attached to a game event
@@ -1041,7 +1041,7 @@
1041
1041
  // 2
1042
1042
  _fpsInterval / 1e3,
1043
1043
  // 3
1044
- _scale,
1044
+ _canvasScale,
1045
1045
  // 4
1046
1046
  _eventListeners,
1047
1047
  // 5
@@ -1130,8 +1130,8 @@
1130
1130
  * @param {MouseEvent | Touch} ev
1131
1131
  */
1132
1132
  (ev) => [
1133
- (ev.pageX - _canvas.offsetLeft) / _scale,
1134
- (ev.pageY - _canvas.offsetTop) / _scale
1133
+ (ev.pageX - _canvas.offsetLeft) / _canvasScale,
1134
+ (ev.pageY - _canvas.offsetTop) / _canvasScale
1135
1135
  ]
1136
1136
  ), _taps = /* @__PURE__ */ new Map(), _registerTap = (
1137
1137
  /**
@@ -1342,8 +1342,8 @@
1342
1342
  );
1343
1343
  }
1344
1344
  _initialized = true;
1345
- instance.emit("init", instance);
1346
1345
  instance.resume();
1346
+ instance.emit("init", instance);
1347
1347
  }
1348
1348
  function drawFrame() {
1349
1349
  _rafid = raf(drawFrame);
@@ -1417,14 +1417,14 @@
1417
1417
  _canvas.style.display = "block";
1418
1418
  _canvas.style.margin = "auto";
1419
1419
  }
1420
- _scale = math.min(innerWidth / width, innerHeight / height);
1421
- _scale = maxScale > 1 && _scale > maxScale ? maxScale : _scale;
1422
- _canvas.style.width = width * _scale + "px";
1423
- _canvas.style.height = height * _scale + "px";
1420
+ _canvasScale = math.min(innerWidth / width, innerHeight / height);
1421
+ _canvasScale = maxScale > 1 && _canvasScale > maxScale ? maxScale : _canvasScale;
1422
+ _canvas.style.width = width * _canvasScale + "px";
1423
+ _canvas.style.height = height * _canvasScale + "px";
1424
1424
  }
1425
1425
  _ctx.imageSmoothingEnabled = false;
1426
1426
  instance.textalign("start", "top");
1427
- instance.emit("resized", _scale);
1427
+ instance.emit("resized", _canvasScale);
1428
1428
  }
1429
1429
  function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
1430
1430
  if (!_eventListeners[eventName]) return;
package/dist/dist.js CHANGED
@@ -29,7 +29,7 @@
29
29
  keyboardEvents: true
30
30
  };
31
31
  settings = Object.assign(defaults, settings);
32
- let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
32
+ let _initialized = false, _paused = true, _canvas, _canvasScale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
33
33
  const instance = {
34
34
  /** @type {number} */
35
35
  W: 0,
@@ -69,7 +69,7 @@
69
69
  * @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
70
70
  */
71
71
  lerp: (start, end, t) => {
72
- return t * (end - start) + start;
72
+ return start + t * (end - start);
73
73
  },
74
74
  /**
75
75
  * Convert degrees to radians
@@ -627,7 +627,7 @@
627
627
  eventName = lowerCase(eventName);
628
628
  _eventListeners[eventName] = _eventListeners[eventName] || /* @__PURE__ */ new Set();
629
629
  _eventListeners[eventName].add(callback);
630
- return () => _eventListeners && _eventListeners[eventName].delete(callback);
630
+ return () => _eventListeners[eventName]?.delete(callback);
631
631
  },
632
632
  /**
633
633
  * Call all listeners attached to a game event
@@ -719,7 +719,7 @@
719
719
  // 2
720
720
  _fpsInterval / 1e3,
721
721
  // 3
722
- _scale,
722
+ _canvasScale,
723
723
  // 4
724
724
  _eventListeners,
725
725
  // 5
@@ -803,8 +803,8 @@
803
803
  * @param {MouseEvent | Touch} ev
804
804
  */
805
805
  (ev) => [
806
- (ev.pageX - _canvas.offsetLeft) / _scale,
807
- (ev.pageY - _canvas.offsetTop) / _scale
806
+ (ev.pageX - _canvas.offsetLeft) / _canvasScale,
807
+ (ev.pageY - _canvas.offsetTop) / _canvasScale
808
808
  ]
809
809
  ), _taps = /* @__PURE__ */ new Map(), _registerTap = (
810
810
  /**
@@ -1007,8 +1007,8 @@
1007
1007
  );
1008
1008
  }
1009
1009
  _initialized = true;
1010
- instance.emit("init", instance);
1011
1010
  instance.resume();
1011
+ instance.emit("init", instance);
1012
1012
  }
1013
1013
  function drawFrame() {
1014
1014
  _rafid = raf(drawFrame);
@@ -1059,14 +1059,14 @@
1059
1059
  _canvas.style.display = "block";
1060
1060
  _canvas.style.margin = "auto";
1061
1061
  }
1062
- _scale = math.min(innerWidth / width, innerHeight / height);
1063
- _scale = maxScale > 1 && _scale > maxScale ? maxScale : _scale;
1064
- _canvas.style.width = width * _scale + "px";
1065
- _canvas.style.height = height * _scale + "px";
1062
+ _canvasScale = math.min(innerWidth / width, innerHeight / height);
1063
+ _canvasScale = maxScale > 1 && _canvasScale > maxScale ? maxScale : _canvasScale;
1064
+ _canvas.style.width = width * _canvasScale + "px";
1065
+ _canvas.style.height = height * _canvasScale + "px";
1066
1066
  }
1067
1067
  _ctx.imageSmoothingEnabled = false;
1068
1068
  instance.textalign("start", "top");
1069
- instance.emit("resized", _scale);
1069
+ instance.emit("resized", _canvasScale);
1070
1070
  }
1071
1071
  function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
1072
1072
  if (!_eventListeners[eventName]) return;
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},f=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,d=0,c=0,u=0,p=0,h=0,g=0,m=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let z=Math,D=2*z.PI,E=d*=500*D/44100/44100,P=n*=(1-t+2*t*z.random(t=[]))*D/44100,T=0,C=0,I=0,L=1,S=0,A=0,M=0,N=k<0?-1:1,q=D*N*k*2/44100,B=z.cos(q),H=z.sin,O=H(q)/4,V=1+O,W=-2*B/V,R=(1-O)/V,F=(1+N*B)/2/V,G=-(N+B)/V,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,c*=500*D/85766121e6,m*=D/44100,u*=D/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,N=i+y+o+r+w|0;I<N;t[I++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?H(T*T):z.max(z.min(z.tan(T),1),-1):1-(2*T/D%2+2)%2:1-4*z.abs(z.round(T/D)-T/D):H(T),M=(h?1-b+b*H(D*I/h):1)*(M<0?-1:1)*z.abs(M)**f*(I<i?I/i:I<i+y?1-(I-i)/y*(1-x):I<i+y+o?x:I<N-w?(N-I-w)/r*x:0),M=w?M/2+(w>I?0:(I<N-w?1:(N-I)/w)*t[I-w|0]/2/e):M,k&&(M=j=F*X+G*(X=Y)+F*(Y=M)-R*$-W*($=j))),T+=(q=(n+=d+=c)*z.cos(m*C++))+q*g*H(I**5),L&&++L>p&&(n+=u,P+=u,L=0),!h||++S%h||(n=P,d=E,L=L||1);(e=a.createBuffer(1,N,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let d=!1,c=!0,u,p=1,h,g=.5,m=1,v,w=1e3/60,x,y,b=3,k="sans-serif",z=20,D=1.2,E=Date.now(),P=e,T=[],C=[.5,0,1750,,,.3,1,,,,600,.1],I={},L={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?L.clamp(o,l,n):o},norm:(e,t,a)=>L.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(E=(1664525*E+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(L.rand(e,t+1)),rseed(e){E=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):L.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),L.stroke(n)},rectfill(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),L.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.fill(l)},oval(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.stroke(n)},ovalfill(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.fill(n)},shape(e){h.beginPath();for(let t=0;t<e.length;t+=2)0===t?h.moveTo(~~e[t],~~e[t+1]):h.lineTo(~~e[t],~~e[t+1]);h.lineTo(~~e[0],~~e[1])},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);h.moveTo(~~e+i,~~t+o),h.lineTo(~~a+i,~~l+o),L.stroke(n)},linewidth(e){h.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=b,n="normal"){h.font=`${n} ${z}px ${k}`,h.fillStyle=q(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)h.fillText(i[a],~~e,~~t+z*D*a)},textgap(e){D=e},textfont(e){k=e},textsize(e){z=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},spr(e,t,a){let l=a.trim().split("\n");for(let a=0;a<l.length;a++){let n=l[a].trim();for(let l=0;l<n.length;l++){let i=n[l];"."!==i&&" "!==i&&L.rectfill(e+l,t+a,1,1,parseInt(i,36)||0)}}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=h;return n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a(h),h=o,n.transferToImageBitmap()},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=L.clamp(e,0,1)},fill(e){h.fillStyle=q(e),h.fill()},stroke(e){h.strokeStyle=q(e),h.stroke()},clip(e){h.beginPath(),e(h),h.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||C,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>u,use(e,t={}){var a=e,l=t;let n=a(L,l);for(let e in n)L.def(e,n[e])},listen:(e,t)=>(I[e=e.toLowerCase()]=I[e]||new Set,I[e].add(t),()=>I&&I[e].delete(t)),emit(e,t,a,l,n){d&&(N("before:"+(e=e.toLowerCase()),t,a,l,n),N(e,t,a,l,n),N("after:"+e,t,a,l,n))},pal(t,a=3){P=t||e,T=[],b=a},palc(e,t){null==e?T=[]:T[e]=t},def(e,a){L[e]=a,t.global&&(l[e]=a)},timescale(e){m=e},framerate(e){w=1e3/~~e},stat(e){let a={index:e,value:[t,d,w/1e3,p,I,P,C,m,l.zzfxV,E,z,k,T,D][e]};return L.emit("stat",a),a.value},pause(){c=!0,cancelAnimationFrame(y)},resume(){d&&c&&(c=!1,x=w,v=Date.now(),y=o(A))},paused:()=>c,quit(){for(let e of(L.emit("quit"),L.pause(),d=!1,I={},r))e();if(t.global){for(let e in L)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(","))L[e]=n[e];function S(){if(t.autoscale&&s(l,"resize",M),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.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&&Date.now()-e.t<=300,o=!1;s(u,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);L.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(u,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,r]=e(a);i(l)&&L.emit("tapped",l.xi,l.yi,0),L.emit("untap",n,r,0),t.delete(0),o=!1}}),s(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);L.def("MX",a),L.def("MY",l),o&&(L.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);L.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(u,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);L.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let r=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&L.emit("tapped",l.xi,l.yi,e),L.emit("untap",l.x,l.y,e),t.delete(e))};s(u,"touchend",r),s(u,"touchcancel",r),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))L.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),L.listen("after:update",()=>t.clear()),L.def("iskeydown",t=>a(e,t)),L.def("iskeypressed",e=>a(t,e)),L.def("lastkey",()=>n)}d=!0,L.emit("init",L),L.resume()}function A(){y=o(A);let e=Date.now(),t=0,a=e-v;for(v=e,x+=a<100?a:w;x>=w;){t++,x-=w;let e=w/1e3*m;L.emit("update",e,t),L.def("T",L.T+e)}t&&(L.emit("draw",h),t>1&&(x=0))}function M(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(L.def("W",e),L.def("H",a),u.width=e,u.height=a,t.autoscale){let l=+t.autoscale;u.style.display||(u.style.display="block",u.style.margin="auto"),p=n.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}h.imageSmoothingEnabled=!1,L.textalign("start","top"),L.emit("resized",p)}function N(e,t,a,l,n){if(I[e])for(let i of I[e])i(t,a,l,n)}function q(e){return P[~~(T[e]??e)%P.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,L),l.ENGINE=L}h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),s(u,"click",()=>focus()),M(),u.parentNode||document.body.appendChild(u),u.style.imageRendering="pixelated",u.oncontextmenu=()=>!1;let B=t.loop?t.loop:l;for(let e of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))B[e]&&L.listen(e,B[e]);return"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(S)):y=o(S),L}})();
1
+ (()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},f=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,d=0,c=0,u=0,p=0,h=0,g=0,m=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let z=Math,D=2*z.PI,E=d*=500*D/44100/44100,P=n*=(1-t+2*t*z.random(t=[]))*D/44100,T=0,C=0,I=0,L=1,S=0,A=0,M=0,N=k<0?-1:1,q=D*N*k*2/44100,B=z.cos(q),H=z.sin,O=H(q)/4,V=1+O,W=-2*B/V,R=(1-O)/V,F=(1+N*B)/2/V,G=-(N+B)/V,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,c*=500*D/85766121e6,m*=D/44100,u*=D/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,N=i+y+o+r+w|0;I<N;t[I++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?H(T*T):z.max(z.min(z.tan(T),1),-1):1-(2*T/D%2+2)%2:1-4*z.abs(z.round(T/D)-T/D):H(T),M=(h?1-b+b*H(D*I/h):1)*(M<0?-1:1)*z.abs(M)**f*(I<i?I/i:I<i+y?1-(I-i)/y*(1-x):I<i+y+o?x:I<N-w?(N-I-w)/r*x:0),M=w?M/2+(w>I?0:(I<N-w?1:(N-I)/w)*t[I-w|0]/2/e):M,k&&(M=j=F*X+G*(X=Y)+F*(Y=M)-R*$-W*($=j))),T+=(q=(n+=d+=c)*z.cos(m*C++))+q*g*H(I**5),L&&++L>p&&(n+=u,P+=u,L=0),!h||++S%h||(n=P,d=E,L=L||1);(e=a.createBuffer(1,N,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let d=!1,c=!0,u,p=1,h,g=.5,m=1,v,w=1e3/60,x,y,b=3,k="sans-serif",z=20,D=1.2,E=Date.now(),P=e,T=[],C=[.5,0,1750,,,.3,1,,,,600,.1],I={},L={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?L.clamp(o,l,n):o},norm:(e,t,a)=>L.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(E=(1664525*E+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(L.rand(e,t+1)),rseed(e){E=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):L.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),L.stroke(n)},rectfill(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),L.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.fill(l)},oval(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.stroke(n)},ovalfill(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.fill(n)},shape(e){h.beginPath();for(let t=0;t<e.length;t+=2)0===t?h.moveTo(~~e[t],~~e[t+1]):h.lineTo(~~e[t],~~e[t+1]);h.lineTo(~~e[0],~~e[1])},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);h.moveTo(~~e+i,~~t+o),h.lineTo(~~a+i,~~l+o),L.stroke(n)},linewidth(e){h.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=b,n="normal"){h.font=`${n} ${z}px ${k}`,h.fillStyle=q(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)h.fillText(i[a],~~e,~~t+z*D*a)},textgap(e){D=e},textfont(e){k=e},textsize(e){z=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},spr(e,t,a){let l=a.trim().split("\n");for(let a=0;a<l.length;a++){let n=l[a].trim();for(let l=0;l<n.length;l++){let i=n[l];"."!==i&&" "!==i&&L.rectfill(e+l,t+a,1,1,parseInt(i,36)||0)}}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=h;return n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a(h),h=o,n.transferToImageBitmap()},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=L.clamp(e,0,1)},fill(e){h.fillStyle=q(e),h.fill()},stroke(e){h.strokeStyle=q(e),h.stroke()},clip(e){h.beginPath(),e(h),h.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||C,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>u,use(e,t={}){var a=e,l=t;let n=a(L,l);for(let e in n)L.def(e,n[e])},listen:(e,t)=>(I[e=e.toLowerCase()]=I[e]||new Set,I[e].add(t),()=>I[e]?.delete(t)),emit(e,t,a,l,n){d&&(N("before:"+(e=e.toLowerCase()),t,a,l,n),N(e,t,a,l,n),N("after:"+e,t,a,l,n))},pal(t,a=3){P=t||e,T=[],b=a},palc(e,t){null==e?T=[]:T[e]=t},def(e,a){L[e]=a,t.global&&(l[e]=a)},timescale(e){m=e},framerate(e){w=1e3/~~e},stat(e){let a={index:e,value:[t,d,w/1e3,p,I,P,C,m,l.zzfxV,E,z,k,T,D][e]};return L.emit("stat",a),a.value},pause(){c=!0,cancelAnimationFrame(y)},resume(){d&&c&&(c=!1,x=w,v=Date.now(),y=o(A))},paused:()=>c,quit(){for(let e of(L.emit("quit"),L.pause(),d=!1,I={},r))e();if(t.global){for(let e in L)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(","))L[e]=n[e];function S(){if(t.autoscale&&s(l,"resize",M),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.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&&Date.now()-e.t<=300,o=!1;s(u,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);L.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(u,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,r]=e(a);i(l)&&L.emit("tapped",l.xi,l.yi,0),L.emit("untap",n,r,0),t.delete(0),o=!1}}),s(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);L.def("MX",a),L.def("MY",l),o&&(L.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);L.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(u,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);L.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let r=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&L.emit("tapped",l.xi,l.yi,e),L.emit("untap",l.x,l.y,e),t.delete(e))};s(u,"touchend",r),s(u,"touchcancel",r),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))L.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),L.listen("after:update",()=>t.clear()),L.def("iskeydown",t=>a(e,t)),L.def("iskeypressed",e=>a(t,e)),L.def("lastkey",()=>n)}d=!0,L.resume(),L.emit("init",L)}function A(){y=o(A);let e=Date.now(),t=0,a=e-v;for(v=e,x+=a<100?a:w;x>=w;){t++,x-=w;let e=w/1e3*m;L.emit("update",e,t),L.def("T",L.T+e)}t&&(L.emit("draw",h),t>1&&(x=0))}function M(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(L.def("W",e),L.def("H",a),u.width=e,u.height=a,t.autoscale){let l=+t.autoscale;u.style.display||(u.style.display="block",u.style.margin="auto"),p=n.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}h.imageSmoothingEnabled=!1,L.textalign("start","top"),L.emit("resized",p)}function N(e,t,a,l,n){if(I[e])for(let i of I[e])i(t,a,l,n)}function q(e){return P[~~(T[e]??e)%P.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,L),l.ENGINE=L}h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),s(u,"click",()=>focus()),M(),u.parentNode||document.body.appendChild(u),u.style.imageRendering="pixelated",u.oncontextmenu=()=>!1;let B=t.loop?t.loop:l;for(let e of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))B[e]&&L.listen(e,B[e]);return"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(S)):y=o(S),L}})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.102.2",
3
+ "version": "0.102.3",
4
4
  "description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and p5.js/Processing.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
@@ -31,16 +31,16 @@
31
31
  "creative coding"
32
32
  ],
33
33
  "devDependencies": {
34
- "@happy-dom/global-registrator": "^18.0.1",
35
- "@size-limit/preset-small-lib": "^11.2.0",
36
- "@swc/core": "^1.15.8",
34
+ "@happy-dom/global-registrator": "^20.7.0",
35
+ "@size-limit/preset-small-lib": "^12.0.0",
36
+ "@swc/core": "^1.15.13",
37
37
  "ava": "^6.4.1",
38
- "esbuild": "^0.25.12",
38
+ "esbuild": "^0.27.3",
39
39
  "genversion": "^3.2.0",
40
40
  "gzip-size": "^7.0.0",
41
- "prettier": "^3.7.4",
41
+ "prettier": "^3.8.1",
42
42
  "sinon": "^21.0.1",
43
- "size-limit": "^11.2.0",
43
+ "size-limit": "^12.0.0",
44
44
  "tap-min": "^3.0.0"
45
45
  },
46
46
  "trustedDependencies": [
package/src/index.js CHANGED
@@ -53,7 +53,7 @@ export default function litecanvas(settings = {}) {
53
53
  /** @type {HTMLCanvasElement} _canvas */
54
54
  _canvas,
55
55
  /** @type {number} */
56
- _scale = 1,
56
+ _canvasScale = 1,
57
57
  /** @type {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} */
58
58
  _ctx,
59
59
  /** @type {number} */
@@ -145,7 +145,7 @@ export default function litecanvas(settings = {}) {
145
145
  DEV: assert(isNumber(end), '[litecanvas] lerp() 2nd param must be a number')
146
146
  DEV: assert(isNumber(t), '[litecanvas] lerp() 3rd param must be a number')
147
147
 
148
- return t * (end - start) + start
148
+ return start + t * (end - start)
149
149
  },
150
150
 
151
151
  /**
@@ -187,6 +187,7 @@ export default function litecanvas(settings = {}) {
187
187
  isNumber(precision) && precision >= 0,
188
188
  '[litecanvas] round() 2nd param must be a positive number or zero'
189
189
  )
190
+
190
191
  if (!precision) {
191
192
  return math.round(n)
192
193
  }
@@ -341,7 +342,7 @@ export default function litecanvas(settings = {}) {
341
342
  DEV: assert(isNumber(min), '[litecanvas] randi() 1st param must be a number')
342
343
  DEV: assert(isNumber(max), '[litecanvas] randi() 2nd param must be a number')
343
344
  DEV: assert(
344
- max > min,
345
+ min <= max,
345
346
  '[litecanvas] randi() the 1st param must be less than the 2nd param'
346
347
  )
347
348
 
@@ -360,6 +361,7 @@ export default function litecanvas(settings = {}) {
360
361
  isNumber(value) && value >= 0,
361
362
  '[litecanvas] rseed() 1st param must be a positive integer or zero'
362
363
  )
364
+
363
365
  _rngSeed = ~~value
364
366
  },
365
367
 
@@ -1084,7 +1086,7 @@ export default function litecanvas(settings = {}) {
1084
1086
  _eventListeners[eventName].add(callback)
1085
1087
 
1086
1088
  // return a function to remove this event listener
1087
- return () => _eventListeners && _eventListeners[eventName].delete(callback)
1089
+ return () => _eventListeners[eventName]?.delete(callback)
1088
1090
  },
1089
1091
 
1090
1092
  /**
@@ -1229,7 +1231,7 @@ export default function litecanvas(settings = {}) {
1229
1231
  // 2
1230
1232
  _fpsInterval / 1000,
1231
1233
  // 3
1232
- _scale,
1234
+ _canvasScale,
1233
1235
  // 4
1234
1236
  _eventListeners,
1235
1237
  // 5
@@ -1345,8 +1347,8 @@ export default function litecanvas(settings = {}) {
1345
1347
  * @param {MouseEvent | Touch} ev
1346
1348
  */
1347
1349
  (ev) => [
1348
- (ev.pageX - _canvas.offsetLeft) / _scale,
1349
- (ev.pageY - _canvas.offsetTop) / _scale,
1350
+ (ev.pageX - _canvas.offsetLeft) / _canvasScale,
1351
+ (ev.pageY - _canvas.offsetTop) / _canvasScale,
1350
1352
  ],
1351
1353
  _taps = new Map(),
1352
1354
  _registerTap =
@@ -1595,8 +1597,8 @@ export default function litecanvas(settings = {}) {
1595
1597
 
1596
1598
  // start the engine
1597
1599
  _initialized = true
1598
- instance.emit('init', instance)
1599
1600
  instance.resume()
1601
+ instance.emit('init', instance)
1600
1602
  }
1601
1603
 
1602
1604
  function drawFrame() {
@@ -1695,11 +1697,11 @@ export default function litecanvas(settings = {}) {
1695
1697
  _canvas.style.margin = 'auto'
1696
1698
  }
1697
1699
 
1698
- _scale = math.min(innerWidth / width, innerHeight / height)
1699
- _scale = maxScale > 1 && _scale > maxScale ? maxScale : _scale
1700
+ _canvasScale = math.min(innerWidth / width, innerHeight / height)
1701
+ _canvasScale = maxScale > 1 && _canvasScale > maxScale ? maxScale : _canvasScale
1700
1702
 
1701
- _canvas.style.width = width * _scale + 'px'
1702
- _canvas.style.height = height * _scale + 'px'
1703
+ _canvas.style.width = width * _canvasScale + 'px'
1704
+ _canvas.style.height = height * _canvasScale + 'px'
1703
1705
  }
1704
1706
 
1705
1707
  // set canvas image rendering properties
@@ -1710,7 +1712,7 @@ export default function litecanvas(settings = {}) {
1710
1712
 
1711
1713
  // trigger "resized" event
1712
1714
  // note: not triggered before the "init" event
1713
- instance.emit('resized', _scale)
1715
+ instance.emit('resized', _canvasScale)
1714
1716
  }
1715
1717
 
1716
1718
  /**
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.102.2'
2
+ export const version = '0.102.3'