litecanvas 0.75.1 → 0.76.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/README.md CHANGED
@@ -32,7 +32,7 @@ npm install
32
32
  npm run dev
33
33
  ```
34
34
 
35
- If you prefer, you can manually install the package via NPM:
35
+ If you prefer, you can manually install via [NPM](https://www.npmjs.com/package/litecanvas):
36
36
 
37
37
  ```
38
38
  npm install litecanvas
package/dist/dist.dev.js CHANGED
@@ -36,7 +36,6 @@
36
36
  () => elem.removeEventListener(evt, callback, false)
37
37
  );
38
38
  }, isFinite = Number.isFinite, defaults = {
39
- fullscreen: true,
40
39
  width: null,
41
40
  height: null,
42
41
  autoscale: true,
@@ -51,7 +50,7 @@
51
50
  animate: true
52
51
  };
53
52
  settings = Object.assign(defaults, settings);
54
- let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _fullscreen = settings.fullscreen, _autoscale = settings.autoscale, _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 32, _rng_seed = Date.now(), _global = settings.global, _events = {
53
+ let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _autoscale = settings.autoscale, _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 32, _rng_seed = Date.now(), _global = settings.global, _events = {
55
54
  init: null,
56
55
  update: null,
57
56
  draw: null,
@@ -894,9 +893,11 @@
894
893
  "string" === typeof eventName,
895
894
  "emit: 1st param must be a string"
896
895
  );
897
- triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
898
- triggerEvent(eventName, arg1, arg2, arg3, arg4);
899
- triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
896
+ if (_initialized) {
897
+ triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
898
+ triggerEvent(eventName, arg1, arg2, arg3, arg4);
899
+ triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
900
+ }
900
901
  },
901
902
  /**
902
903
  * Get a color by index
@@ -937,11 +938,19 @@
937
938
  * @param {number} height
938
939
  */
939
940
  resize(width, height) {
940
- DEV: assert(isFinite(width), "resize: 1st param must be a number");
941
- DEV: assert(isFinite(height), "resize: 2nd param must be a number");
941
+ DEV: assert(
942
+ isFinite(width) && width > 0,
943
+ "resize: 1st param must be a number"
944
+ );
945
+ DEV: assert(
946
+ isFinite(height) && height > 0,
947
+ "resize: 2nd param must be a number"
948
+ );
942
949
  instance.setvar("WIDTH", _canvas.width = width);
943
950
  instance.setvar("HEIGHT", _canvas.height = height);
944
- pageResized();
951
+ instance.setvar("CENTERX", instance.WIDTH / 2);
952
+ instance.setvar("CENTERY", instance.HEIGHT / 2);
953
+ onResize();
945
954
  },
