litecanvas 0.207.1 → 0.208.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 CHANGED
@@ -113,15 +113,14 @@
113
113
  };
114
114
  var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"];
115
115
  var assert = (condition, message = "Assertion failed") => {
116
- if (!condition) throw new Error("[litecanvas] " + message);
116
+ if (!condition) throw new Error("[Litecanvas] " + message);
117
117
  };
118
- var version = "0.207.1";
118
+ var version = "0.208.0";
119
119
  function litecanvas(settings = {}) {
120
120
  const root = window,
121
121
  math = Math,
122
122
  perf = performance,
123
123
  TWO_PI = math.PI * 2,
124
- loggerPrefix = "[Litecanvas] ",
125
124
  raf = requestAnimationFrame,
126
125
  isNumber = Number.isFinite,
127
126
  _browserEventListeners = [],
@@ -145,6 +144,10 @@
145
144
  tapEvents: true,
146
145
  keyboardEvents: true,
147
146
  };
147
+ DEV: assert(
148
+ null == settings || "object" === typeof settings,
149
+ "litecanvas() 1st parameter must be a object",
150
+ );
148
151
  settings = Object.assign(defaults, settings);
149
152
  let _loop = settings.loop,
150
153
  _initialized = false,
@@ -176,36 +179,32 @@
176
179
  TWO_PI,
177
180
  HALF_PI: TWO_PI / 4,
178
181
  lerp: (start, end, t) => {
179
- DEV: assert(
180
- isNumber(start),
181
- loggerPrefix + "lerp() 1st param must be a number",
182
- );
183
- DEV: assert(
184
- isNumber(end),
185
- loggerPrefix + "lerp() 2nd param must be a number",
186
- );
187
- DEV: assert(
188
- isNumber(t),
189
- loggerPrefix + "lerp() 3rd param must be a number",
190
- );
182
+ DEV: assert(isNumber(start), "lerp() 1st parameter must be a number");
183
+ DEV: assert(isNumber(end), "lerp() 2nd parameter must be a number");
184
+ DEV: assert(isNumber(t), "lerp() 3rd parameter must be a number");
191
185
  return start + t * (end - start);
192
186
  },
193
187
  deg2rad: (degs) => {
194
- DEV: assert(isNumber(degs), "deg2rad() 1st param must be a number");
188
+ DEV: assert(isNumber(degs), "deg2rad() 1st parameter must be a number");
195
189
  return (math.PI / 180) * degs;
196
190
  },
197
191
  rad2deg: (rads) => {
198
- DEV: assert(isNumber(rads), "rad2deg() 1st param must be a number");
192
+ DEV: assert(isNumber(rads), "rad2deg() 1st parameter must be a number");
199
193
  return (180 / math.PI) * rads;
200
194
  },
