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 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, PI = math.PI, TWO_PI = PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
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
- }, isFinite = Number.isFinite, defaults = {
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 = settings.canvas || document.createElement("canvas"), _animated = settings.animate, _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(), _global = settings.global, _events = {
54
- init: null,
55
- update: null,
56
- draw: null,
57
- resized: null,
58
- tap: null,
59
- untap: null,
60
- tapping: null,
61
- tapped: null
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: settings.width,
68
+ WIDTH: 0,
69
69
  /** @type {number} */
70
- HEIGHT: settings.height || settings.width,
70
+ HEIGHT: 0,
71
71
  /** @type {HTMLCanvasElement} */
72
- CANVAS: null,
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, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06],
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(isFinite(start), "lerp: 1st param must be a number");
114
- DEV: assert(isFinite(end), "lerp: 2nd param must be a number");
115
- DEV: assert(isFinite(t), "lerp: 3rd param must be a number");
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(isFinite(degs), "deg2rad: 1st param must be a number");
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(isFinite(rads), "rad2deg: 1st param must be a number");
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(isFinite(n), "round: 1st param must be a number");
148
+ DEV: assert(isNumber(n), "round: 1st param must be a number");
149
149
  DEV: assert(
150
- null === precision || isFinite(precision) && precision >= 0,
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(isFinite(value), "clamp: 1st param must be a number");
169
- DEV: assert(isFinite(min), "clamp: 2nd param must be a number");
170
- DEV: assert(isFinite(max), "clamp: 3rd param must be a number");
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(isFinite(value), "wrap: 1st param must be a number");
189
- DEV: assert(isFinite(min), "wrap: 2nd param must be a number");
190
- DEV: assert(isFinite(max), "wrap: 3rd param must be a number");
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(isFinite(value), "map: 1st param must be a number");
214
- DEV: assert(isFinite(start1), "map: 2nd param must be a number");
215
- DEV: assert(isFinite(stop1), "map: 3rd param must be a number");
216
- DEV: assert(isFinite(start2), "map: 4th param must be a number");
217
- DEV: assert(isFinite(stop2), "map: 5th param must be a number");
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(isFinite(value), "norm: 1st param must be a number");
233
- DEV: assert(isFinite(start), "norm: 2nd param must be a number");
234
- DEV: assert(isFinite(stop), "norm: 3rd param must be a number");
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(isFinite(min), "rand: 1st param must be a number");
248
- DEV: assert(isFinite(max), "rand: 2nd param must be a number");
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(isFinite(min), "randi: 1st param must be a number");
268
- DEV: assert(isFinite(max), "randi: 2nd param must be a number");
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 || isFinite(value) && value >= 0,
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?} color The background color (index) or null/undefined (for transparent)
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 || isFinite(color) && color >= 0,
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 = null) {
323
- DEV: assert(isFinite(x), "rect: 1st param must be a number");
324
- DEV: assert(isFinite(y), "rect: 2nd param must be a number");
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
- isFinite(width) && width > 0,
326
+ isNumber(width) && width > 0,
327
327
  "rect: 3rd param must be a positive number"
328
328
  );
329
329
  DEV: assert(
330
- isFinite(height) && height >= 0,
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 || isFinite(color) && color >= 0,
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 || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
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 = null) {
362
- DEV: assert(isFinite(x), "rectfill: 1st param must be a number");
363
- DEV: assert(isFinite(y), "rectfill: 2nd param must be a number");
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
- isFinite(width) && width >= 0,
365
+ isNumber(width) && width >= 0,
366
366
  "rectfill: 3rd param must be a positive number or zero"
367
367
  );
368
368
  DEV: assert(
369
- isFinite(height) && height >= 0,
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 || isFinite(color) && color >= 0,
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 || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
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(isFinite(x), "circ: 1st param must be a number");
400
- DEV: assert(isFinite(y), "circ: 2nd param must be a number");
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
- isFinite(radius) && radius >= 0,
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 || isFinite(color) && color >= 0,
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(isFinite(x), "circfill: 1st param must be a number");
423
- DEV: assert(isFinite(y), "circfill: 2nd param must be a number");
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
- isFinite(radius) && radius >= 0,
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 || isFinite(color) && color >= 0,
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(isFinite(x1), "line: 1st param must be a number");
447
- DEV: assert(isFinite(y1), "line: 2nd param must be a number");
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
- isFinite(x2),
449
+ isNumber(x2),
450
450
  "line: 3rd param must be a positive number or zero"
451
451
  );
452
452
  DEV: assert(
453
- isFinite(y2),
453
+ isNumber(y2),
454
454
  "line: 4th param must be a positive number or zero"
455
455
  );
456
456
  DEV: assert(
457
- null == color || isFinite(color) && color >= 0,
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
- isFinite(value) && ~~value > 0,
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 === 0 ? 0 : 0.5;
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
- isFinite(offset),
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(isFinite(x), "text: 1st param must be a number");
513
- DEV: assert(isFinite(y), "text: 2nd param must be a number");
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 || isFinite(color) && color >= 0,
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(isFinite(size), "textsize: 1st param must be a number");
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(isFinite(x), "image: 1st param must be a number");
584
- DEV: assert(isFinite(y), "image: 2nd param must be a number");
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
- * Creates a offscreen canvas to draw on it
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 {OffscreenCanvas}
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(isFinite(width), "paint: 1st param must be a number");
601
- DEV: assert(isFinite(height), "paint: 2nd param must be a number");
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 || isFinite(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(isFinite(x), "translate: 1st param must be a number");
668
- DEV: assert(isFinite(y), "translate: 2nd param must be a number");
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(isFinite(x), "scale: 1st param must be a number");
678
+ DEV: assert(isNumber(x), "scale: 1st param must be a number");
679
679
  DEV: assert(
680
- y == null || isFinite(y),
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(isFinite(radians), "rotate: 1st param must be a number");
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(isFinite(value), "alpha: 1st param must be a number");
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 || isFinite(color) && color >= 0,
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 || isFinite(color) && color >= 0,
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(isFinite(pitchSlide), "sfx: 2nd param must be a number");
794
+ DEV: assert(isNumber(pitchSlide), "sfx: 2nd param must be a number");
795
795
  DEV: assert(
796
- isFinite(volumeFactor),
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(isFinite(value), "volume: 1st param must be a number");
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 || isFinite(index) && index >= 0,
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 (value == null) {
902
+ if (null == value) {
903
903
  console.warn(`setvar: key "${key}" was defined as ${value}`);
904
904
  }
905
905
  instance[key] = value;
906
- if (_global) {
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
- isFinite(value),
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
- isFinite(value) && value >= 1,
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 (_global) {
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?} key
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?} key
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 (_animated) {
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 || isFinite(settings.width) && settings.width > 0,
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 || isFinite(settings.height) && settings.height > 0,
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 (!_animated) {
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 (_global) {
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;