litecanvas 0.79.0 → 0.79.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/README.md +1 -1
- package/dist/dist.dev.js +114 -113
- package/dist/dist.js +35 -34
- package/dist/dist.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +120 -122
- package/types/index.d.ts +2 -2
- package/types/types.d.ts +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Litecanvas
|
|
4
4
|
|
|
5
|
-
Litecanvas is a lightweight HTML5 canvas engine suitable for small web games, prototypes, game jams, animations, creative coding, learning game programming and game design, etc.
|
|
5
|
+
Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games, prototypes, game jams, animations, creative coding, learning game programming and game design, etc.
|
|
6
6
|
|
|
7
7
|
:warning: **This project is still under development. All feedback is appreciated!** :warning:
|
|
8
8
|
|
package/dist/dist.dev.js
CHANGED
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
|
|
31
31
|
// src/index.js
|
|
32
32
|
function litecanvas(settings = {}) {
|
|
33
|
-
const root = globalThis, math = Math,
|
|
33
|
+
const root = globalThis, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
|
|
34
34
|
elem.addEventListener(evt, callback, false);
|
|
35
35
|
_browserEventListeners.push(
|
|
36
36
|
() => elem.removeEventListener(evt, callback, false)
|
|
37
37
|
);
|
|
38
|
-
},
|
|
38
|
+
}, isNumber = Number.isFinite, defaults = {
|
|
39
39
|
width: null,
|
|
40
40
|
height: null,
|
|
41
41
|
autoscale: true,
|
|
@@ -50,26 +50,26 @@
|
|
|
50
50
|
animate: true
|
|
51
51
|
};
|
|
52
52
|
settings = Object.assign(defaults, settings);
|
|
53
|
-
let _initialized = false, _plugins = [], _canvas
|
|
54
|
-
init:
|
|
55
|
-
update:
|
|
56
|
-
draw:
|
|
57
|
-
resized:
|
|
58
|
-
tap:
|
|
59
|
-
untap:
|
|
60
|
-
tapping:
|
|
61
|
-
tapped:
|
|
53
|
+
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _events = {
|
|
54
|
+
init: false,
|
|
55
|
+
update: false,
|
|
56
|
+
draw: false,
|
|
57
|
+
resized: false,
|
|
58
|
+
tap: false,
|
|
59
|
+
untap: false,
|
|
60
|
+
tapping: false,
|
|
61
|
+
tapped: false
|
|
62
62
|
}, _helpers = {
|
|
63
63
|
settings: Object.assign({}, settings),
|
|
64
64
|
colors
|
|
65
65
|
};
|
|
66
66
|
const instance = {
|
|
67
67
|
/** @type {number} */
|
|
68
|
-
WIDTH:
|
|
68
|
+
WIDTH: 0,
|
|
69
69
|
/** @type {number} */
|
|
70
|
-
HEIGHT:
|
|
70
|
+
HEIGHT: 0,
|
|
71
71
|
/** @type {HTMLCanvasElement} */
|
|
72
|
-
CANVAS:
|
|
72
|
+
CANVAS: false,
|
|
73
73
|
/** @type {number} */
|
|
74
74
|
ELAPSED: 0,
|
|
75
75
|
/** @type {number} */
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
/** @type {number} */
|
|
82
82
|
MOUSEY: -1,
|
|
83
83
|
/** @type {number[]} */
|
|
84
|
-
DEFAULT_SFX: [0.5, ,
|
|
84
|
+
DEFAULT_SFX: [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
85
85
|
/** MATH API */
|
|
86
86
|
/**
|
|
87
87
|
* Twice the value of the mathematical constant PI (π).
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
*
|
|
100
100
|
* @type {number}
|
|
101
101
|
*/
|
|
102
|
-
HALF_PI: PI / 2,
|
|
102
|
+
HALF_PI: math.PI / 2,
|
|
103
103
|
/**
|
|
104
104
|
* Calculates a linear (interpolation) value over t%.
|
|
105
105
|
*
|
|
@@ -110,9 +110,9 @@
|
|
|
110
110
|
* @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
|
|
111
111
|
*/
|
|
112
112
|
lerp: (start, end, t) => {
|
|
113
|
-
DEV: assert(
|
|
114
|
-
DEV: assert(
|
|
115
|
-
DEV: assert(
|
|
113
|
+
DEV: assert(isNumber(start), "lerp: 1st param must be a number");
|
|
114
|
+
DEV: assert(isNumber(end), "lerp: 2nd param must be a number");
|
|
115
|
+
DEV: assert(isNumber(t), "lerp: 3rd param must be a number");
|
|
116
116
|
return t * (end - start) + start;
|
|
117
117
|
},
|
|
118
118
|
/**
|
|
@@ -122,8 +122,8 @@
|
|
|
122
122
|
* @returns {number} the value in radians
|
|
123
123
|
*/
|
|
124
124
|
deg2rad: (degs) => {
|
|
125
|
-
DEV: assert(
|
|
126
|
-
return PI / 180 * degs;
|
|
125
|
+
DEV: assert(isNumber(degs), "deg2rad: 1st param must be a number");
|
|
126
|
+
return math.PI / 180 * degs;
|
|
127
127
|
},
|
|
128
128
|
/**
|
|
129
129
|
* Convert radians to degrees
|
|
@@ -132,8 +132,8 @@
|
|
|
132
132
|
* @returns {number} the value in degrees
|
|
133
133
|
*/
|
|
134
134
|
rad2deg: (rads) => {
|
|
135
|
-
DEV: assert(
|
|
136
|
-
return 180 / PI * rads;
|
|
135
|
+
DEV: assert(isNumber(rads), "rad2deg: 1st param must be a number");
|
|
136
|
+
return 180 / math.PI * rads;
|
|
137
137
|
},
|
|
138
138
|
/**
|
|
139
139
|
* Returns the rounded value of an number to optional precision (number of digits after the decimal point).
|
|
@@ -145,9 +145,9 @@
|
|
|
145
145
|
* @returns {number} rounded number.
|
|
146
146
|
*/
|
|
147
147
|
round: (n, precision = 0) => {
|
|
148
|
-
DEV: assert(
|
|
148
|
+
DEV: assert(isNumber(n), "round: 1st param must be a number");
|
|
149
149
|
DEV: assert(
|
|
150
|
-
null
|
|
150
|
+
null == precision || isNumber(precision) && precision >= 0,
|
|
151
151
|
"round: 2nd param must be a positive number or zero"
|
|
152
152
|
);
|
|
153
153
|
if (!precision) {
|
|
@@ -165,9 +165,9 @@
|
|
|
165
165
|
* @returns {number}
|
|
166
166
|
*/
|
|
167
167
|
clamp: (value, min, max) => {
|
|
168
|
-
DEV: assert(
|
|
169
|
-
DEV: assert(
|
|
170
|
-
DEV: assert(
|
|
168
|
+
DEV: assert(isNumber(value), "clamp: 1st param must be a number");
|
|
169
|
+
DEV: assert(isNumber(min), "clamp: 2nd param must be a number");
|
|
170
|
+
DEV: assert(isNumber(max), "clamp: 3rd param must be a number");
|
|
171
171
|
DEV: assert(
|
|
172
172
|
max > min,
|
|
173
173
|
"randi: the 2nd param must be less than the 3rd param"
|
|
@@ -185,9 +185,9 @@
|
|
|
185
185
|
* @returns {number}
|
|
186
186
|
*/
|
|
187
187
|
wrap: (value, min, max) => {
|
|
188
|
-
DEV: assert(
|
|
189
|
-
DEV: assert(
|
|
190
|
-
DEV: assert(
|
|
188
|
+
DEV: assert(isNumber(value), "wrap: 1st param must be a number");
|
|
189
|
+
DEV: assert(isNumber(min), "wrap: 2nd param must be a number");
|
|
190
|
+
DEV: assert(isNumber(max), "wrap: 3rd param must be a number");
|
|
191
191
|
DEV: assert(
|
|
192
192
|
max > min,
|
|
193
193
|
"randi: the 2nd param must be less than the 3rd param"
|
|
@@ -210,11 +210,11 @@
|
|
|
210
210
|
* @returns {number} the remapped number
|
|
211
211
|
*/
|
|
212
212
|
map(value, start1, stop1, start2, stop2, withinBounds) {
|
|
213
|
-
DEV: assert(
|
|
214
|
-
DEV: assert(
|
|
215
|
-
DEV: assert(
|
|
216
|
-
DEV: assert(
|
|
217
|
-
DEV: assert(
|
|
213
|
+
DEV: assert(isNumber(value), "map: 1st param must be a number");
|
|
214
|
+
DEV: assert(isNumber(start1), "map: 2nd param must be a number");
|
|
215
|
+
DEV: assert(isNumber(stop1), "map: 3rd param must be a number");
|
|
216
|
+
DEV: assert(isNumber(start2), "map: 4th param must be a number");
|
|
217
|
+
DEV: assert(isNumber(stop2), "map: 5th param must be a number");
|
|
218
218
|
const result = (value - start1) / (stop1 - start1) * (stop2 - start2) + start2;
|
|
219
219
|
return withinBounds ? instance.clamp(result, start2, stop2) : result;
|
|
220
220
|
},
|
|
@@ -229,9 +229,9 @@
|
|
|
229
229
|
* @returns {number} the normalized number.
|
|
230
230
|
*/
|
|
231
231
|
norm: (value, start, stop) => {
|
|
232
|
-
DEV: assert(
|
|
233
|
-
DEV: assert(
|
|
234
|
-
DEV: assert(
|
|
232
|
+
DEV: assert(isNumber(value), "norm: 1st param must be a number");
|
|
233
|
+
DEV: assert(isNumber(start), "norm: 2nd param must be a number");
|
|
234
|
+
DEV: assert(isNumber(stop), "norm: 3rd param must be a number");
|
|
235
235
|
return instance.map(value, start, stop, 0, 1);
|
|
236
236
|
},
|
|
237
237
|
/** RNG API */
|
|
@@ -244,8 +244,8 @@
|
|
|
244
244
|
* @returns {number} the random number
|
|
245
245
|
*/
|
|
246
246
|
rand: (min = 0, max = 1) => {
|
|
247
|
-
DEV: assert(
|
|
248
|
-
DEV: assert(
|
|
247
|
+
DEV: assert(isNumber(min), "rand: 1st param must be a number");
|
|
248
|
+
DEV: assert(isNumber(max), "rand: 2nd param must be a number");
|
|
249
249
|
DEV: assert(
|
|
250
250
|
max > min,
|
|
251
251
|
"rand: the 1st param must be less than the 2nd param"
|
|
@@ -264,8 +264,8 @@
|
|
|
264
264
|
* @returns {number} the random number
|
|
265
265
|
*/
|
|
266
266
|
randi: (min = 0, max = 1) => {
|
|
267
|
-
DEV: assert(
|
|
268
|
-
DEV: assert(
|
|
267
|
+
DEV: assert(isNumber(min), "randi: 1st param must be a number");
|
|
268
|
+
DEV: assert(isNumber(max), "randi: 2nd param must be a number");
|
|
269
269
|
DEV: assert(
|
|
270
270
|
max > min,
|
|
271
271
|
"randi: the 1st param must be less than the 2nd param"
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
*/
|
|
282
282
|
seed: (value) => {
|
|
283
283
|
DEV: assert(
|
|
284
|
-
null == value ||
|
|
284
|
+
null == value || isNumber(value) && value >= 0,
|
|
285
285
|
"seed: 1st param must be a positive number or zero"
|
|
286
286
|
);
|
|
287
287
|
return null == value ? _rng_seed : _rng_seed = ~~value;
|
|
@@ -290,11 +290,11 @@
|
|
|
290
290
|
/**
|
|
291
291
|
* Clear the game screen with an optional color
|
|
292
292
|
*
|
|
293
|
-
* @param {number
|
|
293
|
+
* @param {number} [color] The background color (index) or null/undefined (for transparent)
|
|
294
294
|
*/
|
|
295
295
|
cls(color) {
|
|
296
296
|
DEV: assert(
|
|
297
|
-
null == color ||
|
|
297
|
+
null == color || isNumber(color) && color >= 0,
|
|
298
298
|
"cls: 1st param must be a positive number or zero or undefined"
|
|
299
299
|
);
|
|
300
300
|
if (null == color) {
|
|
@@ -319,23 +319,23 @@
|
|
|
319
319
|
* @param {number} [color=0] the color index
|
|
320
320
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
321
321
|
*/
|
|
322
|
-
rect(x, y, width, height, color, radii
|
|
323
|
-
DEV: assert(
|
|
324
|
-
DEV: assert(
|
|
322
|
+
rect(x, y, width, height, color, radii) {
|
|
323
|
+
DEV: assert(isNumber(x), "rect: 1st param must be a number");
|
|
324
|
+
DEV: assert(isNumber(y), "rect: 2nd param must be a number");
|
|
325
325
|
DEV: assert(
|
|
326
|
-
|
|
326
|
+
isNumber(width) && width > 0,
|
|
327
327
|
"rect: 3rd param must be a positive number"
|
|
328
328
|
);
|
|
329
329
|
DEV: assert(
|
|
330
|
-
|
|
330
|
+
isNumber(height) && height >= 0,
|
|
331
331
|
"rect: 4th param must be a positive number or zero"
|
|
332
332
|
);
|
|
333
333
|
DEV: assert(
|
|
334
|
-
null == color ||
|
|
334
|
+
null == color || isNumber(color) && color >= 0,
|
|
335
335
|
"rect: 5th param must be a positive number or zero"
|
|
336
336
|
);
|
|
337
337
|
DEV: assert(
|
|
338
|
-
null == radii ||
|
|
338
|
+
null == radii || isNumber(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
339
339
|
"rect: 6th param must be a number or array of numbers"
|
|
340
340
|
);
|
|
341
341
|
_ctx.beginPath();
|
|
@@ -358,23 +358,23 @@
|
|
|
358
358
|
* @param {number} [color=0] the color index
|
|
359
359
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
360
360
|
*/
|
|
361
|
-
rectfill(x, y, width, height, color, radii
|
|
362
|
-
DEV: assert(
|
|
363
|
-
DEV: assert(
|
|
361
|
+
rectfill(x, y, width, height, color, radii) {
|
|
362
|
+
DEV: assert(isNumber(x), "rectfill: 1st param must be a number");
|
|
363
|
+
DEV: assert(isNumber(y), "rectfill: 2nd param must be a number");
|
|
364
364
|
DEV: assert(
|
|
365
|
-
|
|
365
|
+
isNumber(width) && width >= 0,
|
|
366
366
|
"rectfill: 3rd param must be a positive number or zero"
|
|
367
367
|
);
|
|
368
368
|
DEV: assert(
|
|
369
|
-
|
|
369
|
+
isNumber(height) && height >= 0,
|
|
370
370
|
"rectfill: 4th param must be a positive number or zero"
|
|
371
371
|
);
|
|
372
372
|
DEV: assert(
|
|
373
|
-
null == color ||
|
|
373
|
+
null == color || isNumber(color) && color >= 0,
|
|
374
374
|
"rectfill: 5th param must be a positive number or zero"
|
|
375
375
|
);
|
|
376
376
|
DEV: assert(
|
|
377
|
-
null == radii ||
|
|
377
|
+
null == radii || isNumber(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
378
378
|
"rectfill: 6th param must be a number or array of at least 2 numbers"
|
|
379
379
|
);
|
|
380
380
|
_ctx.beginPath();
|
|
@@ -396,14 +396,14 @@
|
|
|
396
396
|
* @param {number} [color=0] the color index
|
|
397
397
|
*/
|
|
398
398
|
circ(x, y, radius, color) {
|
|
399
|
-
DEV: assert(
|
|
400
|
-
DEV: assert(
|
|
399
|
+
DEV: assert(isNumber(x), "circ: 1st param must be a number");
|
|
400
|
+
DEV: assert(isNumber(y), "circ: 2nd param must be a number");
|
|
401
401
|
DEV: assert(
|
|
402
|
-
|
|
402
|
+
isNumber(radius) && radius >= 0,
|
|
403
403
|
"circ: 3rd param must be a positive number or zero"
|
|
404
404
|
);
|
|
405
405
|
DEV: assert(
|
|
406
|
-
null == color ||
|
|
406
|
+
null == color || isNumber(color) && color >= 0,
|
|
407
407
|
"circ: 4th param must be a positive number or zero"
|
|
408
408
|
);
|
|
409
409
|
_ctx.beginPath();
|
|
@@ -419,14 +419,14 @@
|
|
|
419
419
|
* @param {number} [color=0] the color index
|
|
420
420
|
*/
|
|
421
421
|
circfill(x, y, radius, color) {
|
|
422
|
-
DEV: assert(
|
|
423
|
-
DEV: assert(
|
|
422
|
+
DEV: assert(isNumber(x), "circfill: 1st param must be a number");
|
|
423
|
+
DEV: assert(isNumber(y), "circfill: 2nd param must be a number");
|
|
424
424
|
DEV: assert(
|
|
425
|
-
|
|
425
|
+
isNumber(radius) && radius >= 0,
|
|
426
426
|
"circfill: 3rd param must be a positive number or zero"
|
|
427
427
|
);
|
|
428
428
|
DEV: assert(
|
|
429
|
-
null == color ||
|
|
429
|
+
null == color || isNumber(color) && color >= 0,
|
|
430
430
|
"circfill: 4th param must be a positive number or zero"
|
|
431
431
|
);
|
|
432
432
|
_ctx.beginPath();
|
|
@@ -443,18 +443,18 @@
|
|
|
443
443
|
* @param {number} [color=0] the color index
|
|
444
444
|
*/
|
|
445
445
|
line(x1, y1, x2, y2, color) {
|
|
446
|
-
DEV: assert(
|
|
447
|
-
DEV: assert(
|
|
446
|
+
DEV: assert(isNumber(x1), "line: 1st param must be a number");
|
|
447
|
+
DEV: assert(isNumber(y1), "line: 2nd param must be a number");
|
|
448
448
|
DEV: assert(
|
|
449
|
-
|
|
449
|
+
isNumber(x2),
|
|
450
450
|
"line: 3rd param must be a positive number or zero"
|
|
451
451
|
);
|
|
452
452
|
DEV: assert(
|
|
453
|
-
|
|
453
|
+
isNumber(y2),
|
|
454
454
|
"line: 4th param must be a positive number or zero"
|
|
455
455
|
);
|
|
456
456
|
DEV: assert(
|
|
457
|
-
null == color ||
|
|
457
|
+
null == color || isNumber(color) && color >= 0,
|
|
458
458
|
"line: 5th param must be a positive number or zero"
|
|
459
459
|
);
|
|
460
460
|
_ctx.beginPath();
|
|
@@ -472,11 +472,11 @@
|
|
|
472
472
|
*/
|
|
473
473
|
linewidth(value) {
|
|
474
474
|
DEV: assert(
|
|
475
|
-
|
|
475
|
+
isNumber(value) && ~~value > 0,
|
|
476
476
|
"linewidth: 1st param must be a positive number"
|
|
477
477
|
);
|
|
478
478
|
_ctx.lineWidth = ~~value;
|
|
479
|
-
_outline_fix = ~~value % 2
|
|
479
|
+
_outline_fix = 0 === ~~value % 2 ? 0 : 0.5;
|
|
480
480
|
},
|
|
481
481
|
/**
|
|
482
482
|
* Sets the line dash pattern used when drawing lines
|
|
@@ -492,7 +492,7 @@
|
|
|
492
492
|
"linedash: 1st param must be an array of numbers"
|
|
493
493
|
);
|
|
494
494
|
DEV: assert(
|
|
495
|
-
|
|
495
|
+
isNumber(offset),
|
|
496
496
|
"linedash: 2nd param must be a number"
|
|
497
497
|
);
|
|
498
498
|
_ctx.setLineDash(segments);
|
|
@@ -509,10 +509,10 @@
|
|
|
509
509
|
* @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
|
|
510
510
|
*/
|
|
511
511
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
512
|
-
DEV: assert(
|
|
513
|
-
DEV: assert(
|
|
512
|
+
DEV: assert(isNumber(x), "text: 1st param must be a number");
|
|
513
|
+
DEV: assert(isNumber(y), "text: 2nd param must be a number");
|
|
514
514
|
DEV: assert(
|
|
515
|
-
null == color ||
|
|
515
|
+
null == color || isNumber(color) && color >= 0,
|
|
516
516
|
"text: 4th param must be a positive number or zero"
|
|
517
517
|
);
|
|
518
518
|
DEV: assert(
|
|
@@ -541,7 +541,7 @@
|
|
|
541
541
|
* @param {number} size
|
|
542
542
|
*/
|
|
543
543
|
textsize(size) {
|
|
544
|
-
DEV: assert(
|
|
544
|
+
DEV: assert(isNumber(size), "textsize: 1st param must be a number");
|
|
545
545
|
_fontSize = size;
|
|
546
546
|
},
|
|
547
547
|
/**
|
|
@@ -580,12 +580,12 @@
|
|
|
580
580
|
* @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} source
|
|
581
581
|
*/
|
|
582
582
|
image(x, y, source) {
|
|
583
|
-
DEV: assert(
|
|
584
|
-
DEV: assert(
|
|
583
|
+
DEV: assert(isNumber(x), "image: 1st param must be a number");
|
|
584
|
+
DEV: assert(isNumber(y), "image: 2nd param must be a number");
|
|
585
585
|
_ctx.drawImage(source, ~~x, ~~y);
|
|
586
586
|
},
|
|
587
587
|
/**
|
|
588
|
-
*
|
|
588
|
+
* Draw in an OffscreenCanvas and returns its image.
|
|
589
589
|
*
|
|
590
590
|
* @param {number} width
|
|
591
591
|
* @param {number} height
|
|
@@ -593,18 +593,18 @@
|
|
|
593
593
|
* @param {object} [options]
|
|
594
594
|
* @param {number} [options.scale=1]
|
|
595
595
|
* @param {OffscreenCanvas | HTMLCanvasElement} [options.canvas]
|
|
596
|
-
* @returns {
|
|
596
|
+
* @returns {ImageBitmap}
|
|
597
597
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
598
598
|
*/
|
|
599
599
|
paint(width, height, drawing, options = {}) {
|
|
600
|
-
DEV: assert(
|
|
601
|
-
DEV: assert(
|
|
600
|
+
DEV: assert(isNumber(width), "paint: 1st param must be a number");
|
|
601
|
+
DEV: assert(isNumber(height), "paint: 2nd param must be a number");
|
|
602
602
|
DEV: assert(
|
|
603
603
|
"function" === typeof drawing || Array.isArray(drawing),
|
|
604
604
|
"paint: 3rd param must be a function or array"
|
|
605
605
|
);
|
|
606
606
|
DEV: assert(
|
|
607
|
-
options && !options.scale ||
|
|
607
|
+
options && !options.scale || isNumber(options.scale),
|
|
608
608
|
"paint: 4th param (options.scale) must be a number"
|
|
609
609
|
);
|
|
610
610
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
@@ -629,7 +629,7 @@
|
|
|
629
629
|
drawing(_ctx);
|
|
630
630
|
}
|
|
631
631
|
_ctx = contextOriginal;
|
|
632
|
-
return canvas;
|
|
632
|
+
return canvas.transferToImageBitmap();
|
|
633
633
|
},
|
|
634
634
|
/** ADVANCED GRAPHICS API */
|
|
635
635
|
/**
|
|
@@ -664,8 +664,8 @@
|
|
|
664
664
|
* @param {number} y
|
|
665
665
|
*/
|
|
666
666
|
translate: (x, y) => {
|
|
667
|
-
DEV: assert(
|
|
668
|
-
DEV: assert(
|
|
667
|
+
DEV: assert(isNumber(x), "translate: 1st param must be a number");
|
|
668
|
+
DEV: assert(isNumber(y), "translate: 2nd param must be a number");
|
|
669
669
|
return _ctx.translate(~~x, ~~y);
|
|
670
670
|
},
|
|
671
671
|
/**
|
|
@@ -675,9 +675,9 @@
|
|
|
675
675
|
* @param {number} [y]
|
|
676
676
|
*/
|
|
677
677
|
scale: (x, y) => {
|
|
678
|
-
DEV: assert(
|
|
678
|
+
DEV: assert(isNumber(x), "scale: 1st param must be a number");
|
|
679
679
|
DEV: assert(
|
|
680
|
-
|
|
680
|
+
null == y || isNumber(y),
|
|
681
681
|
"scale: 2nd param must be a number"
|
|
682
682
|
);
|
|
683
683
|
return _ctx.scale(x, y || x);
|
|
@@ -688,7 +688,7 @@
|
|
|
688
688
|
* @param {number} radians
|
|
689
689
|
*/
|
|
690
690
|
rotate: (radians) => {
|
|
691
|
-
DEV: assert(
|
|
691
|
+
DEV: assert(isNumber(radians), "rotate: 1st param must be a number");
|
|
692
692
|
return _ctx.rotate(radians);
|
|
693
693
|
},
|
|
694
694
|
/**
|
|
@@ -698,7 +698,7 @@
|
|
|
698
698
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha
|
|
699
699
|
*/
|
|
700
700
|
alpha(value) {
|
|
701
|
-
DEV: assert(
|
|
701
|
+
DEV: assert(isNumber(value), "alpha: 1st param must be a number");
|
|
702
702
|
_ctx.globalAlpha = instance.clamp(value, 0, 1);
|
|
703
703
|
},
|
|
704
704
|
/**
|
|
@@ -725,7 +725,7 @@
|
|
|
725
725
|
*/
|
|
726
726
|
fill(color, path) {
|
|
727
727
|
DEV: assert(
|
|
728
|
-
null == color ||
|
|
728
|
+
null == color || isNumber(color) && color >= 0,
|
|
729
729
|
"fill: 1st param must be a positive number or zero"
|
|
730
730
|
);
|
|
731
731
|
DEV: assert(
|
|
@@ -747,7 +747,7 @@
|
|
|
747
747
|
*/
|
|
748
748
|
stroke(color, path) {
|
|
749
749
|
DEV: assert(
|
|
750
|
-
null == color ||
|
|
750
|
+
null == color || isNumber(color) && color >= 0,
|
|
751
751
|
"stroke: 1st param must be a positive number or zero"
|
|
752
752
|
);
|
|
753
753
|
DEV: assert(
|
|
@@ -791,9 +791,9 @@
|
|
|
791
791
|
null == zzfxParams || Array.isArray(zzfxParams),
|
|
792
792
|
"sfx: 1st param must be an array"
|
|
793
793
|
);
|
|
794
|
-
DEV: assert(
|
|
794
|
+
DEV: assert(isNumber(pitchSlide), "sfx: 2nd param must be a number");
|
|
795
795
|
DEV: assert(
|
|
796
|
-
|
|
796
|
+
isNumber(volumeFactor),
|
|
797
797
|
"sfx: 3rd param must be a number"
|
|
798
798
|
);
|
|
799
799
|
if (root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive) {
|
|
@@ -815,7 +815,7 @@
|
|
|
815
815
|
* @param {number} value
|
|
816
816
|
*/
|
|
817
817
|
volume(value) {
|
|
818
|
-
DEV: assert(
|
|
818
|
+
DEV: assert(isNumber(value), "volume: 1st param must be a number");
|
|
819
819
|
root.zzfxV = value;
|
|
820
820
|
},
|
|
821
821
|
/** PLUGINS API */
|
|
@@ -883,7 +883,7 @@
|
|
|
883
883
|
*/
|
|
884
884
|
getcolor: (index) => {
|
|
885
885
|
DEV: assert(
|
|
886
|
-
null == index ||
|
|
886
|
+
null == index || isNumber(index) && index >= 0,
|
|
887
887
|
"getcolor: 1st param must be a number"
|
|
888
888
|
);
|
|
889
889
|
return colors[~~index % colors.length];
|
|
@@ -899,11 +899,11 @@
|
|
|
899
899
|
"string" === typeof key,
|
|
900
900
|
"setvar: 1st param must be a string"
|
|
901
901
|
);
|
|
902
|
-
if (
|
|
902
|
+
if (null == value) {
|
|
903
903
|
console.warn(`setvar: key "${key}" was defined as ${value}`);
|
|
904
904
|
}
|
|
905
905
|
instance[key] = value;
|
|
906
|
-
if (
|
|
906
|
+
if (settings.global) {
|
|
907
907
|
root[key] = value;
|
|
908
908
|
}
|
|
909
909
|
},
|
|
@@ -916,7 +916,7 @@
|
|
|
916
916
|
*/
|
|
917
917
|
timescale(value) {
|
|
918
918
|
DEV: assert(
|
|
919
|
-
|
|
919
|
+
isNumber(value),
|
|
920
920
|
"timescale: 1st param must be a number"
|
|
921
921
|
);
|
|
922
922
|
_timeScale = value;
|
|
@@ -928,7 +928,7 @@
|
|
|
928
928
|
*/
|
|
929
929
|
setfps(value) {
|
|
930
930
|
DEV: assert(
|
|
931
|
-
|
|
931
|
+
isNumber(value) && value >= 1,
|
|
932
932
|
"setfps: 1st param must be a positive number"
|
|
933
933
|
);
|
|
934
934
|
_deltaTime = 1 / ~~value;
|
|
@@ -943,7 +943,7 @@
|
|
|
943
943
|
for (const removeListener of _browserEventListeners) {
|
|
944
944
|
removeListener();
|
|
945
945
|
}
|
|
946
|
-
if (
|
|
946
|
+
if (settings.global) {
|
|
947
947
|
for (const key in instance) {
|
|
948
948
|
delete root[key];
|
|
949
949
|
}
|
|
@@ -1089,7 +1089,7 @@
|
|
|
1089
1089
|
* Checks if a which key is pressed (down) on the keyboard.
|
|
1090
1090
|
* Note: use `iskeydown()` to check for any key.
|
|
1091
1091
|
*
|
|
1092
|
-
* @param {string
|
|
1092
|
+
* @param {string} [key]
|
|
1093
1093
|
* @returns {boolean}
|
|
1094
1094
|
*/
|
|
1095
1095
|
(key) => {
|
|
@@ -1106,7 +1106,7 @@
|
|
|
1106
1106
|
* Checks if a which key just got pressed on the keyboard.
|
|
1107
1107
|
* Note: use `iskeypressed()` to check for any key.
|
|
1108
1108
|
*
|
|
1109
|
-
* @param {string
|
|
1109
|
+
* @param {string} [key]
|
|
1110
1110
|
* @returns {boolean}
|
|
1111
1111
|
*/
|
|
1112
1112
|
(key) => {
|
|
@@ -1135,7 +1135,7 @@
|
|
|
1135
1135
|
function drawFrame(now) {
|
|
1136
1136
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1137
1137
|
_lastFrameTime = now;
|
|
1138
|
-
if (
|
|
1138
|
+
if (settings.animate) {
|
|
1139
1139
|
_rafid = raf(drawFrame);
|
|
1140
1140
|
if (frameTime > 0.3) {
|
|
1141
1141
|
return console.warn("skipping too long frame");
|
|
@@ -1159,6 +1159,7 @@
|
|
|
1159
1159
|
}
|
|
1160
1160
|
}
|
|
1161
1161
|
function setupCanvas() {
|
|
1162
|
+
_canvas = settings.canvas || document.createElement("canvas");
|
|
1162
1163
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
|
1163
1164
|
DEV: assert(
|
|
1164
1165
|
_canvas && _canvas.tagName === "CANVAS",
|
|
@@ -1173,11 +1174,11 @@
|
|
|
1173
1174
|
}
|
|
1174
1175
|
function resizeCanvas() {
|
|
1175
1176
|
DEV: assert(
|
|
1176
|
-
null == settings.width ||
|
|
1177
|
+
null == settings.width || isNumber(settings.width) && settings.width > 0,
|
|
1177
1178
|
`Litecanvas' option "width" should be a positive number when defined`
|
|
1178
1179
|
);
|
|
1179
1180
|
DEV: assert(
|
|
1180
|
-
null == settings.height ||
|
|
1181
|
+
null == settings.height || isNumber(settings.height) && settings.height > 0,
|
|
1181
1182
|
`Litecanvas' option "height" should be a positive number when defined`
|
|
1182
1183
|
);
|
|
1183
1184
|
DEV: assert(
|
|
@@ -1207,7 +1208,7 @@
|
|
|
1207
1208
|
_canvas.style.imageRendering = "pixelated";
|
|
1208
1209
|
}
|
|
1209
1210
|
instance.emit("resized", _scale);
|
|
1210
|
-
if (!
|
|
1211
|
+
if (!settings.animate) {
|
|
1211
1212
|
raf(drawFrame);
|
|
1212
1213
|
}
|
|
1213
1214
|
}
|
|
@@ -1227,9 +1228,9 @@
|
|
|
1227
1228
|
instance.setvar(key, pluginData[key]);
|
|
1228
1229
|
}
|
|
1229
1230
|
}
|
|
1230
|
-
if (
|
|
1231
|
+
if (settings.global) {
|
|
1231
1232
|
if (root.ENGINE) {
|
|
1232
|
-
throw "two global litecanvas detected";
|
|
1233
|
+
throw new Error("two global litecanvas detected");
|
|
1233
1234
|
}
|
|
1234
1235
|
Object.assign(root, instance);
|
|
1235
1236
|
root.ENGINE = instance;
|