litecanvas 0.75.0 → 0.75.1
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 +293 -384
- package/dist/dist.js +1 -383
- package/package.json +2 -2
- package/src/index.js +349 -397
package/dist/dist.dev.js
CHANGED
|
@@ -111,11 +111,9 @@
|
|
|
111
111
|
* @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
|
|
112
112
|
*/
|
|
113
113
|
lerp: (start, end, t) => {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
assert(isFinite(t), "lerp: 3rd param must be a number");
|
|
118
|
-
}
|
|
114
|
+
DEV: assert(isFinite(start), "lerp: 1st param must be a number");
|
|
115
|
+
DEV: assert(isFinite(end), "lerp: 2nd param must be a number");
|
|
116
|
+
DEV: assert(isFinite(t), "lerp: 3rd param must be a number");
|
|
119
117
|
return t * (end - start) + start;
|
|
120
118
|
},
|
|
121
119
|
/**
|
|
@@ -125,9 +123,7 @@
|
|
|
125
123
|
* @returns {number} the value in radians
|
|
126
124
|
*/
|
|
127
125
|
deg2rad: (degs) => {
|
|
128
|
-
|
|
129
|
-
assert(isFinite(degs), "deg2rad: 1st param must be a number");
|
|
130
|
-
}
|
|
126
|
+
DEV: assert(isFinite(degs), "deg2rad: 1st param must be a number");
|
|
131
127
|
return PI / 180 * degs;
|
|
132
128
|
},
|
|
133
129
|
/**
|
|
@@ -137,9 +133,7 @@
|
|
|
137
133
|
* @returns {number} the value in degrees
|
|
138
134
|
*/
|
|
139
135
|
rad2deg: (rads) => {
|
|
140
|
-
|
|
141
|
-
assert(isFinite(rads), "rad2deg: 1st param must be a number");
|
|
142
|
-
}
|
|
136
|
+
DEV: assert(isFinite(rads), "rad2deg: 1st param must be a number");
|
|
143
137
|
return 180 / PI * rads;
|
|
144
138
|
},
|
|
145
139
|
/**
|
|
@@ -151,15 +145,13 @@
|
|
|
151
145
|
* @returns {number}
|
|
152
146
|
*/
|
|
153
147
|
clamp: (value, min, max) => {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
);
|
|
162
|
-
}
|
|
148
|
+
DEV: assert(isFinite(value), "clamp: 1st param must be a number");
|
|
149
|
+
DEV: assert(isFinite(min), "clamp: 2nd param must be a number");
|
|
150
|
+
DEV: assert(isFinite(max), "clamp: 3rd param must be a number");
|
|
151
|
+
DEV: assert(
|
|
152
|
+
max > min,
|
|
153
|
+
"randi: the 2nd param must be less than the 3rd param"
|
|
154
|
+
);
|
|
163
155
|
if (value < min) return min;
|
|
164
156
|
if (value > max) return max;
|
|
165
157
|
return value;
|
|
@@ -173,19 +165,17 @@
|
|
|
173
165
|
* @returns {number}
|
|
174
166
|
*/
|
|
175
167
|
wrap: (value, min, max) => {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
);
|
|
188
|
-
}
|
|
168
|
+
DEV: assert(isFinite(value), "wrap: 1st param must be a number");
|
|
169
|
+
DEV: assert(isFinite(min), "wrap: 2nd param must be a number");
|
|
170
|
+
DEV: assert(isFinite(max), "wrap: 3rd param must be a number");
|
|
171
|
+
DEV: assert(
|
|
172
|
+
max > min,
|
|
173
|
+
"randi: the 2nd param must be less than the 3rd param"
|
|
174
|
+
);
|
|
175
|
+
DEV: assert(
|
|
176
|
+
max !== min,
|
|
177
|
+
"randi: the 2nd param must be not equal to the 3rd param"
|
|
178
|
+
);
|
|
189
179
|
return value - (max - min) * Math.floor((value - min) / (max - min));
|
|
190
180
|
},
|
|
191
181
|
/**
|
|
@@ -200,13 +190,11 @@
|
|
|
200
190
|
* @returns {number} the remapped number
|
|
201
191
|
*/
|
|
202
192
|
map(value, start1, stop1, start2, stop2, withinBounds) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
assert(isFinite(stop2), "map: 5th param must be a number");
|
|
209
|
-
}
|
|
193
|
+
DEV: assert(isFinite(value), "map: 1st param must be a number");
|
|
194
|
+
DEV: assert(isFinite(start1), "map: 2nd param must be a number");
|
|
195
|
+
DEV: assert(isFinite(stop1), "map: 3rd param must be a number");
|
|
196
|
+
DEV: assert(isFinite(start2), "map: 4th param must be a number");
|
|
197
|
+
DEV: assert(isFinite(stop2), "map: 5th param must be a number");
|
|
210
198
|
const result = (value - start1) / (stop1 - start1) * (stop2 - start2) + start2;
|
|
211
199
|
return withinBounds ? instance.clamp(result, start2, stop2) : result;
|
|
212
200
|
},
|
|
@@ -221,11 +209,9 @@
|
|
|
221
209
|
* @returns {number} the normalized number.
|
|
222
210
|
*/
|
|
223
211
|
norm: (value, start, stop) => {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
assert(isFinite(stop), "norm: 3rd param must be a number");
|
|
228
|
-
}
|
|
212
|
+
DEV: assert(isFinite(value), "norm: 1st param must be a number");
|
|
213
|
+
DEV: assert(isFinite(start), "norm: 2nd param must be a number");
|
|
214
|
+
DEV: assert(isFinite(stop), "norm: 3rd param must be a number");
|
|
229
215
|
return instance.map(value, start, stop, 0, 1);
|
|
230
216
|
},
|
|
231
217
|
/** RNG API */
|
|
@@ -238,14 +224,12 @@
|
|
|
238
224
|
* @returns {number} the random number
|
|
239
225
|
*/
|
|
240
226
|
rand: (min = 0, max = 1) => {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
);
|
|
248
|
-
}
|
|
227
|
+
DEV: assert(isFinite(min), "rand: 1st param must be a number");
|
|
228
|
+
DEV: assert(isFinite(max), "rand: 2nd param must be a number");
|
|
229
|
+
DEV: assert(
|
|
230
|
+
max > min,
|
|
231
|
+
"rand: the 1st param must be less than the 2nd param"
|
|
232
|
+
);
|
|
249
233
|
const a = 1664525;
|
|
250
234
|
const c = 1013904223;
|
|
251
235
|
const m = 4294967296;
|
|
@@ -260,14 +244,12 @@
|
|
|
260
244
|
* @returns {number} the random number
|
|
261
245
|
*/
|
|
262
246
|
randi: (min = 0, max = 1) => {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
);
|
|
270
|
-
}
|
|
247
|
+
DEV: assert(isFinite(min), "randi: 1st param must be a number");
|
|
248
|
+
DEV: assert(isFinite(max), "randi: 2nd param must be a number");
|
|
249
|
+
DEV: assert(
|
|
250
|
+
max > min,
|
|
251
|
+
"randi: the 1st param must be less than the 2nd param"
|
|
252
|
+
);
|
|
271
253
|
return Math.floor(instance.rand(min, max + 1));
|
|
272
254
|
},
|
|
273
255
|
/**
|
|
@@ -278,12 +260,10 @@
|
|
|
278
260
|
* @returns {number} the seed state
|
|
279
261
|
*/
|
|
280
262
|
seed: (value) => {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
);
|
|
286
|
-
}
|
|
263
|
+
DEV: assert(
|
|
264
|
+
null == value || isFinite(value) && value >= 0,
|
|
265
|
+
"seed: 1st param must be a positive number or zero"
|
|
266
|
+
);
|
|
287
267
|
return null == value ? _rng_seed : _rng_seed = ~~value;
|
|
288
268
|
},
|
|
289
269
|
/** BASIC GRAPHICS API */
|
|
@@ -293,12 +273,10 @@
|
|
|
293
273
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
294
274
|
*/
|
|
295
275
|
cls(color) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
);
|
|
301
|
-
}
|
|
276
|
+
DEV: assert(
|
|
277
|
+
null == color || isFinite(color) && color >= 0,
|
|
278
|
+
"cls: 1st param must be a positive number or zero or null"
|
|
279
|
+
);
|
|
302
280
|
if (null == color) {
|
|
303
281
|
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);
|
|
304
282
|
} else {
|
|
@@ -322,26 +300,24 @@
|
|
|
322
300
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
323
301
|
*/
|
|
324
302
|
rect(x, y, width, height, color, radii = null) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
);
|
|
344
|
-
}
|
|
303
|
+
DEV: assert(isFinite(x), "rect: 1st param must be a number");
|
|
304
|
+
DEV: assert(isFinite(y), "rect: 2nd param must be a number");
|
|
305
|
+
DEV: assert(
|
|
306
|
+
isFinite(width) && width > 0,
|
|
307
|
+
"rect: 3rd param must be a positive number"
|
|
308
|
+
);
|
|
309
|
+
DEV: assert(
|
|
310
|
+
isFinite(height) && height >= 0,
|
|
311
|
+
"rect: 4th param must be a positive number or zero"
|
|
312
|
+
);
|
|
313
|
+
DEV: assert(
|
|
314
|
+
null == color || isFinite(color) && color >= 0,
|
|
315
|
+
"rect: 5th param must be a positive number or zero"
|
|
316
|
+
);
|
|
317
|
+
DEV: assert(
|
|
318
|
+
null == radii || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
319
|
+
"rect: 6th param must be a number or array of numbers"
|
|
320
|
+
);
|
|
345
321
|
_ctx.beginPath();
|
|
346
322
|
_ctx[radii ? "roundRect" : "rect"](
|
|
347
323
|
~~x - _outline_fix,
|
|
@@ -363,26 +339,24 @@
|
|
|
363
339
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
364
340
|
*/
|
|
365
341
|
rectfill(x, y, width, height, color, radii = null) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
);
|
|
385
|
-
}
|
|
342
|
+
DEV: assert(isFinite(x), "rectfill: 1st param must be a number");
|
|
343
|
+
DEV: assert(isFinite(y), "rectfill: 2nd param must be a number");
|
|
344
|
+
DEV: assert(
|
|
345
|
+
isFinite(width) && width >= 0,
|
|
346
|
+
"rectfill: 3rd param must be a positive number or zero"
|
|
347
|
+
);
|
|
348
|
+
DEV: assert(
|
|
349
|
+
isFinite(height) && height >= 0,
|
|
350
|
+
"rectfill: 4th param must be a positive number or zero"
|
|
351
|
+
);
|
|
352
|
+
DEV: assert(
|
|
353
|
+
null == color || isFinite(color) && color >= 0,
|
|
354
|
+
"rectfill: 5th param must be a positive number or zero"
|
|
355
|
+
);
|
|
356
|
+
DEV: assert(
|
|
357
|
+
null == radii || isFinite(radii) || Array.isArray(radii) && radii.length >= 1,
|
|
358
|
+
"rectfill: 6th param must be a number or array of at least 2 numbers"
|
|
359
|
+
);
|
|
386
360
|
_ctx.beginPath();
|
|
387
361
|
_ctx[radii ? "roundRect" : "rect"](
|
|
388
362
|
~~x,
|
|
@@ -402,18 +376,16 @@
|
|
|
402
376
|
* @param {number} [color=0] the color index
|
|
403
377
|
*/
|
|
404
378
|
circ(x, y, radius, color) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
);
|
|
416
|
-
}
|
|
379
|
+
DEV: assert(isFinite(x), "circ: 1st param must be a number");
|
|
380
|
+
DEV: assert(isFinite(y), "circ: 2nd param must be a number");
|
|
381
|
+
DEV: assert(
|
|
382
|
+
isFinite(radius) && radius >= 0,
|
|
383
|
+
"circ: 3rd param must be a positive number or zero"
|
|
384
|
+
);
|
|
385
|
+
DEV: assert(
|
|
386
|
+
null == color || isFinite(color) && color >= 0,
|
|
387
|
+
"circ: 4th param must be a positive number or zero"
|
|
388
|
+
);
|
|
417
389
|
_ctx.beginPath();
|
|
418
390
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
419
391
|
instance.stroke(color);
|
|
@@ -427,18 +399,16 @@
|
|
|
427
399
|
* @param {number} [color=0] the color index
|
|
428
400
|
*/
|
|
429
401
|
circfill(x, y, radius, color) {
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
);
|
|
441
|
-
}
|
|
402
|
+
DEV: assert(isFinite(x), "circfill: 1st param must be a number");
|
|
403
|
+
DEV: assert(isFinite(y), "circfill: 2nd param must be a number");
|
|
404
|
+
DEV: assert(
|
|
405
|
+
isFinite(radius) && radius >= 0,
|
|
406
|
+
"circfill: 3rd param must be a positive number or zero"
|
|
407
|
+
);
|
|
408
|
+
DEV: assert(
|
|
409
|
+
null == color || isFinite(color) && color >= 0,
|
|
410
|
+
"circfill: 4th param must be a positive number or zero"
|
|
411
|
+
);
|
|
442
412
|
_ctx.beginPath();
|
|
443
413
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
444
414
|
instance.fill(color);
|
|
@@ -453,22 +423,20 @@
|
|
|
453
423
|
* @param {number} [color=0] the color index
|
|
454
424
|
*/
|
|
455
425
|
line(x1, y1, x2, y2, color) {
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
);
|
|
471
|
-
}
|
|
426
|
+
DEV: assert(isFinite(x1), "line: 1st param must be a number");
|
|
427
|
+
DEV: assert(isFinite(y1), "line: 2nd param must be a number");
|
|
428
|
+
DEV: assert(
|
|
429
|
+
isFinite(x2),
|
|
430
|
+
"line: 3rd param must be a positive number or zero"
|
|
431
|
+
);
|
|
432
|
+
DEV: assert(
|
|
433
|
+
isFinite(y2),
|
|
434
|
+
"line: 4th param must be a positive number or zero"
|
|
435
|
+
);
|
|
436
|
+
DEV: assert(
|
|
437
|
+
null == color || isFinite(color) && color >= 0,
|
|
438
|
+
"line: 5th param must be a positive number or zero"
|
|
439
|
+
);
|
|
472
440
|
_ctx.beginPath();
|
|
473
441
|
let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0;
|
|
474
442
|
let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0;
|
|
@@ -483,12 +451,10 @@
|
|
|
483
451
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth
|
|
484
452
|
*/
|
|
485
453
|
linewidth(value) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
);
|
|
491
|
-
}
|
|
454
|
+
DEV: assert(
|
|
455
|
+
isFinite(value) && ~~value > 0,
|
|
456
|
+
"linewidth: 1st param must be a positive number"
|
|
457
|
+
);
|
|
492
458
|
_ctx.lineWidth = ~~value;
|
|
493
459
|
_outline_fix = ~~value % 2 === 0 ? 0 : 0.5;
|
|
494
460
|
},
|
|
@@ -501,13 +467,14 @@
|
|
|
501
467
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
|
|
502
468
|
*/
|
|
503
469
|
linedash(segments, offset = 0) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
470
|
+
DEV: assert(
|
|
471
|
+
Array.isArray(segments) && segments.length > 0,
|
|
472
|
+
"linedash: 1st param must be an array of numbers"
|
|
473
|
+
);
|
|
474
|
+
DEV: assert(
|
|
475
|
+
isFinite(offset),
|
|
476
|
+
"linedash: 2nd param must be a number"
|
|
477
|
+
);
|
|
511
478
|
_ctx.setLineDash(segments);
|
|
512
479
|
_ctx.lineDashOffset = offset;
|
|
513
480
|
},
|
|
@@ -522,18 +489,16 @@
|
|
|
522
489
|
* @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
|
|
523
490
|
*/
|
|
524
491
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
);
|
|
536
|
-
}
|
|
492
|
+
DEV: assert(isFinite(x), "text: 1st param must be a number");
|
|
493
|
+
DEV: assert(isFinite(y), "text: 2nd param must be a number");
|
|
494
|
+
DEV: assert(
|
|
495
|
+
null == color || isFinite(color) && color >= 0,
|
|
496
|
+
"text: 4th param must be a positive number or zero"
|
|
497
|
+
);
|
|
498
|
+
DEV: assert(
|
|
499
|
+
"string" === typeof fontStyle,
|
|
500
|
+
"text: 5th param must be a string"
|
|
501
|
+
);
|
|
537
502
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
538
503
|
_ctx.fillStyle = instance.getcolor(color);
|
|
539
504
|
_ctx.fillText(message, ~~x, ~~y);
|
|
@@ -544,12 +509,10 @@
|
|
|
544
509
|
* @param {string} family
|
|
545
510
|
*/
|
|
546
511
|
textfont(family) {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
);
|
|
552
|
-
}
|
|
512
|
+
DEV: assert(
|
|
513
|
+
"string" === typeof family,
|
|
514
|
+
"textfont: 1st param must be a string"
|
|
515
|
+
);
|
|
553
516
|
_fontFamily = family;
|
|
554
517
|
},
|
|
555
518
|
/**
|
|
@@ -558,9 +521,7 @@
|
|
|
558
521
|
* @param {number} size
|
|
559
522
|
*/
|
|
560
523
|
textsize(size) {
|
|
561
|
-
|
|
562
|
-
assert(isFinite(size), "textsize: 1st param must be a number");
|
|
563
|
-
}
|
|
524
|
+
DEV: assert(isFinite(size), "textsize: 1st param must be a number");
|
|
564
525
|
_fontSize = size;
|
|
565
526
|
},
|
|
566
527
|
/**
|
|
@@ -572,25 +533,21 @@
|
|
|
572
533
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
573
534
|
*/
|
|
574
535
|
textalign(align, baseline) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
].includes(baseline),
|
|
591
|
-
"textalign: 2nd param must be a string"
|
|
592
|
-
);
|
|
593
|
-
}
|
|
536
|
+
DEV: assert(
|
|
537
|
+
null == align || ["left", "right", "center", "start", "end"].includes(align),
|
|
538
|
+
"textalign: 1st param must be a string"
|
|
539
|
+
);
|
|
540
|
+
DEV: assert(
|
|
541
|
+
null == baseline || [
|
|
542
|
+
"top",
|
|
543
|
+
"bottom",
|
|
544
|
+
"middle",
|
|
545
|
+
"hanging",
|
|
546
|
+
"alphabetic",
|
|
547
|
+
"ideographic"
|
|
548
|
+
].includes(baseline),
|
|
549
|
+
"textalign: 2nd param must be a string"
|
|
550
|
+
);
|
|
594
551
|
if (align) _ctx.textAlign = align;
|
|
595
552
|
if (baseline) _ctx.textBaseline = baseline;
|
|
596
553
|
},
|
|
@@ -603,10 +560,8 @@
|
|
|
603
560
|
* @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} source
|
|
604
561
|
*/
|
|
605
562
|
image(x, y, source) {
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
assert(isFinite(y), "image: 2nd param must be a number");
|
|
609
|
-
}
|
|
563
|
+
DEV: assert(isFinite(x), "image: 1st param must be a number");
|
|
564
|
+
DEV: assert(isFinite(y), "image: 2nd param must be a number");
|
|
610
565
|
_ctx.drawImage(source, ~~x, ~~y);
|
|
611
566
|
},
|
|
612
567
|
/**
|
|
@@ -622,18 +577,16 @@
|
|
|
622
577
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
623
578
|
*/
|
|
624
579
|
paint(width, height, drawing, options = {}) {
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
);
|
|
636
|
-
}
|
|
580
|
+
DEV: assert(isFinite(width), "paint: 1st param must be a number");
|
|
581
|
+
DEV: assert(isFinite(height), "paint: 2nd param must be a number");
|
|
582
|
+
DEV: assert(
|
|
583
|
+
"function" === typeof drawing || Array.isArray(drawing),
|
|
584
|
+
"paint: 3rd param must be a function or array"
|
|
585
|
+
);
|
|
586
|
+
DEV: assert(
|
|
587
|
+
options && !options.scale || isFinite(options.scale),
|
|
588
|
+
"paint: 4th param (options.scale) must be a number"
|
|
589
|
+
);
|
|
637
590
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
638
591
|
canvas.width = width * scale;
|
|
639
592
|
canvas.height = height * scale;
|
|
@@ -667,8 +620,6 @@
|
|
|
667
620
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
668
621
|
*/
|
|
669
622
|
ctx(context) {
|
|
670
|
-
if (true) {
|
|
671
|
-
}
|
|
672
623
|
if (context) {
|
|
673
624
|
_ctx = context;
|
|
674
625
|
}
|
|
@@ -693,10 +644,8 @@
|
|
|
693
644
|
* @param {number} y
|
|
694
645
|
*/
|
|
695
646
|
translate: (x, y) => {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
assert(isFinite(y), "translate: 2nd param must be a number");
|
|
699
|
-
}
|
|
647
|
+
DEV: assert(isFinite(x), "translate: 1st param must be a number");
|
|
648
|
+
DEV: assert(isFinite(y), "translate: 2nd param must be a number");
|
|
700
649
|
return _ctx.translate(~~x, ~~y);
|
|
701
650
|
},
|
|
702
651
|
/**
|
|
@@ -706,13 +655,11 @@
|
|
|
706
655
|
* @param {number} [y]
|
|
707
656
|
*/
|
|
708
657
|
scale: (x, y) => {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
);
|
|
715
|
-
}
|
|
658
|
+
DEV: assert(isFinite(x), "scale: 1st param must be a number");
|
|
659
|
+
DEV: assert(
|
|
660
|
+
y == null || isFinite(y),
|
|
661
|
+
"scale: 2nd param must be a number"
|
|
662
|
+
);
|
|
716
663
|
return _ctx.scale(x, y || x);
|
|
717
664
|
},
|
|
718
665
|
/**
|
|
@@ -721,9 +668,7 @@
|
|
|
721
668
|
* @param {number} radians
|
|
722
669
|
*/
|
|
723
670
|
rotate: (radians) => {
|
|
724
|
-
|
|
725
|
-
assert(isFinite(radians), "rotate: 1st param must be a number");
|
|
726
|
-
}
|
|
671
|
+
DEV: assert(isFinite(radians), "rotate: 1st param must be a number");
|
|
727
672
|
return _ctx.rotate(radians);
|
|
728
673
|
},
|
|
729
674
|
/**
|
|
@@ -733,9 +678,7 @@
|
|
|
733
678
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha
|
|
734
679
|
*/
|
|
735
680
|
alpha(value) {
|
|
736
|
-
|
|
737
|
-
assert(isFinite(value), "alpha: 1st param must be a number");
|
|
738
|
-
}
|
|
681
|
+
DEV: assert(isFinite(value), "alpha: 1st param must be a number");
|
|
739
682
|
_ctx.globalAlpha = instance.clamp(value, 0, 1);
|
|
740
683
|
},
|
|
741
684
|
/**
|
|
@@ -748,12 +691,10 @@
|
|
|
748
691
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D
|
|
749
692
|
*/
|
|
750
693
|
path: (arg) => {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
);
|
|
756
|
-
}
|
|
694
|
+
DEV: assert(
|
|
695
|
+
null == arg || "string" === typeof arg || arg instanceof Path2D,
|
|
696
|
+
"path: 1st param must be a string or a Path2D instance"
|
|
697
|
+
);
|
|
757
698
|
return new Path2D(arg);
|
|
758
699
|
},
|
|
759
700
|
/**
|
|
@@ -763,16 +704,14 @@
|
|
|
763
704
|
* @param {Path2D} [path]
|
|
764
705
|
*/
|
|
765
706
|
fill(color, path) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
);
|
|
775
|
-
}
|
|
707
|
+
DEV: assert(
|
|
708
|
+
null == color || isFinite(color) && color >= 0,
|
|
709
|
+
"fill: 1st param must be a positive number or zero"
|
|
710
|
+
);
|
|
711
|
+
DEV: assert(
|
|
712
|
+
null == path || path instanceof Path2D,
|
|
713
|
+
"fill: 2nd param must be a Path2D instance"
|
|
714
|
+
);
|
|
776
715
|
_ctx.fillStyle = instance.getcolor(color);
|
|
777
716
|
if (path) {
|
|
778
717
|
_ctx.fill(path);
|
|
@@ -787,16 +726,14 @@
|
|
|
787
726
|
* @param {Path2D} [path]
|
|
788
727
|
*/
|
|
789
728
|
stroke(color, path) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
);
|
|
799
|
-
}
|
|
729
|
+
DEV: assert(
|
|
730
|
+
null == color || isFinite(color) && color >= 0,
|
|
731
|
+
"stroke: 1st param must be a positive number or zero"
|
|
732
|
+
);
|
|
733
|
+
DEV: assert(
|
|
734
|
+
null == path || path instanceof Path2D,
|
|
735
|
+
"stroke: 2nd param must be a Path2D instance"
|
|
736
|
+
);
|
|
800
737
|
_ctx.strokeStyle = instance.getcolor(color);
|
|
801
738
|
if (path) {
|
|
802
739
|
_ctx.stroke(path);
|
|
@@ -811,12 +748,10 @@
|
|
|
811
748
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip
|
|
812
749
|
*/
|
|
813
750
|
clip(path) {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
);
|
|
819
|
-
}
|
|
751
|
+
DEV: assert(
|
|
752
|
+
path instanceof Path2D,
|
|
753
|
+
"clip: 1st param must be a Path2D instance"
|
|
754
|
+
);
|
|
820
755
|
_ctx.clip(path);
|
|
821
756
|
},
|
|
822
757
|
/** SOUND API */
|
|
@@ -832,17 +767,15 @@
|
|
|
832
767
|
* @see https://github.com/KilledByAPixel/ZzFX
|
|
833
768
|
*/
|
|
834
769
|
sfx(zzfxParams, pitchSlide = 0, volumeFactor = 1) {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
);
|
|
845
|
-
}
|
|
770
|
+
DEV: assert(
|
|
771
|
+
null == zzfxParams || Array.isArray(zzfxParams),
|
|
772
|
+
"sfx: 1st param must be an array"
|
|
773
|
+
);
|
|
774
|
+
DEV: assert(isFinite(pitchSlide), "sfx: 2nd param must be a number");
|
|
775
|
+
DEV: assert(
|
|
776
|
+
isFinite(volumeFactor),
|
|
777
|
+
"sfx: 3rd param must be a number"
|
|
778
|
+
);
|
|
846
779
|
if (root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive) {
|
|
847
780
|
return false;
|
|
848
781
|
}
|
|
@@ -862,9 +795,7 @@
|
|
|
862
795
|
* @param {number} value
|
|
863
796
|
*/
|
|
864
797
|
volume(value) {
|
|
865
|
-
|
|
866
|
-
assert(isFinite(value), "volume: 1st param must be a number");
|
|
867
|
-
}
|
|
798
|
+
DEV: assert(isFinite(value), "volume: 1st param must be a number");
|
|
868
799
|
root.zzfxV = value;
|
|
869
800
|
},
|
|
870
801
|
/** UTILS API */
|
|
@@ -882,16 +813,14 @@
|
|
|
882
813
|
* @returns {boolean}
|
|
883
814
|
*/
|
|
884
815
|
colrect: (x1, y1, w1, h1, x2, y2, w2, h2) => {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
assert(isFinite(h2), "colrect: 8th param must be a number");
|
|
894
|
-
}
|
|
816
|
+
DEV: assert(isFinite(x1), "colrect: 1st param must be a number");
|
|
817
|
+
DEV: assert(isFinite(y1), "colrect: 2nd param must be a number");
|
|
818
|
+
DEV: assert(isFinite(w1), "colrect: 3rd param must be a number");
|
|
819
|
+
DEV: assert(isFinite(h1), "colrect: 4th param must be a number");
|
|
820
|
+
DEV: assert(isFinite(x2), "colrect: 5th param must be a number");
|
|
821
|
+
DEV: assert(isFinite(y2), "colrect: 6th param must be a number");
|
|
822
|
+
DEV: assert(isFinite(w2), "colrect: 7th param must be a number");
|
|
823
|
+
DEV: assert(isFinite(h2), "colrect: 8th param must be a number");
|
|
895
824
|
return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2;
|
|
896
825
|
},
|
|
897
826
|
/**
|
|
@@ -906,14 +835,12 @@
|
|
|
906
835
|
* @returns {boolean}
|
|
907
836
|
*/
|
|
908
837
|
colcirc: (x1, y1, r1, x2, y2, r2) => {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
916
|
-
}
|
|
838
|
+
DEV: assert(isFinite(x1), "colcirc: 1st param must be a number");
|
|
839
|
+
DEV: assert(isFinite(y1), "colcirc: 2nd param must be a number");
|
|
840
|
+
DEV: assert(isFinite(r1), "colcirc: 3rd param must be a number");
|
|
841
|
+
DEV: assert(isFinite(x2), "colcirc: 4th param must be a number");
|
|
842
|
+
DEV: assert(isFinite(y2), "colcirc: 5th param must be a number");
|
|
843
|
+
DEV: assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
917
844
|
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2);
|
|
918
845
|
},
|
|
919
846
|
/** PLUGINS API */
|
|
@@ -923,16 +850,14 @@
|
|
|
923
850
|
* @param {pluginCallback} callback
|
|
924
851
|
*/
|
|
925
852
|
use(callback, config = {}) {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
);
|
|
935
|
-
}
|
|
853
|
+
DEV: assert(
|
|
854
|
+
"function" === typeof callback,
|
|
855
|
+
"use: 1st param must be a function"
|
|
856
|
+
);
|
|
857
|
+
DEV: assert(
|
|
858
|
+
"object" === typeof config,
|
|
859
|
+
"use: 2nd param must be an object"
|
|
860
|
+
);
|
|
936
861
|
_initialized ? loadPlugin(callback, config) : _plugins.push([callback, config]);
|
|
937
862
|
},
|
|
938
863
|
/**
|
|
@@ -943,16 +868,14 @@
|
|
|
943
868
|
* @returns {Function} a function to remove the listener
|
|
944
869
|
*/
|
|
945
870
|
listen(eventName, callback) {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
);
|
|
955
|
-
}
|
|
871
|
+
DEV: assert(
|
|
872
|
+
"string" === typeof eventName,
|
|
873
|
+
"listen: 1st param must be a string"
|
|
874
|
+
);
|
|
875
|
+
DEV: assert(
|
|
876
|
+
"function" === typeof callback,
|
|
877
|
+
"listen: 2nd param must be a function"
|
|
878
|
+
);
|
|
956
879
|
_events[eventName] = _events[eventName] || /* @__PURE__ */ new Set();
|
|
957
880
|
_events[eventName].add(callback);
|
|
958
881
|
return () => _events[eventName].delete(callback);
|
|
@@ -967,12 +890,10 @@
|
|
|
967
890
|
* @param {*} [arg4] any data to be passed over the listeners
|
|
968
891
|
*/
|
|
969
892
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
);
|
|
975
|
-
}
|
|
893
|
+
DEV: assert(
|
|
894
|
+
"string" === typeof eventName,
|
|
895
|
+
"emit: 1st param must be a string"
|
|
896
|
+
);
|
|
976
897
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
977
898
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
978
899
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
@@ -984,12 +905,10 @@
|
|
|
984
905
|
* @returns {string} the color code
|
|
985
906
|
*/
|
|
986
907
|
getcolor: (index) => {
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
);
|
|
992
|
-
}
|
|
908
|
+
DEV: assert(
|
|
909
|
+
null == index || isFinite(index) && index >= 0,
|
|
910
|
+
"getcolor: 1st param must be a number"
|
|
911
|
+
);
|
|
993
912
|
return colors[~~index % colors.length];
|
|
994
913
|
},
|
|
995
914
|
/**
|
|
@@ -999,13 +918,12 @@
|
|
|
999
918
|
* @param {*} value
|
|
1000
919
|
*/
|
|
1001
920
|
setvar(key, value) {
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
}
|
|
921
|
+
DEV: assert(
|
|
922
|
+
"string" === typeof key,
|
|
923
|
+
"setvar: 1st param must be a string"
|
|
924
|
+
);
|
|
925
|
+
if (value == null) {
|
|
926
|
+
console.warn(`setvar: key "${key}" was defined as ${value}`);
|
|
1009
927
|
}
|
|
1010
928
|
instance[key] = value;
|
|
1011
929
|
if (_global) {
|
|
@@ -1019,10 +937,8 @@
|
|
|
1019
937
|
* @param {number} height
|
|
1020
938
|
*/
|
|
1021
939
|
resize(width, height) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
assert(isFinite(height), "resize: 2nd param must be a number");
|
|
1025
|
-
}
|
|
940
|
+
DEV: assert(isFinite(width), "resize: 1st param must be a number");
|
|
941
|
+
DEV: assert(isFinite(height), "resize: 2nd param must be a number");
|
|
1026
942
|
instance.setvar("WIDTH", _canvas.width = width);
|
|
1027
943
|
instance.setvar("HEIGHT", _canvas.height = height);
|
|
1028
944
|
pageResized();
|
|
@@ -1035,9 +951,10 @@
|
|
|
1035
951
|
* @param {number} value
|
|
1036
952
|
*/
|
|
1037
953
|
timescale(value) {
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
954
|
+
DEV: assert(
|
|
955
|
+
isFinite(value),
|
|
956
|
+
"timescale: 1st param must be a number"
|
|
957
|
+
);
|
|
1041
958
|
_timeScale = value;
|
|
1042
959
|
},
|
|
1043
960
|
/**
|
|
@@ -1046,12 +963,10 @@
|
|
|
1046
963
|
* @param {number} value
|
|
1047
964
|
*/
|
|
1048
965
|
setfps(value) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
);
|
|
1054
|
-
}
|
|
966
|
+
DEV: assert(
|
|
967
|
+
isFinite(value) && value >= 1,
|
|
968
|
+
"setfps: 1st param must be a positive number"
|
|
969
|
+
);
|
|
1055
970
|
_deltaTime = 1 / ~~value;
|
|
1056
971
|
},
|
|
1057
972
|
/**
|
|
@@ -1188,12 +1103,10 @@
|
|
|
1188
1103
|
if (settings.keyboardEvents) {
|
|
1189
1104
|
const _keys = /* @__PURE__ */ new Set();
|
|
1190
1105
|
const iskeydown = (key) => {
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
);
|
|
1196
|
-
}
|
|
1106
|
+
DEV: assert(
|
|
1107
|
+
"string" === typeof key,
|
|
1108
|
+
"iskeydown: 1st param must be a string"
|
|
1109
|
+
);
|
|
1197
1110
|
return "any" === key ? _keys.size > 0 : _keys.has(key.toLowerCase());
|
|
1198
1111
|
};
|
|
1199
1112
|
instance.setvar("iskeydown", iskeydown);
|
|
@@ -1227,7 +1140,7 @@
|
|
|
1227
1140
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1228
1141
|
_lastFrameTime = now;
|
|
1229
1142
|
if (frameTime > _deltaTime * 30)
|
|
1230
|
-
return
|
|
1143
|
+
return console.log("skipping too long frame");
|
|
1231
1144
|
_accumulated += frameTime;
|
|
1232
1145
|
if (!_animated) {
|
|
1233
1146
|
_accumulated = _deltaTime;
|
|
@@ -1247,20 +1160,18 @@
|
|
|
1247
1160
|
}
|
|
1248
1161
|
function setupCanvas() {
|
|
1249
1162
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
);
|
|
1263
|
-
}
|
|
1163
|
+
DEV: assert(
|
|
1164
|
+
_canvas && _canvas.tagName === "CANVAS",
|
|
1165
|
+
"Invalid canvas element"
|
|
1166
|
+
);
|
|
1167
|
+
DEV: assert(
|
|
1168
|
+
null === instance.WIDTH || instance.WIDTH > 0,
|
|
1169
|
+
`Litecanvas' "width" option should be null or a positive number`
|
|
1170
|
+
);
|
|
1171
|
+
DEV: assert(
|
|
1172
|
+
null === instance.HEIGHT || instance.HEIGHT > 0,
|
|
1173
|
+
`Litecanvas' "width" option should be null or a positive number`
|
|
1174
|
+
);
|
|
1264
1175
|
instance.setvar("CANVAS", _canvas);
|
|
1265
1176
|
_ctx = _canvas.getContext("2d");
|
|
1266
1177
|
on(_canvas, "click", () => root.focus());
|
|
@@ -1309,12 +1220,10 @@
|
|
|
1309
1220
|
}
|
|
1310
1221
|
function loadPlugin(callback, config) {
|
|
1311
1222
|
const pluginData = callback(instance, _helpers, config);
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
);
|
|
1317
|
-
}
|
|
1223
|
+
DEV: assert(
|
|
1224
|
+
null == pluginData || "object" === typeof pluginData,
|
|
1225
|
+
"Litecanvas plugins should return an object or nothing"
|
|
1226
|
+
);
|
|
1318
1227
|
for (const key in pluginData) {
|
|
1319
1228
|
instance.setvar(key, pluginData[key]);
|
|
1320
1229
|
}
|