litecanvas 0.74.0 → 0.74.2
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 +48 -31
- package/dist/dist.js +48 -31
- package/dist/dist.min.js +1 -1
- package/package.json +3 -3
- package/src/index.js +60 -37
- package/types/index.d.ts +1 -1
- package/types/types.d.ts +1 -1
package/dist/dist.dev.js
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
animate: true
|
|
69
69
|
};
|
|
70
70
|
settings = Object.assign(defaults, settings);
|
|
71
|
-
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,
|
|
71
|
+
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 = {
|
|
72
72
|
init: null,
|
|
73
73
|
update: null,
|
|
74
74
|
draw: null,
|
|
@@ -312,7 +312,7 @@
|
|
|
312
312
|
},
|
|
313
313
|
/** BASIC GRAPHICS API */
|
|
314
314
|
/**
|
|
315
|
-
* Clear the game screen
|
|
315
|
+
* Clear the game screen with an optional color
|
|
316
316
|
*
|
|
317
317
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
318
318
|
*/
|
|
@@ -320,14 +320,19 @@
|
|
|
320
320
|
if (true) {
|
|
321
321
|
assert(
|
|
322
322
|
null == color || isFinite(color) && color >= 0,
|
|
323
|
-
"cls: 1st param must be a number"
|
|
323
|
+
"cls: 1st param must be a positive number or zero or null"
|
|
324
324
|
);
|
|
325
325
|
}
|
|
326
|
-
let width = _ctx.canvas.width, height = _ctx.canvas.height;
|
|
327
326
|
if (null == color) {
|
|
328
|
-
_ctx.clearRect(0, 0, width, height);
|
|
327
|
+
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);
|
|
329
328
|
} else {
|
|
330
|
-
instance.rectfill(
|
|
329
|
+
instance.rectfill(
|
|
330
|
+
0,
|
|
331
|
+
0,
|
|
332
|
+
_ctx.canvas.width,
|
|
333
|
+
_ctx.canvas.height,
|
|
334
|
+
color
|
|
335
|
+
);
|
|
331
336
|
}
|
|
332
337
|
},
|
|
333
338
|
/**
|
|
@@ -593,11 +598,20 @@
|
|
|
593
598
|
textalign(align, baseline) {
|
|
594
599
|
if (true) {
|
|
595
600
|
assert(
|
|
596
|
-
null == align || "
|
|
601
|
+
null == align || ["left", "right", "center", "start", "end"].includes(
|
|
602
|
+
align
|
|
603
|
+
),
|
|
597
604
|
"textalign: 1st param must be a string"
|
|
598
605
|
);
|
|
599
606
|
assert(
|
|
600
|
-
null == baseline ||
|
|
607
|
+
null == baseline || [
|
|
608
|
+
"top",
|
|
609
|
+
"bottom",
|
|
610
|
+
"middle",
|
|
611
|
+
"hanging",
|
|
612
|
+
"alphabetic",
|
|
613
|
+
"ideographic"
|
|
614
|
+
].includes(baseline),
|
|
601
615
|
"textalign: 2nd param must be a string"
|
|
602
616
|
);
|
|
603
617
|
}
|
|
@@ -672,8 +686,8 @@
|
|
|
672
686
|
/**
|
|
673
687
|
* Get or set the canvas context 2D
|
|
674
688
|
*
|
|
675
|
-
* @param {CanvasRenderingContext2D} [context]
|
|
676
|
-
* @returns {CanvasRenderingContext2D}
|
|
689
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
690
|
+
* @returns {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}
|
|
677
691
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
678
692
|
*/
|
|
679
693
|
ctx(context) {
|
|
@@ -857,7 +871,7 @@
|
|
|
857
871
|
return false;
|
|
858
872
|
}
|
|
859
873
|
zzfxParams = zzfxParams || instance.DEFAULT_SFX;
|
|
860
|
-
if (pitchSlide
|
|
874
|
+
if (pitchSlide !== 0 || volumeFactor !== 1) {
|
|
861
875
|
zzfxParams = zzfxParams.slice();
|
|
862
876
|
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1);
|
|
863
877
|
zzfxParams[10] = ~~zzfxParams[10] + pitchSlide;
|
|
@@ -924,7 +938,7 @@
|
|
|
924
938
|
assert(isFinite(y2), "colcirc: 5th param must be a number");
|
|
925
939
|
assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
926
940
|
}
|
|
927
|
-
return (x2 - x1)
|
|
941
|
+
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2);
|
|
928
942
|
},
|
|
929
943
|
/** PLUGINS API */
|
|
930
944
|
/**
|
|
@@ -1015,7 +1029,6 @@
|
|
|
1015
1029
|
"setvar: 1st param must be a string"
|
|
1016
1030
|
);
|
|
1017
1031
|
if (value == null) {
|
|
1018
|
-
console.warn(`setvar: key "${key}" was defined as ${value}`);
|
|
1019
1032
|
}
|
|
1020
1033
|
}
|
|
1021
1034
|
instance[key] = value;
|
|
@@ -1063,8 +1076,7 @@
|
|
|
1063
1076
|
"setfps: 1st param must be a positive number"
|
|
1064
1077
|
);
|
|
1065
1078
|
}
|
|
1066
|
-
|
|
1067
|
-
_accumulated = 0;
|
|
1079
|
+
_deltaTime = 1 / ~~value;
|
|
1068
1080
|
},
|
|
1069
1081
|
/**
|
|
1070
1082
|
* Stops the litecanvas instance and remove all event listeners.
|
|
@@ -1074,7 +1086,8 @@
|
|
|
1074
1086
|
for (const removeListener of _browserEventListeners) {
|
|
1075
1087
|
removeListener();
|
|
1076
1088
|
}
|
|
1077
|
-
|
|
1089
|
+
cancelAnimationFrame(_rafid);
|
|
1090
|
+
_events = false;
|
|
1078
1091
|
if (_global) {
|
|
1079
1092
|
for (const key in instance) {
|
|
1080
1093
|
delete root[key];
|
|
@@ -1231,38 +1244,42 @@
|
|
|
1231
1244
|
}
|
|
1232
1245
|
if (settings.pauseOnBlur) {
|
|
1233
1246
|
on(root, "blur", () => {
|
|
1234
|
-
|
|
1247
|
+
_rafid = cancelAnimationFrame(_rafid);
|
|
1235
1248
|
});
|
|
1236
1249
|
on(root, "focus", () => {
|
|
1237
|
-
|
|
1238
|
-
|
|
1250
|
+
if (!_rafid) {
|
|
1251
|
+
_lastFrameTime = performance.now();
|
|
1252
|
+
_rafid = raf(drawFrame);
|
|
1253
|
+
}
|
|
1239
1254
|
});
|
|
1240
1255
|
}
|
|
1241
1256
|
instance.setfps(60);
|
|
1242
1257
|
instance.emit("init", instance);
|
|
1243
1258
|
_lastFrameTime = performance.now();
|
|
1244
|
-
raf(drawFrame);
|
|
1259
|
+
_rafid = raf(drawFrame);
|
|
1245
1260
|
}
|
|
1246
1261
|
function drawFrame(now) {
|
|
1247
|
-
|
|
1248
|
-
|
|
1262
|
+
if (_animated) {
|
|
1263
|
+
_rafid = raf(drawFrame);
|
|
1264
|
+
}
|
|
1265
|
+
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1266
|
+
_accumulated += frameTime;
|
|
1249
1267
|
_lastFrameTime = now;
|
|
1250
|
-
|
|
1251
|
-
|
|
1268
|
+
if (!_animated) {
|
|
1269
|
+
_accumulated = _deltaTime;
|
|
1270
|
+
}
|
|
1271
|
+
for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
|
|
1272
|
+
instance.emit("update", _deltaTime * _timeScale);
|
|
1252
1273
|
instance.setvar(
|
|
1253
1274
|
"ELAPSED",
|
|
1254
|
-
instance.ELAPSED +
|
|
1275
|
+
instance.ELAPSED + _deltaTime * _timeScale
|
|
1255
1276
|
);
|
|
1256
|
-
|
|
1257
|
-
shouldRender = true;
|
|
1277
|
+
updated++;
|
|
1258
1278
|
}
|
|
1259
|
-
if (
|
|
1279
|
+
if (updated) {
|
|
1260
1280
|
instance.textalign("start", "top");
|
|
1261
1281
|
instance.emit("draw");
|
|
1262
1282
|
}
|
|
1263
|
-
if (_focused && _animated) {
|
|
1264
|
-
raf(drawFrame);
|
|
1265
|
-
}
|
|
1266
1283
|
}
|
|
1267
1284
|
function setupCanvas() {
|
|
1268
1285
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
package/dist/dist.js
CHANGED
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
animate: true
|
|
64
64
|
};
|
|
65
65
|
settings = Object.assign(defaults, settings);
|
|
66
|
-
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,
|
|
66
|
+
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 = {
|
|
67
67
|
init: null,
|
|
68
68
|
update: null,
|
|
69
69
|
draw: null,
|
|
@@ -307,7 +307,7 @@
|
|
|
307
307
|
},
|
|
308
308
|
/** BASIC GRAPHICS API */
|
|
309
309
|
/**
|
|
310
|
-
* Clear the game screen
|
|
310
|
+
* Clear the game screen with an optional color
|
|
311
311
|
*
|
|
312
312
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
313
313
|
*/
|
|
@@ -315,14 +315,19 @@
|
|
|
315
315
|
if (false) {
|
|
316
316
|
assert(
|
|
317
317
|
null == color || isFinite(color) && color >= 0,
|
|
318
|
-
"cls: 1st param must be a number"
|
|
318
|
+
"cls: 1st param must be a positive number or zero or null"
|
|
319
319
|
);
|
|
320
320
|
}
|
|
321
|
-
let width = _ctx.canvas.width, height = _ctx.canvas.height;
|
|
322
321
|
if (null == color) {
|
|
323
|
-
_ctx.clearRect(0, 0, width, height);
|
|
322
|
+
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);
|
|
324
323
|
} else {
|
|
325
|
-
instance.rectfill(
|
|
324
|
+
instance.rectfill(
|
|
325
|
+
0,
|
|
326
|
+
0,
|
|
327
|
+
_ctx.canvas.width,
|
|
328
|
+
_ctx.canvas.height,
|
|
329
|
+
color
|
|
330
|
+
);
|
|
326
331
|
}
|
|
327
332
|
},
|
|
328
333
|
/**
|
|
@@ -588,11 +593,20 @@
|
|
|
588
593
|
textalign(align, baseline) {
|
|
589
594
|
if (false) {
|
|
590
595
|
assert(
|
|
591
|
-
null == align || "
|
|
596
|
+
null == align || ["left", "right", "center", "start", "end"].includes(
|
|
597
|
+
align
|
|
598
|
+
),
|
|
592
599
|
"textalign: 1st param must be a string"
|
|
593
600
|
);
|
|
594
601
|
assert(
|
|
595
|
-
null == baseline ||
|
|
602
|
+
null == baseline || [
|
|
603
|
+
"top",
|
|
604
|
+
"bottom",
|
|
605
|
+
"middle",
|
|
606
|
+
"hanging",
|
|
607
|
+
"alphabetic",
|
|
608
|
+
"ideographic"
|
|
609
|
+
].includes(baseline),
|
|
596
610
|
"textalign: 2nd param must be a string"
|
|
597
611
|
);
|
|
598
612
|
}
|
|
@@ -667,8 +681,8 @@
|
|
|
667
681
|
/**
|
|
668
682
|
* Get or set the canvas context 2D
|
|
669
683
|
*
|
|
670
|
-
* @param {CanvasRenderingContext2D} [context]
|
|
671
|
-
* @returns {CanvasRenderingContext2D}
|
|
684
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
685
|
+
* @returns {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}
|
|
672
686
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
673
687
|
*/
|
|
674
688
|
ctx(context) {
|
|
@@ -852,7 +866,7 @@
|
|
|
852
866
|
return false;
|
|
853
867
|
}
|
|
854
868
|
zzfxParams = zzfxParams || instance.DEFAULT_SFX;
|
|
855
|
-
if (pitchSlide
|
|
869
|
+
if (pitchSlide !== 0 || volumeFactor !== 1) {
|
|
856
870
|
zzfxParams = zzfxParams.slice();
|
|
857
871
|
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1);
|
|
858
872
|
zzfxParams[10] = ~~zzfxParams[10] + pitchSlide;
|
|
@@ -919,7 +933,7 @@
|
|
|
919
933
|
assert(isFinite(y2), "colcirc: 5th param must be a number");
|
|
920
934
|
assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
921
935
|
}
|
|
922
|
-
return (x2 - x1)
|
|
936
|
+
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2);
|
|
923
937
|
},
|
|
924
938
|
/** PLUGINS API */
|
|
925
939
|
/**
|
|
@@ -1010,7 +1024,6 @@
|
|
|
1010
1024
|
"setvar: 1st param must be a string"
|
|
1011
1025
|
);
|
|
1012
1026
|
if (value == null) {
|
|
1013
|
-
console.warn(`setvar: key "${key}" was defined as ${value}`);
|
|
1014
1027
|
}
|
|
1015
1028
|
}
|
|
1016
1029
|
instance[key] = value;
|
|
@@ -1058,8 +1071,7 @@
|
|
|
1058
1071
|
"setfps: 1st param must be a positive number"
|
|
1059
1072
|
);
|
|
1060
1073
|
}
|
|
1061
|
-
|
|
1062
|
-
_accumulated = 0;
|
|
1074
|
+
_deltaTime = 1 / ~~value;
|
|
1063
1075
|
},
|
|
1064
1076
|
/**
|
|
1065
1077
|
* Stops the litecanvas instance and remove all event listeners.
|
|
@@ -1069,7 +1081,8 @@
|
|
|
1069
1081
|
for (const removeListener of _browserEventListeners) {
|
|
1070
1082
|
removeListener();
|
|
1071
1083
|
}
|
|
1072
|
-
|
|
1084
|
+
cancelAnimationFrame(_rafid);
|
|
1085
|
+
_events = false;
|
|
1073
1086
|
if (_global) {
|
|
1074
1087
|
for (const key in instance) {
|
|
1075
1088
|
delete root[key];
|
|
@@ -1226,38 +1239,42 @@
|
|
|
1226
1239
|
}
|
|
1227
1240
|
if (settings.pauseOnBlur) {
|
|
1228
1241
|
on(root, "blur", () => {
|
|
1229
|
-
|
|
1242
|
+
_rafid = cancelAnimationFrame(_rafid);
|
|
1230
1243
|
});
|
|
1231
1244
|
on(root, "focus", () => {
|
|
1232
|
-
|
|
1233
|
-
|
|
1245
|
+
if (!_rafid) {
|
|
1246
|
+
_lastFrameTime = performance.now();
|
|
1247
|
+
_rafid = raf(drawFrame);
|
|
1248
|
+
}
|
|
1234
1249
|
});
|
|
1235
1250
|
}
|
|
1236
1251
|
instance.setfps(60);
|
|
1237
1252
|
instance.emit("init", instance);
|
|
1238
1253
|
_lastFrameTime = performance.now();
|
|
1239
|
-
raf(drawFrame);
|
|
1254
|
+
_rafid = raf(drawFrame);
|
|
1240
1255
|
}
|
|
1241
1256
|
function drawFrame(now) {
|
|
1242
|
-
|
|
1243
|
-
|
|
1257
|
+
if (_animated) {
|
|
1258
|
+
_rafid = raf(drawFrame);
|
|
1259
|
+
}
|
|
1260
|
+
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1261
|
+
_accumulated += frameTime;
|
|
1244
1262
|
_lastFrameTime = now;
|
|
1245
|
-
|
|
1246
|
-
|
|
1263
|
+
if (!_animated) {
|
|
1264
|
+
_accumulated = _deltaTime;
|
|
1265
|
+
}
|
|
1266
|
+
for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
|
|
1267
|
+
instance.emit("update", _deltaTime * _timeScale);
|
|
1247
1268
|
instance.setvar(
|
|
1248
1269
|
"ELAPSED",
|
|
1249
|
-
instance.ELAPSED +
|
|
1270
|
+
instance.ELAPSED + _deltaTime * _timeScale
|
|
1250
1271
|
);
|
|
1251
|
-
|
|
1252
|
-
shouldRender = true;
|
|
1272
|
+
updated++;
|
|
1253
1273
|
}
|
|
1254
|
-
if (
|
|
1274
|
+
if (updated) {
|
|
1255
1275
|
instance.textalign("start", "top");
|
|
1256
1276
|
instance.emit("draw");
|
|
1257
1277
|
}
|
|
1258
|
-
if (_focused && _animated) {
|
|
1259
|
-
raf(drawFrame);
|
|
1260
|
-
}
|
|
1261
1278
|
}
|
|
1262
1279
|
function setupCanvas() {
|
|
1263
1280
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,
|
|
1
|
+
(()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,c=0,f=0,p=0,u=0,d=0,h=0,g=0,m=0,v=0,E=1,b=0,w=0,T=0)=>{let x=Math,y=2*x.PI,D=c*=500*y/44100/44100,H=l*=(1-a+2*a*x.random(a=[]))*y/44100,I=0,S=0,A=0,k=1,C=0,L=0,X=0,O=T<0?-1:1,z=y*O*T*2/44100,M=x.cos(z),P=x.sin,Y=P(z)/4,F=1+Y,W=-2*M/F,_=(1-Y)/F,R=(1+O*M)/2/F,G=-(O+M)/F,N=0,B=0,U=0,j=0;for(n=44100*n+9,b*=44100,i*=44100,r*=44100,v*=44100,f*=500*y/85766121e6,g*=y/44100,p*=y/44100,u*=44100,d=44100*d|0,t*=.3*(globalThis.zzfxV||1),O=n+b+i+r+v|0;A<O;a[A++]=X*t)++L%(100*m|0)||(X=o?1<o?2<o?3<o?P(I*I):x.max(x.min(x.tan(I),1),-1):1-(2*I/y%2+2)%2:1-4*x.abs(x.round(I/y)-I/y):P(I),X=(d?1-w+w*P(y*A/d):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<O-v?(O-A-v)/r*E:0),X=v?X/2+(v>A?0:(A<O-v?1:(O-A)/v)*a[A-v|0]/2/t):X,T&&(X=j=R*N+G*(N=B)+R*(B=X)-_*U-W*(U=j))),I+=(z=(l+=c+=f)*x.cos(g*S++))+z*h*P(A**5),k&&++k>u&&(l+=p,H+=p,k=0),!d||++C%d||(l=H,c=D,k=k||1);(t=e.createBuffer(1,O,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,r=requestAnimationFrame,o=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),o.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=[],p=e.canvas||document.createElement("canvas"),u=e.fullscreen,d=e.autoscale,h=e.animate,g=1,m,v=.5,E=1,b,w,T=0,x,y="sans-serif",D=32,H=Date.now(),I=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],PI:n,TWO_PI:i,HALF_PI:.5*n,lerp:(e,t,a)=>e+a*(t-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 r=(e-t)/(a-t)*(n-l)+l;return i?k.clamp(r,l,n):r},norm:(e,t,a)=>k.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(k.rand(e,t+1)),seed:e=>null==e?H:H=~~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),r=.5*(0!==v&&~~t==~~l);m.moveTo(~~e+i,~~t+r),m.lineTo(~~a+i,~~l+r),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} ${D}px ${y}`,m.fillStyle=k.getcolor(l),m.fillText(a,~~e,~~t)},textfont(e){y=e},textsize(e){D=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,r=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=r,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,r,o)=>e<n+r&&e+a>n&&t<i+o&&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){O("before:"+e,t,a,l,n),O(e,t,a,l,n),O("after:"+e,t,a,l,n)},getcolor:e=>a[~~e%a.length],setvar(e,t){k[e]=t,I&&(l[e]=t)},resize(e,t){k.setvar("WIDTH",p.width=e),k.setvar("HEIGHT",p.height=t),X()},timescale(e){E=e},setfps(e){w=1/~~e},quit(){for(let e of(k.emit("quit"),o))e();if(cancelAnimationFrame(x),S=!1,I){for(let e in k)delete l[e];delete l.__litecanvas}}};for(let e of["sin","cos","atan2","hypot","tan","abs","ceil","round","floor","trunc","min","max","pow","sqrt","sign","exp"])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((u||d)&&s(l,"resize",X),X(),e.tapEvents){let e=(e,t)=>[(e-p.offsetLeft)/g,(t-p.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,r=!1;s(p,"mousedown",t=>{t.preventDefault();let[l,n]=e(t.pageX,t.pageY);k.emit("tap",l,n,0),a(0,l,n),r=!0}),s(p,"mousemove",t=>{t.preventDefault();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(p,"mouseup",a=>{a.preventDefault();let l=t.get(0),[n,o]=e(a.pageX,a.pageY);i(l)&&k.emit("tapped",l.startX,l.startY,0),k.emit("untap",n,o,0),t.delete(0),r=!1}),s(p,"touchstart",t=>{for(let l of(t.preventDefault(),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(p,"touchmove",t=>{for(let a of(t.preventDefault(),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 o=e=>{e.preventDefault();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(p,"touchend",o),s(p,"touchcancel",o),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||(b=performance.now(),x=r(L))})),k.setfps(60),k.emit("init",k),b=performance.now(),x=r(L)}function L(e){h&&(x=r(L));let t=0;for(T+=(e-b)/1e3,b=e,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=p.style;n.display="block",u?(n.position="absolute",n.inset=0,k.setvar("WIDTH",p.width=t),k.setvar("HEIGHT",p.height=a)):d&&(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,p.style.imageRendering="pixelated"),k.emit("resized",g),h||r(L)}function O(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);if("object"==typeof a)for(let e of Object.keys(a))k.setvar(e,a[e])}if(I){if(l.__litecanvas)throw"global litecanvas already instantiated";Object.assign(l,k),l.__litecanvas=k}return p="string"==typeof p?document.querySelector(p):p,k.setvar("CANVAS",p),m=p.getContext("2d"),s(p,"click",()=>l.focus()),k.WIDTH>0&&(u=!1),p.style="",p.width=k.WIDTH,p.height=k.HEIGHT||k.WIDTH,p.parentNode||document.body.appendChild(p),"loading"===document.readyState?s(l,"DOMContentLoaded",()=>r(C)):r(C),k}})();
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.74.
|
|
3
|
+
"version": "0.74.2",
|
|
4
4
|
"description": "Lightweight HTML5 canvas engine suitable for small games and animations.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Luiz Bills <luizbills@pm.me>",
|
|
7
7
|
"contributors": [],
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"@swc/core": "^1.
|
|
9
|
+
"@swc/core": "^1.11.4",
|
|
10
10
|
"ava": "^6.2.0",
|
|
11
11
|
"esbuild": "^0.25.0",
|
|
12
12
|
"gzip-size": "^7.0.0",
|
|
13
|
-
"prettier": "^3.5.
|
|
13
|
+
"prettier": "^3.5.2"
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://litecanvas.github.io/about.html",
|
|
16
16
|
"repository": {
|
package/src/index.js
CHANGED
|
@@ -67,11 +67,11 @@ export default function litecanvas(settings = {}) {
|
|
|
67
67
|
/** @type {number} */
|
|
68
68
|
_lastFrameTime,
|
|
69
69
|
/** @type {number} */
|
|
70
|
-
|
|
70
|
+
_deltaTime,
|
|
71
71
|
/** @type {number} */
|
|
72
|
-
_accumulated,
|
|
72
|
+
_accumulated = 0,
|
|
73
73
|
/** @type {number} */
|
|
74
|
-
|
|
74
|
+
_rafid,
|
|
75
75
|
/** @type {string} */
|
|
76
76
|
_fontFamily = 'sans-serif',
|
|
77
77
|
/** @type {number} */
|
|
@@ -361,7 +361,7 @@ export default function litecanvas(settings = {}) {
|
|
|
361
361
|
|
|
362
362
|
/** BASIC GRAPHICS API */
|
|
363
363
|
/**
|
|
364
|
-
* Clear the game screen
|
|
364
|
+
* Clear the game screen with an optional color
|
|
365
365
|
*
|
|
366
366
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
367
367
|
*/
|
|
@@ -369,15 +369,19 @@ export default function litecanvas(settings = {}) {
|
|
|
369
369
|
if (DEV_BUILD) {
|
|
370
370
|
assert(
|
|
371
371
|
null == color || (isFinite(color) && color >= 0),
|
|
372
|
-
'cls: 1st param must be a number'
|
|
372
|
+
'cls: 1st param must be a positive number or zero or null'
|
|
373
373
|
)
|
|
374
374
|
}
|
|
375
|
-
let width = _ctx.canvas.width,
|
|
376
|
-
height = _ctx.canvas.height
|
|
377
375
|
if (null == color) {
|
|
378
|
-
_ctx.clearRect(0, 0, width, height)
|
|
376
|
+
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height)
|
|
379
377
|
} else {
|
|
380
|
-
instance.rectfill(
|
|
378
|
+
instance.rectfill(
|
|
379
|
+
0,
|
|
380
|
+
0,
|
|
381
|
+
_ctx.canvas.width,
|
|
382
|
+
_ctx.canvas.height,
|
|
383
|
+
color
|
|
384
|
+
)
|
|
381
385
|
}
|
|
382
386
|
},
|
|
383
387
|
|
|
@@ -665,11 +669,22 @@ export default function litecanvas(settings = {}) {
|
|
|
665
669
|
textalign(align, baseline) {
|
|
666
670
|
if (DEV_BUILD) {
|
|
667
671
|
assert(
|
|
668
|
-
null == align ||
|
|
672
|
+
null == align ||
|
|
673
|
+
['left', 'right', 'center', 'start', 'end'].includes(
|
|
674
|
+
align
|
|
675
|
+
),
|
|
669
676
|
'textalign: 1st param must be a string'
|
|
670
677
|
)
|
|
671
678
|
assert(
|
|
672
|
-
null == baseline ||
|
|
679
|
+
null == baseline ||
|
|
680
|
+
[
|
|
681
|
+
'top',
|
|
682
|
+
'bottom',
|
|
683
|
+
'middle',
|
|
684
|
+
'hanging',
|
|
685
|
+
'alphabetic',
|
|
686
|
+
'ideographic',
|
|
687
|
+
].includes(baseline),
|
|
673
688
|
'textalign: 2nd param must be a string'
|
|
674
689
|
)
|
|
675
690
|
}
|
|
@@ -759,8 +774,8 @@ export default function litecanvas(settings = {}) {
|
|
|
759
774
|
/**
|
|
760
775
|
* Get or set the canvas context 2D
|
|
761
776
|
*
|
|
762
|
-
* @param {CanvasRenderingContext2D} [context]
|
|
763
|
-
* @returns {CanvasRenderingContext2D}
|
|
777
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
778
|
+
* @returns {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}
|
|
764
779
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
765
780
|
*/
|
|
766
781
|
ctx(context) {
|
|
@@ -965,7 +980,7 @@ export default function litecanvas(settings = {}) {
|
|
|
965
980
|
zzfxParams = zzfxParams || instance.DEFAULT_SFX
|
|
966
981
|
|
|
967
982
|
// if has other arguments, copy the sound to not change the original
|
|
968
|
-
if (pitchSlide
|
|
983
|
+
if (pitchSlide !== 0 || volumeFactor !== 1) {
|
|
969
984
|
zzfxParams = zzfxParams.slice()
|
|
970
985
|
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1)
|
|
971
986
|
zzfxParams[10] = ~~zzfxParams[10] + pitchSlide
|
|
@@ -1037,7 +1052,10 @@ export default function litecanvas(settings = {}) {
|
|
|
1037
1052
|
assert(isFinite(y2), 'colcirc: 5th param must be a number')
|
|
1038
1053
|
assert(isFinite(r2), 'colcirc: 6th param must be a number')
|
|
1039
1054
|
}
|
|
1040
|
-
return (
|
|
1055
|
+
return (
|
|
1056
|
+
(x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <=
|
|
1057
|
+
(r1 + r2) * (r1 + r2)
|
|
1058
|
+
)
|
|
1041
1059
|
},
|
|
1042
1060
|
|
|
1043
1061
|
/** PLUGINS API */
|
|
@@ -1188,8 +1206,7 @@ export default function litecanvas(settings = {}) {
|
|
|
1188
1206
|
'setfps: 1st param must be a positive number'
|
|
1189
1207
|
)
|
|
1190
1208
|
}
|
|
1191
|
-
|
|
1192
|
-
_accumulated = 0
|
|
1209
|
+
_deltaTime = 1 / ~~value
|
|
1193
1210
|
},
|
|
1194
1211
|
|
|
1195
1212
|
/**
|
|
@@ -1200,7 +1217,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1200
1217
|
for (const removeListener of _browserEventListeners) {
|
|
1201
1218
|
removeListener()
|
|
1202
1219
|
}
|
|
1203
|
-
|
|
1220
|
+
cancelAnimationFrame(_rafid)
|
|
1221
|
+
_events = false
|
|
1204
1222
|
if (_global) {
|
|
1205
1223
|
for (const key in instance) {
|
|
1206
1224
|
delete root[key]
|
|
@@ -1410,12 +1428,14 @@ export default function litecanvas(settings = {}) {
|
|
|
1410
1428
|
// listen browser focus/blur events and pause the update/draw loop
|
|
1411
1429
|
if (settings.pauseOnBlur) {
|
|
1412
1430
|
on(root, 'blur', () => {
|
|
1413
|
-
|
|
1431
|
+
_rafid = cancelAnimationFrame(_rafid)
|
|
1414
1432
|
})
|
|
1415
1433
|
|
|
1416
1434
|
on(root, 'focus', () => {
|
|
1417
|
-
|
|
1418
|
-
|
|
1435
|
+
if (!_rafid) {
|
|
1436
|
+
_lastFrameTime = performance.now()
|
|
1437
|
+
_rafid = raf(drawFrame)
|
|
1438
|
+
}
|
|
1419
1439
|
})
|
|
1420
1440
|
}
|
|
1421
1441
|
|
|
@@ -1425,37 +1445,40 @@ export default function litecanvas(settings = {}) {
|
|
|
1425
1445
|
instance.emit('init', instance)
|
|
1426
1446
|
|
|
1427
1447
|
_lastFrameTime = performance.now()
|
|
1428
|
-
raf(drawFrame)
|
|
1448
|
+
_rafid = raf(drawFrame)
|
|
1429
1449
|
}
|
|
1430
1450
|
|
|
1431
1451
|
/**
|
|
1432
|
-
* @param {
|
|
1452
|
+
* @param {DOMHighResTimeStamp} now
|
|
1433
1453
|
*/
|
|
1434
1454
|
function drawFrame(now) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1455
|
+
if (_animated) {
|
|
1456
|
+
_rafid = raf(drawFrame)
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
let updated = 0,
|
|
1460
|
+
frameTime = (now - _lastFrameTime) / 1000
|
|
1438
1461
|
|
|
1439
|
-
_accumulated += frameTime
|
|
1462
|
+
_accumulated += frameTime
|
|
1440
1463
|
_lastFrameTime = now
|
|
1441
1464
|
|
|
1442
|
-
|
|
1443
|
-
|
|
1465
|
+
if (!_animated) {
|
|
1466
|
+
_accumulated = _deltaTime
|
|
1467
|
+
}
|
|
1468
|
+
|
|
1469
|
+
for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
|
|
1470
|
+
instance.emit('update', _deltaTime * _timeScale)
|
|
1444
1471
|
instance.setvar(
|
|
1445
1472
|
'ELAPSED',
|
|
1446
|
-
instance.ELAPSED +
|
|
1473
|
+
instance.ELAPSED + _deltaTime * _timeScale
|
|
1447
1474
|
)
|
|
1448
|
-
|
|
1449
|
-
shouldRender = true
|
|
1475
|
+
updated++
|
|
1450
1476
|
}
|
|
1451
1477
|
|
|
1452
|
-
if (
|
|
1478
|
+
if (updated) {
|
|
1453
1479
|
instance.textalign('start', 'top') // default values for textAlign & textBaseline
|
|
1454
1480
|
instance.emit('draw')
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
if (_focused && _animated) {
|
|
1458
|
-
raf(drawFrame)
|
|
1481
|
+
console.log(updated)
|
|
1459
1482
|
}
|
|
1460
1483
|
}
|
|
1461
1484
|
|
package/types/index.d.ts
CHANGED