201
- round: (n, precision = 0) => {
195
+ mod(a, b) {
196
+ DEV: assert(isNumber(a), "mod() 1st parameter must be a number");
202
197
  DEV: assert(
203
- isNumber(n),
204
- loggerPrefix + "round() 1st param must be a number",
198
+ isNumber(b) && b >= 0,
199
+ "mod() 2nd parameter must be a non-negative number",
205
200
  );
201
+ return ((a % b) + b) % b || 0;
202
+ },
203
+ round: (n, precision = 0) => {
204
+ DEV: assert(isNumber(n), "round() 1st parameter must be a number");
206
205
  DEV: assert(
207
206
  isNumber(precision) && precision >= 0,
208
- loggerPrefix + "round() 2nd param must be a positive number or zero",
207
+ "round() 2nd parameter must be a non-negative number",
209
208
  );
210
209
  if (!precision) {
211
210
  return math.round(n);
@@ -214,127 +213,64 @@
214
213
  return math.round(n * multiplier) / multiplier;
215
214
  },
216
215
  clamp: (value, min, max) => {
217
- DEV: assert(
218
- isNumber(value),
219
- loggerPrefix + "clamp() 1st param must be a number",
220
- );
221
- DEV: assert(
222
- isNumber(min),
223
- loggerPrefix + "clamp() 2nd param must be a number",
224
- );
225
- DEV: assert(
226
- isNumber(max),
227
- loggerPrefix + "clamp() 3rd param must be a number",
228
- );
216
+ DEV: assert(isNumber(value), "clamp() 1st parameter must be a number");
217
+ DEV: assert(isNumber(min), "clamp() 2nd parameter must be a number");
218
+ DEV: assert(isNumber(max), "clamp() 3rd parameter must be a number");
229
219
  DEV: assert(
230
220
  max >= min,
231
- loggerPrefix +
232
- "clamp() the 2nd param must be less than the 3rd param",
221
+ "clamp() the 2nd parameter must be less than the 3rd parameter",
233
222
  );
234
223
  if (value < min) return min;
235
224
  if (value > max) return max;
236
225
  return value;
237
226
  },
238
227
  dist: (x1, y1, x2, y2) => {
239
- DEV: assert(
240
- isNumber(x1),
241
- loggerPrefix + "dist() 1st param must be a number",
242
- );
243
- DEV: assert(
244
- isNumber(y1),
245
- loggerPrefix + "dist() 2nd param must be a number",
246
- );
247
- DEV: assert(
248
- isNumber(x2),
249
- loggerPrefix + "dist() 3rd param must be a number",
250
- );
251
- DEV: assert(
252
- isNumber(y2),
253
- loggerPrefix + "dist() 4th param must be a number",
254
- );
228
+ DEV: assert(isNumber(x1), "dist() 1st parameter must be a number");
229
+ DEV: assert(isNumber(y1), "dist() 2nd parameter must be a number");
230
+ DEV: assert(isNumber(x2), "dist() 3rd parameter must be a number");
231
+ DEV: assert(isNumber(y2), "dist() 4th parameter must be a number");
255
232
  return math.hypot(x2 - x1, y2 - y1);
256
233
  },
257
234
  wrap: (value, min, max) => {
258
- DEV: assert(
259
- isNumber(value),
260
- loggerPrefix + "wrap() 1st param must be a number",
261
- );
262
- DEV: assert(
263
- isNumber(min),
264
- loggerPrefix + "wrap() 2nd param must be a number",
265
- );
266
- DEV: assert(
267
- isNumber(max),
268
- loggerPrefix + "wrap() 3rd param must be a number",
269
- );
235
+ DEV: assert(isNumber(value), "wrap() 1st parameter must be a number");
236
+ DEV: assert(isNumber(min), "wrap() 2nd parameter must be a number");
237
+ DEV: assert(isNumber(max), "wrap() 3rd parameter must be a number");
270
238
  DEV: assert(
271
239
  max > min,
272
- loggerPrefix + "wrap() the 2nd param must be less than the 3rd param",
240
+ "wrap() the 2nd parameter must be less than the 3rd parameter",
273
241
  );
274
242
  return value - (max - min) * math.floor((value - min) / (max - min));
275
243
  },
276
244
  map(value, start1, stop1, start2, stop2, withinBounds) {
277
- DEV: assert(
278
- isNumber(value),
279
- loggerPrefix + "map() 1st param must be a number",
280
- );
281
- DEV: assert(
282
- isNumber(start1),
283
- loggerPrefix + "map() 2nd param must be a number",
284
- );
285
- DEV: assert(
286
- isNumber(stop1),
287
- loggerPrefix + "map() 3rd param must be a number",
288
- );
289
- DEV: assert(
290
- isNumber(start2),
291
- loggerPrefix + "map() 4th param must be a number",
292
- );
293
- DEV: assert(
294
- isNumber(stop2),
295
- loggerPrefix + "map() 5th param must be a number",
296
- );
245
+ DEV: assert(isNumber(value), "map() 1st parameter must be a number");
246
+ DEV: assert(isNumber(start1), "map() 2nd parameter must be a number");
247
+ DEV: assert(isNumber(stop1), "map() 3rd parameter must be a number");
248
+ DEV: assert(isNumber(start2), "map() 4th parameter must be a number");
249
+ DEV: assert(isNumber(stop2), "map() 5th parameter must be a number");
297
250
  DEV: assert(
298
251
  stop1 !== start1,
299
- loggerPrefix +
300
- "map() the 2nd param must be different than the 3rd param",
252
+ "map() the 2nd parameter must be different than the 3rd parameter",
301
253
  );
302
254
  const result =
303
255
  ((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
304
256
  return withinBounds ? instance.clamp(result, start2, stop2) : result;
305
257
  },
306
258
  norm: (value, start, stop) => {
307
- DEV: assert(
308
- isNumber(value),
309
- loggerPrefix + "norm() 1st param must be a number",
310
- );
311
- DEV: assert(
312
- isNumber(start),
313
- loggerPrefix + "norm() 2nd param must be a number",
314
- );
315
- DEV: assert(
316
- isNumber(stop),
317
- loggerPrefix + "norm() 3rd param must be a number",
318
- );
259
+ DEV: assert(isNumber(value), "norm() 1st parameter must be a number");
260
+ DEV: assert(isNumber(start), "norm() 2nd parameter must be a number");
261
+ DEV: assert(isNumber(stop), "norm() 3rd parameter must be a number");
319
262
  DEV: assert(
320
263
  start !== stop,
321
- loggerPrefix +
322
- "norm() the 2nd param must be different than the 3rd param",
264
+ "norm() the 2nd parameter must be different than the 3rd parameter",
323
265
  );
324
266
  return instance.map(value, start, stop, 0, 1);
325
267
  },
326
268
  rand: (min = 0, max = 1) => {
327
- DEV: assert(
328
- isNumber(min),
329
- loggerPrefix + "rand() 1st param must be a number",
330
- );
331
- DEV: assert(
332
- isNumber(max),
333
- loggerPrefix + "rand() 2nd param must be a number",
334
- );
269
+ DEV: assert(isNumber(min), "rand() 1st parameter must be a number");
270
+ DEV: assert(isNumber(max), "rand() 2nd parameter must be a number");
335
271
  DEV: assert(
336
272
  max >= min,
337
- loggerPrefix + "rand() the 1st param must be less than the 2nd param",
273
+ "rand() the 1st parameter must be less than the 2nd parameter",
338
274
  );
339
275
  const a = 1664525;
340
276
  const c = 1013904223;
@@ -343,33 +279,25 @@
343
279
  return (_rngSeed / m) * (max - min) + min;
344
280
  },
345
281
  randi: (min = 0, max = 1) => {
346
- DEV: assert(
347
- isNumber(min),
348
- loggerPrefix + "randi() 1st param must be a number",
349
- );
350
- DEV: assert(
351
- isNumber(max),
352
- loggerPrefix + "randi() 2nd param must be a number",
353
- );
282
+ DEV: assert(isNumber(min), "randi() 1st parameter must be a number");
283
+ DEV: assert(isNumber(max), "randi() 2nd parameter must be a number");
354
284
  DEV: assert(
355
285
  max >= min,
356
- loggerPrefix +
357
- "randi() the 1st param must be less than the 2nd param",
286
+ "randi() the 1st parameter must be less than the 2nd parameter",
358
287
  );
359
288
  return ~~instance.rand(min, max + 1);
360
289
  },
361
290
  rseed(value) {
362
291
  DEV: assert(
363
292
  isNumber(value) && value >= 0,
364
- loggerPrefix + "rseed() 1st param must be a positive integer or zero",
293
+ "rseed() 1st parameter must be a non-negative integer",
365
294
  );
366
295
  _rngSeed = ~~value;
367
296
  },
368
297
  cls(color) {
369
298
  DEV: assert(
370
299
  null == color || (isNumber(color) && color >= 0),
371
- loggerPrefix +
372
- "cls() 1st param must be a positive number or zero or undefined",
300
+ "cls() 1st parameter must be a non-negative number",
373
301
  );
374
302
  if (null == color) {
375
303
  _ctx.clearRect(0, 0, instance.W, instance.H);
@@ -378,32 +306,25 @@
378
306
  }
379
307
  },
380
308
  rect(x, y, width, height, color, radii) {
381
- DEV: assert(
382
- isNumber(x),
383
- loggerPrefix + "rect() 1st param must be a number",
384
- );
385
- DEV: assert(
386
- isNumber(y),
387
- loggerPrefix + "rect() 2nd param must be a number",
388
- );
309
+ DEV: assert(isNumber(x), "rect() 1st parameter must be a number");
310
+ DEV: assert(isNumber(y), "rect() 2nd parameter must be a number");
389
311
  DEV: assert(
390
312
  isNumber(width) && width > 0,
391
- loggerPrefix + "rect() 3rd param must be a positive number",
313
+ "rect() 3rd parameter must be a positive number",
392
314
  );
393
315
  DEV: assert(
394
316
  isNumber(height) && height >= 0,
395
- loggerPrefix + "rect() 4th param must be a positive number or zero",
317
+ "rect() 4th parameter must be a non-negative number",
396
318
  );
397
319
  DEV: assert(
398
320
  null == color || (isNumber(color) && color >= 0),
399
- loggerPrefix + "rect() 5th param must be a positive number or zero",
321
+ "rect() 5th parameter must be a non-negative number",
400
322
  );
401
323
  DEV: assert(
402
324
  null == radii ||
403
325
  isNumber(radii) ||
404
326
  (Array.isArray(radii) && radii.length >= 1),
405
- loggerPrefix +
406
- "rect() 6th param must be a number or array of numbers",
327
+ "rect() 6th parameter must be a number or array of numbers",
407
328
  );
408
329
  beginPath(_ctx);
409
330
  _ctx[radii ? "roundRect" : "rect"](
@@ -416,177 +337,131 @@
416
337
  instance.stroke(color);
417
338
  },
418
339
  rectfill(x, y, width, height, color, radii) {
419
- DEV: assert(
420
- isNumber(x),
421
- loggerPrefix + "rectfill() 1st param must be a number",
422
- );
423
- DEV: assert(
424
- isNumber(y),
425
- loggerPrefix + "rectfill() 2nd param must be a number",
426
- );
340
+ DEV: assert(isNumber(x), "rectfill() 1st parameter must be a number");
341
+ DEV: assert(isNumber(y), "rectfill() 2nd parameter must be a number");
427
342
  DEV: assert(
428
343
  isNumber(width) && width >= 0,
429
- loggerPrefix +
430
- "rectfill() 3rd param must be a positive number or zero",
344
+ "rectfill() 3rd parameter must be a non-negative number",
431
345
  );
432
346
  DEV: assert(
433
347
  isNumber(height) && height >= 0,
434
- loggerPrefix +
435
- "rectfill() 4th param must be a positive number or zero",
348
+ "rectfill() 4th parameter must be a non-negative number",
436
349
  );
437
350
  DEV: assert(
438
351
  null == color || (isNumber(color) && color >= 0),
439
- loggerPrefix +
440
- "rectfill() 5th param must be a positive number or zero",
352
+ "rectfill() 5th parameter must be a non-negative number",
441
353
  );
442
354
  DEV: assert(
443
355
  null == radii ||
444
356
  isNumber(radii) ||
445
357
  (Array.isArray(radii) && radii.length >= 1),
446
- loggerPrefix +
447
- "rectfill() 6th param must be a number or array of at least 2 numbers",
358
+ "rectfill() 6th parameter must be a number or array of at least 2 numbers",
448
359
  );
449
360
  beginPath(_ctx);
450
361
  _ctx[radii ? "roundRect" : "rect"](~~x, ~~y, ~~width, ~~height, radii);
451
362
  instance.fill(color);
452
363
  },
453
364
  oval(x, y, radiusX, radiusY, color) {
454
- DEV: assert(
455
- isNumber(x),
456
- loggerPrefix + "oval() 1st param must be a number",
457
- );
458
- DEV: assert(
459
- isNumber(y),
460
- loggerPrefix + "oval() 2nd param must be a number",
461
- );
365
+ DEV: assert(isNumber(x), "oval() 1st parameter must be a number");
366
+ DEV: assert(isNumber(y), "oval() 2nd parameter must be a number");
462
367
  DEV: assert(
463
368
  isNumber(radiusX) && radiusX >= 0,
464
- loggerPrefix + "oval() 3rd param must be a positive number or zero",
369
+ "oval() 3rd parameter must be a non-negative number",
465
370
  );
466
371
  DEV: assert(
467
372
  isNumber(radiusY) && radiusY >= 0,
468
- loggerPrefix + "oval() 4th param must be a positive number or zero",
373
+ "oval() 4th parameter must be a non-negative number",
469
374
  );
470
375
  DEV: assert(
471
376
  null == color || (isNumber(color) && color >= 0),
472
- loggerPrefix + "oval() 5th param must be a positive number or zero",
377
+ "oval() 5th parameter must be a non-negative number",
473
378
  );
474
379
  beginPath(_ctx);
475
380
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
476
381
  instance.stroke(color);
477
382
  },
478
383
  ovalfill(x, y, radiusX, radiusY, color) {
479
- DEV: assert(
480
- isNumber(x),
481
- loggerPrefix + "ovalfill() 1st param must be a number",
482
- );
483
- DEV: assert(
484
- isNumber(y),
485
- loggerPrefix + "ovalfill() 2nd param must be a number",
486
- );
384
+ DEV: assert(isNumber(x), "ovalfill() 1st parameter must be a number");
385
+ DEV: assert(isNumber(y), "ovalfill() 2nd parameter must be a number");
487
386
  DEV: assert(
488
387
  isNumber(radiusX) && radiusX >= 0,
489
- loggerPrefix +
490
- "ovalfill() 3rd param must be a positive number or zero",
388
+ "ovalfill() 3rd parameter must be a non-negative number",
491
389
  );
492
390
  DEV: assert(
493
391
  isNumber(radiusY) && radiusY >= 0,
494
- loggerPrefix +
495
- "ovalfill() 4th param must be a positive number or zero",
392
+ "ovalfill() 4th parameter must be a non-negative number",
496
393
  );
497
394
  DEV: assert(
498
395
  null == color || (isNumber(color) && color >= 0),
499
- loggerPrefix +
500
- "ovalfill() 5th param must be a positive number or zero",
396
+ "ovalfill() 5th parameter must be a non-negative number",
501
397
  );
502
398
  beginPath(_ctx);
503
399
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
504
400
  instance.fill(color);
505
401
  },
506
402
  circ(x, y, radius, color) {
507
- DEV: assert(
508
- isNumber(x),
509
- loggerPrefix + "circ() 1st param must be a number",
510
- );
511
- DEV: assert(
512
- isNumber(y),
513
- loggerPrefix + "circ() 2nd param must be a number",
514
- );
403
+ DEV: assert(isNumber(x), "circ() 1st parameter must be a number");
404
+ DEV: assert(isNumber(y), "circ() 2nd parameter must be a number");
515
405
  DEV: assert(
516
406
  isNumber(radius) && radius >= 0,
517
- loggerPrefix + "circ() 3rd param must be a positive number or zero",
407
+ "circ() 3rd parameter must be a non-negative number",
518
408
  );
519
409
  DEV: assert(
520
410
  null == color || (isNumber(color) && color >= 0),
521
- loggerPrefix + "circ() 4th param must be a positive number or zero",
411
+ "circ() 4th parameter must be a non-negative number",
522
412
  );
523
413
  instance.oval(x, y, radius, radius, color);
524
414
  },
525
415
  circfill(x, y, radius, color) {
526
- DEV: assert(
527
- isNumber(x),
528
- loggerPrefix + "circfill() 1st param must be a number",
529
- );
530
- DEV: assert(
531
- isNumber(y),
532
- loggerPrefix + "circfill() 2nd param must be a number",
533
- );
416
+ DEV: assert(isNumber(x), "circfill() 1st parameter must be a number");
417
+ DEV: assert(isNumber(y), "circfill() 2nd parameter must be a number");
534
418
  DEV: assert(
535
419
  isNumber(radius) && radius >= 0,
536
- loggerPrefix +
537
- "circfill() 3rd param must be a positive number or zero",
420
+ "circfill() 3rd parameter must be a non-negative number",
538
421
  );
539
422
  DEV: assert(
540
423
  null == color || (isNumber(color) && color >= 0),
541
- loggerPrefix +
542
- "circfill() 4th param must be a positive number or zero",
424
+ "circfill() 4th parameter must be a non-negative number",
543
425
  );
544
426
  instance.ovalfill(x, y, radius, radius, color);
545
427
  },
546
428
  shape(points) {
547
429
  DEV: assert(
548
430
  Array.isArray(points),
549
- loggerPrefix + "shape() 1st param must be an array of numbers",
431
+ "shape() 1st parameter must be an array of numbers",
550
432
  );
551
433
  DEV: assert(
552
434
  points.length >= 6,
553
- loggerPrefix +
554
- "shape() 1st param must be an array with at least 6 numbers (3 points)",
435
+ "shape() 1st parameter must be an array with at least 6 numbers (3 points)",
555
436
  );
556
437
  beginPath(_ctx);
557
438
  for (let i = 0; i < points.length; i += 2) {
558
- if (0 === i) {
559
- _ctx.moveTo(~~points[i], ~~points[i + 1]);
560
- } else {
439
+ if (i) {
561
440
  _ctx.lineTo(~~points[i], ~~points[i + 1]);
441
+ } else {
442
+ _ctx.moveTo(~~points[i], ~~points[i + 1]);
562
443
  }
563
444
  }
564
445
  _ctx.lineTo(~~points[0], ~~points[1]);
565
446
  },
566
447
  line(x1, y1, x2, y2, color) {
567
- DEV: assert(
568
- isNumber(x1),
569
- loggerPrefix + "line() 1st param must be a number",
570
- );
571
- DEV: assert(
572
- isNumber(y1),
573
- loggerPrefix + "line() 2nd param must be a number",
574
- );
448
+ DEV: assert(isNumber(x1), "line() 1st parameter must be a number");
449
+ DEV: assert(isNumber(y1), "line() 2nd parameter must be a number");
575
450
  DEV: assert(
576
451
  isNumber(x2),
577
- loggerPrefix + "line() 3rd param must be a positive number or zero",
452
+ "line() 3rd parameter must be a non-negative number",
578
453
  );
579
454
  DEV: assert(
580
455
  isNumber(y2),
581
- loggerPrefix + "line() 4th param must be a positive number or zero",
456
+ "line() 4th parameter must be a non-negative number",
582
457
  );
583
458
  DEV: assert(
584
459
  null == color || (isNumber(color) && color >= 0),
585
- loggerPrefix + "line() 5th param must be a positive number or zero",
460
+ "line() 5th parameter must be a non-negative number",
586
461
  );
587
462
  beginPath(_ctx);
588
- let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0;
589
- let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0;
463
+ let xfix = _outline_fix && ~~x1 === ~~x2 ? 0.5 : 0;
464
+ let yfix = _outline_fix && ~~y1 === ~~y2 ? 0.5 : 0;
590
465
  _ctx.moveTo(~~x1 + xfix, ~~y1 + yfix);
591
466
  _ctx.lineTo(~~x2 + xfix, ~~y2 + yfix);
592
467
  instance.stroke(color);
@@ -594,40 +469,33 @@
594
469
  linewidth(value) {
595
470
  DEV: assert(
596
471
  isNumber(value) && value >= 0,
597
- loggerPrefix +
598
- "linewidth() 1st param must be a positive number or zero",
472
+ "linewidth() 1st parameter must be a non-negative integer",
599
473
  );
600
474
  _ctx.lineWidth = ~~value;
601
- _outline_fix = 0 === ~~value % 2 ? 0 : 0.5;
475
+ _outline_fix = ~~value % 2 ? 0.5 : 0;
602
476
  },
603
477
  linedash(segments, offset = 0) {
604
478
  DEV: assert(
605
479
  Array.isArray(segments) && segments.length > 0,
606
- loggerPrefix + "linedash() 1st param must be an array of numbers",
480
+ "linedash() 1st parameter must be an array of numbers",
607
481
  );
608
482
  DEV: assert(
609
483
  isNumber(offset),
610
- loggerPrefix + "linedash() 2nd param must be a number",
484
+ "linedash() 2nd parameter must be a number",
611
485
  );
612
486
  _ctx.setLineDash(segments);
613
487
  _ctx.lineDashOffset = offset;
614
488
  },
615
489
  text(x, y, message, color = _defaultTextColor, fontStyle = "normal") {
616
- DEV: assert(
617
- isNumber(x),
618
- loggerPrefix + "text() 1st param must be a number",
619
- );
620
- DEV: assert(
621
- isNumber(y),
622
- loggerPrefix + "text() 2nd param must be a number",
623
- );
490
+ DEV: assert(isNumber(x), "text() 1st parameter must be a number");
491
+ DEV: assert(isNumber(y), "text() 2nd parameter must be a number");
624
492
  DEV: assert(
625
493
  null == color || (isNumber(color) && color >= 0),
626
- loggerPrefix + "text() 4th param must be a positive number or zero",
494
+ "text() 4th parameter must be a non-negative number",
627
495
  );
628
496
  DEV: assert(
629
497
  "string" === typeof fontStyle,
630
- loggerPrefix + "text() 5th param must be a string",
498
+ "text() 5th parameter must be a string",
631
499
  );
632
500
  _ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
633
501
  _ctx.fillStyle = getColor(color);
@@ -643,21 +511,21 @@
643
511
  textgap(value) {
644
512
  DEV: assert(
645
513
  isNumber(value),
646
- loggerPrefix + "textgap() 1st param must be a number",
514
+ "textgap() 1st parameter must be a number",
647
515
  );
648
516
  _fontLineHeight = value;
649
517
  },
650
518
  textfont(family) {
651
519
  DEV: assert(
652
520
  "string" === typeof family,
653
- loggerPrefix + "textfont() 1st param must be a string",
521
+ "textfont() 1st parameter must be a string",
654
522
  );
655
523
  _fontFamily = family;
656
524
  },
657
525
  textsize(size) {
658
526
  DEV: assert(
659
527
  isNumber(size),
660
- loggerPrefix + "textsize() 1st param must be a number",
528
+ "textsize() 1st parameter must be a number",
661
529
  );
662
530
  _fontSize = size;
663
531
  },
@@ -665,8 +533,7 @@
665
533
  DEV: assert(
666
534
  null == align ||
667
535
  ["left", "right", "center", "start", "end"].includes(align),
668
- loggerPrefix +
669
- "textalign() 1st param must be null or one of the following strings: center, left, right, start or end.",
536
+ "textalign() 1st parameter must be null or one of the following strings: center, left, right, start or end.",
670
537
  );
671
538
  DEV: assert(
672
539
  null == baseline ||
@@ -678,35 +545,22 @@
678
545
  "alphabetic",
679
546
  "ideographic",
680
547
  ].includes(baseline),
681
- loggerPrefix +
682
- "textalign() 2nd param must be null or one of the following strings: middle, top, bottom, hanging, alphabetic or ideographic.",
548
+ "textalign() 2nd parameter must be null or one of the following strings: middle, top, bottom, hanging, alphabetic or ideographic.",
683
549
  );
684
550
  if (align) _ctx.textAlign = align;
685
551
  if (baseline) _ctx.textBaseline = baseline;
686
552
  },
687
553
  image(x, y, source) {
688
- DEV: assert(
689
- isNumber(x),
690
- loggerPrefix + "image() 1st param must be a number",
691
- );
692
- DEV: assert(
693
- isNumber(y),
694
- loggerPrefix + "image() 2nd param must be a number",
695
- );
554
+ DEV: assert(isNumber(x), "image() 1st parameter must be a number");
555
+ DEV: assert(isNumber(y), "image() 2nd parameter must be a number");
696
556
  _ctx.drawImage(source, ~~x, ~~y);
697
557
  },
698
558
  spr(x, y, pixels) {
699
- DEV: assert(
700
- isNumber(x),
701
- loggerPrefix + "spr() 1st param must be a number",
702
- );
703
- DEV: assert(
704
- isNumber(y),
705
- loggerPrefix + "spr() 2nd param must be a number",
706
- );
559
+ DEV: assert(isNumber(x), "spr() 1st parameter must be a number");
560
+ DEV: assert(isNumber(y), "spr() 2nd parameter must be a number");
707
561
  DEV: assert(
708
562
  "string" === typeof pixels,
709
- loggerPrefix + "spr() 3rd param must be a string",
563
+ "spr() 3rd parameter must be a string",
710
564
  );
711
565
  const rows = pixels.trim().split("\n");
712
566
  for (let row = 0; row < rows.length; row++) {
@@ -728,27 +582,25 @@
728
582
  paint(width, height, callback, options = {}) {
729
583
  DEV: assert(
730
584
  isNumber(width) && width >= 1,
731
- loggerPrefix + "paint() 1st param must be a positive number",
585
+ "paint() 1st parameter must be a positive number",
732
586
  );
733
587
  DEV: assert(
734
588
  isNumber(height) && height >= 1,
735
- loggerPrefix + "paint() 2nd param must be a positive number",
589
+ "paint() 2nd parameter must be a positive number",
736
590
  );
737
591
  DEV: assert(
738
592
  "function" === typeof callback,
739
- loggerPrefix + "paint() 3rd param must be a function",
593
+ "paint() 3rd parameter must be a function",
740
594
  );
741
595
  DEV: assert(
742
596
  (options && null == options.scale) ||
743
597
  (isNumber(options.scale) && options.scale > 0),
744
- loggerPrefix +
745
- "paint() 4th param (options.scale) must be a positive number",
598
+ "paint() 4th parameter (options.scale) must be a positive number",
746
599
  );
747
600
  DEV: assert(
748
601
  (options && null == options.canvas) ||
749
602
  options.canvas instanceof OffscreenCanvas,
750
- loggerPrefix +
751
- "paint() 4th param (options.canvas) must be an OffscreenCanvas",
603
+ "paint() 4th parameter (options.canvas) must be an OffscreenCanvas",
752
604
  );
753
605
  const canvas = options.canvas || new OffscreenCanvas(1, 1),
754
606
  scale = options.scale || 1,
@@ -766,60 +618,67 @@
766
618
  null == context ||
767
619
  context instanceof CanvasRenderingContext2D ||
768
620
  context instanceof OffscreenCanvasRenderingContext2D,
769
- loggerPrefix +
770
- "ctx() 1st param must be an [Offscreen]CanvasRenderingContext2D",
621
+ "ctx() 1st parameter must be an [Offscreen]CanvasRenderingContext2D",
771
622
  );
772
623
  if (context) {
773
624
  _ctx = context;
774
625
  }
775
626
  return _ctx;
776
627
  },
777
- push() {
628
+ push(
629
+ translateX = 0,
630
+ translateY = translateX,
631
+ rotation = 0,
632
+ scaleX = 1,
633
+ scaleY = scaleX,
634
+ ) {
635
+ DEV: assert(
636
+ isNumber(translateX),
637
+ "push() 1st parameter must be a number",
638
+ );
639
+ DEV: assert(
640
+ isNumber(translateY),
641
+ "push() 2nd parameter must be a number",
642
+ );
643
+ DEV: assert(
644
+ isNumber(rotation),
645
+ "push() 3rd parameter must be a number",
646
+ );
647
+ DEV: assert(isNumber(scaleX), "push() 4th parameter must be a number");
648
+ DEV: assert(isNumber(scaleY), "push() 5th parameter must be a number");
778
649
  _ctx.save();
650
+ instance.translate(translateX, translateY);
651
+ instance.rotate(rotation);
652
+ instance.scale(scaleX, scaleY);
779
653
  },
780
654
  pop() {
781
655
  _ctx.restore();
782
656
  },
783
657
  translate(x, y) {
784
- DEV: assert(
785
- isNumber(x),
786
- loggerPrefix + "translate() 1st param must be a number",
787
- );
788
- DEV: assert(
789
- isNumber(y),
790
- loggerPrefix + "translate() 2nd param must be a number",
791
- );
658
+ DEV: assert(isNumber(x), "translate() 1st parameter must be a number");
659
+ DEV: assert(isNumber(y), "translate() 2nd parameter must be a number");
792
660
  _ctx.translate(~~x, ~~y);
793
661
  },
794
662
  scale(x, y = x) {
795
- DEV: assert(
796
- isNumber(x),
797
- loggerPrefix + "scale() 1st param must be a number",
798
- );
799
- DEV: assert(
800
- isNumber(y),
801
- loggerPrefix + "scale() 2nd param must be a number",
802
- );
663
+ DEV: assert(isNumber(x), "scale() 1st parameter must be a number");
664
+ DEV: assert(isNumber(y), "scale() 2nd parameter must be a number");
803
665
  _ctx.scale(x, y);
804
666
  },
805
667
  rotate(radians) {
806
668
  DEV: assert(
807
669
  isNumber(radians),
808
- loggerPrefix + "rotate() 1st param must be a number",
670
+ "rotate() 1st parameter must be a number",
809
671
  );
810
672
  _ctx.rotate(radians);
811
673
  },
812
674
  alpha(value) {
813
- DEV: assert(
814
- isNumber(value),
815
- loggerPrefix + "alpha() 1st param must be a number",
816
- );
675
+ DEV: assert(isNumber(value), "alpha() 1st parameter must be a number");
817
676
  _ctx.globalAlpha = instance.clamp(value, 0, 1);
818
677
  },
819
678
  fill(color) {
820
679
  DEV: assert(
821
680
  null == color || (isNumber(color) && color >= 0),
822
- loggerPrefix + "fill() 1st param must be a positive number or zero",
681
+ "fill() 1st parameter must be a non-negative number",
823
682
  );
824
683
  _ctx.fillStyle = getColor(color);
825
684
  _ctx.fill();
@@ -827,7 +686,7 @@
827
686
  stroke(color) {
828
687
  DEV: assert(
829
688
  null == color || (isNumber(color) && color >= 0),
830
- loggerPrefix + "stroke() 1st param must be a positive number or zero",
689
+ "stroke() 1st parameter must be a non-negative number",
831
690
  );
832
691
  _ctx.strokeStyle = getColor(color);
833
692
  _ctx.stroke();
@@ -835,7 +694,7 @@
835
694
  clip(callback) {
836
695
  DEV: assert(
837
696
  "function" === typeof callback,
838
- loggerPrefix + "clip() 1st param must be a function (ctx) => void",
697
+ "clip() 1st parameter must be a function (ctx) => void",
839
698
  );
840
699
  beginPath(_ctx);
841
700
  callback(_ctx);
@@ -844,15 +703,15 @@
844
703
  sfx(zzfxParams, pitchSlide, volumeFactor) {
845
704
  DEV: assert(
846
705
  null == zzfxParams || Array.isArray(zzfxParams),
847
- loggerPrefix + "sfx() 1st param must be an array",
706
+ "sfx() 1st parameter must be an array",
848
707
  );
849
708
  DEV: assert(
850
709
  null == pitchSlide || isNumber(pitchSlide),
851
- loggerPrefix + "sfx() 2nd param must be a number",
710
+ "sfx() 2nd parameter must be a number",
852
711
  );
853
712
  DEV: assert(
854
713
  null == volumeFactor || isNumber(volumeFactor),
855
- loggerPrefix + "sfx() 3rd param must be a number",
714
+ "sfx() 3rd parameter must be a number",
856
715
  );
857
716
  if (
858
717
  !root.zzfxV ||
@@ -865,7 +724,6 @@
865
724
  zzfxParams = zzfxParams.slice();
866
725
  zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1);
867
726
  zzfxParams[10] = ~~zzfxParams[10] + pitchSlide;
868
- console.log(zzfxParams);
869
727
  }
870
728
  zzfx.apply(0, zzfxParams);
871
729
  return zzfxParams;
@@ -873,7 +731,7 @@
873
731
  volume(value) {
874
732
  DEV: assert(
875
733
  isNumber(value) && value >= 0,
876
- loggerPrefix + "volume() 1st param must be a positive number or zero",
734
+ "volume() 1st parameter must be a non-negative number",
877
735
  );
878
736
  root.zzfxV = value;
879
737
  },
@@ -881,23 +739,22 @@
881
739
  use(callback, config = {}) {
882
740
  DEV: assert(
883
741
  "function" === typeof callback,
884
- loggerPrefix +
885
- "use() 1st param must be a function (instance, config) => any",
742
+ "use() 1st parameter must be a function (instance, config) => any",
886
743
  );
887
744
  DEV: assert(
888
745
  "object" === typeof config,
889
- loggerPrefix + "use() 2nd param must be an object",
746
+ "use() 2nd parameter must be an object",
890
747
  );
891
748
  loadPlugin(callback, config);
892
749
  },
893
750
  listen: (eventName, callback) => {
894
751
  DEV: assert(
895
752
  "string" === typeof eventName,
896
- loggerPrefix + "listen() 1st param must be a string",
753
+ "listen() 1st parameter must be a string",
897
754
  );
898
755
  DEV: assert(
899
756
  "function" === typeof callback,
900
- loggerPrefix + "listen() 2nd param must be a function",
757
+ "listen() 2nd parameter must be a function",
901
758
  );
902
759
  eventName = lowerCase(eventName);
903
760
  _eventListeners[eventName] = _eventListeners[eventName] || new Set();
@@ -906,11 +763,11 @@
906
763
  unlisten: (eventName, callback) => {
907
764
  DEV: assert(
908
765
  "string" === typeof eventName,
909
- loggerPrefix + "unlisten() 1st param must be a string",
766
+ "unlisten() 1st parameter must be a string",
910
767
  );
911
768
  DEV: assert(
912
769
  "function" === typeof callback,
913
- loggerPrefix + "unlisten() 2nd param must be a function",
770
+ "unlisten() 2nd parameter must be a function",
914
771
  );
915
772
  eventName = lowerCase(eventName);
916
773
  if (_eventListeners[eventName]) {
@@ -920,7 +777,7 @@
920
777
  emit(eventName, arg1, arg2, arg3, arg4) {
921
778
  DEV: assert(
922
779
  "string" === typeof eventName,
923
- loggerPrefix + "emit() 1st param must be a string",
780
+ "emit() 1st parameter must be a string",
924
781
  );
925
782
  if (_initialized) {
926
783
  eventName = lowerCase(eventName);
@@ -940,11 +797,11 @@
940
797
  pal(colors, textColor = 3) {
941
798
  DEV: assert(
942
799
  null == colors || (Array.isArray(colors) && colors.length > 0),
943
- loggerPrefix + "pal() 1st param must be a array of color strings",
800
+ "pal() 1st parameter must be null or an array of colors",
944
801
  );
945
802
  DEV: assert(
946
803
  isNumber(textColor) && textColor >= 0,
947
- loggerPrefix + "pal() 2nd param must be a positive number or zero",
804
+ "pal() 2nd parameter must be a non-negative number",
948
805
  );
949
806
  _colorPalette = colors || defaultPalette;
950
807
  _colorPaletteState = [];
@@ -954,13 +811,13 @@
954
811
  palc(a, b) {
955
812
  DEV: assert(
956
813
  null == a || (isNumber(a) && a >= 0),
957
- loggerPrefix + "palc() 1st param must be a positive number",
814
+ "palc() 1st parameter must be a positive number",
958
815
  );
959
816
  DEV: assert(
960
817
  isNumber(a) ? isNumber(b) && b >= 0 : null == b,
961
- loggerPrefix + "palc() 2nd param must be a positive number",
818
+ "palc() 2nd parameter must be a positive number",
962
819
  );
963
- if (a == null) {
820
+ if (null == a) {
964
821
  _colorPaletteState = [];
965
822
  } else {
966
823
  _colorPaletteState[a] = b;
@@ -969,12 +826,11 @@
969
826
  def(key, value) {
970
827
  DEV: assert(
971
828
  "string" === typeof key,
972
- loggerPrefix + "def() 1st param must be a string",
829
+ "def() 1st parameter must be a string",
973
830
  );
974
831
  DEV: if (null == value) {
975
832
  console.warn(
976
- loggerPrefix +
977
- `def() changed the key "${key}" to null (previous value was ${instance[key]})`,
833
+ `[litecanvas] def() changed the key "${key}" to null (previous value was ${instance[key]})`,
978
834
  );
979
835
  }
980
836
  instance[key] = value;
@@ -985,23 +841,19 @@
985
841
  timescale(value) {
986
842
  DEV: assert(
987
843
  isNumber(value) && value >= 0,
988
- loggerPrefix +
989
- "timescale() 1st param must be a positive number or zero",
844
+ "timescale() 1st parameter must be a non-negative number",
990
845
  );
991
846
  _timeScale = value;
992
847
  },
993
848
  framerate(value) {
994
849
  DEV: assert(
995
850
  isNumber(value) && value >= 1,
996
- loggerPrefix + "framerate() 1st param must be a positive number",
851
+ "framerate() 1st parameter must be a positive number",
997
852
  );
998
853
  _fpsInterval = 1e3 / ~~value;
999
854
  },
1000
855
  stat(index) {
1001
- DEV: assert(
1002
- isNumber(index),
1003
- loggerPrefix + "stat() 1st param must be a number",
1004
- );
856
+ DEV: assert(isNumber(index), "stat() 1st parameter must be a number");
1005
857
  const internals = [
1006
858
  settings,
1007
859
  _initialized,
@@ -1020,8 +872,7 @@
1020
872
  ];
1021
873
  DEV: assert(
1022
874
  index >= 0 && index < internals.length,
1023
- loggerPrefix +
1024
- "stat() 1st param must be a number between 0 and " +
875
+ "stat() 1st parameter must be a number between 0 and " +
1025
876
  (internals.length - 1),
1026
877
  );
1027
878
  return internals[index];
@@ -1036,8 +887,7 @@
1036
887
  resume() {
1037
888
  DEV: assert(
1038
889
  _initialized,
1039
- loggerPrefix +
1040
- 'resume() cannot be called before the "init" event and neither after the quit() function',
890
+ 'resume() cannot be called before the "init" event and neither after the quit() function',
1041
891
  );
1042
892
  if (_initialized && _paused) {
1043
893
  startGameLoop();
@@ -1063,7 +913,7 @@
1063
913
  delete root.ENGINE;
1064
914
  }
1065
915
  DEV: console.warn(
1066
- loggerPrefix + "quit() terminated a Litecanvas instance.",
916
+ "[litecanvas] quit() terminated a Litecanvas instance.",
1067
917
  );
1068
918
  },
1069
919
  };
@@ -1102,7 +952,7 @@
1102
952
  _checkTapped = (tap) => tap && perf.now() - tap.t <= 300;
1103
953
  let _pressingMouse = false;
1104
954
  on(_canvas, "mousedown", (ev) => {
1105
- if (ev.button === 0) {
955
+ if (!ev.button) {
1106
956
  preventDefault(ev);
1107
957
  const [x, y] = _getXY(ev);
1108
958
  instance.emit("tap", x, y, 0);
@@ -1111,7 +961,7 @@
1111
961
  }
1112
962
  });
1113
963
  on(_canvas, "mouseup", (ev) => {
1114
- if (ev.button === 0) {
964
+ if (!ev.button) {
1115
965
  preventDefault(ev);
1116
966
  const tap = _taps.get(0);
1117
967
  const [x, y] = _getXY(ev);
@@ -1153,10 +1003,8 @@
1153
1003
  const _touchEndHandler = (ev) => {
1154
1004
  preventDefault(ev);
1155
1005
  const existing = [];
1156
- if (ev.targetTouches.length > 0) {
1157
- for (const touch of ev.targetTouches) {
1158
- existing.push(touch.identifier + 1);
1159
- }
1006
+ for (const touch of ev.targetTouches) {
1007
+ existing.push(touch.identifier + 1);
1160
1008
  }
1161
1009
  for (const [id, tap] of _taps) {
1162
1010
  if (existing.includes(id)) continue;
@@ -1203,16 +1051,14 @@
1203
1051
  instance.def("iskeydown", (key) => {
1204
1052
  DEV: assert(
1205
1053
  null == key || "string" === typeof key,
1206
- loggerPrefix +
1207
- "iskeydown() 1st param must be a string or undefined",
1054
+ "iskeydown() 1st parameter must be a string or undefined",
1208
1055
  );
1209
1056
  return keyCheck(_keysDown, key);
1210
1057
  });
1211
1058
  instance.def("iskeypressed", (key) => {
1212
1059
  DEV: assert(
1213
1060
  null == key || "string" === typeof key,
1214
- loggerPrefix +
1215
- "iskeypressed() 1st param must be a string or undefined",
1061
+ "iskeypressed() 1st parameter must be a string or undefined",
1216
1062
  );
1217
1063
  return keyCheck(_keysPress, key);
1218
1064
  });
@@ -1251,8 +1097,7 @@
1251
1097
  _canvas = d.querySelector(settings.canvas);
1252
1098
  DEV: assert(
1253
1099
  null != _canvas,
1254
- loggerPrefix +
1255
- 'litecanvas() option "canvas" is an invalid CSS selector',
1100
+ 'litecanvas() option "canvas" is an invalid CSS selector',
1256
1101
  );
1257
1102
  } else {
1258
1103
  _canvas = settings.canvas;
@@ -1260,8 +1105,7 @@
1260
1105
  _canvas = _canvas || d.createElement("canvas");
1261
1106
  DEV: assert(
1262
1107
  _canvas instanceof HTMLElement && "CANVAS" === _canvas.tagName,
1263
- loggerPrefix +
1264
- 'litecanvas() option "canvas" should be a canvas element or string (CSS selector of a canvas)',
1108
+ 'litecanvas() option "canvas" should be a canvas element or string (CSS selector of a canvas)',
1265
1109
  );
1266
1110
  _ctx = _canvas.getContext("2d");
1267
1111
  on(_canvas, "click", () => focus());
@@ -1276,19 +1120,16 @@
1276
1120
  DEV: assert(
1277
1121
  null == settings.width ||
1278
1122
  (isNumber(settings.width) && settings.width > 0),
1279
- loggerPrefix +
1280
- 'litecanvas() option "width" should be a positive number when defined',
1123
+ 'litecanvas() option "width" should be a positive number when defined',
1281
1124
  );
1282
1125
  DEV: assert(
1283
1126
  null == settings.height ||
1284
1127
  (isNumber(settings.height) && settings.height > 0),
1285
- loggerPrefix +
1286
- 'litecanvas() option "height" should be a positive number when defined',
1128
+ 'litecanvas() option "height" should be a positive number when defined',
1287
1129
  );
1288
1130
  DEV: assert(
1289
1131
  null == settings.height || (settings.width > 0 && settings.height > 0),
1290
- loggerPrefix +
1291
- 'litecanvas() option "width" is required when the option "height" is defined',
1132
+ 'litecanvas() option "width" is required when the option "height" is defined',
1292
1133
  );
1293
1134
  const width = settings.width > 0 ? settings.width : innerWidth,
1294
1135
  height =
@@ -1324,8 +1165,7 @@
1324
1165
  const pluginData = callback(instance, config);
1325
1166
  DEV: assert(
1326
1167
  null == pluginData || "object" === typeof pluginData,
1327
- loggerPrefix +
1328
- "litecanvas() plugins should return an object or nothing",
1168
+ "litecanvas() plugins should return an object or nothing",
1329
1169
  );
1330
1170
  for (const key in pluginData) {
1331
1171
  instance.def(key, pluginData[key]);
@@ -1342,8 +1182,8 @@
1342
1182
  Object.assign(root, instance);
1343
1183
  root.ENGINE = instance;
1344
1184
  }
1345
- DEV: console.info(loggerPrefix + `version ${version} started`);
1346
- DEV: console.debug(loggerPrefix + `litecanvas() options =`, settings);
1185
+ DEV: console.info(`[litecanvas] version ${version} started`);
1186
+ DEV: console.debug(`[litecanvas] litecanvas() options =`, settings);
1347
1187
  setupCanvas();
1348
1188
  if (_loop) {
1349
1189
  for (const eventName in _loop) {