litecanvas 0.401.0 → 0.402.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 +49 -30
- package/dist/dist.js +32 -13
- package/dist/dist.min.js +1 -1
- package/package.json +3 -3
- package/src/index.js +52 -55
- package/src/mulberry32.js +21 -0
- package/src/version.js +1 -1
- package/types/global.d.ts +4 -5
- package/types/types.d.ts +7 -6
package/dist/dist.dev.js
CHANGED
|
@@ -115,7 +115,15 @@
|
|
|
115
115
|
var assert = (condition, message = "Assertion failed") => {
|
|
116
116
|
if (!condition) throw new Error("[Litecanvas] " + message);
|
|
117
117
|
};
|
|
118
|
-
var version = "0.
|
|
118
|
+
var version = "0.402.0";
|
|
119
|
+
var mulberry32 = (seed) => {
|
|
120
|
+
return () => {
|
|
121
|
+
let t = (seed += 1831565813);
|
|
122
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
123
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
124
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
119
127
|
function litecanvas(settings = {}) {
|
|
120
128
|
const root = window,
|
|
121
129
|
math = Math,
|
|
@@ -166,6 +174,7 @@
|
|
|
166
174
|
_fontSize = 20,
|
|
167
175
|
_fontLineHeight = 1.2,
|
|
168
176
|
_rngSeed = Date.now(),
|
|
177
|
+
_rngNext = mulberry32(_rngSeed >>> 0),
|
|
169
178
|
_currentPalette = defaultPalette,
|
|
170
179
|
_lastPalette = defaultPalette,
|
|
171
180
|
_colorPaletteState = [],
|
|
@@ -177,6 +186,32 @@
|
|
|
177
186
|
T: 0,
|
|
178
187
|
MX: -1,
|
|
179
188
|
MY: -1,
|
|
189
|
+
rand: (min = 0, max = 1) => {
|
|
190
|
+
DEV: assert(isNumber(min), "rand() 1st argument must be a number");
|
|
191
|
+
DEV: assert(isNumber(max), "rand() 2nd argument must be a number");
|
|
192
|
+
DEV: assert(
|
|
193
|
+
max >= min,
|
|
194
|
+
"rand() the 1st argument must be less than the 2nd argument",
|
|
195
|
+
);
|
|
196
|
+
return min + _rngNext() * (max - min);
|
|
197
|
+
},
|
|
198
|
+
randi: (min = 0, max = 1) => {
|
|
199
|
+
DEV: assert(isNumber(min), "randi() 1st argument must be a number");
|
|
200
|
+
DEV: assert(isNumber(max), "randi() 2nd argument must be a number");
|
|
201
|
+
DEV: assert(
|
|
202
|
+
max >= min,
|
|
203
|
+
"randi() the 1st argument must be less than the 2nd argument",
|
|
204
|
+
);
|
|
205
|
+
return ~~instance.rand(min, max + 1);
|
|
206
|
+
},
|
|
207
|
+
rseed(value) {
|
|
208
|
+
DEV: assert(
|
|
209
|
+
isNumber(value) && value >= 0,
|
|
210
|
+
"rseed() 1st argument must be a non-negative integer",
|
|
211
|
+
);
|
|
212
|
+
_rngSeed = value;
|
|
213
|
+
_rngNext = mulberry32(_rngSeed >>> 0);
|
|
214
|
+
},
|
|
180
215
|
TAU,
|
|
181
216
|
lerp: (start, end, t) => {
|
|
182
217
|
DEV: assert(isNumber(start), "lerp() 1st argument must be a number");
|
|
@@ -265,35 +300,6 @@
|
|
|
265
300
|
);
|
|
266
301
|
return instance.map(value, start, stop, 0, 1);
|
|
267
302
|
},
|
|
268
|
-
rand: (min = 0, max = 1) => {
|
|
269
|
-
DEV: assert(isNumber(min), "rand() 1st argument must be a number");
|
|
270
|
-
DEV: assert(isNumber(max), "rand() 2nd argument must be a number");
|
|
271
|
-
DEV: assert(
|
|
272
|
-
max >= min,
|
|
273
|
-
"rand() the 1st argument must be less than the 2nd argument",
|
|
274
|
-
);
|
|
275
|
-
const a = 1664525;
|
|
276
|
-
const c = 1013904223;
|
|
277
|
-
const m = 4294967296;
|
|
278
|
-
_rngSeed = (a * _rngSeed + c) % m;
|
|
279
|
-
return (_rngSeed / m) * (max - min) + min;
|
|
280
|
-
},
|
|
281
|
-
randi: (min = 0, max = 1) => {
|
|
282
|
-
DEV: assert(isNumber(min), "randi() 1st argument must be a number");
|
|
283
|
-
DEV: assert(isNumber(max), "randi() 2nd argument must be a number");
|
|
284
|
-
DEV: assert(
|
|
285
|
-
max >= min,
|
|
286
|
-
"randi() the 1st argument must be less than the 2nd argument",
|
|
287
|
-
);
|
|
288
|
-
return ~~instance.rand(min, max + 1);
|
|
289
|
-
},
|
|
290
|
-
rseed(value) {
|
|
291
|
-
DEV: assert(
|
|
292
|
-
isNumber(value) && value >= 0,
|
|
293
|
-
"rseed() 1st argument must be a non-negative integer",
|
|
294
|
-
);
|
|
295
|
-
_rngSeed = ~~value;
|
|
296
|
-
},
|
|
297
303
|
cls(color) {
|
|
298
304
|
DEV: assert(
|
|
299
305
|
null == color ||
|
|
@@ -1221,3 +1227,16 @@
|
|
|
1221
1227
|
}
|
|
1222
1228
|
window.litecanvas = litecanvas;
|
|
1223
1229
|
})();
|
|
1230
|
+
/**
|
|
1231
|
+
* Mulberry32 is a 32-bit pseudo-random number generator (PRNG).
|
|
1232
|
+
* You provide a 32-bit seed, and it produces a deterministic sequence of values.
|
|
1233
|
+
* The same seed always gives the same sequence.
|
|
1234
|
+
*
|
|
1235
|
+
* @copyright https://gist.github.com/tommyettinger/46a874533244883189143505d203312c
|
|
1236
|
+
* @license CC0-1.0 (Public Domain)
|
|
1237
|
+
*
|
|
1238
|
+
* @param {number} seed an unsigned 32-bit integer
|
|
1239
|
+
* @param {number} t
|
|
1240
|
+
* @param {typeof Math.imul} i
|
|
1241
|
+
* @returns {() => number}
|
|
1242
|
+
*/
|
package/dist/dist.js
CHANGED
|
@@ -112,6 +112,14 @@
|
|
|
112
112
|
};
|
|
113
113
|
};
|
|
114
114
|
var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"];
|
|
115
|
+
var mulberry32 = (seed) => {
|
|
116
|
+
return () => {
|
|
117
|
+
let t = (seed += 1831565813);
|
|
118
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
119
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
120
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
115
123
|
function litecanvas(settings = {}) {
|
|
116
124
|
const root = window,
|
|
117
125
|
math = Math,
|
|
@@ -158,6 +166,7 @@
|
|
|
158
166
|
_fontSize = 20,
|
|
159
167
|
_fontLineHeight = 1.2,
|
|
160
168
|
_rngSeed = Date.now(),
|
|
169
|
+
_rngNext = mulberry32(_rngSeed >>> 0),
|
|
161
170
|
_currentPalette = defaultPalette,
|
|
162
171
|
_lastPalette = defaultPalette,
|
|
163
172
|
_colorPaletteState = [],
|
|
@@ -169,6 +178,16 @@
|
|
|
169
178
|
T: 0,
|
|
170
179
|
MX: -1,
|
|
171
180
|
MY: -1,
|
|
181
|
+
rand: (min = 0, max = 1) => {
|
|
182
|
+
return min + _rngNext() * (max - min);
|
|
183
|
+
},
|
|
184
|
+
randi: (min = 0, max = 1) => {
|
|
185
|
+
return ~~instance.rand(min, max + 1);
|
|
186
|
+
},
|
|
187
|
+
rseed(value) {
|
|
188
|
+
_rngSeed = value;
|
|
189
|
+
_rngNext = mulberry32(_rngSeed >>> 0);
|
|
190
|
+
},
|
|
172
191
|
TAU,
|
|
173
192
|
lerp: (start, end, t) => {
|
|
174
193
|
return start + t * (end - start);
|
|
@@ -208,19 +227,6 @@
|
|
|
208
227
|
norm: (value, start, stop) => {
|
|
209
228
|
return instance.map(value, start, stop, 0, 1);
|
|
210
229
|
},
|
|
211
|
-
rand: (min = 0, max = 1) => {
|
|
212
|
-
const a = 1664525;
|
|
213
|
-
const c = 1013904223;
|
|
214
|
-
const m = 4294967296;
|
|
215
|
-
_rngSeed = (a * _rngSeed + c) % m;
|
|
216
|
-
return (_rngSeed / m) * (max - min) + min;
|
|
217
|
-
},
|
|
218
|
-
randi: (min = 0, max = 1) => {
|
|
219
|
-
return ~~instance.rand(min, max + 1);
|
|
220
|
-
},
|
|
221
|
-
rseed(value) {
|
|
222
|
-
_rngSeed = ~~value;
|
|
223
|
-
},
|
|
224
230
|
cls(color) {
|
|
225
231
|
if (null == color) {
|
|
226
232
|
_ctx.clearRect(0, 0, instance.W, instance.H);
|
|
@@ -754,3 +760,16 @@
|
|
|
754
760
|
}
|
|
755
761
|
window.litecanvas = litecanvas;
|
|
756
762
|
})();
|
|
763
|
+
/**
|
|
764
|
+
* Mulberry32 is a 32-bit pseudo-random number generator (PRNG).
|
|
765
|
+
* You provide a 32-bit seed, and it produces a deterministic sequence of values.
|
|
766
|
+
* The same seed always gives the same sequence.
|
|
767
|
+
*
|
|
768
|
+
* @copyright https://gist.github.com/tommyettinger/46a874533244883189143505d203312c
|
|
769
|
+
* @license CC0-1.0 (Public Domain)
|
|
770
|
+
*
|
|
771
|
+
* @param {number} seed an unsigned 32-bit integer
|
|
772
|
+
* @param {number} t
|
|
773
|
+
* @param {typeof Math.imul} i
|
|
774
|
+
* @returns {() => number}
|
|
775
|
+
*/
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(
|
|
1
|
+
(()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"],t=e=>()=>{let t=e+=0x6d2b79f5;return t=Math.imul(t^t>>>15,1|t),(((t^=t+Math.imul(t^t>>>7,61|t))^t>>>14)>>>0)/0x100000000};window.litecanvas=function(a={}){let n,l=window,i=Math,o=performance,r=2*i.PI,s=requestAnimationFrame,f=[],d=(e,t,a)=>{e.addEventListener(t,a,!1),f.push(()=>e.removeEventListener(t,a,!1))},c=(l.zzfxX=new AudioContext,l.zzfxV=1,(e=1,t=.05,a=220,n=0,l=0,i=.1,o=0,r=1,s=0,f=0,d=0,c=0,p=0,u=0,h=0,m=0,g=0,w=1,x=0,y=0,v=0)=>{let b=Math,z=2*b.PI,k=s*=500*z/44100/44100,C=a*=(1-t+2*t*b.random(t=[]))*z/44100,E=0,P=0,I=0,T=1,L=0,M=0,S=0,A=v<0?-1:1,N=z*A*v*2/44100,W=b.cos(N),X=b.sin,H=X(N)/4,q=1+H,B=-2*W/q,V=(1-H)/q,D=(1+A*W)/2/q,O=-(A+W)/q,G=0,R=0,Y=0,$=0;for(n=44100*n+9,x*=44100,l*=44100,i*=44100,g*=44100,f*=500*z/85766121e6,h*=z/44100,d*=z/44100,c*=44100,p=44100*p|0,e*=.3*zzfxV,A=n+x+l+i+g|0;I<A;t[I++]=S*e)++M%(100*m|0)||(S=o?1<o?2<o?3<o?X(E*E):b.max(b.min(b.tan(E),1),-1):1-(2*E/z%2+2)%2:1-4*b.abs(b.round(E/z)-E/z):X(E),S=(p?1-y+y*X(z*I/p):1)*(S<0?-1:1)*b.abs(S)**r*(I<n?I/n:I<n+x?1-(I-n)/x*(1-w):I<n+x+l?w:I<A-g?(A-I-g)/i*w:0),S=g?S/2+(g>I?0:(I<A-g?1:(A-I)/g)*t[I-g|0]/2/e):S,v&&(S=$=D*G+O*(G=R)+D*(R=S)-V*Y-B*(Y=$))),E+=(N=(a+=s+=f)*b.cos(h*P++))+N*u*X(I**5),T&&++T>c&&(a+=d,C+=d,T=0),!p||++L%p||(a=C,s=k,T=T||1);(e=zzfxX.createBuffer(1,A,44100)).getChannelData(0).set(t),(a=zzfxX.createBufferSource()).buffer=e,a.connect(zzfxX.destination),a.start()}),p=(a=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},a)).loop,u,h,m,g=1,w,x=.5,y=1,v,b=1e3/60,z,k=0,C=3,E="sans-serif",P=20,I=1.2,T=Date.now(),L=t(T>>>0),M=e,S=e,A=[],N=[.5,0,1750,,,.3,1,,,,600,.1],W={},X={W:0,H:0,T:0,MX:-1,MY:-1,rand:(e=0,t=1)=>e+L()*(t-e),randi:(e=0,t=1)=>~~X.rand(e,t+1),rseed(e){L=t((T=e)>>>0)},TAU:r,lerp:(e,t,a)=>e+a*(t-e),deg2rad:e=>i.PI/180*e,rad2deg:e=>180/i.PI*e,mod:(e,t)=>(e%t+t)%t||0,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,dist:(e,t,a,n)=>i.hypot(a-e,n-t),wrap:(e,t,a)=>e-(a-t)*i.floor((e-t)/(a-t)),map(e,t,a,n,l,i){let o=(e-t)/(a-t)*(l-n)+n;return i?X.clamp(o,n,l):o},norm:(e,t,a)=>X.map(e,t,a,0,1),cls(e){null==e?w.clearRect(0,0,X.W,X.H):X.rectfill(0,0,X.W,X.H,e)},rect(e,t,a,n,l,i){w.beginPath(),w[i?"roundRect":"rect"](~~e-x,~~t-x,~~a+2*x,~~n+2*x,i),X.stroke(l)},rectfill(e,t,a,n,l,i){w.beginPath(),w[i?"roundRect":"rect"](~~e,~~t,~~a,~~n,i),X.fill(l)},oval(e,t,a,n,l){w.beginPath(),w.ellipse(~~e,~~t,~~a,~~n,0,0,r),X.stroke(l)},ovalfill(e,t,a,n,l){w.beginPath(),w.ellipse(~~e,~~t,~~a,~~n,0,0,r),X.fill(l)},circ(e,t,a,n){X.oval(e,t,a,a,n)},circfill(e,t,a,n){X.ovalfill(e,t,a,a,n)},shape(e){w.beginPath();for(let t=0;t<e.length;t+=2)t?w.lineTo(~~e[t],~~e[t+1]):w.moveTo(~~e[t],~~e[t+1]);w.lineTo(~~e[0],~~e[1])},line(e,t,a,n,l){w.beginPath();let i=x&&~~e==~~a?.5:0,o=x&&~~t==~~n?.5:0;w.moveTo(~~e+i,~~t+o),w.lineTo(~~a+i,~~n+o),X.stroke(l)},linewidth(e){w.lineWidth=~~e,x=~~e%2?.5:0},linedash(e,t=0){w.setLineDash(e),w.lineDashOffset=t},text(e,t,a,n=C,l="normal"){w.font=`${l} ${P}px ${E}`,w.fillStyle=D(n);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)w.fillText(i[a],~~e,~~t+P*I*a)},textgap(e){I=e},textfont(e){E=e},textsize(e){P=e},textalign(e,t){e&&(w.textAlign=e),t&&(w.textBaseline=t)},image(e,t,a){w.drawImage(a,~~e,~~t)},spr(e,t,a){let n=a.replace(/[^\w.\n]/g,"").split("\n").filter(e=>e);for(let a=0;a<n.length;a++)for(let l=0;l<n[a].length;l++)"."!==n[a][l]&&X.rectfill(e+l,t+a,1,1,parseInt(n[a][l],36)||0)},paint(e,t,a,n={}){let l=n.canvas||new OffscreenCanvas(1,1),i=n.scale||1,o=w;return l.width=e*i,l.height=t*i,(w=l.getContext("2d")).scale(i,i),a(w),w=o,l.transferToImageBitmap()},ctx:e=>(e&&(w=e),w),push(e=0,t=e,a=0,n=1,l=n){w.save(),X.translate(e,t),X.rotate(a),X.scale(n,l)},pop(){w.restore()},translate(e,t){w.translate(~~e,~~t)},scale(e,t=e){w.scale(e,t)},rotate(e){w.rotate(e)},alpha(e){w.globalAlpha=X.clamp(e,0,1)},fill(e){w.fillStyle=D(e),w.fill()},stroke(e){w.strokeStyle=D(e),w.stroke()},clip(e){w.beginPath(),e(w),w.clip()},sfx:(e,t,a)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e||=N,(t||a>=0)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),c.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>m,use(e,t={}){var a=e,n=t;let l=a(X,n);for(let e in l)X.def(e,l[e])},resize(e,t=e,n){a.width=e,a.height=t,a.autoscale=null==n?a.autoscale:n,B()},listen:(e,t)=>{W[e=e.toLowerCase()]=W[e]||new Set,W[e].add(t)},unlisten:(e,t)=>{W[e=e.toLowerCase()]&&W[e].delete(t)},emit:(e,t,a,n,i)=>(u&&(V("before:"+(e=e.toLowerCase()),t,a,n,i),p||l[e]===X[e]||"function"!=typeof l[e]||l[e](t,a,n,i),V(e,t,a,n,i),V("after:"+e,t,a,n,i)),t),pal(e,t=3){null==e?M=S:(S=M,M=e),A=[],C=t,X.emit("pal",M,C)},palc(e,t){null==e?A=[]:A[e]=t},def(e,t){X[e]=t,a.global&&(l[e]=t)},timescale(e){y=e},framerate(e){b=1e3/~~e},stat:e=>[a,u,b/1e3,g,W,M,N,y,l.zzfxV,T,P,E,A,I][e],ispaused:()=>h,pause(){h||(h=!0,k=~~cancelAnimationFrame(k),X.emit("paused"))},resume(){u&&h&&(H(),h=!1,X.emit("resumed"))},quit(){for(let e of(X.emit("quit"),X.pause(),u=!1,W={},f))e();if(a.global){for(let e in X)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,min,max,pow,sqrt,sign".split(","))X[e]=i[e];function H(){k||(z=0,v=o.now(),k=s(q))}function q(){k=s(q);let e=o.now(),t=0,a=e-v;for(v=e,z+=a<100?a:b;z>=b;){t++,z-=b;let e=b/1e3*y;X.emit("update",e,t),X.def("T",X.T+e)}t&&(X.emit("draw",w),t>1&&(z=0))}function B(){let e=a.width>0?a.width:innerWidth,t=a.width>0?a.height||a.width:innerHeight;if(X.def("W",e),X.def("H",t),m.width=e,m.height=t,m.style="image-rendering:pixelated;touch-action:none",a.autoscale){let n=+a.autoscale;m.style.display||(m.style.display="block",m.style.margin="auto"),g=i.min(innerWidth/e,innerHeight/t),g=n>1&&g>n?n:g,m.style.width=e*g+"px",m.style.height=t*g+"px"}w.imageSmoothingEnabled=!1,X.textalign("start","top"),X.emit("resized",g)}function V(e,t,a,n,l){if(W[e])for(let i of W[e])i(t,a,n,l)}function D(e){return e>=0?M[~~(A[e]??e)%M.length]:e}if(a.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,X),l.ENGINE=X}if(n=document,w=(m=(m="string"==typeof a.canvas?n.querySelector(a.canvas):a.canvas)||n.createElement("canvas")).getContext("2d"),d(m,"click",()=>focus()),m.parentNode||n.body.appendChild(m),m.oncontextmenu=()=>!1,B(),p)for(let e in p)p[e]&&X.listen(e,p[e]);return s(function(){if(a.autoscale&&d(l,"resize",B),a.tapEvents){let e=e=>[(e.pageX-m.offsetLeft)/g,(e.pageY-m.offsetTop)/g],t=new Map,a=(e,a,n)=>{let l={x:a,y:n,xi:a,yi:n,t:o.now()};return t.set(e,l),l},n=!1;d(m,"pointerdown",t=>{let[l,i]=e(t);if("mouse"===t.pointerType){if(t.button)return;n=!0}let o=t.pointerId;a(o,l,i),X.emit("tap",l,i,o),m.setPointerCapture(o)}),d(m,"pointermove",l=>{let[i,o]=e(l);if("mouse"===l.pointerType&&(X.def("MX",i),X.def("MY",o),!n))return;let r=l.pointerId;if(t.get(r)){let e;X.emit("tapping",i,o,r),(e=t.get(r)||a(r)).x=i,e.y=o}});let i=a=>{let l=a.pointerId,i=t.get(l),[r,s]=e(a);if(i){if("mouse"===a.pointerType){if(a.button)return;n=!1}i&&o.now()-i.t<=300&&X.emit("tapped",i.xi,i.yi,l),X.emit("untap",r,s,l),t.delete(l),m.releasePointerCapture(l)}};d(m,"pointerup",i),d(m,"pointercancel",i),d(l,"blur",()=>{for(let[e,a]of(n=!1,t)){X.emit("untap",a.x,a.y,e),t.delete(e);try{m.releasePointerCapture(e)}catch(e){}}})}if(a.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";d(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),d(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),d(l,"blur",()=>e.clear()),X.listen("after:update",()=>t.clear()),X.def("iskeydown",t=>a(e,t)),X.def("iskeypressed",e=>a(t,e)),X.def("lastkey",()=>n)}u=!0,X.emit("init",X),h||H()}),X}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.402.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>",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"creative coding"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@happy-dom/global-registrator": "^21.0.
|
|
35
|
+
"@happy-dom/global-registrator": "^21.0.3",
|
|
36
36
|
"@size-limit/preset-small-lib": "^14.2.0",
|
|
37
37
|
"@swc/core": "^1.16.18",
|
|
38
|
-
"ava": "^8.0
|
|
38
|
+
"ava": "^8.1.0",
|
|
39
39
|
"esbuild": "^0.28.2",
|
|
40
40
|
"genversion": "^3.2.0",
|
|
41
41
|
"gzip-size": "^7.0.0",
|
package/src/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { setupZzFX } from './zzfx.js'
|
|
|
3
3
|
import { defaultPalette } from './palette.js'
|
|
4
4
|
import { assert } from './dev.js'
|
|
5
5
|
import { version } from './version.js'
|
|
6
|
+
import { mulberry32 } from './mulberry32.js'
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* The litecanvas constructor
|
|
@@ -84,13 +85,15 @@ export default function litecanvas(settings = {}) {
|
|
|
84
85
|
_fontLineHeight = 1.2,
|
|
85
86
|
/** @type {number} */
|
|
86
87
|
_rngSeed = Date.now(),
|
|
88
|
+
/** @type {() => number} */
|
|
89
|
+
_rngNext = mulberry32(_rngSeed >>> 0),
|
|
87
90
|
/** @type {string[]} */
|
|
88
91
|
_currentPalette = defaultPalette,
|
|
89
92
|
/** @type {string[]} */
|
|
90
93
|
_lastPalette = defaultPalette,
|
|
91
94
|
/** @type {number[]} */
|
|
92
95
|
_colorPaletteState = [],
|
|
93
|
-
/** @type {number[]} */
|
|
96
|
+
/** @type {(number|undefined)[]} */
|
|
94
97
|
_defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
95
98
|
/**
|
|
96
99
|
* @type {Object<string,Set<Function>>} game event listeners
|
|
@@ -114,6 +117,54 @@ export default function litecanvas(settings = {}) {
|
|
|
114
117
|
/** @type {number} */
|
|
115
118
|
MY: -1,
|
|
116
119
|
|
|
120
|
+
/** RNG API */
|
|
121
|
+
/**
|
|
122
|
+
* Generates a pseudo random float between min (inclusive) and max (exclusive)
|
|
123
|
+
* using the Mulberry32 algorithm.
|
|
124
|
+
*
|
|
125
|
+
* @param {number} [min=0.0]
|
|
126
|
+
* @param {number} [max=1.0]
|
|
127
|
+
* @returns {number} the random number
|
|
128
|
+
*/
|
|
129
|
+
rand: (min = 0.0, max = 1.0) => {
|
|
130
|
+
DEV: assert(isNumber(min), 'rand() 1st argument must be a number')
|
|
131
|
+
DEV: assert(isNumber(max), 'rand() 2nd argument must be a number')
|
|
132
|
+
DEV: assert(max >= min, 'rand() the 1st argument must be less than the 2nd argument')
|
|
133
|
+
|
|
134
|
+
return min + _rngNext() * (max - min)
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Generates a pseudo random integer between min (inclusive) and max (inclusive).
|
|
139
|
+
*
|
|
140
|
+
* @param {number} [min=0]
|
|
141
|
+
* @param {number} [max=1]
|
|
142
|
+
* @returns {number} the random number
|
|
143
|
+
*/
|
|
144
|
+
randi: (min = 0, max = 1) => {
|
|
145
|
+
DEV: assert(isNumber(min), 'randi() 1st argument must be a number')
|
|
146
|
+
DEV: assert(isNumber(max), 'randi() 2nd argument must be a number')
|
|
147
|
+
DEV: assert(max >= min, 'randi() the 1st argument must be less than the 2nd argument')
|
|
148
|
+
|
|
149
|
+
return ~~instance.rand(min, max + 1)
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Initializes the random number generator with an explicit seed value.
|
|
154
|
+
*
|
|
155
|
+
* Note: The seed should be a integer number greater than or equal to zero.
|
|
156
|
+
*
|
|
157
|
+
* @param {number} value
|
|
158
|
+
*/
|
|
159
|
+
rseed(value) {
|
|
160
|
+
DEV: assert(
|
|
161
|
+
isNumber(value) && value >= 0,
|
|
162
|
+
'rseed() 1st argument must be a non-negative integer'
|
|
163
|
+
)
|
|
164
|
+
_rngSeed = value
|
|
165
|
+
_rngNext = mulberry32(_rngSeed >>> 0)
|
|
166
|
+
},
|
|
167
|
+
|
|
117
168
|
/** MATH API */
|
|
118
169
|
/**
|
|
119
170
|
* Twice the value of the mathematical constant PI (π).
|
|
@@ -306,60 +357,6 @@ export default function litecanvas(settings = {}) {
|
|
|
306
357
|
return instance.map(value, start, stop, 0, 1)
|
|
307
358
|
},
|
|
308
359
|
|
|
309
|
-
/** RNG API */
|
|
310
|
-
/**
|
|
311
|
-
* Generates a pseudorandom float between min (inclusive) and max (exclusive)
|
|
312
|
-
* using the Linear Congruential Generator (LCG) algorithm.
|
|
313
|
-
*
|
|
314
|
-
* @param {number} [min=0.0]
|
|
315
|
-
* @param {number} [max=1.0]
|
|
316
|
-
* @returns {number} the random number
|
|
317
|
-
*/
|
|
318
|
-
rand: (min = 0.0, max = 1.0) => {
|
|
319
|
-
DEV: assert(isNumber(min), 'rand() 1st argument must be a number')
|
|
320
|
-
DEV: assert(isNumber(max), 'rand() 2nd argument must be a number')
|
|
321
|
-
DEV: assert(max >= min, 'rand() the 1st argument must be less than the 2nd argument')
|
|
322
|
-
|
|
323
|
-
const a = 1664525
|
|
324
|
-
const c = 1013904223
|
|
325
|
-
const m = 4294967296
|
|
326
|
-
|
|
327
|
-
_rngSeed = (a * _rngSeed + c) % m
|
|
328
|
-
|
|
329
|
-
return (_rngSeed / m) * (max - min) + min
|
|
330
|
-
},
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Generates a pseudorandom integer between min (inclusive) and max (inclusive)
|
|
334
|
-
*
|
|
335
|
-
* @param {number} [min=0]
|
|
336
|
-
* @param {number} [max=1]
|
|
337
|
-
* @returns {number} the random number
|
|
338
|
-
*/
|
|
339
|
-
randi: (min = 0, max = 1) => {
|
|
340
|
-
DEV: assert(isNumber(min), 'randi() 1st argument must be a number')
|
|
341
|
-
DEV: assert(isNumber(max), 'randi() 2nd argument must be a number')
|
|
342
|
-
DEV: assert(max >= min, 'randi() the 1st argument must be less than the 2nd argument')
|
|
343
|
-
|
|
344
|
-
return ~~instance.rand(min, max + 1)
|
|
345
|
-
},
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Initializes the random number generator with an explicit seed value.
|
|
349
|
-
*
|
|
350
|
-
* Note: The seed should be a integer number greater than or equal to zero.
|
|
351
|
-
*
|
|
352
|
-
* @param {number} value
|
|
353
|
-
*/
|
|
354
|
-
rseed(value) {
|
|
355
|
-
DEV: assert(
|
|
356
|
-
isNumber(value) && value >= 0,
|
|
357
|
-
'rseed() 1st argument must be a non-negative integer'
|
|
358
|
-
)
|
|
359
|
-
|
|
360
|
-
_rngSeed = ~~value
|
|
361
|
-
},
|
|
362
|
-
|
|
363
360
|
/** BASIC GRAPHICS API */
|
|
364
361
|
/**
|
|
365
362
|
* Clear the game screen with an optional color.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mulberry32 is a 32-bit pseudo-random number generator (PRNG).
|
|
3
|
+
* You provide a 32-bit seed, and it produces a deterministic sequence of values.
|
|
4
|
+
* The same seed always gives the same sequence.
|
|
5
|
+
*
|
|
6
|
+
* @copyright https://gist.github.com/tommyettinger/46a874533244883189143505d203312c
|
|
7
|
+
* @license CC0-1.0 (Public Domain)
|
|
8
|
+
*
|
|
9
|
+
* @param {number} seed an unsigned 32-bit integer
|
|
10
|
+
* @param {number} t
|
|
11
|
+
* @param {typeof Math.imul} i
|
|
12
|
+
* @returns {() => number}
|
|
13
|
+
*/
|
|
14
|
+
export const mulberry32 = (seed) => {
|
|
15
|
+
return () => {
|
|
16
|
+
let t = (seed += 0x6d2b79f5)
|
|
17
|
+
t = Math.imul(t ^ (t >>> 15), t | 1)
|
|
18
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61)
|
|
19
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.402.0'
|
package/types/global.d.ts
CHANGED
|
@@ -186,7 +186,8 @@ declare global {
|
|
|
186
186
|
|
|
187
187
|
/** RNG API */
|
|
188
188
|
/**
|
|
189
|
-
* Generates a
|
|
189
|
+
* Generates a pseudo random float between min (inclusive) and max (exclusive)
|
|
190
|
+
* using the Mulberry32 algorithm.
|
|
190
191
|
*
|
|
191
192
|
* @param [min=0.0]
|
|
192
193
|
* @param [max=1.0]
|
|
@@ -194,7 +195,7 @@ declare global {
|
|
|
194
195
|
*/
|
|
195
196
|
function rand(min?: number, max?: number): number
|
|
196
197
|
/**
|
|
197
|
-
* Generates a
|
|
198
|
+
* Generates a pseudo random integer between min (inclusive) and max (inclusive).
|
|
198
199
|
*
|
|
199
200
|
* @param [min=0]
|
|
200
201
|
* @param [max=1]
|
|
@@ -204,9 +205,7 @@ declare global {
|
|
|
204
205
|
/**
|
|
205
206
|
* Initializes the random number generator with an explicit seed value.
|
|
206
207
|
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* @param value
|
|
208
|
+
* @param value the PRNG seed. Must be an non-negative number.
|
|
210
209
|
*/
|
|
211
210
|
function rseed(value: number): void
|
|
212
211
|
|
package/types/types.d.ts
CHANGED
|
@@ -180,7 +180,8 @@ type LitecanvasInstance = {
|
|
|
180
180
|
|
|
181
181
|
/** RNG API */
|
|
182
182
|
/**
|
|
183
|
-
* Generates a
|
|
183
|
+
* Generates a pseudo random float between min (inclusive) and max (exclusive)
|
|
184
|
+
* using the Mulberry32 algorithm.
|
|
184
185
|
*
|
|
185
186
|
* @param [min=0.0]
|
|
186
187
|
* @param [max=1.0]
|
|
@@ -188,7 +189,7 @@ type LitecanvasInstance = {
|
|
|
188
189
|
*/
|
|
189
190
|
rand(min?: number, max?: number): number
|
|
190
191
|
/**
|
|
191
|
-
* Generates a
|
|
192
|
+
* Generates a pseudo random integer between min (inclusive) and max (inclusive)
|
|
192
193
|
*
|
|
193
194
|
* @param [min=0]
|
|
194
195
|
* @param [max=1]
|
|
@@ -196,11 +197,11 @@ type LitecanvasInstance = {
|
|
|
196
197
|
*/
|
|
197
198
|
randi(min?: number, max?: number): number
|
|
198
199
|
/**
|
|
199
|
-
*
|
|
200
|
+
* Generates a pseudo random integer between min (inclusive) and max (inclusive).
|
|
200
201
|
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* @
|
|
202
|
+
* @param [min=0]
|
|
203
|
+
* @param [max=1]
|
|
204
|
+
* @returns the random number
|
|
204
205
|
*/
|
|
205
206
|
rseed(value: number): void
|
|
206
207
|
|