946
955
  /**
947
956
  * The scale of the game's delta time (dt).
@@ -999,10 +1008,9 @@
999
1008
  for (const [callback, config] of _plugins) {
1000
1009
  loadPlugin(callback, config);
1001
1010
  }
1002
- if (_fullscreen || _autoscale) {
1003
- on(root, "resize", pageResized);
1011
+ if (_autoscale) {
1012
+ on(root, "resize", onResize);
1004
1013
  }
1005
- pageResized();
1006
1014
  if (settings.tapEvents) {
1007
1015
  const _getXY = (pageX, pageY) => [
1008
1016
  (pageX - _canvas.offsetLeft) / _scale,
@@ -1139,21 +1147,23 @@
1139
1147
  }
1140
1148
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
1141
1149
  _lastFrameTime = now;
1142
- if (frameTime > _deltaTime * 30)
1143
- return console.log("skipping too long frame");
1144
- _accumulated += frameTime;
1145
- if (!_animated) {
1146
- _accumulated = _deltaTime;
1147
- }
1148
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1149
- instance.emit("update", _deltaTime * _timeScale);
1150
- instance.setvar(
1151
- "ELAPSED",
1152
- instance.ELAPSED + _deltaTime * _timeScale
1153
- );
1154
- updated++;
1150
+ if (frameTime > _deltaTime * 30) {
1151
+ console.log("skipping too long frame");
1152
+ } else {
1153
+ _accumulated += frameTime;
1154
+ if (!_animated) {
1155
+ _accumulated = _deltaTime;
1156
+ }
1157
+ for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1158
+ instance.emit("update", _deltaTime * _timeScale);
1159
+ instance.setvar(
1160
+ "ELAPSED",
1161
+ instance.ELAPSED + _deltaTime * _timeScale
1162
+ );
1163
+ updated++;
1164
+ }
1155
1165
  }
1156
- if (updated) {
1166
+ if (updated || !_animated) {
1157
1167
  instance.textalign("start", "top");
1158
1168
  instance.emit("draw");
1159
1169
  }
@@ -1165,44 +1175,43 @@
1165
1175
  "Invalid canvas element"
1166
1176
  );
1167
1177
  DEV: assert(
1168
- null === instance.WIDTH || instance.WIDTH > 0,
1178
+ null == instance.WIDTH || instance.WIDTH > 0,
1169
1179
  `Litecanvas' "width" option should be null or a positive number`
1170
1180
  );
1171
1181
  DEV: assert(
1172
- null === instance.HEIGHT || instance.HEIGHT > 0,
1182
+ null == instance.HEIGHT || instance.HEIGHT > 0,
1173
1183
  `Litecanvas' "width" option should be null or a positive number`
1174
1184
  );
1185
+ DEV: assert(
1186
+ null == instance.HEIGHT || instance.WIDTH > 0 && instance.HEIGHT > 0,
1187
+ `Litecanvas' "width" is required when "heigth" is passed`
1188
+ );
1175
1189
  instance.setvar("CANVAS", _canvas);
1176
1190
  _ctx = _canvas.getContext("2d");
1177
1191
  on(_canvas, "click", () => root.focus());
1178
- if (instance.WIDTH > 0) {
1179
- _fullscreen = false;
1180
- }
1181
1192
  _canvas.style = "";
1182
- _canvas.width = instance.WIDTH;
1183
- _canvas.height = instance.HEIGHT || instance.WIDTH;
1193
+ if (!instance.WIDTH) {
1194
+ instance.WIDTH = root.innerWidth;
1195
+ instance.HEIGHT = root.innerHeight;
1196
+ }
1197
+ instance.resize(instance.WIDTH, instance.HEIGHT, false);
1184
1198
  if (!_canvas.parentNode) document.body.appendChild(_canvas);
1185
1199
  }
1186
- function pageResized() {
1187
- const pageWidth = root.innerWidth, pageHeight = root.innerHeight, styles = _canvas.style;
1188
- styles.display = "block";
1189
- if (_fullscreen) {
1190
- styles.position = "absolute";
1191
- styles.inset = 0;
1192
- instance.setvar("WIDTH", _canvas.width = pageWidth);
1193
- instance.setvar("HEIGHT", _canvas.height = pageHeight);
1194
- } else if (_autoscale) {
1195
- styles.margin = "auto";
1200
+ function onResize() {
1201
+ const styles = _canvas.style;
1202
+ if (_autoscale) {
1203
+ if (!styles.display) {
1204
+ styles.display = "block";
1205
+ styles.margin = "auto";
1206
+ }
1196
1207
  _scale = Math.min(
1197
- pageWidth / instance.WIDTH,
1198
- pageHeight / instance.HEIGHT
1208
+ root.innerWidth / instance.WIDTH,
1209
+ root.innerHeight / instance.HEIGHT
1199
1210
  );
1200
1211
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1;
1201
1212
  styles.width = instance.WIDTH * _scale + "px";
1202
1213
  styles.height = instance.HEIGHT * _scale + "px";
1203
1214
  }
1204
- instance.setvar("CENTERX", instance.WIDTH / 2);
1205
- instance.setvar("CENTERY", instance.HEIGHT / 2);
1206
1215
  if (!settings.antialias || settings.pixelart) {
1207
1216
  _ctx.imageSmoothingEnabled = false;
1208
1217
  styles.imageRendering = "pixelated";
package/dist/dist.js CHANGED
@@ -31,7 +31,6 @@
31
31
  () => elem.removeEventListener(evt, callback, false)
32
32
  );
33
33
  }, isFinite = Number.isFinite, defaults = {
34
- fullscreen: true,
35
34
  width: null,
36
35
  height: null,
37
36
  autoscale: true,
@@ -46,7 +45,7 @@
46
45
  animate: true
47
46
  };
48
47
  settings = Object.assign(defaults, settings);
49
- let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _fullscreen = settings.fullscreen, _autoscale = settings.autoscale, _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 32, _rng_seed = Date.now(), _global = settings.global, _events = {
48
+ let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _autoscale = settings.autoscale, _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 32, _rng_seed = Date.now(), _global = settings.global, _events = {
50
49
  init: null,
51
50
  update: null,
52
51
  draw: null,
@@ -637,9 +636,11 @@
637
636
  * @param {*} [arg4] any data to be passed over the listeners
638
637
  */
639
638
  emit(eventName, arg1, arg2, arg3, arg4) {
640
- triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
641
- triggerEvent(eventName, arg1, arg2, arg3, arg4);
642
- triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
639
+ if (_initialized) {
640
+ triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
641
+ triggerEvent(eventName, arg1, arg2, arg3, arg4);
642
+ triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
643
+ }
643
644
  },
