litecanvas 0.94.1 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dist.dev.js CHANGED
@@ -32,18 +32,18 @@
32
32
  };
33
33
 
34
34
  // src/version.js
35
- var version = "0.94.1";
35
+ var version = "0.95.0";
36
36
 
37
37
  // src/index.js
38
38
  function litecanvas(settings = {}) {
39
39
  const root = window, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
40
40
  elem.addEventListener(evt, callback, false);
41
41
  _browserEventListeners.push(() => elem.removeEventListener(evt, callback, false));
42
- }, beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
42
+ }, preventDefault = (ev) => ev.preventDefault(), beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
43
43
  width: null,
44
44
  height: null,
45
45
  autoscale: true,
46
- pixelart: false,
46
+ pixelart: true,
47
47
  canvas: null,
48
48
  global: true,
49
49
  loop: null,
@@ -1106,11 +1106,6 @@
1106
1106
  * @param {{t: number}} tap
1107
1107
  */
1108
1108
  (tap) => tap && Date.now() - tap.t <= 300
1109
- ), preventDefault = (
1110
- /**
1111
- * @param {Event} ev
1112
- */
1113
- (ev) => ev.preventDefault()
1114
1109
  );
1115
1110
  let _pressingMouse = false;
1116
1111
  on(
@@ -1231,11 +1226,13 @@
1231
1226
  key = key.toLowerCase();
1232
1227
  return !key ? keySet.size > 0 : keySet.has("space" === key ? " " : key);
1233
1228
  };
1229
+ let _lastKey = "";
1234
1230
  on(root, "keydown", (event) => {
1235
1231
  const key = event.key.toLowerCase();
1236
1232
  if (!_keysDown.has(key)) {
1237
1233
  _keysDown.add(key);
1238
1234
  _keysPress.add(key);
1235
+ _lastKey = key === " " ? "space" : key;
1239
1236
  }
1240
1237
  });
1241
1238
  on(root, "keyup", (event) => {
@@ -1246,9 +1243,6 @@
1246
1243
  instance.def(
1247
1244
  "iskeydown",
1248
1245
  /**
1249
- * Checks if a which key is pressed (down) on the keyboard.
1250
- * Note: use `iskeydown()` to check for any key.
1251
- *
1252
1246
  * @param {string} [key]
1253
1247
  * @returns {boolean}
1254
1248
  */
@@ -1263,9 +1257,6 @@
1263
1257
  instance.def(
1264
1258
  "iskeypressed",
1265
1259
  /**
1266
- * Checks if a which key just got pressed on the keyboard.
1267
- * Note: use `iskeypressed()` to check for any key.
1268
- *
1269
1260
  * @param {string} [key]
1270
1261
  * @returns {boolean}
1271
1262
  */
@@ -1277,6 +1268,13 @@
1277
1268
  return keyCheck(_keysPress, key);
1278
1269
  }
1279
1270
  );
1271
+ instance.def(
1272
+ "lastkey",
1273
+ /**
1274
+ * @returns {string}
1275
+ */
1276
+ () => _lastKey
1277
+ );
1280
1278
  }
1281
1279
  _initialized = true;
1282
1280
  instance.emit("init", instance);
package/dist/dist.js CHANGED
@@ -31,11 +31,11 @@
31
31
  const root = window, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
32
32
  elem.addEventListener(evt, callback, false);
33
33
  _browserEventListeners.push(() => elem.removeEventListener(evt, callback, false));
34
- }, beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
34
+ }, preventDefault = (ev) => ev.preventDefault(), beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
35
35
  width: null,
36
36
  height: null,
37
37
  autoscale: true,
38
- pixelart: false,
38
+ pixelart: true,
39
39
  canvas: null,
40
40
  global: true,
41
41
  loop: null,
@@ -807,11 +807,6 @@
807
807
  * @param {{t: number}} tap
808
808
  */
809
809
  (tap) => tap && Date.now() - tap.t <= 300
