litecanvas 0.75.0 → 0.76.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/README.md +1 -1
- package/dist/dist.dev.js +342 -424
- package/dist/dist.js +40 -424
- package/dist/dist.min.js +1 -1
- package/package.json +4 -4
- package/src/index.js +406 -447
- package/src/types.js +0 -2
- package/types/types.d.ts +1 -9
package/dist/dist.js
CHANGED
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
() => elem.removeEventListener(evt, callback, false)
|
|
32
32
|
);
|
|
33
33
|
}, isFinite = Number.isFinite, defaults = {
|
|
34
|
-
fullscreen: true,
|
|
35
34
|
width: null,
|
|
36
35
|
height: null,
|
|
37
36
|
autoscale: true,
|
|
@@ -46,7 +45,7 @@
|
|
|
46
45
|
animate: true
|
|
47
46
|
};
|
|
48
47
|
settings = Object.assign(defaults, settings);
|
|
49
|
-
let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"),
|
|
48
|
+
let _initialized = false, _plugins = [], _canvas = settings.canvas || document.createElement("canvas"), _autoscale = settings.autoscale, _animated = settings.animate, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 32, _rng_seed = Date.now(), _global = settings.global, _events = {
|
|
50
49
|
init: null,
|
|
51
50
|
update: null,
|
|
52
51
|
draw: null,
|
|
@@ -106,11 +105,6 @@
|
|
|
106
105
|
* @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
|
|
107
106
|
*/
|
|
108
107
|
lerp: (start, end, t) => {
|
|
109
|
-
if (false) {
|
|
110
|
-
assert(isFinite(start), "lerp: 1st param must be a number");
|
|
111
|
-
assert(isFinite(end), "lerp: 2nd param must be a number");
|
|
112
|
-
assert(isFinite(t), "lerp: 3rd param must be a number");
|
|
113
|
-
}
|
|
114
108
|
return t * (end - start) + start;
|
|
115
109
|
},
|
|
116
110
|
/**
|
|
@@ -120,9 +114,6 @@
|
|
|
120
114
|
* @returns {number} the value in radians
|
|
121
115
|
*/
|
|
122
116
|
deg2rad: (degs) => {
|
|
123
|
-
if (false) {
|
|
124
|
-
assert(isFinite(degs), "deg2rad: 1st param must be a number");
|
|
125
|
-
}
|
|
126
117
|
return PI / 180 * degs;
|
|
127
118
|
},
|
|
128
119
|
/**
|
|
@@ -132,9 +123,6 @@
|
|
|
132
123
|
* @returns {number} the value in degrees
|
|
133
124
|
*/
|
|
134
125
|
rad2deg: (rads) => {
|
|
135
|
-
if (false) {
|
|
136
|
-
assert(isFinite(rads), "rad2deg: 1st param must be a number");
|
|
137
|
-
}
|
|
138
126
|
return 180 / PI * rads;
|
|
139
127
|
},
|
|
140
128
|
/**
|
|
@@ -146,15 +134,6 @@
|
|
|
146
134
|
* @returns {number}
|
|
147
135
|
*/
|
|
148
136
|
clamp: (value, min, max) => {
|
|
149
|
-
if (false) {
|
|
150
|
-
assert(isFinite(value), "clamp: 1st param must be a number");
|
|
151
|
-
assert(isFinite(min), "clamp: 2nd param must be a number");
|
|
152
|
-
assert(isFinite(max), "clamp: 3rd param must be a number");
|
|
153
|
-
assert(
|
|
154
|
-
max > min,
|
|
155
|
-
"randi: the 2nd param must be less than the 3rd param"
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
137
|
if (value < min) return min;
|
|
159
138
|
if (value > max) return max;
|
|
160
139
|
return value;
|
|
@@ -168,19 +147,6 @@
|
|
|
168
147
|
* @returns {number}
|
|
169
148
|
*/
|
|
170
149
|
wrap: (value, min, max) => {
|
|
171
|
-
if (false) {
|
|
172
|
-
assert(isFinite(value), "wrap: 1st param must be a number");
|
|
173
|
-
assert(isFinite(min), "wrap: 2nd param must be a number");
|
|
174
|
-
assert(isFinite(max), "wrap: 3rd param must be a number");
|
|
175
|
-
assert(
|
|
176
|
-
max > min,
|
|
177
|
-
"randi: the 2nd param must be less than the 3rd param"
|
|
178
|
-
);
|
|
179
|
-
assert(
|
|
180
|
-
max !== min,
|
|
181
|
-
"randi: the 2nd param must be not equal to the 3rd param"
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
150
|
return value - (max - min) * Math.floor((value - min) / (max - min));
|
|
185
151
|
},
|
|
186
152
|
/**
|
|
@@ -195,13 +161,6 @@
|
|
|
195
161
|
* @returns {number} the remapped number
|
|
196
162
|
*/
|
|
197
163
|
map(value, start1, stop1, start2, stop2, withinBounds) {
|
|
198
|
-
if (false) {
|
|
199
|
-
assert(isFinite(value), "map: 1st param must be a number");
|
|
200
|
-
assert(isFinite(start1), "map: 2nd param must be a number");
|
|
201
|
-
assert(isFinite(stop1), "map: 3rd param must be a number");
|
|
202
|
-
assert(isFinite(start2), "map: 4th param must be a number");
|
|
203
|
-
assert(isFinite(stop2), "map: 5th param must be a number");
|
|
204
|
-
}
|
|
205
164
|
const result = (value - start1) / (stop1 - start1) * (stop2 - start2) + start2;
|
|
206
165
|
return withinBounds ? instance.clamp(result, start2, stop2) : result;
|
|
207
166
|
},
|
|
@@ -216,11 +175,6 @@
|
|
|
216
175
|
* @returns {number} the normalized number.
|
|
217
176
|
*/
|
|
218
177
|
norm: (value, start, stop) => {
|
|
219
|
-
if (false) {
|
|
220
|
-
assert(isFinite(value), "norm: 1st param must be a number");
|
|
221
|
-
assert(isFinite(start), "norm: 2nd param must be a number");
|
|
222
|
-
assert(isFinite(stop), "norm: 3rd param must be a number");
|
|
223
|
-
}
|
|
224
178
|
return instance.map(value, start, stop, 0, 1);
|
|
225
179
|
},
|
|
226
180
|
/** RNG API */
|
|
@@ -233,14 +187,6 @@
|
|
|
233
187
|
* @returns {number} the random number
|
|
234
188
|
*/
|
|
235
189
|
rand: (min = 0, max = 1) => {
|
|
236
|
-
if (false) {
|
|
237
|
-
assert(isFinite(min), "rand: 1st param must be a number");
|
|
238
|
-
assert(isFinite(max), "rand: 2nd param must be a number");
|
|
239
|
-
assert(
|
|
240
|
-
max > min,
|
|
241
|
-
"rand: the 1st param must be less than the 2nd param"
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
190
|
const a = 1664525;
|
|
245
191
|
const c = 1013904223;
|
|
246
192
|
const m = 4294967296;
|
|
@@ -255,14 +201,6 @@
|
|
|
255
201
|
* @returns {number} the random number
|
|
256
202
|
*/
|
|
257
203
|
randi: (min = 0, max = 1) => {
|
|
258
|
-
if (false) {
|
|
259
|
-
assert(isFinite(min), "randi: 1st param must be a number");
|
|
260
|
-
assert(isFinite(max), "randi: 2nd param must be a number");
|
|
261
|
-
assert(
|
|
262
|
-
max > min,
|
|
263
|
-
"randi: the 1st param must be less than the 2nd param"
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
204
|
return Math.floor(instance.rand(min, max + 1));
|
|
267
205
|
},
|
|
268
206
|
/**
|
|
@@ -273,12 +211,6 @@
|
|
|
273
211
|
* @returns {number} the seed state
|
|
274
212
|
*/
|
|
275
213
|
seed: (value) => {
|
|
276
|
-
if (false) {
|
|
277
|
-
assert(
|
|
278
|
-
null == value || isFinite(value) && value >= 0,
|
|
279
|
-
"seed: 1st param must be a positive number or zero"
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
214
|
return null == value ? _rng_seed : _rng_seed = ~~value;
|
|
283
215
|
},
|
|
284
216
|
/** BASIC GRAPHICS API */
|
|
@@ -288,12 +220,6 @@
|
|
|
288
220
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
289
221
|
*/
|
|
290
222
|
cls(color) {
|
|
291
|
-
if (false) {
|
|
292
|
-
assert(
|
|
293
|
-
null == color || isFinite(color) && color >= 0,
|
|
294
|
-
"cls: 1st param must be a positive number or zero or null"
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
223
|
if (null == color) {
|
|
298
224
|
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);
|
|
299
225
|
} else {
|
|
@@ -317,26 +243,6 @@
|
|
|
317
243
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
318
244
|
*/
|
|
319
245
|
rect(x, y, width, height, color, radii = null) {
|
|
320
|
-
if (false) {
|
|
321
|
-
assert(isFinite(x), "rect: 1st param must be a number");
|
|
322
|
-
assert(isFinite(y), "rect: 2nd param must be a number");
|
|
323
|
-
assert(
|
|
324
|
-
isFinite(width) && width > 0,
|
|
325
|
-
"rect: 3rd param must be a positive number"
|
|
326
|
-
);
|
|
327
|
-
assert(
|
|
328
|
-
isFinite(height) && height >= 0,
|
|
329
|
-
"rect: 4th param must be a positive number or zero"
|
|
330
|
-
);
|
|
331
|
-
assert(
|
|
332
|
-
null == color || isFinite(color) && color >= 0,
|
|
333
|
-
"rect: 5th param must be a positive number or zero"
|
|
334
|
-
);
|
|
335
|
-
assert(
|
|
336
|
-
null == radii || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
337
|
-
"rect: 6th param must be a number or array of numbers"
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
246
|
_ctx.beginPath();
|
|
341
247
|
_ctx[radii ? "roundRect" : "rect"](
|
|
342
248
|
~~x - _outline_fix,
|
|
@@ -358,26 +264,6 @@
|
|
|
358
264
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
359
265
|
*/
|
|
360
266
|
rectfill(x, y, width, height, color, radii = null) {
|
|
361
|
-
if (false) {
|
|
362
|
-
assert(isFinite(x), "rectfill: 1st param must be a number");
|
|
363
|
-
assert(isFinite(y), "rectfill: 2nd param must be a number");
|
|
364
|
-
assert(
|
|
365
|
-
isFinite(width) && width >= 0,
|
|
366
|
-
"rectfill: 3rd param must be a positive number or zero"
|
|
367
|
-
);
|
|
368
|
-
assert(
|
|
369
|
-
isFinite(height) && height >= 0,
|
|
370
|
-
"rectfill: 4th param must be a positive number or zero"
|
|
371
|
-
);
|
|
372
|
-
assert(
|
|
373
|
-
null == color || isFinite(color) && color >= 0,
|
|
374
|
-
"rectfill: 5th param must be a positive number or zero"
|
|
375
|
-
);
|
|
376
|
-
assert(
|
|
377
|
-
null == radii || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
378
|
-
"rectfill: 6th param must be a number or array of at least 2 numbers"
|
|
379
|
-
);
|
|
380
|
-
}
|
|
381
267
|
_ctx.beginPath();
|
|
382
268
|
_ctx[radii ? "roundRect" : "rect"](
|
|
383
269
|
~~x,
|
|
@@ -397,18 +283,6 @@
|
|
|
397
283
|
* @param {number} [color=0] the color index
|
|
398
284
|
*/
|
|
399
285
|
circ(x, y, radius, color) {
|
|
400
|
-
if (false) {
|
|
401
|
-
assert(isFinite(x), "circ: 1st param must be a number");
|
|
402
|
-
assert(isFinite(y), "circ: 2nd param must be a number");
|
|
403
|
-
assert(
|
|
404
|
-
isFinite(radius) && radius >= 0,
|
|
405
|
-
"circ: 3rd param must be a positive number or zero"
|
|
406
|
-
);
|
|
407
|
-
assert(
|
|
408
|
-
null == color || isFinite(color) && color >= 0,
|
|
409
|
-
"circ: 4th param must be a positive number or zero"
|
|
410
|
-
);
|
|
411
|
-
}
|
|
412
286
|
_ctx.beginPath();
|
|
413
287
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
414
288
|
instance.stroke(color);
|
|
@@ -422,18 +296,6 @@
|
|
|
422
296
|
* @param {number} [color=0] the color index
|
|
423
297
|
*/
|
|
424
298
|
circfill(x, y, radius, color) {
|
|
425
|
-
if (false) {
|
|
426
|
-
assert(isFinite(x), "circfill: 1st param must be a number");
|
|
427
|
-
assert(isFinite(y), "circfill: 2nd param must be a number");
|
|
428
|
-
assert(
|
|
429
|
-
isFinite(radius) && radius >= 0,
|
|
430
|
-
"circfill: 3rd param must be a positive number or zero"
|
|
431
|
-
);
|
|
432
|
-
assert(
|
|
433
|
-
null == color || isFinite(color) && color >= 0,
|
|
434
|
-
"circfill: 4th param must be a positive number or zero"
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
299
|
_ctx.beginPath();
|
|
438
300
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
439
301
|
instance.fill(color);
|
|
@@ -448,22 +310,6 @@
|
|
|
448
310
|
* @param {number} [color=0] the color index
|
|
449
311
|
*/
|
|
450
312
|
line(x1, y1, x2, y2, color) {
|
|
451
|
-
if (false) {
|
|
452
|
-
assert(isFinite(x1), "line: 1st param must be a number");
|
|
453
|
-
assert(isFinite(y1), "line: 2nd param must be a number");
|
|
454
|
-
assert(
|
|
455
|
-
isFinite(x2),
|
|
456
|
-
"line: 3rd param must be a positive number or zero"
|
|
457
|
-
);
|
|
458
|
-
assert(
|
|
459
|
-
isFinite(y2),
|
|
460
|
-
"line: 4th param must be a positive number or zero"
|
|
461
|
-
);
|
|
462
|
-
assert(
|
|
463
|
-
null == color || isFinite(color) && color >= 0,
|
|
464
|
-
"line: 5th param must be a positive number or zero"
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
313
|
_ctx.beginPath();
|
|
468
314
|
let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0;
|
|
469
315
|
let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0;
|
|
@@ -478,12 +324,6 @@
|
|
|
478
324
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth
|
|
479
325
|
*/
|
|
480
326
|
linewidth(value) {
|
|
481
|
-
if (false) {
|
|
482
|
-
assert(
|
|
483
|
-
isFinite(value) && ~~value > 0,
|
|
484
|
-
"linewidth: 1st param must be a positive number"
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
327
|
_ctx.lineWidth = ~~value;
|
|
488
328
|
_outline_fix = ~~value % 2 === 0 ? 0 : 0.5;
|
|
489
329
|
},
|
|
@@ -496,13 +336,6 @@
|
|
|
496
336
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
|
|
497
337
|
*/
|
|
498
338
|
linedash(segments, offset = 0) {
|
|
499
|
-
if (false) {
|
|
500
|
-
assert(
|
|
501
|
-
Array.isArray(segments) && segments.length > 0,
|
|
502
|
-
"linedash: 1st param must be an array of numbers"
|
|
503
|
-
);
|
|
504
|
-
assert(isFinite(offset), "linedash: 2nd param must be a number");
|
|
505
|
-
}
|
|
506
339
|
_ctx.setLineDash(segments);
|
|
507
340
|
_ctx.lineDashOffset = offset;
|
|
508
341
|
},
|
|
@@ -517,18 +350,6 @@
|
|
|
517
350
|
* @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
|
|
518
351
|
*/
|
|
519
352
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
520
|
-
if (false) {
|
|
521
|
-
assert(isFinite(x), "text: 1st param must be a number");
|
|
522
|
-
assert(isFinite(y), "text: 2nd param must be a number");
|
|
523
|
-
assert(
|
|
524
|
-
null == color || isFinite(color) && color >= 0,
|
|
525
|
-
"text: 4th param must be a positive number or zero"
|
|
526
|
-
);
|
|
527
|
-
assert(
|
|
528
|
-
"string" === typeof fontStyle,
|
|
529
|
-
"text: 5th param must be a string"
|
|
530
|
-
);
|
|
531
|
-
}
|
|
532
353
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
533
354
|
_ctx.fillStyle = instance.getcolor(color);
|
|
534
355
|
_ctx.fillText(message, ~~x, ~~y);
|
|
@@ -539,12 +360,6 @@
|
|
|
539
360
|
* @param {string} family
|
|
540
361
|
*/
|
|
541
362
|
textfont(family) {
|
|
542
|
-
if (false) {
|
|
543
|
-
assert(
|
|
544
|
-
"string" === typeof family,
|
|
545
|
-
"textfont: 1st param must be a string"
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
363
|
_fontFamily = family;
|
|
549
364
|
},
|
|
550
365
|
/**
|
|
@@ -553,9 +368,6 @@
|
|
|
553
368
|
* @param {number} size
|
|
554
369
|
*/
|
|
555
370
|
textsize(size) {
|
|
556
|
-
if (false) {
|
|
557
|
-
assert(isFinite(size), "textsize: 1st param must be a number");
|
|
558
|
-
}
|
|
559
371
|
_fontSize = size;
|
|
560
372
|
},
|
|
561
373
|
/**
|
|
@@ -567,25 +379,6 @@
|
|
|
567
379
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
568
380
|
*/
|
|
569
381
|
textalign(align, baseline) {
|
|
570
|
-
if (false) {
|
|
571
|
-
assert(
|
|
572
|
-
null == align || ["left", "right", "center", "start", "end"].includes(
|
|
573
|
-
align
|
|
574
|
-
),
|
|
575
|
-
"textalign: 1st param must be a string"
|
|
576
|
-
);
|
|
577
|
-
assert(
|
|
578
|
-
null == baseline || [
|
|
579
|
-
"top",
|
|
580
|
-
"bottom",
|
|
581
|
-
"middle",
|
|
582
|
-
"hanging",
|
|
583
|
-
"alphabetic",
|
|
584
|
-
"ideographic"
|
|
585
|
-
].includes(baseline),
|
|
586
|
-
"textalign: 2nd param must be a string"
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
382
|
if (align) _ctx.textAlign = align;
|
|
590
383
|
if (baseline) _ctx.textBaseline = baseline;
|
|
591
384
|
},
|
|
@@ -598,10 +391,6 @@
|
|
|
598
391
|
* @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} source
|
|
599
392
|
*/
|
|
600
393
|
image(x, y, source) {
|
|
601
|
-
if (false) {
|
|
602
|
-
assert(isFinite(x), "image: 1st param must be a number");
|
|
603
|
-
assert(isFinite(y), "image: 2nd param must be a number");
|
|
604
|
-
}
|
|
605
394
|
_ctx.drawImage(source, ~~x, ~~y);
|
|
606
395
|
},
|
|
607
396
|
/**
|
|
@@ -617,18 +406,6 @@
|
|
|
617
406
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
618
407
|
*/
|
|
619
408
|
paint(width, height, drawing, options = {}) {
|
|
620
|
-
if (false) {
|
|
621
|
-
assert(isFinite(width), "paint: 1st param must be a number");
|
|
622
|
-
assert(isFinite(height), "paint: 2nd param must be a number");
|
|
623
|
-
assert(
|
|
624
|
-
"function" === typeof drawing || Array.isArray(drawing),
|
|
625
|
-
"paint: 3rd param must be a function or array"
|
|
626
|
-
);
|
|
627
|
-
assert(
|
|
628
|
-
options && !options.scale || isFinite(options.scale),
|
|
629
|
-
"paint: 4th param (options.scale) must be a number"
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
409
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
633
410
|
canvas.width = width * scale;
|
|
634
411
|
canvas.height = height * scale;
|
|
@@ -662,8 +439,6 @@
|
|
|
662
439
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
663
440
|
*/
|
|
664
441
|
ctx(context) {
|
|
665
|
-
if (false) {
|
|
666
|
-
}
|
|
667
442
|
if (context) {
|
|
668
443
|
_ctx = context;
|
|
669
444
|
}
|
|
@@ -688,10 +463,6 @@
|
|
|
688
463
|
* @param {number} y
|
|
689
464
|
*/
|
|
690
465
|
translate: (x, y) => {
|
|
691
|
-
if (false) {
|
|
692
|
-
assert(isFinite(x), "translate: 1st param must be a number");
|
|
693
|
-
assert(isFinite(y), "translate: 2nd param must be a number");
|
|
694
|
-
}
|
|
695
466
|
return _ctx.translate(~~x, ~~y);
|
|
696
467
|
},
|
|
697
468
|
/**
|
|
@@ -701,13 +472,6 @@
|
|
|
701
472
|
* @param {number} [y]
|
|
702
473
|
*/
|
|
703
474
|
scale: (x, y) => {
|
|
704
|
-
if (false) {
|
|
705
|
-
assert(isFinite(x), "scale: 1st param must be a number");
|
|
706
|
-
assert(
|
|
707
|
-
y == null || isFinite(y),
|
|
708
|
-
"scale: 2nd param must be a number"
|
|
709
|
-
);
|
|
710
|
-
}
|
|
711
475
|
return _ctx.scale(x, y || x);
|
|
712
476
|
},
|
|
713
477
|
/**
|
|
@@ -716,9 +480,6 @@
|
|
|
716
480
|
* @param {number} radians
|
|
717
481
|
*/
|
|
718
482
|
rotate: (radians) => {
|
|
719
|
-
if (false) {
|
|
720
|
-
assert(isFinite(radians), "rotate: 1st param must be a number");
|
|
721
|
-
}
|
|
722
483
|
return _ctx.rotate(radians);
|
|
723
484
|
},
|
|
724
485
|
/**
|
|
@@ -728,9 +489,6 @@
|
|
|
728
489
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha
|
|
729
490
|
*/
|
|
730
491
|
alpha(value) {
|
|
731
|
-
if (false) {
|
|
732
|
-
assert(isFinite(value), "alpha: 1st param must be a number");
|
|
733
|
-
}
|
|
734
492
|
_ctx.globalAlpha = instance.clamp(value, 0, 1);
|
|
735
493
|
},
|
|
736
494
|
/**
|
|
@@ -743,12 +501,6 @@
|
|
|
743
501
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D
|
|
744
502
|
*/
|
|
745
503
|
path: (arg) => {
|
|
746
|
-
if (false) {
|
|
747
|
-
assert(
|
|
748
|
-
null == arg || "string" === typeof arg || arg instanceof Path2D,
|
|
749
|
-
"path: 1st param must be a string or a Path2D instance"
|
|
750
|
-
);
|
|
751
|
-
}
|
|
752
504
|
return new Path2D(arg);
|
|
753
505
|
},
|
|
754
506
|
/**
|
|
@@ -758,16 +510,6 @@
|
|
|
758
510
|
* @param {Path2D} [path]
|
|
759
511
|
*/
|
|
760
512
|
fill(color, path) {
|
|
761
|
-
if (false) {
|
|
762
|
-
assert(
|
|
763
|
-
null == color || isFinite(color) && color >= 0,
|
|
764
|
-
"fill: 1st param must be a positive number or zero"
|
|
765
|
-
);
|
|
766
|
-
assert(
|
|
767
|
-
null == path || path instanceof Path2D,
|
|
768
|
-
"fill: 2nd param must be a Path2D instance"
|
|
769
|
-
);
|
|
770
|
-
}
|
|
771
513
|
_ctx.fillStyle = instance.getcolor(color);
|
|
772
514
|
if (path) {
|
|
773
515
|
_ctx.fill(path);
|
|
@@ -782,16 +524,6 @@
|
|
|
782
524
|
* @param {Path2D} [path]
|
|
783
525
|
*/
|
|
784
526
|
stroke(color, path) {
|
|
785
|
-
if (false) {
|
|
786
|
-
assert(
|
|
787
|
-
null == color || isFinite(color) && color >= 0,
|
|
788
|
-
"stroke: 1st param must be a positive number or zero"
|
|
789
|
-
);
|
|
790
|
-
assert(
|
|
791
|
-
null == path || path instanceof Path2D,
|
|
792
|
-
"stroke: 2nd param must be a Path2D instance"
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
527
|
_ctx.strokeStyle = instance.getcolor(color);
|
|
796
528
|
if (path) {
|
|
797
529
|
_ctx.stroke(path);
|
|
@@ -806,12 +538,6 @@
|
|
|
806
538
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip
|
|
807
539
|
*/
|
|
808
540
|
clip(path) {
|
|
809
|
-
if (false) {
|
|
810
|
-
assert(
|
|
811
|
-
path instanceof Path2D,
|
|
812
|
-
"clip: 1st param must be a Path2D instance"
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
541
|
_ctx.clip(path);
|
|
816
542
|
},
|
|
817
543
|
/** SOUND API */
|
|
@@ -827,17 +553,6 @@
|
|
|
827
553
|
* @see https://github.com/KilledByAPixel/ZzFX
|
|
828
554
|
*/
|
|
829
555
|
sfx(zzfxParams, pitchSlide = 0, volumeFactor = 1) {
|
|
830
|
-
if (false) {
|
|
831
|
-
assert(
|
|
832
|
-
null == zzfxParams || Array.isArray(zzfxParams),
|
|
833
|
-
"sfx: 1st param must be an array"
|
|
834
|
-
);
|
|
835
|
-
assert(isFinite(pitchSlide), "sfx: 2nd param must be a number");
|
|
836
|
-
assert(
|
|
837
|
-
isFinite(volumeFactor),
|
|
838
|
-
"sfx: 3rd param must be a number"
|
|
839
|
-
);
|
|
840
|
-
}
|
|
841
556
|
if (root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive) {
|
|
842
557
|
return false;
|
|
843
558
|
}
|
|
@@ -857,9 +572,6 @@
|
|
|
857
572
|
* @param {number} value
|
|
858
573
|
*/
|
|
859
574
|
volume(value) {
|
|
860
|
-
if (false) {
|
|
861
|
-
assert(isFinite(value), "volume: 1st param must be a number");
|
|
862
|
-
}
|
|
863
575
|
root.zzfxV = value;
|
|
864
576
|
},
|
|
865
577
|
/** UTILS API */
|
|
@@ -877,16 +589,6 @@
|
|
|
877
589
|
* @returns {boolean}
|
|
878
590
|
*/
|
|
879
591
|
colrect: (x1, y1, w1, h1, x2, y2, w2, h2) => {
|
|
880
|
-
if (false) {
|
|
881
|
-
assert(isFinite(x1), "colrect: 1st param must be a number");
|
|
882
|
-
assert(isFinite(y1), "colrect: 2nd param must be a number");
|
|
883
|
-
assert(isFinite(w1), "colrect: 3rd param must be a number");
|
|
884
|
-
assert(isFinite(h1), "colrect: 4th param must be a number");
|
|
885
|
-
assert(isFinite(x2), "colrect: 5th param must be a number");
|
|
886
|
-
assert(isFinite(y2), "colrect: 6th param must be a number");
|
|
887
|
-
assert(isFinite(w2), "colrect: 7th param must be a number");
|
|
888
|
-
assert(isFinite(h2), "colrect: 8th param must be a number");
|
|
889
|
-
}
|
|
890
592
|
return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2;
|
|
891
593
|
},
|
|
892
594
|
/**
|
|
@@ -901,14 +603,6 @@
|
|
|
901
603
|
* @returns {boolean}
|
|
902
604
|
*/
|
|
903
605
|
colcirc: (x1, y1, r1, x2, y2, r2) => {
|
|
904
|
-
if (false) {
|
|
905
|
-
assert(isFinite(x1), "colcirc: 1st param must be a number");
|
|
906
|
-
assert(isFinite(y1), "colcirc: 2nd param must be a number");
|
|
907
|
-
assert(isFinite(r1), "colcirc: 3rd param must be a number");
|
|
908
|
-
assert(isFinite(x2), "colcirc: 4th param must be a number");
|
|
909
|
-
assert(isFinite(y2), "colcirc: 5th param must be a number");
|
|
910
|
-
assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
911
|
-
}
|
|
912
606
|
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2);
|
|
913
607
|
},
|
|
914
608
|
/** PLUGINS API */
|
|
@@ -918,16 +612,6 @@
|
|
|
918
612
|
* @param {pluginCallback} callback
|
|
919
613
|
*/
|
|
920
614
|
use(callback, config = {}) {
|
|
921
|
-
if (false) {
|
|
922
|
-
assert(
|
|
923
|
-
"function" === typeof callback,
|
|
924
|
-
"use: 1st param must be a function"
|
|
925
|
-
);
|
|
926
|
-
assert(
|
|
927
|
-
"object" === typeof config,
|
|
928
|
-
"use: 2nd param must be an object"
|
|
929
|
-
);
|
|
930
|
-
}
|
|
931
615
|
_initialized ? loadPlugin(callback, config) : _plugins.push([callback, config]);
|
|
932
616
|
},
|
|
933
617
|
/**
|
|
@@ -938,16 +622,6 @@
|
|
|
938
622
|
* @returns {Function} a function to remove the listener
|
|
939
623
|
*/
|
|
940
624
|
listen(eventName, callback) {
|
|
941
|
-
if (false) {
|
|
942
|
-
assert(
|
|
943
|
-
"string" === typeof eventName,
|
|
944
|
-
"listen: 1st param must be a string"
|
|
945
|
-
);
|
|
946
|
-
assert(
|
|
947
|
-
"function" === typeof callback,
|
|
948
|
-
"listen: 2nd param must be a function"
|
|
949
|
-
);
|
|
950
|
-
}
|
|
951
625
|
_events[eventName] = _events[eventName] || /* @__PURE__ */ new Set();
|
|
952
626
|
_events[eventName].add(callback);
|
|
953
627
|
return () => _events[eventName].delete(callback);
|
|
@@ -962,15 +636,11 @@
|
|
|
962
636
|
* @param {*} [arg4] any data to be passed over the listeners
|
|
963
637
|
*/
|
|
964
638
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
965
|
-
if (
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
);
|
|
639
|
+
if (_initialized) {
|
|
640
|
+
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
641
|
+
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
642
|
+
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
970
643
|
}
|
|
971
|
-
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
972
|
-
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
973
|
-
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
974
644
|
},
|
|
975
645
|
/**
|
|
976
646
|
* Get a color by index
|
|
@@ -979,12 +649,6 @@
|
|
|
979
649
|
* @returns {string} the color code
|
|
980
650
|
*/
|
|
981
651
|
getcolor: (index) => {
|
|
982
|
-
if (false) {
|
|
983
|
-
assert(
|
|
984
|
-
null == index || isFinite(index) && index >= 0,
|
|
985
|
-
"getcolor: 1st param must be a number"
|
|
986
|
-
);
|
|
987
|
-
}
|
|
988
652
|
return colors[~~index % colors.length];
|
|
989
653
|
},
|
|
990
654
|
/**
|
|
@@ -994,13 +658,7 @@
|
|
|
994
658
|
* @param {*} value
|
|
995
659
|
*/
|
|
996
660
|
setvar(key, value) {
|
|
997
|
-
if (
|
|
998
|
-
assert(
|
|
999
|
-
"string" === typeof key,
|
|
1000
|
-
"setvar: 1st param must be a string"
|
|
1001
|
-
);
|
|
1002
|
-
if (value == null) {
|
|
1003
|
-
}
|
|
661
|
+
if (value == null) {
|
|
1004
662
|
}
|
|
1005
663
|
instance[key] = value;
|
|
1006
664
|
if (_global) {
|
|
@@ -1014,13 +672,11 @@
|
|
|
1014
672
|
* @param {number} height
|
|
1015
673
|
*/
|
|
1016
674
|
resize(width, height) {
|
|
1017
|
-
if (false) {
|
|
1018
|
-
assert(isFinite(width), "resize: 1st param must be a number");
|
|
1019
|
-
assert(isFinite(height), "resize: 2nd param must be a number");
|
|
1020
|
-
}
|
|
1021
675
|
instance.setvar("WIDTH", _canvas.width = width);
|
|
1022
676
|
instance.setvar("HEIGHT", _canvas.height = height);
|
|
1023
|
-
|
|
677
|
+
instance.setvar("CENTERX", instance.WIDTH / 2);
|
|
678
|
+
instance.setvar("CENTERY", instance.HEIGHT / 2);
|
|
679
|
+
onResize();
|
|
1024
680
|
},
|
|
1025
681
|
/**
|
|
1026
682
|
* The scale of the game's delta time (dt).
|
|
@@ -1030,9 +686,6 @@
|
|
|
1030
686
|
* @param {number} value
|
|
1031
687
|
*/
|
|
1032
688
|
timescale(value) {
|
|
1033
|
-
if (false) {
|
|
1034
|
-
assert(isFinite(value), "timescale: 1st param must be a number");
|
|
1035
|
-
}
|
|
1036
689
|
_timeScale = value;
|
|
1037
690
|
},
|
|
1038
691
|
/**
|
|
@@ -1041,12 +694,6 @@
|
|
|
1041
694
|
* @param {number} value
|
|
1042
695
|
*/
|
|
1043
696
|
setfps(value) {
|
|
1044
|
-
if (false) {
|
|
1045
|
-
assert(
|
|
1046
|
-
isFinite(value) && value >= 1,
|
|
1047
|
-
"setfps: 1st param must be a positive number"
|
|
1048
|
-
);
|
|
1049
|
-
}
|
|
1050
697
|
_deltaTime = 1 / ~~value;
|
|
1051
698
|
},
|
|
1052
699
|
/**
|
|
@@ -1079,10 +726,9 @@
|
|
|
1079
726
|
for (const [callback, config] of _plugins) {
|
|
1080
727
|
loadPlugin(callback, config);
|
|
1081
728
|
}
|
|
1082
|
-
if (
|
|
1083
|
-
on(root, "resize",
|
|
729
|
+
if (_autoscale) {
|
|
730
|
+
on(root, "resize", onResize);
|
|
1084
731
|
}
|
|
1085
|
-
pageResized();
|
|
1086
732
|
if (settings.tapEvents) {
|
|
1087
733
|
const _getXY = (pageX, pageY) => [
|
|
1088
734
|
(pageX - _canvas.offsetLeft) / _scale,
|
|
@@ -1183,12 +829,6 @@
|
|
|
1183
829
|
if (settings.keyboardEvents) {
|
|
1184
830
|
const _keys = /* @__PURE__ */ new Set();
|
|
1185
831
|
const iskeydown = (key) => {
|
|
1186
|
-
if (false) {
|
|
1187
|
-
assert(
|
|
1188
|
-
"string" === typeof key,
|
|
1189
|
-
"iskeydown: 1st param must be a string"
|
|
1190
|
-
);
|
|
1191
|
-
}
|
|
1192
832
|
return "any" === key ? _keys.size > 0 : _keys.has(key.toLowerCase());
|
|
1193
833
|
};
|
|
1194
834
|
instance.setvar("iskeydown", iskeydown);
|
|
@@ -1221,72 +861,54 @@
|
|
|
1221
861
|
}
|
|
1222
862
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1223
863
|
_lastFrameTime = now;
|
|
1224
|
-
if (frameTime > _deltaTime * 30)
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
864
|
+
if (frameTime > _deltaTime * 30) {
|
|
865
|
+
} else {
|
|
866
|
+
_accumulated += frameTime;
|
|
867
|
+
if (!_animated) {
|
|
868
|
+
_accumulated = _deltaTime;
|
|
869
|
+
}
|
|
870
|
+
for (; _accumulated >= _deltaTime; _accumulated -= _deltaTime) {
|
|
871
|
+
instance.emit("update", _deltaTime * _timeScale);
|
|
872
|
+
instance.setvar(
|
|
873
|
+
"ELAPSED",
|
|
874
|
+
instance.ELAPSED + _deltaTime * _timeScale
|
|
875
|
+
);
|
|
876
|
+
updated++;
|
|
877
|
+
}
|
|
1237
878
|
}
|
|
1238
|
-
if (updated) {
|
|
879
|
+
if (updated || !_animated) {
|
|
1239
880
|
instance.textalign("start", "top");
|
|
1240
881
|
instance.emit("draw");
|
|
1241
882
|
}
|
|
1242
883
|
}
|
|
1243
884
|
function setupCanvas() {
|
|
1244
885
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
|
1245
|
-
if (false) {
|
|
1246
|
-
assert(
|
|
1247
|
-
_canvas && _canvas.tagName === "CANVAS",
|
|
1248
|
-
"Invalid canvas element"
|
|
1249
|
-
);
|
|
1250
|
-
assert(
|
|
1251
|
-
null === instance.WIDTH || instance.WIDTH > 0,
|
|
1252
|
-
`Litecanvas' "width" option should be null or a positive number`
|
|
1253
|
-
);
|
|
1254
|
-
assert(
|
|
1255
|
-
null === instance.HEIGHT || instance.HEIGHT > 0,
|
|
1256
|
-
`Litecanvas' "width" option should be null or a positive number`
|
|
1257
|
-
);
|
|
1258
|
-
}
|
|
1259
886
|
instance.setvar("CANVAS", _canvas);
|
|
1260
887
|
_ctx = _canvas.getContext("2d");
|
|
1261
888
|
on(_canvas, "click", () => root.focus());
|
|
1262
|
-
if (instance.WIDTH > 0) {
|
|
1263
|
-
_fullscreen = false;
|
|
1264
|
-
}
|
|
1265
889
|
_canvas.style = "";
|
|
1266
|
-
|
|
1267
|
-
|
|
890
|
+
if (!instance.WIDTH) {
|
|
891
|
+
instance.WIDTH = root.innerWidth;
|
|
892
|
+
instance.HEIGHT = root.innerHeight;
|
|
893
|
+
}
|
|
894
|
+
instance.resize(instance.WIDTH, instance.HEIGHT, false);
|
|
1268
895
|
if (!_canvas.parentNode) document.body.appendChild(_canvas);
|
|
1269
896
|
}
|
|
1270
|
-
function
|
|
1271
|
-
const
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
instance.setvar("HEIGHT", _canvas.height = pageHeight);
|
|
1278
|
-
} else if (_autoscale) {
|
|
1279
|
-
styles.margin = "auto";
|
|
897
|
+
function onResize() {
|
|
898
|
+
const styles = _canvas.style;
|
|
899
|
+
if (_autoscale) {
|
|
900
|
+
if (!styles.display) {
|
|
901
|
+
styles.display = "block";
|
|
902
|
+
styles.margin = "auto";
|
|
903
|
+
}
|
|
1280
904
|
_scale = Math.min(
|
|
1281
|
-
|
|
1282
|
-
|
|
905
|
+
root.innerWidth / instance.WIDTH,
|
|
906
|
+
root.innerHeight / instance.HEIGHT
|
|
1283
907
|
);
|
|
1284
908
|
_scale = (settings.pixelart ? ~~_scale : _scale) || 1;
|
|
1285
909
|
styles.width = instance.WIDTH * _scale + "px";
|
|
1286
910
|
styles.height = instance.HEIGHT * _scale + "px";
|
|
1287
911
|
}
|
|
1288
|
-
instance.setvar("CENTERX", instance.WIDTH / 2);
|
|
1289
|
-
instance.setvar("CENTERY", instance.HEIGHT / 2);
|
|
1290
912
|
if (!settings.antialias || settings.pixelart) {
|
|
1291
913
|
_ctx.imageSmoothingEnabled = false;
|
|
1292
914
|
styles.imageRendering = "pixelated";
|
|
@@ -1304,12 +926,6 @@
|
|
|
1304
926
|
}
|
|
1305
927
|
function loadPlugin(callback, config) {
|
|
1306
928
|
const pluginData = callback(instance, _helpers, config);
|
|
1307
|
-
if (false) {
|
|
1308
|
-
assert(
|
|
1309
|
-
null == pluginData || "object" === typeof pluginData,
|
|
1310
|
-
"Litecanvas plugins should return an object or nothing"
|
|
1311
|
-
);
|
|
1312
|
-
}
|
|
1313
929
|
for (const key in pluginData) {
|
|
1314
930
|
instance.setvar(key, pluginData[key]);
|
|
1315
931
|
}
|