litecanvas 0.98.4 → 0.99.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 +2 -1
- package/dist/dist.dev.js +35 -27
- package/dist/dist.js +29 -26
- package/dist/dist.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +48 -36
- package/src/version.js +1 -1
- package/types/global.d.ts +9 -8
- package/types/types.d.ts +9 -8
package/README.md
CHANGED
|
@@ -205,6 +205,7 @@ const japan = paint(
|
|
|
205
205
|
|
|
206
206
|
function draw() {
|
|
207
207
|
cls(0)
|
|
208
|
+
|
|
208
209
|
// now the japan variable holds a image
|
|
209
210
|
image(W/2 - japan.width/2, H/2 - japan.height/2, japan)
|
|
210
211
|
}
|
|
@@ -212,7 +213,7 @@ function draw() {
|
|
|
212
213
|
|
|
213
214
|
It's very useful when you need to draw something the same way every time. This way, you create an image of that drawing, working as a kind of cache.
|
|
214
215
|
|
|
215
|
-
You can also use the image() function to draw PNG/JPG images, but you'll need to load them first:
|
|
216
|
+
You can also use the `image()` function to draw PNG/JPG images, but you'll need to load them first:
|
|
216
217
|
|
|
217
218
|
```js
|
|
218
219
|
litecanvas()
|
package/dist/dist.dev.js
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
// src/version.js
|
|
35
|
-
var version = "0.
|
|
35
|
+
var version = "0.99.0";
|
|
36
36
|
|
|
37
37
|
// src/index.js
|
|
38
38
|
function litecanvas(settings = {}) {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
keyboardEvents: true
|
|
51
51
|
};
|
|
52
52
|
settings = Object.assign(defaults, settings);
|
|
53
|
-
let _initialized = false, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _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 = {};
|
|
53
|
+
let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _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 = {};
|
|
54
54
|
const instance = {
|
|
55
55
|
/** @type {number} */
|
|
56
56
|
W: 0,
|
|
@@ -995,7 +995,7 @@
|
|
|
995
995
|
_fpsInterval = 1e3 / ~~value;
|
|
996
996
|
},
|
|
997
997
|
/**
|
|
998
|
-
* Returns information about
|
|
998
|
+
* Returns information about the engine instance.
|
|
999
999
|
*
|
|
1000
1000
|
* @param {number|string} index
|
|
1001
1001
|
* @returns {any}
|
|
@@ -1028,43 +1028,32 @@
|
|
|
1028
1028
|
_rngSeed,
|
|
1029
1029
|
// 10
|
|
1030
1030
|
_fontSize,
|
|
1031
|
-
//
|
|
1032
|
-
_fontFamily
|
|
1031
|
+
// 11
|
|
1032
|
+
_fontFamily,
|
|
1033
|
+
// 12
|
|
1034
|
+
_colorPaletteState
|
|
1033
1035
|
];
|
|
1034
1036
|
const data = { index, value: internals[index] };
|
|
1035
1037
|
instance.emit("stat", data);
|
|
1036
1038
|
return data.value;
|
|
1037
1039
|
},
|
|
1038
|
-
/**
|
|
1039
|
-
* Stops the litecanvas instance and remove all event listeners.
|
|
1040
|
-
*/
|
|
1041
|
-
quit() {
|
|
1042
|
-
instance.pause();
|
|
1043
|
-
instance.emit("quit");
|
|
1044
|
-
_eventListeners = {};
|
|
1045
|
-
for (const removeListener of _browserEventListeners) {
|
|
1046
|
-
removeListener();
|
|
1047
|
-
}
|
|
1048
|
-
if (settings.global) {
|
|
1049
|
-
for (const key in instance) {
|
|
1050
|
-
delete root[key];
|
|
1051
|
-
}
|
|
1052
|
-
delete root.ENGINE;
|
|
1053
|
-
}
|
|
1054
|
-
_initialized = false;
|
|
1055
|
-
},
|
|
1056
1040
|
/**
|
|
1057
1041
|
* Pauses the engine loop (update & draw).
|
|
1058
1042
|
*/
|
|
1059
1043
|
pause() {
|
|
1044
|
+
_paused = true;
|
|
1060
1045
|
cancelAnimationFrame(_rafid);
|
|
1061
|
-
_rafid = 0;
|
|
1062
1046
|
},
|
|
1063
1047
|
/**
|
|
1064
1048
|
* Resumes (if paused) the engine loop.
|
|
1065
1049
|
*/
|
|
1066
1050
|
resume() {
|
|
1067
|
-
|
|
1051
|
+
DEV: assert(
|
|
1052
|
+
_initialized,
|
|
1053
|
+
'[litecanvas] resume() cannot be called before the "init" event and neither after the quit() function'
|
|
1054
|
+
);
|
|
1055
|
+
if (_initialized && _paused) {
|
|
1056
|
+
_paused = false;
|
|
1068
1057
|
_accumulated = _fpsInterval;
|
|
1069
1058
|
_lastFrameTime = Date.now();
|
|
1070
1059
|
_rafid = raf(drawFrame);
|
|
@@ -1076,7 +1065,26 @@
|
|
|
1076
1065
|
* @returns {boolean}
|
|
1077
1066
|
*/
|
|
1078
1067
|
paused() {
|
|
1079
|
-
return
|
|
1068
|
+
return _paused;
|
|
1069
|
+
},
|
|
1070
|
+
/**
|
|
1071
|
+
* Shutdown the litecanvas instance and remove all event listeners.
|
|
1072
|
+
*/
|
|
1073
|
+
quit() {
|
|
1074
|
+
instance.emit("quit");
|
|
1075
|
+
instance.pause();
|
|
1076
|
+
_initialized = false;
|
|
1077
|
+
_eventListeners = {};
|
|
1078
|
+
for (const removeListener of _browserEventListeners) {
|
|
1079
|
+
removeListener();
|
|
1080
|
+
}
|
|
1081
|
+
if (settings.global) {
|
|
1082
|
+
for (const key in instance) {
|
|
1083
|
+
delete root[key];
|
|
1084
|
+
}
|
|
1085
|
+
delete root.ENGINE;
|
|
1086
|
+
}
|
|
1087
|
+
DEV: console.warn("[litecanvas] quit() terminated a Litecanvas instance.");
|
|
1080
1088
|
}
|
|
1081
1089
|
};
|
|
1082
1090
|
for (const k of _mathFunctions.split(",")) {
|
|
@@ -1428,7 +1436,7 @@
|
|
|
1428
1436
|
if ("loading" === document.readyState) {
|
|
1429
1437
|
on(root, "DOMContentLoaded", () => raf(init));
|
|
1430
1438
|
} else {
|
|
1431
|
-
raf(init);
|
|
1439
|
+
_rafid = raf(init);
|
|
1432
1440
|
}
|
|
1433
1441
|
return instance;
|
|
1434
1442
|
}
|
package/dist/dist.js
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
keyboardEvents: true
|
|
43
43
|
};
|
|
44
44
|
settings = Object.assign(defaults, settings);
|
|
45
|
-
let _initialized = false, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _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 = {};
|
|
45
|
+
let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _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 = {};
|
|
46
46
|
const instance = {
|
|
47
47
|
/** @type {number} */
|
|
48
48
|
W: 0,
|
|
@@ -687,7 +687,7 @@
|
|
|
687
687
|
_fpsInterval = 1e3 / ~~value;
|
|
688
688
|
},
|
|
689
689
|
/**
|
|
690
|
-
* Returns information about
|
|
690
|
+
* Returns information about the engine instance.
|
|
691
691
|
*
|
|
692
692
|
* @param {number|string} index
|
|
693
693
|
* @returns {any}
|
|
@@ -716,43 +716,28 @@
|
|
|
716
716
|
_rngSeed,
|
|
717
717
|
// 10
|
|
718
718
|
_fontSize,
|
|
719
|
-
//
|
|
720
|
-
_fontFamily
|
|
719
|
+
// 11
|
|
720
|
+
_fontFamily,
|
|
721
|
+
// 12
|
|
722
|
+
_colorPaletteState
|
|
721
723
|
];
|
|
722
724
|
const data = { index, value: internals[index] };
|
|
723
725
|
instance.emit("stat", data);
|
|
724
726
|
return data.value;
|
|
725
727
|
},
|
|
726
|
-
/**
|
|
727
|
-
* Stops the litecanvas instance and remove all event listeners.
|
|
728
|
-
*/
|
|
729
|
-
quit() {
|
|
730
|
-
instance.pause();
|
|
731
|
-
instance.emit("quit");
|
|
732
|
-
_eventListeners = {};
|
|
733
|
-
for (const removeListener of _browserEventListeners) {
|
|
734
|
-
removeListener();
|
|
735
|
-
}
|
|
736
|
-
if (settings.global) {
|
|
737
|
-
for (const key in instance) {
|
|
738
|
-
delete root[key];
|
|
739
|
-
}
|
|
740
|
-
delete root.ENGINE;
|
|
741
|
-
}
|
|
742
|
-
_initialized = false;
|
|
743
|
-
},
|
|
744
728
|
/**
|
|
745
729
|
* Pauses the engine loop (update & draw).
|
|
746
730
|
*/
|
|
747
731
|
pause() {
|
|
732
|
+
_paused = true;
|
|
748
733
|
cancelAnimationFrame(_rafid);
|
|
749
|
-
_rafid = 0;
|
|
750
734
|
},
|
|
751
735
|
/**
|
|
752
736
|
* Resumes (if paused) the engine loop.
|
|
753
737
|
*/
|
|
754
738
|
resume() {
|
|
755
|
-
if (_initialized &&
|
|
739
|
+
if (_initialized && _paused) {
|
|
740
|
+
_paused = false;
|
|
756
741
|
_accumulated = _fpsInterval;
|
|
757
742
|
_lastFrameTime = Date.now();
|
|
758
743
|
_rafid = raf(drawFrame);
|
|
@@ -764,7 +749,25 @@
|
|
|
764
749
|
* @returns {boolean}
|
|
765
750
|
*/
|
|
766
751
|
paused() {
|
|
767
|
-
return
|
|
752
|
+
return _paused;
|
|
753
|
+
},
|
|
754
|
+
/**
|
|
755
|
+
* Shutdown the litecanvas instance and remove all event listeners.
|
|
756
|
+
*/
|
|
757
|
+
quit() {
|
|
758
|
+
instance.emit("quit");
|
|
759
|
+
instance.pause();
|
|
760
|
+
_initialized = false;
|
|
761
|
+
_eventListeners = {};
|
|
762
|
+
for (const removeListener of _browserEventListeners) {
|
|
763
|
+
removeListener();
|
|
764
|
+
}
|
|
765
|
+
if (settings.global) {
|
|
766
|
+
for (const key in instance) {
|
|
767
|
+
delete root[key];
|
|
768
|
+
}
|
|
769
|
+
delete root.ENGINE;
|
|
770
|
+
}
|
|
768
771
|
}
|
|
769
772
|
};
|
|
770
773
|
for (const k of _mathFunctions.split(",")) {
|
|
@@ -1076,7 +1079,7 @@
|
|
|
1076
1079
|
if ("loading" === document.readyState) {
|
|
1077
1080
|
on(root, "DOMContentLoaded", () => raf(init));
|
|
1078
1081
|
} else {
|
|
1079
|
-
raf(init);
|
|
1082
|
+
_rafid = raf(init);
|
|
1080
1083
|
}
|
|
1081
1084
|
return instance;
|
|
1082
1085
|
}
|
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,l=Math,n=2*l.PI,i=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.toLowerCase(),c=e=>e.preventDefault(),f=e=>e.beginPath(),d=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,l=.05,n=220,i=0,o=0,r=.1,s=0,c=1,f=0,d=0,u=0,p=0,h=0,m=0,g=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=f*=500*z/44100/44100,I=n*=(1-l+2*l*E.random(l=[]))*z/44100,D=0,S=0,A=0,M=1,C=0,L=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(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=i+y+o+r+w|0;A<P;l[A++]=N*a)++L%(100*v|0)||(N=s?1<s?2<s?3<s?B(D*D):E.max(E.min(E.tan(D),1),-1):1-(2*D/z%2+2)%2:1-4*E.abs(E.round(D/z)-D/z):B(D),N=(h?1-b+b*B(z*A/h):1)*(N<0?-1:1)*E.abs(N)**c*(A<i?A/i:A<i+y?1-(A-i)/y*(1-x):A<i+y+o?x:A<P-w?(P-A-w)/r*x:0),N=w?N/2+(w>A?0:(A<P-w?1:(P-A)/w)*l[A-w|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),D+=(F=(n+=f+=d)*E.cos(g*S++))+F*m*B(A**5),M&&++M>p&&(n+=u,I+=u,M=0),!h||++C%h||(n=I,f=T,M=M||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(l),(n=t.createBufferSource()).buffer=a,n.connect(t.destination),n.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let u=!1,p,h=1,
|
|
1
|
+
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,l=Math,n=2*l.PI,i=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.toLowerCase(),c=e=>e.preventDefault(),f=e=>e.beginPath(),d=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,l=.05,n=220,i=0,o=0,r=.1,s=0,c=1,f=0,d=0,u=0,p=0,h=0,m=0,g=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=f*=500*z/44100/44100,I=n*=(1-l+2*l*E.random(l=[]))*z/44100,D=0,S=0,A=0,M=1,C=0,L=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(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=i+y+o+r+w|0;A<P;l[A++]=N*a)++L%(100*v|0)||(N=s?1<s?2<s?3<s?B(D*D):E.max(E.min(E.tan(D),1),-1):1-(2*D/z%2+2)%2:1-4*E.abs(E.round(D/z)-D/z):B(D),N=(h?1-b+b*B(z*A/h):1)*(N<0?-1:1)*E.abs(N)**c*(A<i?A/i:A<i+y?1-(A-i)/y*(1-x):A<i+y+o?x:A<P-w?(P-A-w)/r*x:0),N=w?N/2+(w>A?0:(A<P-w?1:(P-A)/w)*l[A-w|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),D+=(F=(n+=f+=d)*E.cos(g*S++))+F*m*B(A**5),M&&++M>p&&(n+=u,I+=u,M=0),!h||++C%h||(n=I,f=T,M=M||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(l),(n=t.createBufferSource()).buffer=a,n.connect(t.destination),n.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let u=!1,p=!0,h,m=1,g,v=.5,w=1,x,y=1e3/60,b,k,E="sans-serif",z=20,T=Date.now(),I=e,D=[],S=[.5,0,1750,,,.3,1,,,,600,.1],A={},M={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:n,HALF_PI:n/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>l.PI/180*e,rad2deg:e=>180/l.PI*e,round:(e,t=0)=>{if(!t)return l.round(e);let a=10**t;return l.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*l.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?M.clamp(o,l,n):o},norm:(e,t,a)=>M.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)=>(T=(1664525*T+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>l.floor(M.rand(e,t+1)),rseed(e){T=~~e},cls(e){null==e?g.clearRect(0,0,g.canvas.width,g.canvas.height):M.rectfill(0,0,g.canvas.width,g.canvas.height,e)},rect(e,t,a,l,n,i){f(g),g[i?"roundRect":"rect"](~~e-v,~~t-v,~~a+2*v,~~l+2*v,i),M.stroke(n)},rectfill(e,t,a,l,n,i){f(g),g[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),M.fill(n)},circ(e,t,a,l){f(g),g.arc(~~e,~~t,~~a,0,n),M.stroke(l)},circfill(e,t,a,l){f(g),g.arc(~~e,~~t,~~a,0,n),M.fill(l)},oval(e,t,a,l,i){f(g),g.ellipse(~~e,~~t,~~a,~~l,0,0,n),M.stroke(i)},ovalfill(e,t,a,l,i){f(g),g.ellipse(~~e,~~t,~~a,~~l,0,0,n),M.fill(i)},line(e,t,a,l,n){f(g);let i=.5*(0!==v&&~~e==~~a),o=.5*(0!==v&&~~t==~~l);g.moveTo(~~e+i,~~t+o),g.lineTo(~~a+i,~~l+o),M.stroke(n)},linewidth(e){g.lineWidth=~~e,v=.5*(0!=~~e%2)},linedash(e,t=0){g.setLineDash(e),g.lineDashOffset=t},text(e,t,a,l=3,n="normal"){g.font=`${n} ${z}px ${E}`,g.fillStyle=F(l),g.fillText(a,~~e,~~t)},textfont(e){E=e},textsize(e){z=e},textalign(e,t){e&&(g.textAlign=e),t&&(g.textBaseline=t)},image(e,t,a){g.drawImage(a,~~e,~~t)},spr(e,t,a,l,n){let i=n.replace(/\s/g,"");for(let n=0;n<a;n++)for(let o=0;o<l;o++){let l=i[a*o+n]||".";"."!==l&&M.rectfill(e+n,t+o,1,1,parseInt(l,36)||0)}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=g;return n.width=e*i,n.height=t*i,(g=n.getContext("2d")).scale(i,i),a(g),g=o,n.transferToImageBitmap()},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=M.clamp(e,0,1)},fill(e){g.fillStyle=F(e),g.fill()},stroke(e){g.strokeStyle=F(e),g.stroke()},clip(e){f(g),e(g),g.clip()},sfx:(e,t=0,l=1)=>!!a.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||S,(0!==t||1!==l)&&((e=e.slice())[0]=l*(e[0]||1),e[10]=~~e[10]+t),d.apply(0,e),e),volume(e){a.zzfxV=e},canvas:()=>h,use(e,t={}){var a=e,l=t;let n=a(M,l);for(let e in n)M.def(e,n[e])},listen:(e,t)=>(A[e=s(e)]=A[e]||new Set,A[e].add(t),()=>A&&A[e].delete(t)),emit(e,t,a,l,n){u&&(P("before:"+(e=s(e)),t,a,l,n),P(e,t,a,l,n),P("after:"+e,t,a,l,n))},pal(t=e){I=t,D=[]},palc(e,t){null==e?D=[]:D[e]=t},def(e,l){M[e]=l,t.global&&(a[e]=l)},timescale(e){w=e},framerate(e){y=1e3/~~e},stat(e){let l={index:e,value:[t,u,y/1e3,m,A,I,S,w,a.zzfxV,T,z,E,D][e]};return M.emit("stat",l),l.value},pause(){p=!0,cancelAnimationFrame(k)},resume(){u&&p&&(p=!1,b=y,x=Date.now(),k=i(L))},paused:()=>p,quit(){for(let e of(M.emit("quit"),M.pause(),u=!1,A={},o))e();if(t.global){for(let e in M)delete a[e];delete a.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))M[e]=l[e];function C(){let e=t.loop?t.loop:a;for(let t of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))e[t]&&M.listen(t,e[t]);if(t.autoscale&&r(a,"resize",N),t.tapEvents){let e=e=>[(e.pageX-h.offsetLeft)/m,(e.pageY-h.offsetTop)/m],t=new Map,l=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.now()};return t.set(e,n),n},n=(e,a,n)=>{let i=t.get(e)||l(e);i.x=a,i.y=n},i=e=>e&&Date.now()-e.t<=300,o=!1;r(h,"mousedown",t=>{if(0===t.button){c(t);let[a,n]=e(t);M.emit("tap",a,n,0),l(0,a,n),o=!0}}),r(h,"mouseup",a=>{if(0===a.button){c(a);let l=t.get(0),[n,r]=e(a);i(l)&&M.emit("tapped",l.xi,l.yi,0),M.emit("untap",n,r,0),t.delete(0),o=!1}}),r(a,"mousemove",t=>{c(t);let[a,l]=e(t);M.def("MX",a),M.def("MY",l),o&&(M.emit("tapping",a,l,0),n(0,a,l))}),r(h,"touchstart",t=>{for(let a of(c(t),t.changedTouches)){let[t,n]=e(a);M.emit("tap",t,n,a.identifier+1),l(a.identifier+1,t,n)}}),r(h,"touchmove",t=>{for(let a of(c(t),t.changedTouches)){let[t,l]=e(a);M.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{c(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)&&M.emit("tapped",l.xi,l.yi,e),M.emit("untap",l.x,l.y,e),t.delete(e))};r(h,"touchend",s),r(h,"touchcancel",s),r(a,"blur",()=>{for(let[e,a]of(o=!1,t))M.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,l=(e,t="")=>(t=s(t))?e.has("space"===t?" ":t):e.size>0,n="";r(a,"keydown",a=>{let l=s(a.key);e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),r(a,"keyup",t=>{e.delete(s(t.key))}),r(a,"blur",()=>e.clear()),M.listen("after:update",()=>t.clear()),M.def("iskeydown",t=>l(e,t)),M.def("iskeypressed",e=>l(t,e)),M.def("lastkey",()=>n)}u=!0,M.emit("init",M),M.resume()}function L(){k=i(L);let e=Date.now(),t=0,a=e-x;for(x=e,b+=a<100?a:y;b>=y;){t++,b-=y;let e=y/1e3*w;M.emit("update",e,t),M.def("T",M.T+e)}t&&(M.emit("draw",g),t>1&&(b=0))}function N(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(M.def("W",e),M.def("H",a),h.width=e,h.height=a,t.autoscale){let n=+t.autoscale;h.style.display||(h.style.display="block",h.style.margin="auto"),m=l.min(innerWidth/e,innerHeight/a),m=n>1&&m>n?n:m,h.style.width=e*m+"px",h.style.height=a*m+"px"}g.imageSmoothingEnabled=!1,M.textalign("start","top"),M.emit("resized",m)}function P(e,t,a,l,n){if(A[e])for(let i of A[e])i(t,a,l,n)}function F(e){return I[~~(D[e]??e)%I.length]}if(t.global){if(a.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(a,M),a.ENGINE=M}return g=(h=(h="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),r(h,"click",()=>focus()),N(),h.parentNode||document.body.appendChild(h),h.style.imageRendering="pixelated",h.oncontextmenu=()=>!1,"loading"===document.readyState?r(a,"DOMContentLoaded",()=>i(C)):k=i(C),M}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.99.0",
|
|
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>",
|
package/src/index.js
CHANGED
|
@@ -48,6 +48,8 @@ export default function litecanvas(settings = {}) {
|
|
|
48
48
|
|
|
49
49
|
let /** @type {boolean} */
|
|
50
50
|
_initialized = false,
|
|
51
|
+
/** @type {boolean} */
|
|
52
|
+
_paused = true,
|
|
51
53
|
/** @type {HTMLCanvasElement} _canvas */
|
|
52
54
|
_canvas,
|
|
53
55
|
/** @type {number} */
|
|
@@ -1056,6 +1058,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1056
1058
|
'string' === typeof eventName,
|
|
1057
1059
|
'[litecanvas] emit() 1st param must be a string'
|
|
1058
1060
|
)
|
|
1061
|
+
|
|
1059
1062
|
if (_initialized) {
|
|
1060
1063
|
eventName = lowerCase(eventName)
|
|
1061
1064
|
|
|
@@ -1156,7 +1159,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1156
1159
|
},
|
|
1157
1160
|
|
|
1158
1161
|
/**
|
|
1159
|
-
* Returns information about
|
|
1162
|
+
* Returns information about the engine instance.
|
|
1160
1163
|
*
|
|
1161
1164
|
* @param {number|string} index
|
|
1162
1165
|
* @returns {any}
|
|
@@ -1190,8 +1193,10 @@ export default function litecanvas(settings = {}) {
|
|
|
1190
1193
|
_rngSeed,
|
|
1191
1194
|
// 10
|
|
1192
1195
|
_fontSize,
|
|
1193
|
-
//
|
|
1196
|
+
// 11
|
|
1194
1197
|
_fontFamily,
|
|
1198
|
+
// 12
|
|
1199
|
+
_colorPaletteState,
|
|
1195
1200
|
]
|
|
1196
1201
|
|
|
1197
1202
|
const data = { index, value: internals[index] }
|
|
@@ -1202,49 +1207,24 @@ export default function litecanvas(settings = {}) {
|
|
|
1202
1207
|
return data.value
|
|
1203
1208
|
},
|
|
1204
1209
|
|
|
1205
|
-
/**
|
|
1206
|
-
* Stops the litecanvas instance and remove all event listeners.
|
|
1207
|
-
*/
|
|
1208
|
-
quit() {
|
|
1209
|
-
// stop the game loop (update & draw)
|
|
1210
|
-
instance.pause()
|
|
1211
|
-
|
|
1212
|
-
// emit "quit" event to manual clean ups
|
|
1213
|
-
instance.emit('quit')
|
|
1214
|
-
|
|
1215
|
-
// clear all engine event listeners
|
|
1216
|
-
_eventListeners = {}
|
|
1217
|
-
|
|
1218
|
-
// clear all browser event listeners
|
|
1219
|
-
for (const removeListener of _browserEventListeners) {
|
|
1220
|
-
removeListener()
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
// maybe clear global context
|
|
1224
|
-
if (settings.global) {
|
|
1225
|
-
for (const key in instance) {
|
|
1226
|
-
delete root[key]
|
|
1227
|
-
}
|
|
1228
|
-
delete root.ENGINE
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
// unset that flag
|
|
1232
|
-
_initialized = false
|
|
1233
|
-
},
|
|
1234
|
-
|
|
1235
1210
|
/**
|
|
1236
1211
|
* Pauses the engine loop (update & draw).
|
|
1237
1212
|
*/
|
|
1238
1213
|
pause() {
|
|
1214
|
+
_paused = true
|
|
1239
1215
|
cancelAnimationFrame(_rafid)
|
|
1240
|
-
_rafid = 0
|
|
1241
1216
|
},
|
|
1242
1217
|
|
|
1243
1218
|
/**
|
|
1244
1219
|
* Resumes (if paused) the engine loop.
|
|
1245
1220
|
*/
|
|
1246
1221
|
resume() {
|
|
1247
|
-
|
|
1222
|
+
DEV: assert(
|
|
1223
|
+
_initialized,
|
|
1224
|
+
'[litecanvas] resume() cannot be called before the "init" event and neither after the quit() function'
|
|
1225
|
+
)
|
|
1226
|
+
if (_initialized && _paused) {
|
|
1227
|
+
_paused = false
|
|
1248
1228
|
_accumulated = _fpsInterval
|
|
1249
1229
|
_lastFrameTime = Date.now()
|
|
1250
1230
|
_rafid = raf(drawFrame)
|
|
@@ -1257,7 +1237,39 @@ export default function litecanvas(settings = {}) {
|
|
|
1257
1237
|
* @returns {boolean}
|
|
1258
1238
|
*/
|
|
1259
1239
|
paused() {
|
|
1260
|
-
return
|
|
1240
|
+
return _paused
|
|
1241
|
+
},
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Shutdown the litecanvas instance and remove all event listeners.
|
|
1245
|
+
*/
|
|
1246
|
+
quit() {
|
|
1247
|
+
// emit "quit" event to manual clean ups
|
|
1248
|
+
instance.emit('quit')
|
|
1249
|
+
|
|
1250
|
+
// stop the game loop (update & draw)
|
|
1251
|
+
instance.pause()
|
|
1252
|
+
|
|
1253
|
+
// deinitialize the engine
|
|
1254
|
+
_initialized = false
|
|
1255
|
+
|
|
1256
|
+
// clear all engine event listeners
|
|
1257
|
+
_eventListeners = {}
|
|
1258
|
+
|
|
1259
|
+
// clear all browser event listeners
|
|
1260
|
+
for (const removeListener of _browserEventListeners) {
|
|
1261
|
+
removeListener()
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
// maybe clear global context
|
|
1265
|
+
if (settings.global) {
|
|
1266
|
+
for (const key in instance) {
|
|
1267
|
+
delete root[key]
|
|
1268
|
+
}
|
|
1269
|
+
delete root.ENGINE
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
DEV: console.warn('[litecanvas] quit() terminated a Litecanvas instance.')
|
|
1261
1273
|
},
|
|
1262
1274
|
}
|
|
1263
1275
|
|
|
@@ -1713,7 +1725,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1713
1725
|
if ('loading' === document.readyState) {
|
|
1714
1726
|
on(root, 'DOMContentLoaded', () => raf(init))
|
|
1715
1727
|
} else {
|
|
1716
|
-
raf(init)
|
|
1728
|
+
_rafid = raf(init)
|
|
1717
1729
|
}
|
|
1718
1730
|
|
|
1719
1731
|
return instance
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.99.0'
|
package/types/global.d.ts
CHANGED
|
@@ -583,9 +583,9 @@ declare global {
|
|
|
583
583
|
*/
|
|
584
584
|
function framerate(fps: number): void
|
|
585
585
|
/**
|
|
586
|
-
* Returns information about
|
|
586
|
+
* Returns information about the engine instance.
|
|
587
587
|
*
|
|
588
|
-
* - n = 0: the settings passed to
|
|
588
|
+
* - n = 0: the settings passed to this instance
|
|
589
589
|
* - n = 1: returns true if the "init" event has already been emitted
|
|
590
590
|
* - n = 2: the current delta time (dt)
|
|
591
591
|
* - n = 3: the current canvas element scale (not the context 2D scale)
|
|
@@ -597,15 +597,12 @@ declare global {
|
|
|
597
597
|
* - n = 9: the current RNG state
|
|
598
598
|
* - n = 10: the current font size
|
|
599
599
|
* - n = 11: the current font family
|
|
600
|
+
* - n = 12: the current state of the color palette
|
|
600
601
|
* - n = *any other value*: probably returns undefined
|
|
601
602
|
*
|
|
602
|
-
* @param
|
|
603
|
+
* @param index
|
|
603
604
|
*/
|
|
604
|
-
function stat(
|
|
605
|
-
/**
|
|
606
|
-
* Shutdown the litecanvas instance and remove all event listeners.
|
|
607
|
-
*/
|
|
608
|
-
function quit(): void
|
|
605
|
+
function stat(index: number | string): any
|
|
609
606
|
/**
|
|
610
607
|
* Pauses the engine loop (update & draw).
|
|
611
608
|
*/
|
|
@@ -618,4 +615,8 @@ declare global {
|
|
|
618
615
|
* Returns `true` if the engine loop is paused.
|
|
619
616
|
*/
|
|
620
617
|
function paused(): boolean
|
|
618
|
+
/**
|
|
619
|
+
* Shutdown the litecanvas instance and remove all event listeners.
|
|
620
|
+
*/
|
|
621
|
+
function quit(): void
|
|
621
622
|
}
|
package/types/types.d.ts
CHANGED
|
@@ -573,9 +573,9 @@ type LitecanvasInstance = {
|
|
|
573
573
|
*/
|
|
574
574
|
framerate(fps: number): void
|
|
575
575
|
/**
|
|
576
|
-
* Returns information about
|
|
576
|
+
* Returns information about the engine instance.
|
|
577
577
|
*
|
|
578
|
-
* - n = 0: the settings passed to
|
|
578
|
+
* - n = 0: the settings passed to this instance
|
|
579
579
|
* - n = 1: returns true if the "init" event has already been emitted
|
|
580
580
|
* - n = 2: the current delta time (dt)
|
|
581
581
|
* - n = 3: the current canvas element scale (not the context 2D scale)
|
|
@@ -587,15 +587,12 @@ type LitecanvasInstance = {
|
|
|
587
587
|
* - n = 9: the current RNG state
|
|
588
588
|
* - n = 10: the current font size
|
|
589
589
|
* - n = 11: the current font family
|
|
590
|
+
* - n = 12: the current state of the color palette
|
|
590
591
|
* - n = *any other value*: probably returns undefined
|
|
591
592
|
*
|
|
592
|
-
* @param
|
|
593
|
+
* @param index
|
|
593
594
|
*/
|
|
594
|
-
stat(
|
|
595
|
-
/**
|
|
596
|
-
* Stops the litecanvas instance and remove all event listeners.
|
|
597
|
-
*/
|
|
598
|
-
quit(): void
|
|
595
|
+
stat(index: number | string): any
|
|
599
596
|
/**
|
|
600
597
|
* Pauses the engine loop (update & draw).
|
|
601
598
|
*/
|
|
@@ -608,6 +605,10 @@ type LitecanvasInstance = {
|
|
|
608
605
|
* Returns `true` if the engine loop is paused.
|
|
609
606
|
*/
|
|
610
607
|
paused(): boolean
|
|
608
|
+
/**
|
|
609
|
+
* Shutdown the litecanvas instance and remove all event listeners.
|
|
610
|
+
*/
|
|
611
|
+
quit(): void
|
|
611
612
|
}
|
|
612
613
|
|
|
613
614
|
type LitecanvasOptions = {
|