810
- ), preventDefault = (
811
- /**
812
- * @param {Event} ev
813
- */
814
- (ev) => ev.preventDefault()
815
810
  );
816
811
  let _pressingMouse = false;
817
812
  on(
@@ -932,11 +927,13 @@
932
927
  key = key.toLowerCase();
933
928
  return !key ? keySet.size > 0 : keySet.has("space" === key ? " " : key);
934
929
  };
930
+ let _lastKey = "";
935
931
  on(root, "keydown", (event) => {
936
932
  const key = event.key.toLowerCase();
937
933
  if (!_keysDown.has(key)) {
938
934
  _keysDown.add(key);
939
935
  _keysPress.add(key);
936
+ _lastKey = key === " " ? "space" : key;
940
937
  }
941
938
  });
942
939
  on(root, "keyup", (event) => {
@@ -947,9 +944,6 @@
947
944
  instance.def(
948
945
  "iskeydown",
949
946
  /**
950
- * Checks if a which key is pressed (down) on the keyboard.
951
- * Note: use `iskeydown()` to check for any key.
952
- *
953
947
  * @param {string} [key]
954
948
  * @returns {boolean}
955
949
  */
@@ -960,9 +954,6 @@
960
954
  instance.def(
961
955
  "iskeypressed",
962
956
  /**
963
- * Checks if a which key just got pressed on the keyboard.
964
- * Note: use `iskeypressed()` to check for any key.
965
- *
966
957
  * @param {string} [key]
967
958
  * @returns {boolean}
968
959
  */
@@ -970,6 +961,13 @@
970
961
  return keyCheck(_keysPress, key);
971
962
  }
972
963
  );
964
+ instance.def(
965
+ "lastkey",
966
+ /**
967
+ * @returns {string}
968
+ */
969
+ () => _lastKey
970
+ );
973
971
  }
974
972
  _initialized = true;
975
973
  instance.emit("init", instance);
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,i=Math,l=2*i.PI,n=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.beginPath(),f=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,i=.05,l=220,n=0,o=0,r=.1,s=0,f=1,c=0,d=0,u=0,p=0,h=0,m=0,g=0,w=0,v=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=c*=500*z/44100/44100,C=l*=(1-i+2*i*E.random(i=[]))*z/44100,I=0,A=0,L=0,S=1,D=0,M=0,N=0,P=k<0?-1:1,F=z*P*k*2/44100,q=E.cos(F),B=E.sin,H=B(F)/4,O=1+H,V=-2*q/O,W=(1-H)/O,R=(1+P*q)/2/O,G=-(P+q)/O,X=0,Y=0,$=0,j=0;for(n=44100*n+9,y*=44100,o*=44100,r*=44100,v*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=n+y+o+r+v|0;L<P;i[L++]=N*a)++M%(100*w|0)||(N=s?1<s?2<s?3<s?B(I*I):E.max(E.min(E.tan(I),1),-1):1-(2*I/z%2+2)%2:1-4*E.abs(E.round(I/z)-I/z):B(I),N=(h?1-b+b*B(z*L/h):1)*(N<0?-1:1)*E.abs(N)**f*(L<n?L/n:L<n+y?1-(L-n)/y*(1-x):L<n+y+o?x:L<P-v?(P-L-v)/r*x:0),N=v?N/2+(v>L?0:(L<P-v?1:(P-L)/v)*i[L-v|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),I+=(F=(l+=c+=d)*E.cos(g*A++))+F*m*B(L**5),S&&++S>p&&(l+=u,C+=u,S=0),!h||++D%h||(l=C,c=T,S=S||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(i),(l=t.createBufferSource()).buffer=a,l.connect(t.destination),l.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0,animate:!0},t);let c=!1,d=[],u,p=1,h,m=.5,g=1,w,v=1e3/60,x,y,b="sans-serif",k=20,E=Date.now(),z=e,T=[.5,0,1750,,,.3,1,,,,600,.1],C={},I={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:l,HALF_PI:l/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i.PI/180*e,rad2deg:e=>180/i.PI*e,round:(e,t=0)=>{if(!t)return i.round(e);let a=10**t;return i.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*i.floor((e-t)/(a-t)),map(e,t,a,i,l,n){let o=(e-t)/(a-t)*(l-i)+i;return n?I.clamp(o,i,l):o},norm:(e,t,a)=>I.map(e,t,a,0,1),wave:(e,t,a,i=Math.sin)=>e+(i(a)+1)/2*(t-e),rand:(e=0,t=1)=>(E=(1664525*E+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>i.floor(I.rand(e,t+1)),rseed(e){E=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):I.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,i,l,n){s(h),h[n?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~i+2*m,n),I.stroke(l)},rectfill(e,t,a,i,l,n){s(h),h[n?"roundRect":"rect"](~~e,~~t,~~a,~~i,n),I.fill(l)},circ(e,t,a,i){s(h),h.arc(~~e,~~t,~~a,0,l),I.stroke(i)},circfill(e,t,a,i){s(h),h.arc(~~e,~~t,~~a,0,l),I.fill(i)},oval(e,t,a,i,n){s(h),h.ellipse(~~e,~~t,~~a,~~i,0,0,l),I.stroke(n)},ovalfill(e,t,a,i,n){s(h),h.ellipse(~~e,~~t,~~a,~~i,0,0,l),I.fill(n)},line(e,t,a,i,l){s(h);let n=.5*(0!==m&&~~e==~~a),o=.5*(0!==m&&~~t==~~i);h.moveTo(~~e+n,~~t+o),h.lineTo(~~a+n,~~i+o),I.stroke(l)},linewidth(e){h.lineWidth=~~e,m=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,i=3,l="normal"){h.font=`${l} ${k}px ${b}`,h.fillStyle=z[~~i%z.length],h.fillText(a,~~e,~~t)},textfont(e){b=e},textsize(e){k=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,i={}){let l=i.canvas||new OffscreenCanvas(1,1),n=i.scale||1,o=h;if(l.width=e*n,l.height=t*n,(h=l.getContext("2d")).scale(n,n),Array.isArray(a)){let e=0,t=0;for(let i of(h.imageSmoothingEnabled=!1,a)){for(let a of i)" "!==a&&"."!==a&&I.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(h);return h=o,l.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=I.clamp(e,0,1)},fill(e){h.fillStyle=z[~~e%z.length],h.fill()},stroke(e){h.strokeStyle=z[~~e%z.length],h.stroke()},clip(e){s(h),e(h),h.clip()},sfx:(e,t=0,i=1)=>!!a.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||T,(0!==t||1!==i)&&((e=e.slice())[0]=i*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){a.zzfxV=e},canvas:()=>u,use(e,t={}){c?M(e,t):d.push([e,t])},listen:(e,t)=>(C[e=e.toLowerCase()]=C[e]||new Set,C[e].add(t),()=>C&&C[e].delete(t)),emit(e,t,a,i,l){c&&(D("before:"+(e=e.toLowerCase()),t,a,i,l),D(e,t,a,i,l),D("after:"+e,t,a,i,l))},pal(t=e){z=t},def(e,i){I[e]=i,t.global&&(a[e]=i)},timescale(e){g=e},framerate(e){v=1e3/~~e},stat(e){let i={index:e,value:[t,c,v/1e3,p,C,z,T,g,a.zzfxV,E,k,b][e]};return I.emit("stat",i),i.value},quit(){for(let e of(I.pause(),I.emit("quit"),C={},o))e();if(t.global){for(let e in I)delete a[e];delete a.ENGINE}c=!1},pause(){cancelAnimationFrame(y),y=0},resume(){c&&!y&&(x=v,w=Date.now(),y=n(L))},paused:()=>!y};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))I[e]=i[e];function A(){let e=t.loop?t.loop:a;for(let t of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))e[t]&&I.listen(t,e[t]);for(let[e,t]of d)M(e,t);if(t.autoscale&&r(a,"resize",S),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,i=(e,a,i)=>{let l={x:a,y:i,xi:a,yi:i,t:Date.now()};return t.set(e,l),l},l=(e,a,l)=>{let n=t.get(e)||i(e);n.x=a,n.y=l},n=e=>e&&Date.now()-e.t<=300,o=e=>e.preventDefault(),s=!1;r(u,"mousedown",t=>{if(0===t.button){o(t);let[a,l]=e(t);I.emit("tap",a,l,0),i(0,a,l),s=!0}}),r(u,"mouseup",a=>{if(0===a.button){o(a);let i=t.get(0),[l,r]=e(a);n(i)&&I.emit("tapped",i.xi,i.yi,0),I.emit("untap",l,r,0),t.delete(0),s=!1}}),r(a,"mousemove",t=>{o(t);let[a,i]=e(t);I.def("MX",a),I.def("MY",i),s&&(I.emit("tapping",a,i,0),l(0,a,i))}),r(u,"touchstart",t=>{for(let a of(o(t),t.changedTouches)){let[t,l]=e(a);I.emit("tap",t,l,a.identifier+1),i(a.identifier+1,t,l)}}),r(u,"touchmove",t=>{for(let a of(o(t),t.changedTouches)){let[t,i]=e(a);I.emit("tapping",t,i,a.identifier+1),l(a.identifier+1,t,i)}});let f=e=>{o(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,i]of t)a.includes(e)||(n(i)&&I.emit("tapped",i.xi,i.yi,e),I.emit("untap",i.x,i.y,e),t.delete(e))};r(u,"touchend",f),r(u,"touchcancel",f),r(a,"blur",()=>{for(let[e,a]of(s=!1,t))I.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,i=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0;r(a,"keydown",a=>{let i=a.key.toLowerCase();e.has(i)||(e.add(i),t.add(i))}),r(a,"keyup",t=>{e.delete(t.key.toLowerCase())}),r(a,"blur",()=>e.clear()),I.listen("after:update",()=>t.clear()),I.def("iskeydown",t=>i(e,t)),I.def("iskeypressed",e=>i(t,e))}c=!0,I.emit("init",I),I.resume()}function L(){if(!t.animate)return I.emit("draw",h);let e=Date.now(),a=0,i=e-w;for(w=e,x+=i<100?i:v;x>=v;){a++,x-=v;let e=v/1e3*g;I.emit("update",e,a),I.def("T",I.T+e)}a&&(I.emit("draw",h),a>1&&(x=0)),y=n(L)}function S(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(I.def("W",e),I.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=i.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}t.pixelart&&(h.imageSmoothingEnabled=!1,u.style.imageRendering="pixelated"),I.textalign("start","top"),I.emit("resized",p),t.animate||n(L)}function D(e,t,a,i,l){if(C[e])for(let n of C[e])n(t,a,i,l)}function M(e,t){let a=e(I,t);for(let e in a)I.def(e,a[e])}if(t.global){if(a.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(a,I),a.ENGINE=I}return h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),r(u,"click",()=>focus()),u.style="",S(),u.parentNode||document.body.appendChild(u),u.oncontextmenu=()=>!1,"loading"===document.readyState?r(a,"DOMContentLoaded",()=>n(A)):n(A),I}})();
1
+ (()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,i=Math,l=2*i.PI,n=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.preventDefault(),f=e=>e.beginPath(),c=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,i=.05,l=220,n=0,o=0,r=.1,s=0,f=1,c=0,d=0,u=0,p=0,h=0,m=0,g=0,w=0,v=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=c*=500*z/44100/44100,C=l*=(1-i+2*i*E.random(i=[]))*z/44100,I=0,A=0,L=0,S=1,D=0,M=0,N=0,P=k<0?-1:1,F=z*P*k*2/44100,q=E.cos(F),B=E.sin,H=B(F)/4,O=1+H,V=-2*q/O,W=(1-H)/O,R=(1+P*q)/2/O,G=-(P+q)/O,X=0,Y=0,$=0,j=0;for(n=44100*n+9,y*=44100,o*=44100,r*=44100,v*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=n+y+o+r+v|0;L<P;i[L++]=N*a)++M%(100*w|0)||(N=s?1<s?2<s?3<s?B(I*I):E.max(E.min(E.tan(I),1),-1):1-(2*I/z%2+2)%2:1-4*E.abs(E.round(I/z)-I/z):B(I),N=(h?1-b+b*B(z*L/h):1)*(N<0?-1:1)*E.abs(N)**f*(L<n?L/n:L<n+y?1-(L-n)/y*(1-x):L<n+y+o?x:L<P-v?(P-L-v)/r*x:0),N=v?N/2+(v>L?0:(L<P-v?1:(P-L)/v)*i[L-v|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),I+=(F=(l+=c+=d)*E.cos(g*A++))+F*m*B(L**5),S&&++S>p&&(l+=u,C+=u,S=0),!h||++D%h||(l=C,c=T,S=S||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(i),(l=t.createBufferSource()).buffer=a,l.connect(t.destination),l.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,pixelart:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0,animate:!0},t);let d=!1,u=[],p,h=1,m,g=.5,w=1,v,x=1e3/60,y,b,k="sans-serif",E=20,z=Date.now(),T=e,C=[.5,0,1750,,,.3,1,,,,600,.1],I={},A={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:l,HALF_PI:l/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>i.PI/180*e,rad2deg:e=>180/i.PI*e,round:(e,t=0)=>{if(!t)return i.round(e);let a=10**t;return i.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*i.floor((e-t)/(a-t)),map(e,t,a,i,l,n){let o=(e-t)/(a-t)*(l-i)+i;return n?A.clamp(o,i,l):o},norm:(e,t,a)=>A.map(e,t,a,0,1),wave:(e,t,a,i=Math.sin)=>e+(i(a)+1)/2*(t-e),rand:(e=0,t=1)=>(z=(1664525*z+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>i.floor(A.rand(e,t+1)),rseed(e){z=~~e},cls(e){null==e?m.clearRect(0,0,m.canvas.width,m.canvas.height):A.rectfill(0,0,m.canvas.width,m.canvas.height,e)},rect(e,t,a,i,l,n){f(m),m[n?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~i+2*g,n),A.stroke(l)},rectfill(e,t,a,i,l,n){f(m),m[n?"roundRect":"rect"](~~e,~~t,~~a,~~i,n),A.fill(l)},circ(e,t,a,i){f(m),m.arc(~~e,~~t,~~a,0,l),A.stroke(i)},circfill(e,t,a,i){f(m),m.arc(~~e,~~t,~~a,0,l),A.fill(i)},oval(e,t,a,i,n){f(m),m.ellipse(~~e,~~t,~~a,~~i,0,0,l),A.stroke(n)},ovalfill(e,t,a,i,n){f(m),m.ellipse(~~e,~~t,~~a,~~i,0,0,l),A.fill(n)},line(e,t,a,i,l){f(m);let n=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~i);m.moveTo(~~e+n,~~t+o),m.lineTo(~~a+n,~~i+o),A.stroke(l)},linewidth(e){m.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,i=3,l="normal"){m.font=`${l} ${E}px ${k}`,m.fillStyle=T[~~i%T.length],m.fillText(a,~~e,~~t)},textfont(e){k=e},textsize(e){E=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},image(e,t,a){m.drawImage(a,~~e,~~t)},paint(e,t,a,i={}){let l=i.canvas||new OffscreenCanvas(1,1),n=i.scale||1,o=m;if(l.width=e*n,l.height=t*n,(m=l.getContext("2d")).scale(n,n),Array.isArray(a)){let e=0,t=0;for(let i of(m.imageSmoothingEnabled=!1,a)){for(let a of i)" "!==a&&"."!==a&&A.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(m);return m=o,l.transferToImageBitmap()},ctx:e=>(e&&(m=e),m),push:()=>m.save(),pop:()=>m.restore(),translate:(e,t)=>m.translate(~~e,~~t),scale:(e,t)=>m.scale(e,t||e),rotate:e=>m.rotate(e),alpha(e){m.globalAlpha=A.clamp(e,0,1)},fill(e){m.fillStyle=T[~~e%T.length],m.fill()},stroke(e){m.strokeStyle=T[~~e%T.length],m.stroke()},clip(e){f(m),e(m),m.clip()},sfx:(e,t=0,i=1)=>!!a.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||C,(0!==t||1!==i)&&((e=e.slice())[0]=i*(e[0]||1),e[10]=~~e[10]+t),c.apply(0,e),e),volume(e){a.zzfxV=e},canvas:()=>p,use(e,t={}){d?N(e,t):u.push([e,t])},listen:(e,t)=>(I[e=e.toLowerCase()]=I[e]||new Set,I[e].add(t),()=>I&&I[e].delete(t)),emit(e,t,a,i,l){d&&(M("before:"+(e=e.toLowerCase()),t,a,i,l),M(e,t,a,i,l),M("after:"+e,t,a,i,l))},pal(t=e){T=t},def(e,i){A[e]=i,t.global&&(a[e]=i)},timescale(e){w=e},framerate(e){x=1e3/~~e},stat(e){let i={index:e,value:[t,d,x/1e3,h,I,T,C,w,a.zzfxV,z,E,k][e]};return A.emit("stat",i),i.value},quit(){for(let e of(A.pause(),A.emit("quit"),I={},o))e();if(t.global){for(let e in A)delete a[e];delete a.ENGINE}d=!1},pause(){cancelAnimationFrame(b),b=0},resume(){d&&!b&&(y=x,v=Date.now(),b=n(S))},paused:()=>!b};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))A[e]=i[e];function L(){let e=t.loop?t.loop:a;for(let t of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))e[t]&&A.listen(t,e[t]);for(let[e,t]of u)N(e,t);if(t.autoscale&&r(a,"resize",D),t.tapEvents){let e=e=>[(e.pageX-p.offsetLeft)/h,(e.pageY-p.offsetTop)/h],t=new Map,i=(e,a,i)=>{let l={x:a,y:i,xi:a,yi:i,t:Date.now()};return t.set(e,l),l},l=(e,a,l)=>{let n=t.get(e)||i(e);n.x=a,n.y=l},n=e=>e&&Date.now()-e.t<=300,o=!1;r(p,"mousedown",t=>{if(0===t.button){s(t);let[a,l]=e(t);A.emit("tap",a,l,0),i(0,a,l),o=!0}}),r(p,"mouseup",a=>{if(0===a.button){s(a);let i=t.get(0),[l,r]=e(a);n(i)&&A.emit("tapped",i.xi,i.yi,0),A.emit("untap",l,r,0),t.delete(0),o=!1}}),r(a,"mousemove",t=>{s(t);let[a,i]=e(t);A.def("MX",a),A.def("MY",i),o&&(A.emit("tapping",a,i,0),l(0,a,i))}),r(p,"touchstart",t=>{for(let a of(s(t),t.changedTouches)){let[t,l]=e(a);A.emit("tap",t,l,a.identifier+1),i(a.identifier+1,t,l)}}),r(p,"touchmove",t=>{for(let a of(s(t),t.changedTouches)){let[t,i]=e(a);A.emit("tapping",t,i,a.identifier+1),l(a.identifier+1,t,i)}});let f=e=>{s(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,i]of t)a.includes(e)||(n(i)&&A.emit("tapped",i.xi,i.yi,e),A.emit("untap",i.x,i.y,e),t.delete(e))};r(p,"touchend",f),r(p,"touchcancel",f),r(a,"blur",()=>{for(let[e,a]of(o=!1,t))A.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,i=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,l="";r(a,"keydown",a=>{let i=a.key.toLowerCase();e.has(i)||(e.add(i),t.add(i),l=" "===i?"space":i)}),r(a,"keyup",t=>{e.delete(t.key.toLowerCase())}),r(a,"blur",()=>e.clear()),A.listen("after:update",()=>t.clear()),A.def("iskeydown",t=>i(e,t)),A.def("iskeypressed",e=>i(t,e)),A.def("lastkey",()=>l)}d=!0,A.emit("init",A),A.resume()}function S(){if(!t.animate)return A.emit("draw",m);let e=Date.now(),a=0,i=e-v;for(v=e,y+=i<100?i:x;y>=x;){a++,y-=x;let e=x/1e3*w;A.emit("update",e,a),A.def("T",A.T+e)}a&&(A.emit("draw",m),a>1&&(y=0)),b=n(S)}function D(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(A.def("W",e),A.def("H",a),p.width=e,p.height=a,t.autoscale){let l=+t.autoscale;p.style.display||(p.style.display="block",p.style.margin="auto"),h=i.min(innerWidth/e,innerHeight/a),h=l>1&&h>l?l:h,p.style.width=e*h+"px",p.style.height=a*h+"px"}t.pixelart&&(m.imageSmoothingEnabled=!1,p.style.imageRendering="pixelated"),A.textalign("start","top"),A.emit("resized",h),t.animate||n(S)}function M(e,t,a,i,l){if(I[e])for(let n of I[e])n(t,a,i,l)}function N(e,t){let a=e(A,t);for(let e in a)A.def(e,a[e])}if(t.global){if(a.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(a,A),a.ENGINE=A}return m=(p=(p="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),r(p,"click",()=>focus()),p.style="",D(),p.parentNode||document.body.appendChild(p),p.oncontextmenu=()=>!1,"loading"===document.readyState?r(a,"DOMContentLoaded",()=>n(L)):n(L),A}})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.94.1",
3
+ "version": "0.95.0",
4
4
  "description": "Lightweight HTML5 canvas 2D 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>",
@@ -33,7 +33,7 @@
33
33
  "devDependencies": {
34
34
  "@litecanvas/jsdom-extras": "^2.0.1",
35
35
  "@size-limit/preset-small-lib": "^11.2.0",
36
- "@swc/core": "^1.13.1",
36
+ "@swc/core": "^1.13.2",
37
37
  "@types/jsdom": "^21.1.7",
38
38
  "ava": "^6.4.1",
39
39
  "esbuild": "^0.25.8",
package/src/index.js CHANGED
@@ -23,6 +23,8 @@ export default function litecanvas(settings = {}) {
23
23
  elem.addEventListener(evt, callback, false)
24
24
  _browserEventListeners.push(() => elem.removeEventListener(evt, callback, false))
25
25
  },
26
+ /** @type {(ev: Event) => void} */
27
+ preventDefault = (ev) => ev.preventDefault(),
26
28
  /** @type {(c: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D) => void} */
27
29
  beginPath = (c) => c.beginPath(),
28
30
  isNumber = Number.isFinite,
@@ -32,7 +34,7 @@ export default function litecanvas(settings = {}) {
32
34
  width: null,
33
35
  height: null,
34
36
  autoscale: true,
35
- pixelart: false,
37
+ pixelart: true,
36
38
  canvas: null,
37
39
  global: true,
38
40
  loop: null,
@@ -1300,12 +1302,7 @@ export default function litecanvas(settings = {}) {
1300
1302
  /**
1301
1303
  * @param {{t: number}} tap
1302
1304
  */
1303
- (tap) => tap && Date.now() - tap.t <= 300,
1304
- preventDefault =
1305
- /**
1306
- * @param {Event} ev
1307
- */
1308
- (ev) => ev.preventDefault()
1305
+ (tap) => tap && Date.now() - tap.t <= 300
1309
1306
 
1310
1307
  let _pressingMouse = false
1311
1308
 
@@ -1454,11 +1451,15 @@ export default function litecanvas(settings = {}) {
1454
1451
  return !key ? keySet.size > 0 : keySet.has('space' === key ? ' ' : key)
1455
1452
  }
1456
1453
 
1454
+ /** @type {string} */
1455
+ let _lastKey = ''
1456
+
1457
1457
  on(root, 'keydown', (/** @type {KeyboardEvent} */ event) => {
1458
1458
  const key = event.key.toLowerCase()
1459
1459
  if (!_keysDown.has(key)) {
1460
1460
  _keysDown.add(key)
1461
1461
  _keysPress.add(key)
1462
+ _lastKey = key === ' ' ? 'space' : key
1462
1463
  }
1463
1464
  })
1464
1465
 
@@ -1472,9 +1473,6 @@ export default function litecanvas(settings = {}) {
1472
1473
  instance.def(
1473
1474
  'iskeydown',
1474
1475
  /**
1475
- * Checks if a which key is pressed (down) on the keyboard.
1476
- * Note: use `iskeydown()` to check for any key.
1477
- *
1478
1476
  * @param {string} [key]
1479
1477
  * @returns {boolean}
1480
1478
  */
@@ -1490,9 +1488,6 @@ export default function litecanvas(settings = {}) {
1490
1488
  instance.def(
1491
1489
  'iskeypressed',
1492
1490
  /**
1493
- * Checks if a which key just got pressed on the keyboard.
1494
- * Note: use `iskeypressed()` to check for any key.
1495
- *
1496
1491
  * @param {string} [key]
1497
1492
  * @returns {boolean}
1498
1493
  */
@@ -1504,6 +1499,14 @@ export default function litecanvas(settings = {}) {
1504
1499
  return keyCheck(_keysPress, key)
1505
1500
  }
1506
1501
  )
1502
+
1503
+ instance.def(
1504
+ 'lastkey',
1505
+ /**
1506
+ * @returns {string}
1507
+ */
1508
+ () => _lastKey
1509
+ )
1507
1510
  }
1508
1511
 
1509
1512
  // start the engine
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.94.1'
2
+ export const version = '0.95.0'
package/types/global.d.ts CHANGED
@@ -477,7 +477,7 @@ declare global {
477
477
  */
478
478
  function volume(value: number): void
479
479
 
480
- /** UTILS API */
480
+ /** KEYBOARD API */
481
481
  /**
482
482
  * Checks if a which key is pressed on the keyboard.
483
483
  * Note: use `iskeydown()` to check for any key pressed.
@@ -494,6 +494,12 @@ declare global {
494
494
  * @returns `true` if the which key was pressed
495
495
  */
496
496
  function iskeypressed(key: string): boolean
497
+ /**
498
+ * Returns the last pressed.
499
+ *
500
+ * @returns {string}
501
+ */
502
+ function lastkey(): string
497
503
 
498
504
  /** PLUGINS API */
499
505
  /**
package/types/types.d.ts CHANGED
@@ -467,7 +467,7 @@ type LitecanvasInstance = {
467
467
  */
468
468
  volume(value: number): void
469
469
 
470
- /** UTILS API */
470
+ /** KEYBOARD API */
471
471
  /**
472
472
  * Checks if a which key is pressed on the keyboard.
473
473
  * Note: use `iskeydown()` to check for any key pressed.
@@ -484,6 +484,12 @@ type LitecanvasInstance = {
484
484
  * @returns `true` if the which key was pressed
485
485
  */
486
486
  iskeypressed?(key: string): boolean
487
+ /**
488
+ * Returns the last pressed.
489
+ *
490
+ * @returns {string}
491
+ */
492
+ lastkey?(): string
487
493
 
488
494
  /** PLUGINS API */
489
495
  /**
@@ -603,7 +609,7 @@ type LitecanvasOptions = {
603
609
  * If `true`, the pixel art images won't look blurry.
604
610
  * Also, disables canvas built-in antialias.
605
611
  *
606
- * Default: `false`
612
+ * Default: `true`
607
613
  */
608
614
  pixelart?: boolean
609
615
  /**