644
645
  /**
645
646
  * Get a color by index
@@ -673,7 +674,9 @@
673
674
  resize(width, height) {
674
675
  instance.setvar("WIDTH", _canvas.width = width);
675
676
  instance.setvar("HEIGHT", _canvas.height = height);
676
- pageResized();
677
+ instance.setvar("CENTERX", instance.WIDTH / 2);
678
+ instance.setvar("CENTERY", instance.HEIGHT / 2);
679
+ onResize();
677
680
  },
678
681
  /**
679
682
  * The scale of the game's delta time (dt).
@@ -723,10 +726,9 @@
723
726
  for (const [callback, config] of _plugins) {
724
727
  loadPlugin(callback, config);
725
728
  }
726
- if (_fullscreen || _autoscale) {
727
- on(root, "resize", pageResized);
729
+ if (_autoscale) {
730
+ on(root, "resize", onResize);
728
731
  }
729
- pageResized();
730
732
  if (settings.tapEvents) {
731
733
  const _getXY = (pageX, pageY) => [
732
734
  (pageX - _canvas.offsetLeft) / _scale,
@@ -859,21 +861,22 @@
859
861
  }
860
862
  let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
861
863
  _lastFrameTime = now;
862
- if (frameTime > _deltaTime * 30)
863
- return void 0;
864
- _accumulated += frameTime;
865
- if (!_animated) {
866
- _accumulated = _deltaTime;
867
- }
868
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
869
- instance.emit("update", _deltaTime * _timeScale);
870
- instance.setvar(
871
- "ELAPSED",
872
- instance.ELAPSED + _deltaTime * _timeScale
873
- );
874
- updated++;
864
+ if (frameTime > _deltaTime * 30) {
865
+ } else {
866
+ _accumulated += frameTime;
867
+ if (!_animated) {
868
+ _accumulated = _deltaTime;
869
+ }
870
+ for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
871
+ instance.emit("update", _deltaTime * _timeScale);
872
+ instance.setvar(
873
+ "ELAPSED",
874
+ instance.ELAPSED + _deltaTime * _timeScale
875
+ );
876
+ updated++;
877
+ }
875
878
  }
876
- if (updated) {
879
+ if (updated || !_animated) {
877
880
  instance.textalign("start", "top");
878
881
  instance.emit("draw");
879
882
  }
@@ -883,34 +886,29 @@
883
886
  instance.setvar("CANVAS", _canvas);
884
887
  _ctx = _canvas.getContext("2d");
885
888
  on(_canvas, "click", () => root.focus());
886
- if (instance.WIDTH > 0) {
887
- _fullscreen = false;
888
- }
889
889
  _canvas.style = "";
890
- _canvas.width = instance.WIDTH;
891
- _canvas.height = instance.HEIGHT || instance.WIDTH;
890
+ if (!instance.WIDTH) {
891
+ instance.WIDTH = root.innerWidth;
892
+ instance.HEIGHT = root.innerHeight;
893
+ }
894
+ instance.resize(instance.WIDTH, instance.HEIGHT, false);
892
895
  if (!_canvas.parentNode) document.body.appendChild(_canvas);
893
896
  }
894
- function pageResized() {
895
- const pageWidth = root.innerWidth, pageHeight = root.innerHeight, styles = _canvas.style;
896
- styles.display = "block";
897
- if (_fullscreen) {
898
- styles.position = "absolute";
899
- styles.inset = 0;
900
- instance.setvar("WIDTH", _canvas.width = pageWidth);
901
- instance.setvar("HEIGHT", _canvas.height = pageHeight);
902
- } else if (_autoscale) {
903
- styles.margin = "auto";
897
+ function onResize() {
898
+ const styles = _canvas.style;
899
+ if (_autoscale) {
900
+ if (!styles.display) {
901
+ styles.display = "block";
902
+ styles.margin = "auto";
903
+ }
904
904
  _scale = Math.min(
905
- pageWidth / instance.WIDTH,
906
- pageHeight / instance.HEIGHT
905
+ root.innerWidth / instance.WIDTH,
906
+ root.innerHeight / instance.HEIGHT
907
907
  );
908
908
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1;
909
909
  styles.width = instance.WIDTH * _scale + "px";
910
910
  styles.height = instance.HEIGHT * _scale + "px";
911
911
  }
912
- instance.setvar("CENTERX", instance.WIDTH / 2);
913
- instance.setvar("CENTERY", instance.HEIGHT / 2);
914
912
  if (!settings.antialias || settings.pixelart) {
915
913
  _ctx.imageSmoothingEnabled = false;
916
914
  styles.imageRendering = "pixelated";
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,o=.1,r=0,s=1,c=0,f=0,u=0,d=0,p=0,h=0,g=0,m=0,v=0,E=1,b=0,w=0,T=0)=>{let x=Math,H=2*x.PI,y=c*=500*H/44100/44100,I=l*=(1-a+2*a*x.random(a=[]))*H/44100,D=0,S=0,A=0,k=1,C=0,L=0,X=0,P=T<0?-1:1,z=H*P*T*2/44100,M=x.cos(z),O=x.sin,Y=O(z)/4,F=1+Y,W=-2*M/F,_=(1-Y)/F,R=(1+P*M)/2/F,G=-(P+M)/F,N=0,B=0,U=0,q=0;for(n=44100*n+9,b*=44100,i*=44100,o*=44100,v*=44100,f*=500*H/85766121e6,g*=H/44100,u*=H/44100,d*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),P=n+b+i+o+v|0;A<P;a[A++]=X*t)++L%(100*m|0)||(X=r?1<r?2<r?3<r?O(D*D):x.max(x.min(x.tan(D),1),-1):1-(2*D/H%2+2)%2:1-4*x.abs(x.round(D/H)-D/H):O(D),X=(p?1-w+w*O(H*A/p):1)*(X<0?-1:1)*x.abs(X)**s*(A<n?A/n:A<n+b?1-(A-n)/b*(1-E):A<n+b+i?E:A<P-v?(P-A-v)/o*E:0),X=v?X/2+(v>A?0:(A<P-v?1:(P-A)/v)*a[A-v|0]/2/t):X,T&&(X=q=R*N+G*(N=B)+R*(B=X)-_*U-W*(U=q))),D+=(z=(l+=c+=f)*x.cos(g*S++))+z*h*O(A**5),k&&++k>d&&(l+=u,I+=u,k=0),!p||++C%p||(l=I,c=y,k=k||1);(t=e.createBuffer(1,P,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.PI,i=2*n,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({fullscreen:!0,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=[],u=e.canvas||document.createElement("canvas"),d=e.fullscreen,p=e.autoscale,h=e.animate,g=1,m,v=.5,E=1,b,w,T=0,x,H="sans-serif",y=32,I=Date.now(),D=e.global,S={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},A={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:i,HALF_PI:n/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n/180*e,rad2deg:e=>180/n*e,clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*Math.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?k.clamp(o,l,n):o},norm:(e,t,a)=>k.map(e,t,a,0,1),rand:(e=0,t=1)=>(I=(1664525*I+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>Math.floor(k.rand(e,t+1)),seed:e=>null==e?I:I=~~e,cls(e){null==e?m.clearRect(0,0,m.canvas.width,m.canvas.height):k.rectfill(0,0,m.canvas.width,m.canvas.height,e)},rect(e,t,a,l,n,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e-v,~~t-v,~~a+2*v,~~l+2*v,i),k.stroke(n)},rectfill(e,t,a,l,n,i=null){m.beginPath(),m[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),k.fill(n)},circ(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,~~a,0,i),k.stroke(l)},circfill(e,t,a,l){m.beginPath(),m.arc(~~e,~~t,~~a,0,i),k.fill(l)},line(e,t,a,l,n){m.beginPath();let i=.5*(0!==v&&~~e==~~a),o=.5*(0!==v&&~~t==~~l);m.moveTo(~~e+i,~~t+o),m.lineTo(~~a+i,~~l+o),k.stroke(n)},linewidth(e){m.lineWidth=~~e,v=.5*(~~e%2!=0)},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,l=3,n="normal"){m.font=`${n} ${y}px ${H}`,m.fillStyle=k.getcolor(l),m.fillText(a,~~e,~~t)},textfont(e){H=e},textsize(e){y=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,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=m;if(n.width=e*i,n.height=t*i,(m=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(m.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(m);return m=o,n},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=k.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){m.fillStyle=k.getcolor(e),t?m.fill(t):m.fill()},stroke(e,t){m.strokeStyle=k.getcolor(e),t?m.stroke(t):m.stroke()},clip(e){m.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},colrect:(e,t,a,l,n,i,o,r)=>e<n+o&&e+a>n&&t<i+r&&t+l>i,colcirc:(e,t,a,l,n,i)=>(l-e)*(l-e)+(n-t)*(n-t)<=(a+i)*(a+i),use(e,t={}){c?z(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,l,n){P("before:"+e,t,a,l,n),P(e,t,a,l,n),P("after:"+e,t,a,l,n)},getcolor:e=>a[~~e%a.length],setvar(e,t){k[e]=t,D&&(l[e]=t)},resize(e,t){k.setvar("WIDTH",u.width=e),k.setvar("HEIGHT",u.height=t),X()},timescale(e){E=e},setfps(e){w=1/~~e},quit(){for(let e of(k.emit("quit"),r))e();if(cancelAnimationFrame(x),S=!1,D){for(let e in k)delete l[e];delete l.__litecanvas}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,round,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))k[e]=Math[e];function C(){c=!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 f)z(e,t);if((d||p)&&s(l,"resize",X),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<=200,o=e=>e.preventDefault(),r=!1;s(u,"mousedown",t=>{if(0===t.button){o(t);let[l,n]=e(t.pageX,t.pageY);k.emit("tap",l,n,0),a(0,l,n),r=!0}}),s(u,"mouseup",a=>{if(0===a.button){o(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),r=!1}}),s(u,"mousemove",t=>{o(t);let[a,l]=e(t.pageX,t.pageY);k.setvar("MOUSEX",a),k.setvar("MOUSEY",l),r&&(k.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(o(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)}}),s(u,"touchmove",t=>{for(let a of(o(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 c=e=>{o(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))};s(u,"touchend",c),s(u,"touchcancel",c),s(l,"blur",()=>{for(let[e,a]of(r=!1,t))k.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=new Set;k.setvar("iskeydown",t=>"any"===t?e.size>0:e.has(t.toLowerCase())),s(l,"keydown",t=>{e.add(t.key.toLowerCase())}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear())}e.pauseOnBlur&&(s(l,"blur",()=>{x=cancelAnimationFrame(x)}),s(l,"focus",()=>{x||(x=o(L))})),k.setfps(60),k.emit("init",k),b=performance.now(),x=o(L)}function L(e){h&&(x=o(L));let t=0,a=(e-b)/1e3;if(b=e,!(a>30*w)){for(T+=a,h||(T=w);T>=w;T-=w)k.emit("update",w*E),k.setvar("ELAPSED",k.ELAPSED+w*E),t++;t&&(k.textalign("start","top"),k.emit("draw"))}}function X(){let t=l.innerWidth,a=l.innerHeight,n=u.style;n.display="block",d?(n.position="absolute",n.inset=0,k.setvar("WIDTH",u.width=t),k.setvar("HEIGHT",u.height=a)):p&&(n.margin="auto",g=Math.min(t/k.WIDTH,a/k.HEIGHT),g=(e.pixelart?~~g:g)||1,n.width=k.WIDTH*g+"px",n.height=k.HEIGHT*g+"px"),k.setvar("CENTERX",k.WIDTH/2),k.setvar("CENTERY",k.HEIGHT/2),(!e.antialias||e.pixelart)&&(m.imageSmoothingEnabled=!1,n.imageRendering="pixelated"),k.emit("resized",g),h||o(L)}function P(e,t,a,l,n){if(S[e])for(let i of S[e])i(t,a,l,n)}function z(e,t){let a=e(k,A,t);for(let e in a)k.setvar(e,a[e])}if(D){if(l.__litecanvas)throw"global litecanvas already instantiated";Object.assign(l,k),l.__litecanvas=k}return u="string"==typeof u?document.querySelector(u):u,k.setvar("CANVAS",u),m=u.getContext("2d"),s(u,"click",()=>l.focus()),k.WIDTH>0&&(d=!1),u.style="",u.width=k.WIDTH,u.height=k.HEIGHT||k.WIDTH,u.parentNode||document.body.appendChild(u),"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(C)):o(C),k}})();
1
+ (()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,o=.1,r=0,s=1,c=0,f=0,d=0,p=0,u=0,h=0,g=0,m=0,v=0,E=1,b=0,x=0,T=0)=>{let w=Math,y=2*w.PI,H=c*=500*y/44100/44100,I=l*=(1-a+2*a*w.random(a=[]))*y/44100,S=0,D=0,A=0,k=1,C=0,L=0,X=0,z=T<0?-1:1,P=y*z*T*2/44100,M=w.cos(P),O=w.sin,Y=O(P)/4,F=1+Y,W=-2*M/F,_=(1-Y)/F,R=(1+z*M)/2/F,G=-(z+M)/F,N=0,B=0,U=0,q=0;for(n=44100*n+9,b*=44100,i*=44100,o*=44100,v*=44100,f*=500*y/85766121e6,g*=y/44100,d*=y/44100,p*=44100,u=44100*u|0,t*=.3*(globalThis.zzfxV||1),z=n+b+i+o+v|0;A<z;a[A++]=X*t)++L%(100*m|0)||(X=r?1<r?2<r?3<r?O(S*S):w.max(w.min(w.tan(S),1),-1):1-(2*S/y%2+2)%2:1-4*w.abs(w.round(S/y)-S/y):O(S),X=(u?1-x+x*O(y*A/u):1)*(X<0?-1:1)*w.abs(X)**s*(A<n?A/n:A<n+b?1-(A-n)/b*(1-E):A<n+b+i?E:A<z-v?(z-A-v)/o*E:0),X=v?X/2+(v>A?0:(A<z-v?1:(z-A)/v)*a[A-v|0]/2/t):X,T&&(X=q=R*N+G*(N=B)+R*(B=X)-_*U-W*(U=q))),S+=(P=(l+=c+=f)*w.cos(g*D++))+P*h*O(A**5),k&&++k>p&&(l+=d,I+=d,k=0),!u||++C%u||(l=I,c=H,k=k||1);(t=e.createBuffer(1,z,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.PI,i=2*n,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.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=e.canvas||document.createElement("canvas"),p=e.autoscale,u=e.animate,h=1,g,m=.5,v=1,E,b,x=0,T,w="sans-serif",y=32,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},A={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:i,HALF_PI:n/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n/180*e,rad2deg:e=>180/n*e,clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*Math.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?A.clamp(o,l,n):o},norm:(e,t,a)=>A.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)=>Math.floor(A.rand(e,t+1)),seed:e=>null==e?H:H=~~e,cls(e){null==e?g.clearRect(0,0,g.canvas.width,g.canvas.height):A.rectfill(0,0,g.canvas.width,g.canvas.height,e)},rect(e,t,a,l,n,i=null){g.beginPath(),g[i?"roundRect":"rect"](~~e-m,~~t-m,~~a+2*m,~~l+2*m,i),A.stroke(n)},rectfill(e,t,a,l,n,i=null){g.beginPath(),g[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),A.fill(n)},circ(e,t,a,l){g.beginPath(),g.arc(~~e,~~t,~~a,0,i),A.stroke(l)},circfill(e,t,a,l){g.beginPath(),g.arc(~~e,~~t,~~a,0,i),A.fill(l)},line(e,t,a,l,n){g.beginPath();let i=.5*(0!==m&&~~e==~~a),o=.5*(0!==m&&~~t==~~l);g.moveTo(~~e+i,~~t+o),g.lineTo(~~a+i,~~l+o),A.stroke(n)},linewidth(e){g.lineWidth=~~e,m=.5*(~~e%2!=0)},linedash(e,t=0){g.setLineDash(e),g.lineDashOffset=t},text(e,t,a,l=3,n="normal"){g.font=`${n} ${y}px ${w}`,g.fillStyle=A.getcolor(l),g.fillText(a,~~e,~~t)},textfont(e){w=e},textsize(e){y=e},textalign(e,t){e&&(g.textAlign=e),t&&(g.textBaseline=t)},image(e,t,a){g.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=g;if(n.width=e*i,n.height=t*i,(g=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(g.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&A.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(g);return g=o,n},ctx:e=>(e&&(g=e),g),push:()=>g.save(),pop:()=>g.restore(),translate:(e,t)=>g.translate(~~e,~~t),scale:(e,t)=>g.scale(e,t||e),rotate:e=>g.rotate(e),alpha(e){g.globalAlpha=A.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){g.fillStyle=A.getcolor(e),t?g.fill(t):g.fill()},stroke(e,t){g.strokeStyle=A.getcolor(e),t?g.stroke(t):g.stroke()},clip(e){g.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||A.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},colrect:(e,t,a,l,n,i,o,r)=>e<n+o&&e+a>n&&t<i+r&&t+l>i,colcirc:(e,t,a,l,n,i)=>(l-e)*(l-e)+(n-t)*(n-t)<=(a+i)*(a+i),use(e,t={}){c?z(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,l,n){c&&(X("before:"+e,t,a,l,n),X(e,t,a,l,n),X("after:"+e,t,a,l,n))},getcolor:e=>a[~~e%a.length],setvar(e,t){A[e]=t,I&&(l[e]=t)},resize(e,t){A.setvar("WIDTH",d.width=e),A.setvar("HEIGHT",d.height=t),A.setvar("CENTERX",A.WIDTH/2),A.setvar("CENTERY",A.HEIGHT/2),L()},timescale(e){v=e},setfps(e){b=1/~~e},quit(){for(let e of(A.emit("quit"),r))e();if(cancelAnimationFrame(T),S=!1,I){for(let e in A)delete l[e];delete l.__litecanvas}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,round,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))A[e]=Math[e];function k(){c=!0;let t=e.loop?e.loop:l;for(let e in S)t[e]&&A.listen(e,t[e]);for(let[e,t]of f)z(e,t);if(p&&s(l,"resize",L),e.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/h,(t-d.offsetTop)/h],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<=200,o=e=>e.preventDefault(),r=!1;s(d,"mousedown",t=>{if(0===t.button){o(t);let[l,n]=e(t.pageX,t.pageY);A.emit("tap",l,n,0),a(0,l,n),r=!0}}),s(d,"mouseup",a=>{if(0===a.button){o(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&A.emit("tapped",l.startX,l.startY,0),A.emit("untap",n,s,0),t.delete(0),r=!1}}),s(d,"mousemove",t=>{o(t);let[a,l]=e(t.pageX,t.pageY);A.setvar("MOUSEX",a),A.setvar("MOUSEY",l),r&&(A.emit("tapping",a,l,0),n(0,a,l))}),s(d,"touchstart",t=>{for(let l of(o(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);A.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(d,"touchmove",t=>{for(let a of(o(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);A.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let c=e=>{o(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)&&A.emit("tapped",l.startX,l.startY,e),A.emit("untap",l.x,l.y,e),t.delete(e))};s(d,"touchend",c),s(d,"touchcancel",c),s(l,"blur",()=>{for(let[e,a]of(r=!1,t))A.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=new Set;A.setvar("iskeydown",t=>"any"===t?e.size>0:e.has(t.toLowerCase())),s(l,"keydown",t=>{e.add(t.key.toLowerCase())}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear())}e.pauseOnBlur&&(s(l,"blur",()=>{T=cancelAnimationFrame(T)}),s(l,"focus",()=>{T||(T=o(C))})),A.setfps(60),A.emit("init",A),E=performance.now(),T=o(C)}function C(e){u&&(T=o(C));let t=0,a=(e-E)/1e3;if(E=e,a>30*b);else for(x+=a,u||(x=b);x>=b;x-=b)A.emit("update",b*v),A.setvar("ELAPSED",A.ELAPSED+b*v),t++;(t||!u)&&(A.textalign("start","top"),A.emit("draw"))}function L(){let t=d.style;p&&(t.display||(t.display="block",t.margin="auto"),h=Math.min(l.innerWidth/A.WIDTH,l.innerHeight/A.HEIGHT),h=(e.pixelart?~~h:h)||1,t.width=A.WIDTH*h+"px",t.height=A.HEIGHT*h+"px"),(!e.antialias||e.pixelart)&&(g.imageSmoothingEnabled=!1,t.imageRendering="pixelated"),A.emit("resized",h),u||o(C)}function X(e,t,a,l,n){if(S[e])for(let i of S[e])i(t,a,l,n)}function z(e,t){let a=e(A,D,t);for(let e in a)A.setvar(e,a[e])}if(I){if(l.__litecanvas)throw"global litecanvas already instantiated";Object.assign(l,A),l.__litecanvas=A}return d="string"==typeof d?document.querySelector(d):d,A.setvar("CANVAS",d),g=d.getContext("2d"),s(d,"click",()=>l.focus()),d.style="",A.WIDTH||(A.WIDTH=l.innerWidth,A.HEIGHT=l.innerHeight),A.resize(A.WIDTH,A.HEIGHT,!1),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(k)):o(k),A}})();
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.75.1",
3
+ "version": "0.76.0",
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.7",
9
+ "@swc/core": "^1.11.8",
10
10
  "ava": "^6.2.0",
11
- "esbuild": "^0.25.0",
11
+ "esbuild": "^0.25.1",
12
12
  "gzip-size": "^7.0.0",
13
13
  "prettier": "^3.5.3"
14
14
  },
package/src/index.js CHANGED
@@ -26,7 +26,6 @@ export default function litecanvas(settings = {}) {
26
26
  isFinite = Number.isFinite,
27
27
  /** @type {LitecanvasOptions} */
