litecanvas 0.79.4 → 0.80.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
@@ -8,7 +8,7 @@
8
8
  };
9
9
 
10
10
  // src/palette.js
11
- var colors = [
11
+ var defaultPalette = [
12
12
  "#111",
13
13
  "#6a7799",
14
14
  "#aec2c2",
@@ -50,7 +50,7 @@
50
50
  animate: true
51
51
  };
52
52
  settings = Object.assign(defaults, settings);
53
- let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _events = {
53
+ let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _colors = defaultPalette, _events = {
54
54
  init: false,
55
55
  update: false,
56
56
  draw: false,
@@ -60,8 +60,7 @@
60
60
  tapping: false,
61
61
  tapped: false
62
62
  }, _helpers = {
63
- settings: Object.assign({}, settings),
64
- colors
63
+ settings: Object.assign({}, settings)
65
64
  };
66
65
  const instance = {
67
66
  /** @type {number} */
@@ -82,6 +81,8 @@
82
81
  MOUSEY: -1,
83
82
  /** @type {number[]} */
84
83
  DEFAULT_SFX: [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
84
+ /** @type {string[]} */
85
+ COLORS: _colors,
85
86
  /** MATH API */
86
87
  /**
87
88
  * Twice the value of the mathematical constant PI (π).
@@ -875,6 +876,19 @@
875
876
  triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
876
877
  }
877
878
  },
879
+ /**
880
+ * Set or reset the color palette
881
+ *
882
+ * @param {string[]} [colors]
883
+ */
884
+ pal(colors = defaultPalette) {
885
+ DEV: assert(
886
+ Array.isArray(colors) && colors.length > 0,
887
+ "pal: 1st param must be a array of strings"
888
+ );
889
+ _colors = colors;
890
+ instance.setvar("COLORS", _colors);
891
+ },
878
892
  /**
879
893
  * Get a color by index
880
894
  *
@@ -886,7 +900,7 @@
886
900
  null == index || isNumber(index) && index >= 0,
887
901
  "getcolor: 1st param must be a number"
888
902
  );
889
- return colors[~~index % colors.length];
903
+ return _colors[~~index % _colors.length];
890
904
  },
891
905
  /**
892
906
  * Create or update a instance variable
@@ -1124,6 +1138,7 @@
1124
1138
  });
1125
1139
  on(root, "focus", () => {
1126
1140
  if (!_rafid) {
1141
+ _accumulated = 0;
1127
1142
  _rafid = raf(drawFrame);
1128
1143
  }
1129
1144
  });
package/dist/dist.js CHANGED
@@ -8,7 +8,7 @@
8
8
  };
9
9
 
10
10
  // src/palette.js
11
- var colors = [
11
+ var defaultPalette = [
12
12
  "#111",
13
13
  "#6a7799",
14
14
  "#aec2c2",
@@ -45,7 +45,7 @@
45
45
  animate: true
46
46
  };
47
47
  settings = Object.assign(defaults, settings);
48
- let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _events = {
48
+ let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _colors = defaultPalette, _events = {
49
49
  init: false,
50
50
  update: false,
51
51
  draw: false,
@@ -55,8 +55,7 @@
55
55
  tapping: false,
56
56
  tapped: false
57
57
  }, _helpers = {
58
- settings: Object.assign({}, settings),
59
- colors
58
+ settings: Object.assign({}, settings)
60
59
  };
61
60
  const instance = {
62
61
  /** @type {number} */
@@ -77,6 +76,8 @@
77
76
  MOUSEY: -1,
78
77
  /** @type {number[]} */
79
78
  DEFAULT_SFX: [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
79
+ /** @type {string[]} */
80
+ COLORS: _colors,
80
81
  /** MATH API */
81
82
  /**
82
83
  * Twice the value of the mathematical constant PI (π).
@@ -627,6 +628,15 @@
627
628
  triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
628
629
  }
629
630
  },
631
+ /**
632
+ * Set or reset the color palette
633
+ *
634
+ * @param {string[]} [colors]
635
+ */
636
+ pal(colors = defaultPalette) {
637
+ _colors = colors;
638
+ instance.setvar("COLORS", _colors);
639
+ },
630
640
  /**
631
641
  * Get a color by index
632
642
  *
@@ -634,7 +644,7 @@
634
644
  * @returns {string} the color code
635
645
  */
636
646
  getcolor: (index) => {
637
- return colors[~~index % colors.length];
647
+ return _colors[~~index % _colors.length];
638
648
  },
639
649
  /**
640
650
  * Create or update a instance variable
@@ -851,6 +861,7 @@
851
861
  });
852
862
  on(root, "focus", () => {
853
863
  if (!_rafid) {
864
+ _accumulated = 0;
854
865
  _rafid = raf(drawFrame);
855
866
  }
856
867
  });
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=new AudioContext,t=(t=1,a=.05,n=220,i=0,l=0,r=.1,o=0,s=1,c=0,f=0,d=0,p=0,u=0,g=0,h=0,m=0,v=0,E=1,b=0,w=0,x=0)=>{let y=Math,T=2*y.PI,I=c*=500*T/44100/44100,S=n*=(1-a+2*a*y.random(a=[]))*T/44100,k=0,A=0,H=0,D=1,P=0,C=0,X=0,N=x<0?-1:1,L=T*N*x*2/44100,O=y.cos(L),Y=y.sin,z=Y(L)/4,F=1+z,G=-2*O/F,M=(1-z)/F,R=(1+N*O)/2/F,W=-(N+O)/F,B=0,U=0,q=0,V=0;for(i=44100*i+9,b*=44100,l*=44100,r*=44100,v*=44100,f*=500*T/85766121e6,h*=T/44100,d*=T/44100,p*=44100,u=44100*u|0,t*=.3*(globalThis.zzfxV||1),N=i+b+l+r+v|0;H<N;a[H++]=X*t)++C%(100*m|0)||(X=o?1<o?2<o?3<o?Y(k*k):y.max(y.min(y.tan(k),1),-1):1-(2*k/T%2+2)%2:1-4*y.abs(y.round(k/T)-k/T):Y(k),X=(u?1-w+w*Y(T*H/u):1)*(X<0?-1:1)*y.abs(X)**s*(H<i?H/i:H<i+b?1-(H-i)/b*(1-E):H<i+b+l?E:H<N-v?(N-H-v)/r*E:0),X=v?X/2+(v>H?0:(H<N-v?1:(N-H)/v)*a[H-v|0]/2/t):X,x&&(X=V=R*B+W*(B=U)+R*(U=X)-M*q-G*(q=V))),k+=(L=(n+=c+=f)*y.cos(h*A++))+L*g*Y(H**5),D&&++D>p&&(n+=d,S+=d,D=0),!u||++P%u||(n=S,c=I,D=D||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,i=Math,l=2*i.PI,r=requestAnimationFrame,o=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),o.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 c=!1,f=[],d,p=1,u,g=.5,h=1,m,v=1/60,E=0,b,w="sans-serif",x=20,y=Date.now(),T={init:!1,update:!1,draw:!1,resized:!1,tap:!1,untap:!1,tapping:!1,tapped:!1},I={settings:Object.assign({},e),colors:a},S={WIDTH:0,HEIGHT:0,CANVAS:!1,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,0,1750,,,.3,1,,,,600,.1],TWO_PI:l,HALF_PI:i.PI/2,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,n,i,l){let r=(e-t)/(a-t)*(i-n)+n;return l?S.clamp(r,n,i):r},norm:(e,t,a)=>S.map(e,t,a,0,1),rand:(e=0,t=1)=>(y=(1664525*y+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>i.floor(S.rand(e,t+1)),seed:e=>null==e?y:y=~~e,cls(e){null==e?u.clearRect(0,0,u.canvas.width,u.canvas.height):S.rectfill(0,0,u.canvas.width,u.canvas.height,e)},rect(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~n+2*g,l),S.stroke(i)},rectfill(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e,~~t,~~a,~~n,l),S.fill(i)},circ(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),S.stroke(n)},circfill(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),S.fill(n)},line(e,t,a,n,i){u.beginPath();let l=.5*(0!==g&&~~e==~~a),r=.5*(0!==g&&~~t==~~n);u.moveTo(~~e+l,~~t+r),u.lineTo(~~a+l,~~n+r),S.stroke(i)},linewidth(e){u.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){u.setLineDash(e),u.lineDashOffset=t},text(e,t,a,n=3,i="normal"){u.font=`${i} ${x}px ${w}`,u.fillStyle=S.getcolor(n),u.fillText(a,~~e,~~t)},textfont(e){w=e},textsize(e){x=e},textalign(e,t){e&&(u.textAlign=e),t&&(u.textBaseline=t)},image(e,t,a){u.drawImage(a,~~e,~~t)},paint(e,t,a,n={}){let i=n.canvas||new OffscreenCanvas(1,1),l=n.scale||1,r=u;if(i.width=e*l,i.height=t*l,(u=i.getContext("2d")).scale(l,l),a.push){let e=0,t=0;for(let n of(u.imageSmoothingEnabled=!1,a)){for(let a of n)" "!==a&&"."!==a&&S.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(u);return u=r,i.transferToImageBitmap()},ctx:e=>(e&&(u=e),u),push:()=>u.save(),pop:()=>u.restore(),translate:(e,t)=>u.translate(~~e,~~t),scale:(e,t)=>u.scale(e,t||e),rotate:e=>u.rotate(e),alpha(e){u.globalAlpha=S.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){u.fillStyle=S.getcolor(e),t?u.fill(t):u.fill()},stroke(e,t){u.strokeStyle=S.getcolor(e),t?u.stroke(t):u.stroke()},clip(e){u.clip(e)},sfx:(e,a=0,i=1)=>!(n.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||S.DEFAULT_SFX,(0!==a||1!==i)&&((e=e.slice())[0]=i*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){n.zzfxV=e},use(e,t={}){c?P(e,t):f.push([e,t])},listen:(e,t)=>(T[e]=T[e]||new Set,T[e].add(t),()=>T[e].delete(t)),emit(e,t,a,n,i){c&&(D("before:"+e,t,a,n,i),D(e,t,a,n,i),D("after:"+e,t,a,n,i))},getcolor:e=>a[~~e%a.length],setvar(t,a){S[t]=a,e.global&&(n[t]=a)},timescale(e){h=e},setfps(e){v=1/~~e},quit(){for(let e of(cancelAnimationFrame(b),S.emit("quit"),T=[],o))e();if(e.global){for(let e in S)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(","))S[e]=i[e];function k(){c=!0;let t=e.loop?e.loop:n;for(let e in T)t[e]&&S.listen(e,t[e]);for(let[e,t]of f)P(e,t);if(e.autoscale&&s(n,"resize",H),e.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/p,(t-d.offsetTop)/p],t=new Map,a=(e,a,n)=>{let i={x:a,y:n,startX:a,startY:n,ts:performance.now()};return t.set(e,i),i},i=(e,n,i)=>{let l=t.get(e)||a(e);l.x=n,l.y=i},l=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),o=!1;s(d,"mousedown",t=>{if(0===t.button){r(t);let[n,i]=e(t.pageX,t.pageY);S.emit("tap",n,i,0),a(0,n,i),o=!0}}),s(d,"mouseup",a=>{if(0===a.button){r(a);let n=t.get(0),[i,s]=e(a.pageX,a.pageY);l(n)&&S.emit("tapped",n.startX,n.startY,0),S.emit("untap",i,s,0),t.delete(0),o=!1}}),s(d,"mousemove",t=>{r(t);let[a,n]=e(t.pageX,t.pageY);S.setvar("MOUSEX",a),S.setvar("MOUSEY",n),o&&(S.emit("tapping",a,n,0),i(0,a,n))}),s(d,"touchstart",t=>{for(let n of(r(t),t.changedTouches)){let[t,i]=e(n.pageX,n.pageY);S.emit("tap",t,i,n.identifier+1),a(n.identifier+1,t,i)}}),s(d,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,n]=e(a.pageX,a.pageY);S.emit("tapping",t,n,a.identifier+1),i(a.identifier+1,t,n)}});let c=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)||(l(n)&&S.emit("tapped",n.startX,n.startY,e),S.emit("untap",n.x,n.y,e),t.delete(e))};s(d,"touchend",c),s(d,"touchcancel",c),s(n,"blur",()=>{for(let[e,a]of(o=!1,t))S.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,i=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;s(n,"keydown",n=>{t.has(e(n.key))||(t.add(e(n.key)),a.add(e(n.key)))}),s(n,"keyup",a=>{t.delete(e(a.key))}),s(n,"blur",()=>t.clear()),S.listen("after:draw",()=>a.clear()),S.setvar("iskeydown",e=>i(t,e)),S.setvar("iskeypressed",e=>i(a,e))}e.pauseOnBlur&&(s(n,"blur",()=>{b=cancelAnimationFrame(b)}),s(n,"focus",()=>{b||(b=r(A))})),S.emit("init",S),m=performance.now(),b=r(A)}function A(t){let a=0,n=(t-m)/1e3;if(m=t,e.animate){if(b=r(A),n>.3)return;for(E+=n;E>=v;)S.emit("update",v*h),S.setvar("ELAPSED",S.ELAPSED+v*h),a++,E-=v}else a=1;a&&(S.textalign("start","top"),S.emit("draw"))}function H(){let t=e.width||n.innerWidth,a=e.height||e.width||n.innerHeight;S.setvar("WIDTH",d.width=t),S.setvar("HEIGHT",d.height=a),S.setvar("CENTERX",S.WIDTH/2),S.setvar("CENTERY",S.HEIGHT/2),e.autoscale&&(d.style.display||(d.style.display="block",d.style.margin="auto"),p=i.min(n.innerWidth/S.WIDTH,n.innerHeight/S.HEIGHT),p=(e.pixelart?~~p:p)||1,d.style.width=S.WIDTH*p+"px",d.style.height=S.HEIGHT*p+"px"),(!e.antialias||e.pixelart)&&(u.imageSmoothingEnabled=!1,d.style.imageRendering="pixelated"),S.emit("resized",p),e.animate||r(A)}function D(e,t,a,n,i){if(T[e])for(let l of T[e])l(t,a,n,i)}function P(e,t){let a=e(S,I,t);for(let e in a)S.setvar(e,a[e])}if(e.global){if(n.ENGINE)throw Error("two global litecanvas detected");Object.assign(n,S),n.ENGINE=S}return d="string"==typeof(d=e.canvas||document.createElement("canvas"))?document.querySelector(d):d,S.setvar("CANVAS",d),u=d.getContext("2d"),s(d,"click",()=>n.focus()),d.style="",H(),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?s(n,"DOMContentLoaded",()=>r(k)):r(k),S}})();
1
+ (()=>{var e=new AudioContext,t=(t=1,a=.05,n=220,i=0,l=0,r=.1,o=0,s=1,c=0,f=0,d=0,p=0,u=0,g=0,h=0,m=0,v=0,E=1,b=0,w=0,x=0)=>{let y=Math,T=2*y.PI,S=c*=500*T/44100/44100,I=n*=(1-a+2*a*y.random(a=[]))*T/44100,k=0,A=0,H=0,D=1,C=0,O=0,P=0,L=x<0?-1:1,X=T*L*x*2/44100,N=y.cos(X),Y=y.sin,z=Y(X)/4,F=1+z,R=-2*N/F,G=(1-z)/F,M=(1+L*N)/2/F,W=-(L+N)/F,B=0,U=0,q=0,V=0;for(i=44100*i+9,b*=44100,l*=44100,r*=44100,v*=44100,f*=500*T/85766121e6,h*=T/44100,d*=T/44100,p*=44100,u=44100*u|0,t*=.3*(globalThis.zzfxV||1),L=i+b+l+r+v|0;H<L;a[H++]=P*t)++O%(100*m|0)||(P=o?1<o?2<o?3<o?Y(k*k):y.max(y.min(y.tan(k),1),-1):1-(2*k/T%2+2)%2:1-4*y.abs(y.round(k/T)-k/T):Y(k),P=(u?1-w+w*Y(T*H/u):1)*(P<0?-1:1)*y.abs(P)**s*(H<i?H/i:H<i+b?1-(H-i)/b*(1-E):H<i+b+l?E:H<L-v?(L-H-v)/r*E:0),P=v?P/2+(v>H?0:(H<L-v?1:(L-H)/v)*a[H-v|0]/2/t):P,x&&(P=V=M*B+W*(B=U)+M*(U=P)-G*q-R*(q=V))),k+=(X=(n+=c+=f)*y.cos(h*A++))+X*g*Y(H**5),D&&++D>p&&(n+=d,I+=d,D=0),!u||++C%u||(n=I,c=S,D=D||1);(t=e.createBuffer(1,L,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,i=Math,l=2*i.PI,r=requestAnimationFrame,o=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),o.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 c=!1,f=[],d,p=1,u,g=.5,h=1,m,v=1/60,E=0,b,w="sans-serif",x=20,y=Date.now(),T=a,S={init:!1,update:!1,draw:!1,resized:!1,tap:!1,untap:!1,tapping:!1,tapped:!1},I={settings:Object.assign({},e)},k={WIDTH:0,HEIGHT:0,CANVAS:!1,ELAPSED:0,CENTERX:0,CENTERY:0,MOUSEX:-1,MOUSEY:-1,DEFAULT_SFX:[.5,0,1750,,,.3,1,,,,600,.1],COLORS:T,TWO_PI:l,HALF_PI:i.PI/2,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,n,i,l){let r=(e-t)/(a-t)*(i-n)+n;return l?k.clamp(r,n,i):r},norm:(e,t,a)=>k.map(e,t,a,0,1),rand:(e=0,t=1)=>(y=(1664525*y+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>i.floor(k.rand(e,t+1)),seed:e=>null==e?y:y=~~e,cls(e){null==e?u.clearRect(0,0,u.canvas.width,u.canvas.height):k.rectfill(0,0,u.canvas.width,u.canvas.height,e)},rect(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~n+2*g,l),k.stroke(i)},rectfill(e,t,a,n,i,l){u.beginPath(),u[l?"roundRect":"rect"](~~e,~~t,~~a,~~n,l),k.fill(i)},circ(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),k.stroke(n)},circfill(e,t,a,n){u.beginPath(),u.arc(~~e,~~t,~~a,0,l),k.fill(n)},line(e,t,a,n,i){u.beginPath();let l=.5*(0!==g&&~~e==~~a),r=.5*(0!==g&&~~t==~~n);u.moveTo(~~e+l,~~t+r),u.lineTo(~~a+l,~~n+r),k.stroke(i)},linewidth(e){u.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){u.setLineDash(e),u.lineDashOffset=t},text(e,t,a,n=3,i="normal"){u.font=`${i} ${x}px ${w}`,u.fillStyle=k.getcolor(n),u.fillText(a,~~e,~~t)},textfont(e){w=e},textsize(e){x=e},textalign(e,t){e&&(u.textAlign=e),t&&(u.textBaseline=t)},image(e,t,a){u.drawImage(a,~~e,~~t)},paint(e,t,a,n={}){let i=n.canvas||new OffscreenCanvas(1,1),l=n.scale||1,r=u;if(i.width=e*l,i.height=t*l,(u=i.getContext("2d")).scale(l,l),a.push){let e=0,t=0;for(let n of(u.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(u);return u=r,i.transferToImageBitmap()},ctx:e=>(e&&(u=e),u),push:()=>u.save(),pop:()=>u.restore(),translate:(e,t)=>u.translate(~~e,~~t),scale:(e,t)=>u.scale(e,t||e),rotate:e=>u.rotate(e),alpha(e){u.globalAlpha=k.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){u.fillStyle=k.getcolor(e),t?u.fill(t):u.fill()},stroke(e,t){u.strokeStyle=k.getcolor(e),t?u.stroke(t):u.stroke()},clip(e){u.clip(e)},sfx:(e,a=0,i=1)=>!(n.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||k.DEFAULT_SFX,(0!==a||1!==i)&&((e=e.slice())[0]=i*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){n.zzfxV=e},use(e,t={}){c?O(e,t):f.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,i){c&&(C("before:"+e,t,a,n,i),C(e,t,a,n,i),C("after:"+e,t,a,n,i))},pal(e=a){T=e,k.setvar("COLORS",T)},getcolor:e=>T[~~e%T.length],setvar(t,a){k[t]=a,e.global&&(n[t]=a)},timescale(e){h=e},setfps(e){v=1/~~e},quit(){for(let e of(cancelAnimationFrame(b),k.emit("quit"),S=[],o))e();if(e.global){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]=i[e];function A(){c=!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 f)O(e,t);if(e.autoscale&&s(n,"resize",D),e.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/p,(t-d.offsetTop)/p],t=new Map,a=(e,a,n)=>{let i={x:a,y:n,startX:a,startY:n,ts:performance.now()};return t.set(e,i),i},i=(e,n,i)=>{let l=t.get(e)||a(e);l.x=n,l.y=i},l=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),o=!1;s(d,"mousedown",t=>{if(0===t.button){r(t);let[n,i]=e(t.pageX,t.pageY);k.emit("tap",n,i,0),a(0,n,i),o=!0}}),s(d,"mouseup",a=>{if(0===a.button){r(a);let n=t.get(0),[i,s]=e(a.pageX,a.pageY);l(n)&&k.emit("tapped",n.startX,n.startY,0),k.emit("untap",i,s,0),t.delete(0),o=!1}}),s(d,"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),i(0,a,n))}),s(d,"touchstart",t=>{for(let n of(r(t),t.changedTouches)){let[t,i]=e(n.pageX,n.pageY);k.emit("tap",t,i,n.identifier+1),a(n.identifier+1,t,i)}}),s(d,"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),i(a.identifier+1,t,n)}});let c=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)||(l(n)&&k.emit("tapped",n.startX,n.startY,e),k.emit("untap",n.x,n.y,e),t.delete(e))};s(d,"touchend",c),s(d,"touchcancel",c),s(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,i=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;s(n,"keydown",n=>{t.has(e(n.key))||(t.add(e(n.key)),a.add(e(n.key)))}),s(n,"keyup",a=>{t.delete(e(a.key))}),s(n,"blur",()=>t.clear()),k.listen("after:draw",()=>a.clear()),k.setvar("iskeydown",e=>i(t,e)),k.setvar("iskeypressed",e=>i(a,e))}e.pauseOnBlur&&(s(n,"blur",()=>{b=cancelAnimationFrame(b)}),s(n,"focus",()=>{b||(E=0,b=r(H))})),k.emit("init",k),m=performance.now(),b=r(H)}function H(t){let a=0,n=(t-m)/1e3;if(m=t,e.animate){if(b=r(H),n>.3)return;for(E+=n;E>=v;)k.emit("update",v*h),k.setvar("ELAPSED",k.ELAPSED+v*h),a++,E-=v}else a=1;a&&(k.textalign("start","top"),k.emit("draw"))}function D(){let t=e.width||n.innerWidth,a=e.height||e.width||n.innerHeight;k.setvar("WIDTH",d.width=t),k.setvar("HEIGHT",d.height=a),k.setvar("CENTERX",k.WIDTH/2),k.setvar("CENTERY",k.HEIGHT/2),e.autoscale&&(d.style.display||(d.style.display="block",d.style.margin="auto"),p=i.min(n.innerWidth/k.WIDTH,n.innerHeight/k.HEIGHT),p=(e.pixelart?~~p:p)||1,d.style.width=k.WIDTH*p+"px",d.style.height=k.HEIGHT*p+"px"),(!e.antialias||e.pixelart)&&(u.imageSmoothingEnabled=!1,d.style.imageRendering="pixelated"),k.emit("resized",p),e.animate||r(H)}function C(e,t,a,n,i){if(S[e])for(let l of S[e])l(t,a,n,i)}function O(e,t){let a=e(k,I,t);for(let e in a)k.setvar(e,a[e])}if(e.global){if(n.ENGINE)throw Error("two global litecanvas detected");Object.assign(n,k),n.ENGINE=k}return d="string"==typeof(d=e.canvas||document.createElement("canvas"))?document.querySelector(d):d,k.setvar("CANVAS",d),u=d.getContext("2d"),s(d,"click",()=>n.focus()),d.style="",D(),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?s(n,"DOMContentLoaded",()=>r(A)):r(A),k}})();
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.79.4",
3
+ "version": "0.80.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>",
7
7
  "contributors": [],
8
8
  "devDependencies": {
9
- "@swc/core": "^1.11.13",
10
- "ava": "^6.2.0",
11
- "esbuild": "^0.25.2",
9
+ "@swc/core": "^1.11.29",
10
+ "ava": "^6.3.0",
11
+ "esbuild": "^0.25.5",
12
12
  "gzip-size": "^7.0.0",
13
13
  "prettier": "^3.5.3"
14
14
  },
package/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { zzfx } from './zzfx.js'
2
- import { colors } from './palette.js'
2
+ import { defaultPalette } from './palette.js'
3
3
  import { assert } from './dev.js'
4
4
  import './types.js'
5
5
 
@@ -71,6 +71,8 @@ export default function litecanvas(settings = {}) {
71
71
  _fontSize = 20,
72
72
  /** @type {number} */
73
73
  _rng_seed = Date.now(),
74
+ /** @type {string[]} */
75
+ _colors = defaultPalette,
74
76
  /**
75
77
  * default game events
76
78
  * @type {Object<string,Set<Function>>}
@@ -92,7 +94,6 @@ export default function litecanvas(settings = {}) {
92
94
  */
93
95
  _helpers = {
94
96
  settings: Object.assign({}, settings),
95
- colors,
96
97
  }
97
98
 
98
99
  /** @type {LitecanvasInstance} */
@@ -124,6 +125,9 @@ export default function litecanvas(settings = {}) {
124
125
  /** @type {number[]} */
125
126
  DEFAULT_SFX: [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
126
127
 
128
+ /** @type {string[]} */
129
+ COLORS: _colors,
130
+
127
131
  /** MATH API */
128
132
  /**
129
133
  * Twice the value of the mathematical constant PI (π).
@@ -1038,6 +1042,20 @@ export default function litecanvas(settings = {}) {
1038
1042
  }
1039
1043
  },
1040
1044
 
1045
+ /**
1046
+ * Set or reset the color palette
1047
+ *
1048
+ * @param {string[]} [colors]
1049
+ */
1050
+ pal(colors = defaultPalette) {
1051
+ DEV: assert(
1052
+ Array.isArray(colors) && colors.length > 0,
1053
+ 'pal: 1st param must be a array of strings'
1054
+ )
1055
+ _colors = colors
1056
+ instance.setvar('COLORS', _colors)
1057
+ },
1058
+
1041
1059
  /**
1042
1060
  * Get a color by index
1043
1061
  *
@@ -1049,8 +1067,7 @@ export default function litecanvas(settings = {}) {
1049
1067
  null == index || (isNumber(index) && index >= 0),
1050
1068
  'getcolor: 1st param must be a number'
1051
1069
  )
1052
-
1053
- return colors[~~index % colors.length]
1070
+ return _colors[~~index % _colors.length]
1054
1071
  },
1055
1072
 
1056
1073
  /**
@@ -1359,6 +1376,7 @@ export default function litecanvas(settings = {}) {
1359
1376
 
1360
1377
  on(root, 'focus', () => {
1361
1378
  if (!_rafid) {
1379
+ _accumulated = 0
1362
1380
  _rafid = raf(drawFrame)
1363
1381
  }
1364
1382
  })
package/src/palette.js CHANGED
@@ -1,4 +1,4 @@
1
- export const colors = [
1
+ export const defaultPalette = [
2
2
  '#111',
3
3
  '#6a7799',
4
4
  '#aec2c2',