28
28
  defaults = {
29
- fullscreen: true,
30
29
  width: null,
31
30
  height: null,
32
31
  autoscale: true,
@@ -51,8 +50,6 @@ export default function litecanvas(settings = {}) {
51
50
  /** @type {HTMLCanvasElement|string} _canvas */
52
51
  _canvas = settings.canvas || document.createElement('canvas'),
53
52
  /** @type {boolean} */
54
- _fullscreen = settings.fullscreen,
55
- /** @type {boolean} */
56
53
  _autoscale = settings.autoscale,
57
54
  /** @type {boolean} */
58
55
  _animated = settings.animate,
@@ -1069,10 +1066,11 @@ export default function litecanvas(settings = {}) {
1069
1066
  'string' === typeof eventName,
1070
1067
  'emit: 1st param must be a string'
1071
1068
  )
1072
-
1073
- triggerEvent('before:' + eventName, arg1, arg2, arg3, arg4)
1074
- triggerEvent(eventName, arg1, arg2, arg3, arg4)
1075
- triggerEvent('after:' + eventName, arg1, arg2, arg3, arg4)
1069
+ if (_initialized) {
1070
+ triggerEvent('before:' + eventName, arg1, arg2, arg3, arg4)
1071
+ triggerEvent(eventName, arg1, arg2, arg3, arg4)
1072
+ triggerEvent('after:' + eventName, arg1, arg2, arg3, arg4)
1073
+ }
1076
1074
  },
1077
1075
 
1078
1076
  /**
@@ -1118,12 +1116,22 @@ export default function litecanvas(settings = {}) {
1118
1116
  * @param {number} height
1119
1117
  */
1120
1118
  resize(width, height) {
1121
- DEV: assert(isFinite(width), 'resize: 1st param must be a number')
1122
- DEV: assert(isFinite(height), 'resize: 2nd param must be a number')
1119
+ DEV: assert(
1120
+ isFinite(width) && width > 0,
1121
+ 'resize: 1st param must be a number'
1122
+ )
1123
+ DEV: assert(
1124
+ isFinite(height) && height > 0,
1125
+ 'resize: 2nd param must be a number'
1126
+ )
1123
1127
 
1124
1128
  instance.setvar('WIDTH', (_canvas.width = width))
1125
1129
  instance.setvar('HEIGHT', (_canvas.height = height))
1126
- pageResized()
1130
+
1131
+ instance.setvar('CENTERX', instance.WIDTH / 2)
1132
+ instance.setvar('CENTERY', instance.HEIGHT / 2)
1133
+
1134
+ onResize()
1127
1135
  },
1128
1136
 
1129
1137
  /**
@@ -1184,7 +1192,7 @@ export default function litecanvas(settings = {}) {
1184
1192
  function init() {
1185
1193
  _initialized = true
1186
1194
 
1187
- // add listeners for default events
1195
+ // setup default event listeners
1188
1196
  const source = settings.loop ? settings.loop : root
1189
1197
  for (const event in _events) {
1190
1198
  if (source[event]) instance.listen(event, source[event])
@@ -1195,13 +1203,11 @@ export default function litecanvas(settings = {}) {
1195
1203
  loadPlugin(callback, config)
1196
1204
  }
1197
1205
 
1198
- // listen window resize event
1199
- if (_fullscreen || _autoscale) {
1200
- on(root, 'resize', pageResized)
1206
+ // listen window resize event when "autoscale" is enabled
1207
+ if (_autoscale) {
1208
+ on(root, 'resize', onResize)
1201
1209
  }
1202
1210
 
1203
- pageResized()
1204
-
1205
1211
  // default mouse/touch handlers
1206
1212
  if (settings.tapEvents) {
1207
1213
  const _getXY = (pageX, pageY) => [
@@ -1395,25 +1401,26 @@ export default function litecanvas(settings = {}) {
1395
1401
 
1396
1402
  _lastFrameTime = now
1397
1403
 
1398
- if (frameTime > _deltaTime * 30)
1399
- return console.log('skipping too long frame')
1400
-
1401
- _accumulated += frameTime
1404
+ if (frameTime > _deltaTime * 30) {
1405
+ console.log('skipping too long frame')
1406
+ } else {
1407
+ _accumulated += frameTime
1402
1408
 
1403
- if (!_animated) {
1404
- _accumulated = _deltaTime
1405
- }
1409
+ if (!_animated) {
1410
+ _accumulated = _deltaTime
1411
+ }
1406
1412
 
1407
- for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1408
- instance.emit('update', _deltaTime * _timeScale)
1409
- instance.setvar(
1410
- 'ELAPSED',
1411
- instance.ELAPSED + _deltaTime * _timeScale
1412
- )
1413
- updated++
1413
+ for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
1414
+ instance.emit('update', _deltaTime * _timeScale)
1415
+ instance.setvar(
1416
+ 'ELAPSED',
1417
+ instance.ELAPSED + _deltaTime * _timeScale
1418
+ )
1419
+ updated++
1420
+ }
1414
1421
  }
1415
1422
 
1416
- if (updated) {
1423
+ if (updated || !_animated) {
1417
1424
  instance.textalign('start', 'top') // default values for textAlign & textBaseline
1418
1425
  instance.emit('draw')
1419
1426
  }
@@ -1431,57 +1438,56 @@ export default function litecanvas(settings = {}) {
1431
1438
  'Invalid canvas element'
1432
1439
  )
1433
1440
  DEV: assert(
1434
- null === instance.WIDTH || instance.WIDTH > 0,
1441
+ null == instance.WIDTH || instance.WIDTH > 0,
1435
1442
  'Litecanvas\' "width" option should be null or a positive number'
1436
1443
  )
1437
1444
  DEV: assert(
1438
- null === instance.HEIGHT || instance.HEIGHT > 0,
1445
+ null == instance.HEIGHT || instance.HEIGHT > 0,
1439
1446
  'Litecanvas\' "width" option should be null or a positive number'
1440
1447
  )
1448
+ DEV: assert(
1449
+ null == instance.HEIGHT ||
1450
+ (instance.WIDTH > 0 && instance.HEIGHT > 0),
1451
+ 'Litecanvas\' "width" is required when "heigth" is passed'
1452
+ )
1441
1453
 
1442
1454
  instance.setvar('CANVAS', _canvas)
1443
1455
  _ctx = _canvas.getContext('2d')
1444
1456
 
1445
1457
  on(_canvas, 'click', () => root.focus())
1446
1458
 
1447
- // disable fullscreen if a width is specified
1448
- if (instance.WIDTH > 0) {
1449
- _fullscreen = false
1459
+ _canvas.style = ''
1460
+
1461
+ // If width is not set, the canvas will have the size of the page width.
1462
+ if (!instance.WIDTH) {
1463
+ instance.WIDTH = root.innerWidth
1464
+ instance.HEIGHT = root.innerHeight
1450
1465
  }
1451
1466
 
1452
- _canvas.style = ''
1453
- _canvas.width = instance.WIDTH
1454
- _canvas.height = instance.HEIGHT || instance.WIDTH
1467
+ instance.resize(instance.WIDTH, instance.HEIGHT, false)
1455
1468
 
1456
1469
  if (!_canvas.parentNode) document.body.appendChild(_canvas)
1457
1470
  }
1458
1471
 
1459
- function pageResized() {
1460
- const pageWidth = root.innerWidth,
1461
- pageHeight = root.innerHeight,
1462
- styles = _canvas.style
1472
+ function onResize() {
1473
+ const styles = _canvas.style
1463
1474
 
1464
- styles.display = 'block'
1475
+ if (_autoscale) {
1476
+ if (!styles.display) {
1477
+ styles.display = 'block'
1478
+ styles.margin = 'auto'
1479
+ }
1465
1480
 
1466
- if (_fullscreen) {
1467
- styles.position = 'absolute'
1468
- styles.inset = 0
1469
- instance.setvar('WIDTH', (_canvas.width = pageWidth))
1470
- instance.setvar('HEIGHT', (_canvas.height = pageHeight))
1471
- } else if (_autoscale) {
1472
- styles.margin = 'auto'
1473
1481
  _scale = Math.min(
1474
- pageWidth / instance.WIDTH,
1475
- pageHeight / instance.HEIGHT
1482
+ root.innerWidth / instance.WIDTH,
1483
+ root.innerHeight / instance.HEIGHT
1476
1484
  )
1477
1485
  _scale = (settings.pixelart ? ~~_scale : _scale) || 1
1486
+
1478
1487
  styles.width = instance.WIDTH * _scale + 'px'
1479
1488
  styles.height = instance.HEIGHT * _scale + 'px'
1480
1489
  }
1481
1490
 
1482
- instance.setvar('CENTERX', instance.WIDTH / 2)
1483
- instance.setvar('CENTERY', instance.HEIGHT / 2)
1484
-
1485
1491
  // restore canvas image rendering properties
1486
1492
  if (!settings.antialias || settings.pixelart) {
1487
1493
  _ctx.imageSmoothingEnabled = false
@@ -1490,6 +1496,7 @@ export default function litecanvas(settings = {}) {
1490
1496
 
1491
1497
  instance.emit('resized', _scale)
1492
1498
 
1499
+ // force redraw
1493
1500
  if (!_animated) {
1494
1501
  raf(drawFrame)
1495
1502
  }
package/src/types.js CHANGED
@@ -1,8 +1,6 @@
1
1
  /**
2
2
  * @typedef LitecanvasOptions
3
3
  * @type {object}
4
- * @property {number} [fps=60]
5
- * @property {boolean} [fullscreen=true]
6
4
  * @property {number} [width]
7
5
  * @property {number} [height]
8
6
  * @property {boolean} [pauseOnBlur=true]
package/types/types.d.ts CHANGED
@@ -579,15 +579,7 @@ type LitecanvasInstance = {
579
579
 
580
580
  type LitecanvasOptions = {
581
581
  /**
582
- * target FPS
583
- */
584
- fps?: number
585
- /**
586
- * Makes the canvas fills the entire page. By default is `true`.
587
- */
588
- fullscreen?: boolean
589
- /**
590
- * The game screen width. If specified, disables fullscreen.
582
+ * The game screen width. If not set, the canvas will have the size of the webpage.
591
583
  */
592
584
  width?: number
593
585
  /**