litecanvas 0.103.5 → 0.103.7
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 +439 -429
- package/dist/dist.js +297 -287
- package/package.json +2 -2
- package/src/index.js +3 -3
- package/src/version.js +1 -1
package/dist/dist.dev.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
(() => {
|
|
2
2
|
var setupZzFX = (global) => {
|
|
3
|
-
const zzfxX = new AudioContext()
|
|
4
|
-
global.zzfxV = 1
|
|
3
|
+
const zzfxX = new AudioContext();
|
|
4
|
+
global.zzfxV = 1;
|
|
5
5
|
return (
|
|
6
6
|
i = 1,
|
|
7
7
|
d = 0.05,
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
U = 0,
|
|
52
52
|
W = 0,
|
|
53
53
|
Y = 0,
|
|
54
|
-
Z = 0
|
|
54
|
+
Z = 0;
|
|
55
55
|
for (
|
|
56
56
|
e = a * e + 9,
|
|
57
57
|
X *= a,
|
|
@@ -102,20 +102,20 @@
|
|
|
102
102
|
(u = (z += T += H) * n.cos(K * _++)),
|
|
103
103
|
(x += u + u * j * C(f ** 5)),
|
|
104
104
|
g && ++g > J && ((z += V), (O += V), (g = 0)),
|
|
105
|
-
!h || ++$ % h || ((z = O), (T = F), (g = g || 1)))
|
|
106
|
-
|
|
105
|
+
!h || ++$ % h || ((z = O), (T = F), (g = g || 1)));
|
|
106
|
+
((i = zzfxX.createBuffer(1, s, a)),
|
|
107
107
|
i.getChannelData(0).set(d),
|
|
108
108
|
(z = zzfxX.createBufferSource()),
|
|
109
109
|
(z.buffer = i),
|
|
110
110
|
z.connect(zzfxX.destination),
|
|
111
|
-
z.start())
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"]
|
|
111
|
+
z.start());
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"];
|
|
115
115
|
var assert = (condition, message = "Assertion failed") => {
|
|
116
|
-
if (!condition) throw new Error("[litecanvas] " + message)
|
|
117
|
-
}
|
|
118
|
-
var version = "0.103.
|
|
116
|
+
if (!condition) throw new Error("[litecanvas] " + message);
|
|
117
|
+
};
|
|
118
|
+
var version = "0.103.7";
|
|
119
119
|
function litecanvas(settings = {}) {
|
|
120
120
|
const root = window,
|
|
121
121
|
math = Math,
|
|
@@ -125,10 +125,10 @@
|
|
|
125
125
|
raf = requestAnimationFrame,
|
|
126
126
|
_browserEventListeners = [],
|
|
127
127
|
on = (elem, evt, callback) => {
|
|
128
|
-
elem.addEventListener(evt, callback, false)
|
|
128
|
+
elem.addEventListener(evt, callback, false);
|
|
129
129
|
_browserEventListeners.push(() =>
|
|
130
130
|
elem.removeEventListener(evt, callback, false),
|
|
131
|
-
)
|
|
131
|
+
);
|
|
132
132
|
},
|
|
133
133
|
lowerCase = (str) => str.toLowerCase(),
|
|
134
134
|
preventDefault = (ev) => ev.preventDefault(),
|
|
@@ -144,8 +144,8 @@
|
|
|
144
144
|
loop: null,
|
|
145
145
|
tapEvents: true,
|
|
146
146
|
keyboardEvents: true,
|
|
147
|
-
}
|
|
148
|
-
settings = Object.assign(defaults, settings)
|
|
147
|
+
};
|
|
148
|
+
settings = Object.assign(defaults, settings);
|
|
149
149
|
let _initialized = false,
|
|
150
150
|
_paused = true,
|
|
151
151
|
_canvas,
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
_coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized",
|
|
169
169
|
_mathFunctions =
|
|
170
170
|
"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp",
|
|
171
|
-
_eventListeners = {}
|
|
171
|
+
_eventListeners = {};
|
|
172
172
|
const instance = {
|
|
173
173
|
W: 0,
|
|
174
174
|
H: 0,
|
|
@@ -181,483 +181,487 @@
|
|
|
181
181
|
DEV: assert(
|
|
182
182
|
isNumber(start),
|
|
183
183
|
loggerPrefix + "lerp() 1st param must be a number",
|
|
184
|
-
)
|
|
184
|
+
);
|
|
185
185
|
DEV: assert(
|
|
186
186
|
isNumber(end),
|
|
187
187
|
loggerPrefix + "lerp() 2nd param must be a number",
|
|
188
|
-
)
|
|
188
|
+
);
|
|
189
189
|
DEV: assert(
|
|
190
190
|
isNumber(t),
|
|
191
191
|
loggerPrefix + "lerp() 3rd param must be a number",
|
|
192
|
-
)
|
|
193
|
-
return start + t * (end - start)
|
|
192
|
+
);
|
|
193
|
+
return start + t * (end - start);
|
|
194
194
|
},
|
|
195
195
|
deg2rad: (degs) => {
|
|
196
|
-
DEV: assert(isNumber(degs), "deg2rad: 1st param must be a number")
|
|
197
|
-
return (math.PI / 180) * degs
|
|
196
|
+
DEV: assert(isNumber(degs), "deg2rad: 1st param must be a number");
|
|
197
|
+
return (math.PI / 180) * degs;
|
|
198
198
|
},
|
|
199
199
|
rad2deg: (rads) => {
|
|
200
|
-
DEV: assert(isNumber(rads), "rad2deg: 1st param must be a number")
|
|
201
|
-
return (180 / math.PI) * rads
|
|
200
|
+
DEV: assert(isNumber(rads), "rad2deg: 1st param must be a number");
|
|
201
|
+
return (180 / math.PI) * rads;
|
|
202
202
|
},
|
|
203
203
|
round: (n, precision = 0) => {
|
|
204
204
|
DEV: assert(
|
|
205
205
|
isNumber(n),
|
|
206
206
|
loggerPrefix + "round() 1st param must be a number",
|
|
207
|
-
)
|
|
207
|
+
);
|
|
208
208
|
DEV: assert(
|
|
209
209
|
isNumber(precision) && precision >= 0,
|
|
210
210
|
loggerPrefix + "round() 2nd param must be a positive number or zero",
|
|
211
|
-
)
|
|
211
|
+
);
|
|
212
212
|
if (!precision) {
|
|
213
|
-
return math.round(n)
|
|
213
|
+
return math.round(n);
|
|
214
214
|
}
|
|
215
|
-
const multiplier = 10 ** precision
|
|
216
|
-
return math.round(n * multiplier) / multiplier
|
|
215
|
+
const multiplier = 10 ** precision;
|
|
216
|
+
return math.round(n * multiplier) / multiplier;
|
|
217
217
|
},
|
|
218
218
|
clamp: (value, min, max) => {
|
|
219
219
|
DEV: assert(
|
|
220
220
|
isNumber(value),
|
|
221
221
|
loggerPrefix + "clamp() 1st param must be a number",
|
|
222
|
-
)
|
|
222
|
+
);
|
|
223
223
|
DEV: assert(
|
|
224
224
|
isNumber(min),
|
|
225
225
|
loggerPrefix + "clamp() 2nd param must be a number",
|
|
226
|
-
)
|
|
226
|
+
);
|
|
227
227
|
DEV: assert(
|
|
228
228
|
isNumber(max),
|
|
229
229
|
loggerPrefix + "clamp() 3rd param must be a number",
|
|
230
|
-
)
|
|
230
|
+
);
|
|
231
231
|
DEV: assert(
|
|
232
|
-
max
|
|
232
|
+
max >= min,
|
|
233
233
|
loggerPrefix +
|
|
234
234
|
"clamp() the 2nd param must be less than the 3rd param",
|
|
235
|
-
)
|
|
236
|
-
if (value < min) return min
|
|
237
|
-
if (value > max) return max
|
|
238
|
-
return value
|
|
235
|
+
);
|
|
236
|
+
if (value < min) return min;
|
|
237
|
+
if (value > max) return max;
|
|
238
|
+
return value;
|
|
239
239
|
},
|
|
240
240
|
dist: (x1, y1, x2, y2) => {
|
|
241
241
|
DEV: assert(
|
|
242
242
|
isNumber(x1),
|
|
243
243
|
loggerPrefix + "dist() 1st param must be a number",
|
|
244
|
-
)
|
|
244
|
+
);
|
|
245
245
|
DEV: assert(
|
|
246
246
|
isNumber(y1),
|
|
247
247
|
loggerPrefix + "dist() 2nd param must be a number",
|
|
248
|
-
)
|
|
248
|
+
);
|
|
249
249
|
DEV: assert(
|
|
250
250
|
isNumber(x2),
|
|
251
251
|
loggerPrefix + "dist() 3rd param must be a number",
|
|
252
|
-
)
|
|
252
|
+
);
|
|
253
253
|
DEV: assert(
|
|
254
254
|
isNumber(y2),
|
|
255
255
|
loggerPrefix + "dist() 4th param must be a number",
|
|
256
|
-
)
|
|
257
|
-
return math.hypot(x2 - x1, y2 - y1)
|
|
256
|
+
);
|
|
257
|
+
return math.hypot(x2 - x1, y2 - y1);
|
|
258
258
|
},
|
|
259
259
|
wrap: (value, min, max) => {
|
|
260
260
|
DEV: assert(
|
|
261
261
|
isNumber(value),
|
|
262
262
|
loggerPrefix + "wrap() 1st param must be a number",
|
|
263
|
-
)
|
|
263
|
+
);
|
|
264
264
|
DEV: assert(
|
|
265
265
|
isNumber(min),
|
|
266
266
|
loggerPrefix + "wrap() 2nd param must be a number",
|
|
267
|
-
)
|
|
267
|
+
);
|
|
268
268
|
DEV: assert(
|
|
269
269
|
isNumber(max),
|
|
270
270
|
loggerPrefix + "wrap() 3rd param must be a number",
|
|
271
|
-
)
|
|
271
|
+
);
|
|
272
272
|
DEV: assert(
|
|
273
273
|
max > min,
|
|
274
274
|
loggerPrefix + "wrap() the 2nd param must be less than the 3rd param",
|
|
275
|
-
)
|
|
276
|
-
return value - (max - min) * math.floor((value - min) / (max - min))
|
|
275
|
+
);
|
|
276
|
+
return value - (max - min) * math.floor((value - min) / (max - min));
|
|
277
277
|
},
|
|
278
278
|
map(value, start1, stop1, start2, stop2, withinBounds) {
|
|
279
279
|
DEV: assert(
|
|
280
280
|
isNumber(value),
|
|
281
281
|
loggerPrefix + "map() 1st param must be a number",
|
|
282
|
-
)
|
|
282
|
+
);
|
|
283
283
|
DEV: assert(
|
|
284
284
|
isNumber(start1),
|
|
285
285
|
loggerPrefix + "map() 2nd param must be a number",
|
|
286
|
-
)
|
|
286
|
+
);
|
|
287
287
|
DEV: assert(
|
|
288
288
|
isNumber(stop1),
|
|
289
289
|
loggerPrefix + "map() 3rd param must be a number",
|
|
290
|
-
)
|
|
290
|
+
);
|
|
291
291
|
DEV: assert(
|
|
292
292
|
isNumber(start2),
|
|
293
293
|
loggerPrefix + "map() 4th param must be a number",
|
|
294
|
-
)
|
|
294
|
+
);
|
|
295
295
|
DEV: assert(
|
|
296
296
|
isNumber(stop2),
|
|
297
297
|
loggerPrefix + "map() 5th param must be a number",
|
|
298
|
-
)
|
|
298
|
+
);
|
|
299
299
|
DEV: assert(
|
|
300
300
|
stop1 !== start1,
|
|
301
301
|
loggerPrefix +
|
|
302
302
|
"map() the 2nd param must be different than the 3rd param",
|
|
303
|
-
)
|
|
303
|
+
);
|
|
304
304
|
const result =
|
|
305
|
-
((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2
|
|
306
|
-
return withinBounds ? instance.clamp(result, start2, stop2) : result
|
|
305
|
+
((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2;
|
|
306
|
+
return withinBounds ? instance.clamp(result, start2, stop2) : result;
|
|
307
307
|
},
|
|
308
308
|
norm: (value, start, stop) => {
|
|
309
309
|
DEV: assert(
|
|
310
310
|
isNumber(value),
|
|
311
311
|
loggerPrefix + "norm() 1st param must be a number",
|
|
312
|
-
)
|
|
312
|
+
);
|
|
313
313
|
DEV: assert(
|
|
314
314
|
isNumber(start),
|
|
315
315
|
loggerPrefix + "norm() 2nd param must be a number",
|
|
316
|
-
)
|
|
316
|
+
);
|
|
317
317
|
DEV: assert(
|
|
318
318
|
isNumber(stop),
|
|
319
319
|
loggerPrefix + "norm() 3rd param must be a number",
|
|
320
|
-
)
|
|
320
|
+
);
|
|
321
321
|
DEV: assert(
|
|
322
322
|
start !== stop,
|
|
323
323
|
loggerPrefix +
|
|
324
324
|
"norm() the 2nd param must be different than the 3rd param",
|
|
325
|
-
)
|
|
326
|
-
return instance.map(value, start, stop, 0, 1)
|
|
325
|
+
);
|
|
326
|
+
return instance.map(value, start, stop, 0, 1);
|
|
327
327
|
},
|
|
328
328
|
rand: (min = 0, max = 1) => {
|
|
329
329
|
DEV: assert(
|
|
330
330
|
isNumber(min),
|
|
331
331
|
loggerPrefix + "rand() 1st param must be a number",
|
|
332
|
-
)
|
|
332
|
+
);
|
|
333
333
|
DEV: assert(
|
|
334
334
|
isNumber(max),
|
|
335
335
|
loggerPrefix + "rand() 2nd param must be a number",
|
|
336
|
-
)
|
|
336
|
+
);
|
|
337
337
|
DEV: assert(
|
|
338
|
-
max
|
|
338
|
+
max >= min,
|
|
339
339
|
loggerPrefix + "rand() the 1st param must be less than the 2nd param",
|
|
340
|
-
)
|
|
341
|
-
const a = 1664525
|
|
342
|
-
const c = 1013904223
|
|
343
|
-
const m = 4294967296
|
|
344
|
-
_rngSeed = (a * _rngSeed + c) % m
|
|
345
|
-
return (_rngSeed / m) * (max - min) + min
|
|
340
|
+
);
|
|
341
|
+
const a = 1664525;
|
|
342
|
+
const c = 1013904223;
|
|
343
|
+
const m = 4294967296;
|
|
344
|
+
_rngSeed = (a * _rngSeed + c) % m;
|
|
345
|
+
return (_rngSeed / m) * (max - min) + min;
|
|
346
346
|
},
|
|
347
347
|
randi: (min = 0, max = 1) => {
|
|
348
348
|
DEV: assert(
|
|
349
349
|
isNumber(min),
|
|
350
350
|
loggerPrefix + "randi() 1st param must be a number",
|
|
351
|
-
)
|
|
351
|
+
);
|
|
352
352
|
DEV: assert(
|
|
353
353
|
isNumber(max),
|
|
354
354
|
loggerPrefix + "randi() 2nd param must be a number",
|
|
355
|
-
)
|
|
355
|
+
);
|
|
356
356
|
DEV: assert(
|
|
357
|
-
|
|
357
|
+
max >= min,
|
|
358
358
|
loggerPrefix +
|
|
359
359
|
"randi() the 1st param must be less than the 2nd param",
|
|
360
|
-
)
|
|
361
|
-
return ~~instance.rand(min, max + 1)
|
|
360
|
+
);
|
|
361
|
+
return ~~instance.rand(min, max + 1);
|
|
362
362
|
},
|
|
363
363
|
rseed(value) {
|
|
364
364
|
DEV: assert(
|
|
365
365
|
isNumber(value) && value >= 0,
|
|
366
366
|
loggerPrefix + "rseed() 1st param must be a positive integer or zero",
|
|
367
|
-
)
|
|
368
|
-
_rngSeed = ~~value
|
|
367
|
+
);
|
|
368
|
+
_rngSeed = ~~value;
|
|
369
369
|
},
|
|
370
370
|
cls(color) {
|
|
371
371
|
DEV: assert(
|
|
372
372
|
null == color || (isNumber(color) && color >= 0),
|
|
373
373
|
loggerPrefix +
|
|
374
374
|
"cls() 1st param must be a positive number or zero or undefined",
|
|
375
|
-
)
|
|
375
|
+
);
|
|
376
376
|
if (null == color) {
|
|
377
|
-
_ctx.clearRect(0, 0, instance.W, instance.H)
|
|
377
|
+
_ctx.clearRect(0, 0, instance.W, instance.H);
|
|
378
378
|
} else {
|
|
379
|
-
instance.rectfill(0, 0, instance.W, instance.H, color)
|
|
379
|
+
instance.rectfill(0, 0, instance.W, instance.H, color);
|
|
380
380
|
}
|
|
381
381
|
},
|
|
382
382
|
rect(x, y, width, height, color, radii) {
|
|
383
383
|
DEV: assert(
|
|
384
384
|
isNumber(x),
|
|
385
385
|
loggerPrefix + "rect() 1st param must be a number",
|
|
386
|
-
)
|
|
386
|
+
);
|
|
387
387
|
DEV: assert(
|
|
388
388
|
isNumber(y),
|
|
389
389
|
loggerPrefix + "rect() 2nd param must be a number",
|
|
390
|
-
)
|
|
390
|
+
);
|
|
391
391
|
DEV: assert(
|
|
392
392
|
isNumber(width) && width > 0,
|
|
393
393
|
loggerPrefix + "rect() 3rd param must be a positive number",
|
|
394
|
-
)
|
|
394
|
+
);
|
|
395
395
|
DEV: assert(
|
|
396
396
|
isNumber(height) && height >= 0,
|
|
397
397
|
loggerPrefix + "rect() 4th param must be a positive number or zero",
|
|
398
|
-
)
|
|
398
|
+
);
|
|
399
399
|
DEV: assert(
|
|
400
400
|
null == color || (isNumber(color) && color >= 0),
|
|
401
401
|
loggerPrefix + "rect() 5th param must be a positive number or zero",
|
|
402
|
-
)
|
|
402
|
+
);
|
|
403
403
|
DEV: assert(
|
|
404
404
|
null == radii ||
|
|
405
405
|
isNumber(radii) ||
|
|
406
406
|
(Array.isArray(radii) && radii.length >= 1),
|
|
407
407
|
loggerPrefix +
|
|
408
408
|
"rect() 6th param must be a number or array of numbers",
|
|
409
|
-
)
|
|
410
|
-
beginPath(_ctx)
|
|
409
|
+
);
|
|
410
|
+
beginPath(_ctx);
|
|
411
411
|
_ctx[radii ? "roundRect" : "rect"](
|
|
412
412
|
~~x - _outline_fix,
|
|
413
413
|
~~y - _outline_fix,
|
|
414
414
|
~~width + _outline_fix * 2,
|
|
415
415
|
~~height + _outline_fix * 2,
|
|
416
416
|
radii,
|
|
417
|
-
)
|
|
418
|
-
instance.stroke(color)
|
|
417
|
+
);
|
|
418
|
+
instance.stroke(color);
|
|
419
419
|
},
|
|
420
420
|
rectfill(x, y, width, height, color, radii) {
|
|
421
421
|
DEV: assert(
|
|
422
422
|
isNumber(x),
|
|
423
423
|
loggerPrefix + "rectfill() 1st param must be a number",
|
|
424
|
-
)
|
|
424
|
+
);
|
|
425
425
|
DEV: assert(
|
|
426
426
|
isNumber(y),
|
|
427
427
|
loggerPrefix + "rectfill() 2nd param must be a number",
|
|
428
|
-
)
|
|
428
|
+
);
|
|
429
429
|
DEV: assert(
|
|
430
430
|
isNumber(width) && width >= 0,
|
|
431
431
|
loggerPrefix +
|
|
432
432
|
"rectfill() 3rd param must be a positive number or zero",
|
|
433
|
-
)
|
|
433
|
+
);
|
|
434
434
|
DEV: assert(
|
|
435
435
|
isNumber(height) && height >= 0,
|
|
436
436
|
loggerPrefix +
|
|
437
437
|
"rectfill() 4th param must be a positive number or zero",
|
|
438
|
-
)
|
|
438
|
+
);
|
|
439
439
|
DEV: assert(
|
|
440
440
|
null == color || (isNumber(color) && color >= 0),
|
|
441
441
|
loggerPrefix +
|
|
442
442
|
"rectfill() 5th param must be a positive number or zero",
|
|
443
|
-
)
|
|
443
|
+
);
|
|
444
444
|
DEV: assert(
|
|
445
445
|
null == radii ||
|
|
446
446
|
isNumber(radii) ||
|
|
447
447
|
(Array.isArray(radii) && radii.length >= 1),
|
|
448
448
|
loggerPrefix +
|
|
449
449
|
"rectfill() 6th param must be a number or array of at least 2 numbers",
|
|
450
|
-
)
|
|
451
|
-
beginPath(_ctx)
|
|
452
|
-
_ctx[radii ? "roundRect" : "rect"](~~x, ~~y, ~~width, ~~height, radii)
|
|
453
|
-
instance.fill(color)
|
|
450
|
+
);
|
|
451
|
+
beginPath(_ctx);
|
|
452
|
+
_ctx[radii ? "roundRect" : "rect"](~~x, ~~y, ~~width, ~~height, radii);
|
|
453
|
+
instance.fill(color);
|
|
454
454
|
},
|
|
455
455
|
circ(x, y, radius, color) {
|
|
456
456
|
DEV: assert(
|
|
457
457
|
isNumber(x),
|
|
458
458
|
loggerPrefix + "circ() 1st param must be a number",
|
|
459
|
-
)
|
|
459
|
+
);
|
|
460
460
|
DEV: assert(
|
|
461
461
|
isNumber(y),
|
|
462
462
|
loggerPrefix + "circ() 2nd param must be a number",
|
|
463
|
-
)
|
|
463
|
+
);
|
|
464
464
|
DEV: assert(
|
|
465
465
|
isNumber(radius) && radius >= 0,
|
|
466
466
|
loggerPrefix + "circ() 3rd param must be a positive number or zero",
|
|
467
|
-
)
|
|
467
|
+
);
|
|
468
468
|
DEV: assert(
|
|
469
469
|
null == color || (isNumber(color) && color >= 0),
|
|
470
470
|
loggerPrefix + "circ() 4th param must be a positive number or zero",
|
|
471
|
-
)
|
|
472
|
-
beginPath(_ctx)
|
|
473
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)
|
|
474
|
-
instance.stroke(color)
|
|
471
|
+
);
|
|
472
|
+
beginPath(_ctx);
|
|
473
|
+
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
474
|
+
instance.stroke(color);
|
|
475
475
|
},
|
|
476
476
|
circfill(x, y, radius, color) {
|
|
477
477
|
DEV: assert(
|
|
478
478
|
isNumber(x),
|
|
479
479
|
loggerPrefix + "circfill() 1st param must be a number",
|
|
480
|
-
)
|
|
480
|
+
);
|
|
481
481
|
DEV: assert(
|
|
482
482
|
isNumber(y),
|
|
483
483
|
loggerPrefix + "circfill() 2nd param must be a number",
|
|
484
|
-
)
|
|
484
|
+
);
|
|
485
485
|
DEV: assert(
|
|
486
486
|
isNumber(radius) && radius >= 0,
|
|
487
487
|
loggerPrefix +
|
|
488
488
|
"circfill() 3rd param must be a positive number or zero",
|
|
489
|
-
)
|
|
489
|
+
);
|
|
490
490
|
DEV: assert(
|
|
491
491
|
null == color || (isNumber(color) && color >= 0),
|
|
492
492
|
loggerPrefix +
|
|
493
493
|
"circfill() 4th param must be a positive number or zero",
|
|
494
|
-
)
|
|
495
|
-
beginPath(_ctx)
|
|
496
|
-
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI)
|
|
497
|
-
instance.fill(color)
|
|
494
|
+
);
|
|
495
|
+
beginPath(_ctx);
|
|
496
|
+
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
497
|
+
instance.fill(color);
|
|
498
498
|
},
|
|
499
499
|
oval(x, y, radiusX, radiusY, color) {
|
|
500
500
|
DEV: assert(
|
|
501
501
|
isNumber(x),
|
|
502
502
|
loggerPrefix + "oval() 1st param must be a number",
|
|
503
|
-
)
|
|
503
|
+
);
|
|
504
504
|
DEV: assert(
|
|
505
505
|
isNumber(y),
|
|
506
506
|
loggerPrefix + "oval() 2nd param must be a number",
|
|
507
|
-
)
|
|
507
|
+
);
|
|
508
508
|
DEV: assert(
|
|
509
509
|
isNumber(radiusX) && radiusX >= 0,
|
|
510
510
|
loggerPrefix + "oval() 3rd param must be a positive number or zero",
|
|
511
|
-
)
|
|
511
|
+
);
|
|
512
512
|
DEV: assert(
|
|
513
513
|
isNumber(radiusY) && radiusY >= 0,
|
|
514
514
|
loggerPrefix + "oval() 4th param must be a positive number or zero",
|
|
515
|
-
)
|
|
515
|
+
);
|
|
516
516
|
DEV: assert(
|
|
517
517
|
null == color || (isNumber(color) && color >= 0),
|
|
518
518
|
loggerPrefix + "oval() 5th param must be a positive number or zero",
|
|
519
|
-
)
|
|
520
|
-
beginPath(_ctx)
|
|
521
|
-
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI)
|
|
522
|
-
instance.stroke(color)
|
|
519
|
+
);
|
|
520
|
+
beginPath(_ctx);
|
|
521
|
+
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
522
|
+
instance.stroke(color);
|
|
523
523
|
},
|
|
524
524
|
ovalfill(x, y, radiusX, radiusY, color) {
|
|
525
525
|
DEV: assert(
|
|
526
526
|
isNumber(x),
|
|
527
527
|
loggerPrefix + "ovalfill() 1st param must be a number",
|
|
528
|
-
)
|
|
528
|
+
);
|
|
529
529
|
DEV: assert(
|
|
530
530
|
isNumber(y),
|
|
531
531
|
loggerPrefix + "ovalfill() 2nd param must be a number",
|
|
532
|
-
)
|
|
532
|
+
);
|
|
533
533
|
DEV: assert(
|
|
534
534
|
isNumber(radiusX) && radiusX >= 0,
|
|
535
535
|
loggerPrefix +
|
|
536
536
|
"ovalfill() 3rd param must be a positive number or zero",
|
|
537
|
-
)
|
|
537
|
+
);
|
|
538
538
|
DEV: assert(
|
|
539
539
|
isNumber(radiusY) && radiusY >= 0,
|
|
540
540
|
loggerPrefix +
|
|
541
541
|
"ovalfill() 4th param must be a positive number or zero",
|
|
542
|
-
)
|
|
542
|
+
);
|
|
543
543
|
DEV: assert(
|
|
544
544
|
null == color || (isNumber(color) && color >= 0),
|
|
545
545
|
loggerPrefix +
|
|
546
546
|
"ovalfill() 5th param must be a positive number or zero",
|
|
547
|
-
)
|
|
548
|
-
beginPath(_ctx)
|
|
549
|
-
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI)
|
|
550
|
-
instance.fill(color)
|
|
547
|
+
);
|
|
548
|
+
beginPath(_ctx);
|
|
549
|
+
_ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
|
|
550
|
+
instance.fill(color);
|
|
551
551
|
},
|
|
552
552
|
shape(points) {
|
|
553
553
|
DEV: assert(
|
|
554
554
|
Array.isArray(points),
|
|
555
555
|
loggerPrefix + "shape() 1st param must be an array of numbers",
|
|
556
|
-
)
|
|
556
|
+
);
|
|
557
557
|
DEV: assert(
|
|
558
558
|
points.length >= 6,
|
|
559
559
|
loggerPrefix +
|
|
560
560
|
"shape() 1st param must be an array with at least 6 numbers (3 points)",
|
|
561
|
-
)
|
|
562
|
-
beginPath(_ctx)
|
|
561
|
+
);
|
|
562
|
+
beginPath(_ctx);
|
|
563
563
|
for (let i = 0; i < points.length; i += 2) {
|
|
564
564
|
if (0 === i) {
|
|
565
|
-
_ctx.moveTo(~~points[i], ~~points[i + 1])
|
|
565
|
+
_ctx.moveTo(~~points[i], ~~points[i + 1]);
|
|
566
566
|
} else {
|
|
567
|
-
_ctx.lineTo(~~points[i], ~~points[i + 1])
|
|
567
|
+
_ctx.lineTo(~~points[i], ~~points[i + 1]);
|
|
568
568
|
}
|
|
569
569
|
}
|
|
570
|
-
_ctx.lineTo(~~points[0], ~~points[1])
|
|
570
|
+
_ctx.lineTo(~~points[0], ~~points[1]);
|
|
571
571
|
},
|
|
572
572
|
line(x1, y1, x2, y2, color) {
|
|
573
573
|
DEV: assert(
|
|
574
574
|
isNumber(x1),
|
|
575
575
|
loggerPrefix + "line() 1st param must be a number",
|
|
576
|
-
)
|
|
576
|
+
);
|
|
577
577
|
DEV: assert(
|
|
578
578
|
isNumber(y1),
|
|
579
579
|
loggerPrefix + "line() 2nd param must be a number",
|
|
580
|
-
)
|
|
580
|
+
);
|
|
581
581
|
DEV: assert(
|
|
582
582
|
isNumber(x2),
|
|
583
583
|
loggerPrefix + "line() 3rd param must be a positive number or zero",
|
|
584
|
-
)
|
|
584
|
+
);
|
|
585
585
|
DEV: assert(
|
|
586
586
|
isNumber(y2),
|
|
587
587
|
loggerPrefix + "line() 4th param must be a positive number or zero",
|
|
588
|
-
)
|
|
588
|
+
);
|
|
589
589
|
DEV: assert(
|
|
590
590
|
null == color || (isNumber(color) && color >= 0),
|
|
591
591
|
loggerPrefix + "line() 5th param must be a positive number or zero",
|
|
592
|
-
)
|
|
593
|
-
beginPath(_ctx)
|
|
594
|
-
let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0
|
|
595
|
-
let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0
|
|
596
|
-
_ctx.moveTo(~~x1 + xfix, ~~y1 + yfix)
|
|
597
|
-
_ctx.lineTo(~~x2 + xfix, ~~y2 + yfix)
|
|
598
|
-
instance.stroke(color)
|
|
592
|
+
);
|
|
593
|
+
beginPath(_ctx);
|
|
594
|
+
let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0;
|
|
595
|
+
let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0;
|
|
596
|
+
_ctx.moveTo(~~x1 + xfix, ~~y1 + yfix);
|
|
597
|
+
_ctx.lineTo(~~x2 + xfix, ~~y2 + yfix);
|
|
598
|
+
instance.stroke(color);
|
|
599
599
|
},
|
|
600
600
|
linewidth(value) {
|
|
601
601
|
DEV: assert(
|
|
602
602
|
isNumber(value) && value >= 0,
|
|
603
603
|
loggerPrefix +
|
|
604
604
|
"linewidth() 1st param must be a positive number or zero",
|
|
605
|
-
)
|
|
606
|
-
_ctx.lineWidth = ~~value
|
|
607
|
-
_outline_fix = 0 === ~~value % 2 ? 0 : 0.5
|
|
605
|
+
);
|
|
606
|
+
_ctx.lineWidth = ~~value;
|
|
607
|
+
_outline_fix = 0 === ~~value % 2 ? 0 : 0.5;
|
|
608
608
|
},
|
|
609
609
|
linedash(segments, offset = 0) {
|
|
610
610
|
DEV: assert(
|
|
611
611
|
Array.isArray(segments) && segments.length > 0,
|
|
612
612
|
loggerPrefix + "linedash() 1st param must be an array of numbers",
|
|
613
|
-
)
|
|
613
|
+
);
|
|
614
614
|
DEV: assert(
|
|
615
615
|
isNumber(offset),
|
|
616
616
|
loggerPrefix + "linedash() 2nd param must be a number",
|
|
617
|
-
)
|
|
618
|
-
_ctx.setLineDash(segments)
|
|
619
|
-
_ctx.lineDashOffset = offset
|
|
617
|
+
);
|
|
618
|
+
_ctx.setLineDash(segments);
|
|
619
|
+
_ctx.lineDashOffset = offset;
|
|
620
620
|
},
|
|
621
621
|
text(x, y, message, color = _defaultTextColor, fontStyle = "normal") {
|
|
622
622
|
DEV: assert(
|
|
623
623
|
isNumber(x),
|
|
624
624
|
loggerPrefix + "text() 1st param must be a number",
|
|
625
|
-
)
|
|
625
|
+
);
|
|
626
626
|
DEV: assert(
|
|
627
627
|
isNumber(y),
|
|
628
628
|
loggerPrefix + "text() 2nd param must be a number",
|
|
629
|
-
)
|
|
629
|
+
);
|
|
630
630
|
DEV: assert(
|
|
631
631
|
null == color || (isNumber(color) && color >= 0),
|
|
632
632
|
loggerPrefix + "text() 4th param must be a positive number or zero",
|
|
633
|
-
)
|
|
633
|
+
);
|
|
634
634
|
DEV: assert(
|
|
635
635
|
"string" === typeof fontStyle,
|
|
636
636
|
loggerPrefix + "text() 5th param must be a string",
|
|
637
|
-
)
|
|
638
|
-
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}
|
|
639
|
-
_ctx.fillStyle = getColor(color)
|
|
640
|
-
const messages = ("" + message).split("\n")
|
|
637
|
+
);
|
|
638
|
+
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
639
|
+
_ctx.fillStyle = getColor(color);
|
|
640
|
+
const messages = ("" + message).split("\n");
|
|
641
641
|
for (let i = 0; i < messages.length; i++) {
|
|
642
|
-
_ctx.fillText(
|
|
642
|
+
_ctx.fillText(
|
|
643
|
+
messages[i],
|
|
644
|
+
~~x,
|
|
645
|
+
~~y + _fontSize * _fontLineHeight * i,
|
|
646
|
+
);
|
|
643
647
|
}
|
|
644
648
|
},
|
|
645
649
|
textgap(value) {
|
|
646
|
-
_fontLineHeight = value
|
|
650
|
+
_fontLineHeight = value;
|
|
647
651
|
},
|
|
648
652
|
textfont(family) {
|
|
649
653
|
DEV: assert(
|
|
650
654
|
"string" === typeof family,
|
|
651
655
|
loggerPrefix + "textfont() 1st param must be a string",
|
|
652
|
-
)
|
|
653
|
-
_fontFamily = family
|
|
656
|
+
);
|
|
657
|
+
_fontFamily = family;
|
|
654
658
|
},
|
|
655
659
|
textsize(size) {
|
|
656
660
|
DEV: assert(
|
|
657
661
|
isNumber(size),
|
|
658
662
|
loggerPrefix + "textsize() 1st param must be a number",
|
|
659
|
-
)
|
|
660
|
-
_fontSize = size
|
|
663
|
+
);
|
|
664
|
+
_fontSize = size;
|
|
661
665
|
},
|
|
662
666
|
textalign(align, baseline) {
|
|
663
667
|
DEV: assert(
|
|
@@ -665,7 +669,7 @@
|
|
|
665
669
|
["left", "right", "center", "start", "end"].includes(align),
|
|
666
670
|
loggerPrefix +
|
|
667
671
|
"textalign() 1st param must be null or one of the following strings: center, left, right, start or end.",
|
|
668
|
-
)
|
|
672
|
+
);
|
|
669
673
|
DEV: assert(
|
|
670
674
|
null == baseline ||
|
|
671
675
|
[
|
|
@@ -678,41 +682,47 @@
|
|
|
678
682
|
].includes(baseline),
|
|
679
683
|
loggerPrefix +
|
|
680
684
|
"textalign() 2nd param must be null or one of the following strings: middle, top, bottom, hanging, alphabetic or ideographic.",
|
|
681
|
-
)
|
|
682
|
-
if (align) _ctx.textAlign = align
|
|
683
|
-
if (baseline) _ctx.textBaseline = baseline
|
|
685
|
+
);
|
|
686
|
+
if (align) _ctx.textAlign = align;
|
|
687
|
+
if (baseline) _ctx.textBaseline = baseline;
|
|
684
688
|
},
|
|
685
689
|
image(x, y, source2) {
|
|
686
690
|
DEV: assert(
|
|
687
691
|
isNumber(x),
|
|
688
692
|
loggerPrefix + "image() 1st param must be a number",
|
|
689
|
-
)
|
|
693
|
+
);
|
|
690
694
|
DEV: assert(
|
|
691
695
|
isNumber(y),
|
|
692
696
|
loggerPrefix + "image() 2nd param must be a number",
|
|
693
|
-
)
|
|
694
|
-
_ctx.drawImage(source2, ~~x, ~~y)
|
|
697
|
+
);
|
|
698
|
+
_ctx.drawImage(source2, ~~x, ~~y);
|
|
695
699
|
},
|
|
696
700
|
spr(x, y, pixels) {
|
|
697
701
|
DEV: assert(
|
|
698
702
|
isNumber(x),
|
|
699
703
|
loggerPrefix + "spr() 1st param must be a number",
|
|
700
|
-
)
|
|
704
|
+
);
|
|
701
705
|
DEV: assert(
|
|
702
706
|
isNumber(y),
|
|
703
707
|
loggerPrefix + "spr() 2nd param must be a number",
|
|
704
|
-
)
|
|
708
|
+
);
|
|
705
709
|
DEV: assert(
|
|
706
710
|
"string" === typeof pixels,
|
|
707
711
|
loggerPrefix + "spr() 3rd param must be a string",
|
|
708
|
-
)
|
|
709
|
-
const rows = pixels.trim().split("\n")
|
|
712
|
+
);
|
|
713
|
+
const rows = pixels.trim().split("\n");
|
|
710
714
|
for (let row = 0; row < rows.length; row++) {
|
|
711
|
-
const chars = rows[row].trim()
|
|
715
|
+
const chars = rows[row].trim();
|
|
712
716
|
for (let col = 0; col < chars.length; col++) {
|
|
713
|
-
const char = chars[col]
|
|
717
|
+
const char = chars[col];
|
|
714
718
|
if (char !== "." && char !== " ") {
|
|
715
|
-
instance.rectfill(
|
|
719
|
+
instance.rectfill(
|
|
720
|
+
x + col,
|
|
721
|
+
y + row,
|
|
722
|
+
1,
|
|
723
|
+
1,
|
|
724
|
+
parseInt(char, 36) || 0,
|
|
725
|
+
);
|
|
716
726
|
}
|
|
717
727
|
}
|
|
718
728
|
}
|
|
@@ -721,224 +731,224 @@
|
|
|
721
731
|
DEV: assert(
|
|
722
732
|
isNumber(width) && width >= 1,
|
|
723
733
|
loggerPrefix + "paint() 1st param must be a positive number",
|
|
724
|
-
)
|
|
734
|
+
);
|
|
725
735
|
DEV: assert(
|
|
726
736
|
isNumber(height) && height >= 1,
|
|
727
737
|
loggerPrefix + "paint() 2nd param must be a positive number",
|
|
728
|
-
)
|
|
738
|
+
);
|
|
729
739
|
DEV: assert(
|
|
730
740
|
"function" === typeof callback,
|
|
731
741
|
loggerPrefix + "paint() 3rd param must be a function",
|
|
732
|
-
)
|
|
742
|
+
);
|
|
733
743
|
DEV: assert(
|
|
734
744
|
(options && null == options.scale) || isNumber(options.scale),
|
|
735
745
|
loggerPrefix + "paint() 4th param (options.scale) must be a number",
|
|
736
|
-
)
|
|
746
|
+
);
|
|
737
747
|
DEV: assert(
|
|
738
748
|
(options && null == options.canvas) ||
|
|
739
749
|
options.canvas instanceof OffscreenCanvas,
|
|
740
750
|
loggerPrefix +
|
|
741
751
|
"paint() 4th param (options.canvas) must be an OffscreenCanvas",
|
|
742
|
-
)
|
|
752
|
+
);
|
|
743
753
|
const canvas = options.canvas || new OffscreenCanvas(1, 1),
|
|
744
754
|
scale = options.scale || 1,
|
|
745
|
-
currentContext = _ctx
|
|
746
|
-
canvas.width = width * scale
|
|
747
|
-
canvas.height = height * scale
|
|
748
|
-
_ctx = canvas.getContext("2d")
|
|
749
|
-
_ctx.scale(scale, scale)
|
|
750
|
-
callback(_ctx)
|
|
751
|
-
_ctx = currentContext
|
|
752
|
-
return canvas.transferToImageBitmap()
|
|
755
|
+
currentContext = _ctx;
|
|
756
|
+
canvas.width = width * scale;
|
|
757
|
+
canvas.height = height * scale;
|
|
758
|
+
_ctx = canvas.getContext("2d");
|
|
759
|
+
_ctx.scale(scale, scale);
|
|
760
|
+
callback(_ctx);
|
|
761
|
+
_ctx = currentContext;
|
|
762
|
+
return canvas.transferToImageBitmap();
|
|
753
763
|
},
|
|
754
764
|
ctx(context) {
|
|
755
765
|
if (context) {
|
|
756
|
-
_ctx = context
|
|
766
|
+
_ctx = context;
|
|
757
767
|
}
|
|
758
|
-
return _ctx
|
|
768
|
+
return _ctx;
|
|
759
769
|
},
|
|
760
770
|
push() {
|
|
761
|
-
_ctx.save()
|
|
771
|
+
_ctx.save();
|
|
762
772
|
},
|
|
763
773
|
pop() {
|
|
764
|
-
_ctx.restore()
|
|
774
|
+
_ctx.restore();
|
|
765
775
|
},
|
|
766
776
|
translate(x, y) {
|
|
767
777
|
DEV: assert(
|
|
768
778
|
isNumber(x),
|
|
769
779
|
loggerPrefix + "translate() 1st param must be a number",
|
|
770
|
-
)
|
|
780
|
+
);
|
|
771
781
|
DEV: assert(
|
|
772
782
|
isNumber(y),
|
|
773
783
|
loggerPrefix + "translate() 2nd param must be a number",
|
|
774
|
-
)
|
|
775
|
-
_ctx.translate(~~x, ~~y)
|
|
784
|
+
);
|
|
785
|
+
_ctx.translate(~~x, ~~y);
|
|
776
786
|
},
|
|
777
787
|
scale(x, y) {
|
|
778
788
|
DEV: assert(
|
|
779
789
|
isNumber(x),
|
|
780
790
|
loggerPrefix + "scale() 1st param must be a number",
|
|
781
|
-
)
|
|
791
|
+
);
|
|
782
792
|
DEV: assert(
|
|
783
793
|
null == y || isNumber(y),
|
|
784
794
|
loggerPrefix + "scale() 2nd param must be a number",
|
|
785
|
-
)
|
|
786
|
-
_ctx.scale(x, y || x)
|
|
795
|
+
);
|
|
796
|
+
_ctx.scale(x, y || x);
|
|
787
797
|
},
|
|
788
798
|
rotate(radians) {
|
|
789
799
|
DEV: assert(
|
|
790
800
|
isNumber(radians),
|
|
791
801
|
loggerPrefix + "rotate() 1st param must be a number",
|
|
792
|
-
)
|
|
793
|
-
_ctx.rotate(radians)
|
|
802
|
+
);
|
|
803
|
+
_ctx.rotate(radians);
|
|
794
804
|
},
|
|
795
805
|
alpha(value) {
|
|
796
806
|
DEV: assert(
|
|
797
807
|
isNumber(value),
|
|
798
808
|
loggerPrefix + "alpha() 1st param must be a number",
|
|
799
|
-
)
|
|
800
|
-
_ctx.globalAlpha = instance.clamp(value, 0, 1)
|
|
809
|
+
);
|
|
810
|
+
_ctx.globalAlpha = instance.clamp(value, 0, 1);
|
|
801
811
|
},
|
|
802
812
|
fill(color) {
|
|
803
813
|
DEV: assert(
|
|
804
814
|
null == color || (isNumber(color) && color >= 0),
|
|
805
815
|
loggerPrefix + "fill() 1st param must be a positive number or zero",
|
|
806
|
-
)
|
|
807
|
-
_ctx.fillStyle = getColor(color)
|
|
808
|
-
_ctx.fill()
|
|
816
|
+
);
|
|
817
|
+
_ctx.fillStyle = getColor(color);
|
|
818
|
+
_ctx.fill();
|
|
809
819
|
},
|
|
810
820
|
stroke(color) {
|
|
811
821
|
DEV: assert(
|
|
812
822
|
null == color || (isNumber(color) && color >= 0),
|
|
813
823
|
loggerPrefix + "stroke() 1st param must be a positive number or zero",
|
|
814
|
-
)
|
|
815
|
-
_ctx.strokeStyle = getColor(color)
|
|
816
|
-
_ctx.stroke()
|
|
824
|
+
);
|
|
825
|
+
_ctx.strokeStyle = getColor(color);
|
|
826
|
+
_ctx.stroke();
|
|
817
827
|
},
|
|
818
828
|
clip(callback) {
|
|
819
829
|
DEV: assert(
|
|
820
830
|
"function" === typeof callback,
|
|
821
831
|
loggerPrefix + "clip() 1st param must be a function",
|
|
822
|
-
)
|
|
823
|
-
beginPath(_ctx)
|
|
824
|
-
callback(_ctx)
|
|
825
|
-
_ctx.clip()
|
|
832
|
+
);
|
|
833
|
+
beginPath(_ctx);
|
|
834
|
+
callback(_ctx);
|
|
835
|
+
_ctx.clip();
|
|
826
836
|
},
|
|
827
837
|
sfx(zzfxParams, pitchSlide = 0, volumeFactor = 1) {
|
|
828
838
|
DEV: assert(
|
|
829
839
|
null == zzfxParams || Array.isArray(zzfxParams),
|
|
830
840
|
loggerPrefix + "sfx() 1st param must be an array",
|
|
831
|
-
)
|
|
841
|
+
);
|
|
832
842
|
DEV: assert(
|
|
833
843
|
isNumber(pitchSlide),
|
|
834
844
|
loggerPrefix + "sfx() 2nd param must be a number",
|
|
835
|
-
)
|
|
845
|
+
);
|
|
836
846
|
DEV: assert(
|
|
837
847
|
isNumber(volumeFactor),
|
|
838
848
|
loggerPrefix + "sfx() 3rd param must be a number",
|
|
839
|
-
)
|
|
849
|
+
);
|
|
840
850
|
if (
|
|
841
851
|
!root.zzfxV ||
|
|
842
852
|
(navigator.userActivation && !navigator.userActivation.hasBeenActive)
|
|
843
853
|
) {
|
|
844
|
-
return false
|
|
854
|
+
return false;
|
|
845
855
|
}
|
|
846
|
-
zzfxParams = zzfxParams || _defaultSound
|
|
856
|
+
zzfxParams = zzfxParams || _defaultSound;
|
|
847
857
|
if (pitchSlide !== 0 || volumeFactor !== 1) {
|
|
848
|
-
zzfxParams = zzfxParams.slice()
|
|
849
|
-
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1)
|
|
850
|
-
zzfxParams[10] = ~~zzfxParams[10] + pitchSlide
|
|
858
|
+
zzfxParams = zzfxParams.slice();
|
|
859
|
+
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1);
|
|
860
|
+
zzfxParams[10] = ~~zzfxParams[10] + pitchSlide;
|
|
851
861
|
}
|
|
852
|
-
zzfx.apply(0, zzfxParams)
|
|
853
|
-
return zzfxParams
|
|
862
|
+
zzfx.apply(0, zzfxParams);
|
|
863
|
+
return zzfxParams;
|
|
854
864
|
},
|
|
855
865
|
volume(value) {
|
|
856
866
|
DEV: assert(
|
|
857
867
|
isNumber(value) && value >= 0,
|
|
858
868
|
loggerPrefix + "volume() 1st param must be a positive number or zero",
|
|
859
|
-
)
|
|
860
|
-
root.zzfxV = value
|
|
869
|
+
);
|
|
870
|
+
root.zzfxV = value;
|
|
861
871
|
},
|
|
862
872
|
canvas: () => _canvas,
|
|
863
873
|
use(callback, config = {}) {
|
|
864
874
|
DEV: assert(
|
|
865
875
|
"function" === typeof callback,
|
|
866
876
|
loggerPrefix + "use() 1st param must be a function",
|
|
867
|
-
)
|
|
877
|
+
);
|
|
868
878
|
DEV: assert(
|
|
869
879
|
"object" === typeof config,
|
|
870
880
|
loggerPrefix + "use() 2nd param must be an object",
|
|
871
|
-
)
|
|
872
|
-
loadPlugin(callback, config)
|
|
881
|
+
);
|
|
882
|
+
loadPlugin(callback, config);
|
|
873
883
|
},
|
|
874
884
|
listen(eventName, callback) {
|
|
875
885
|
DEV: assert(
|
|
876
886
|
"string" === typeof eventName,
|
|
877
887
|
loggerPrefix + "listen() 1st param must be a string",
|
|
878
|
-
)
|
|
888
|
+
);
|
|
879
889
|
DEV: assert(
|
|
880
890
|
"function" === typeof callback,
|
|
881
891
|
loggerPrefix + "listen() 2nd param must be a function",
|
|
882
|
-
)
|
|
883
|
-
eventName = lowerCase(eventName)
|
|
884
|
-
_eventListeners[eventName] = _eventListeners[eventName] || new Set()
|
|
885
|
-
_eventListeners[eventName].add(callback)
|
|
886
|
-
return () => _eventListeners[eventName]?.delete(callback)
|
|
892
|
+
);
|
|
893
|
+
eventName = lowerCase(eventName);
|
|
894
|
+
_eventListeners[eventName] = _eventListeners[eventName] || new Set();
|
|
895
|
+
_eventListeners[eventName].add(callback);
|
|
896
|
+
return () => _eventListeners[eventName]?.delete(callback);
|
|
887
897
|
},
|
|
888
898
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
889
899
|
DEV: assert(
|
|
890
900
|
"string" === typeof eventName,
|
|
891
901
|
loggerPrefix + "emit() 1st param must be a string",
|
|
892
|
-
)
|
|
902
|
+
);
|
|
893
903
|
if (_initialized) {
|
|
894
|
-
eventName = lowerCase(eventName)
|
|
895
|
-
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4)
|
|
896
|
-
triggerEvent(eventName, arg1, arg2, arg3, arg4)
|
|
897
|
-
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4)
|
|
904
|
+
eventName = lowerCase(eventName);
|
|
905
|
+
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
906
|
+
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
907
|
+
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
898
908
|
}
|
|
899
909
|
},
|
|
900
910
|
pal(colors, textColor = 3) {
|
|
901
911
|
DEV: assert(
|
|
902
912
|
null == colors || (Array.isArray(colors) && colors.length > 0),
|
|
903
913
|
loggerPrefix + "pal() 1st param must be a array of color strings",
|
|
904
|
-
)
|
|
914
|
+
);
|
|
905
915
|
DEV: assert(
|
|
906
916
|
isNumber(textColor) && textColor >= 0,
|
|
907
917
|
loggerPrefix + "pal() 2nd param must be a positive number or zero",
|
|
908
|
-
)
|
|
909
|
-
_colorPalette = colors || defaultPalette
|
|
910
|
-
_colorPaletteState = []
|
|
911
|
-
_defaultTextColor = textColor
|
|
918
|
+
);
|
|
919
|
+
_colorPalette = colors || defaultPalette;
|
|
920
|
+
_colorPaletteState = [];
|
|
921
|
+
_defaultTextColor = textColor;
|
|
912
922
|
},
|
|
913
923
|
palc(a, b) {
|
|
914
924
|
DEV: assert(
|
|
915
925
|
null == a || (isNumber(a) && a >= 0),
|
|
916
926
|
loggerPrefix + "palc() 1st param must be a positive number",
|
|
917
|
-
)
|
|
927
|
+
);
|
|
918
928
|
DEV: assert(
|
|
919
929
|
isNumber(a) ? isNumber(b) && b >= 0 : null == b,
|
|
920
930
|
loggerPrefix + "palc() 2nd param must be a positive number",
|
|
921
|
-
)
|
|
931
|
+
);
|
|
922
932
|
if (a == null) {
|
|
923
|
-
_colorPaletteState = []
|
|
933
|
+
_colorPaletteState = [];
|
|
924
934
|
} else {
|
|
925
|
-
_colorPaletteState[a] = b
|
|
935
|
+
_colorPaletteState[a] = b;
|
|
926
936
|
}
|
|
927
937
|
},
|
|
928
938
|
def(key, value) {
|
|
929
939
|
DEV: assert(
|
|
930
940
|
"string" === typeof key,
|
|
931
941
|
loggerPrefix + "def() 1st param must be a string",
|
|
932
|
-
)
|
|
942
|
+
);
|
|
933
943
|
DEV: if (null == value) {
|
|
934
944
|
console.warn(
|
|
935
945
|
loggerPrefix +
|
|
936
946
|
`def() changed the key "${key}" to null (previous value was ${instance[key]})`,
|
|
937
|
-
)
|
|
947
|
+
);
|
|
938
948
|
}
|
|
939
|
-
instance[key] = value
|
|
949
|
+
instance[key] = value;
|
|
940
950
|
if (settings.global) {
|
|
941
|
-
root[key] = value
|
|
951
|
+
root[key] = value;
|
|
942
952
|
}
|
|
943
953
|
},
|
|
944
954
|
timescale(value) {
|
|
@@ -946,21 +956,21 @@
|
|
|
946
956
|
isNumber(value) && value >= 0,
|
|
947
957
|
loggerPrefix +
|
|
948
958
|
"timescale() 1st param must be a positive number or zero",
|
|
949
|
-
)
|
|
950
|
-
_timeScale = value
|
|
959
|
+
);
|
|
960
|
+
_timeScale = value;
|
|
951
961
|
},
|
|
952
962
|
framerate(value) {
|
|
953
963
|
DEV: assert(
|
|
954
964
|
isNumber(value) && value >= 1,
|
|
955
965
|
loggerPrefix + "framerate() 1st param must be a positive number",
|
|
956
|
-
)
|
|
957
|
-
_fpsInterval = 1e3 / ~~value
|
|
966
|
+
);
|
|
967
|
+
_fpsInterval = 1e3 / ~~value;
|
|
958
968
|
},
|
|
959
969
|
stat(index) {
|
|
960
970
|
DEV: assert(
|
|
961
971
|
isNumber(index) || "string" === typeof index,
|
|
962
972
|
loggerPrefix + "stat() 1st param must be a number or string",
|
|
963
|
-
)
|
|
973
|
+
);
|
|
964
974
|
const internals = [
|
|
965
975
|
settings,
|
|
966
976
|
_initialized,
|
|
@@ -976,56 +986,56 @@
|
|
|
976
986
|
_fontFamily,
|
|
977
987
|
_colorPaletteState,
|
|
978
988
|
_fontLineHeight,
|
|
979
|
-
]
|
|
980
|
-
const data = { index, value: internals[index] }
|
|
981
|
-
instance.emit("stat", data)
|
|
982
|
-
return data.value
|
|
989
|
+
];
|
|
990
|
+
const data = { index, value: internals[index] };
|
|
991
|
+
instance.emit("stat", data);
|
|
992
|
+
return data.value;
|
|
983
993
|
},
|
|
984
994
|
pause() {
|
|
985
|
-
_paused = true
|
|
986
|
-
cancelAnimationFrame(_rafid)
|
|
995
|
+
_paused = true;
|
|
996
|
+
cancelAnimationFrame(_rafid);
|
|
987
997
|
},
|
|
988
998
|
resume() {
|
|
989
999
|
DEV: assert(
|
|
990
1000
|
_initialized,
|
|
991
1001
|
loggerPrefix +
|
|
992
1002
|
'resume() cannot be called before the "init" event and neither after the quit() function',
|
|
993
|
-
)
|
|
1003
|
+
);
|
|
994
1004
|
if (_initialized && _paused) {
|
|
995
|
-
_paused = false
|
|
996
|
-
_accumulated = _fpsInterval
|
|
997
|
-
_lastFrameTime = perf.now()
|
|
998
|
-
_rafid = raf(drawFrame)
|
|
1005
|
+
_paused = false;
|
|
1006
|
+
_accumulated = _fpsInterval;
|
|
1007
|
+
_lastFrameTime = perf.now();
|
|
1008
|
+
_rafid = raf(drawFrame);
|
|
999
1009
|
}
|
|
1000
1010
|
},
|
|
1001
1011
|
paused() {
|
|
1002
|
-
return _paused
|
|
1012
|
+
return _paused;
|
|
1003
1013
|
},
|
|
1004
1014
|
quit() {
|
|
1005
|
-
instance.emit("quit")
|
|
1006
|
-
instance.pause()
|
|
1007
|
-
_initialized = false
|
|
1008
|
-
_eventListeners = {}
|
|
1015
|
+
instance.emit("quit");
|
|
1016
|
+
instance.pause();
|
|
1017
|
+
_initialized = false;
|
|
1018
|
+
_eventListeners = {};
|
|
1009
1019
|
for (const removeListener of _browserEventListeners) {
|
|
1010
|
-
removeListener()
|
|
1020
|
+
removeListener();
|
|
1011
1021
|
}
|
|
1012
1022
|
if (settings.global) {
|
|
1013
1023
|
for (const key in instance) {
|
|
1014
|
-
delete root[key]
|
|
1024
|
+
delete root[key];
|
|
1015
1025
|
}
|
|
1016
|
-
delete root.ENGINE
|
|
1026
|
+
delete root.ENGINE;
|
|
1017
1027
|
}
|
|
1018
1028
|
DEV: console.warn(
|
|
1019
1029
|
loggerPrefix + "quit() terminated a Litecanvas instance.",
|
|
1020
|
-
)
|
|
1030
|
+
);
|
|
1021
1031
|
},
|
|
1022
|
-
}
|
|
1032
|
+
};
|
|
1023
1033
|
for (const k of _mathFunctions.split(",")) {
|
|
1024
|
-
instance[k] = math[k]
|
|
1034
|
+
instance[k] = math[k];
|
|
1025
1035
|
}
|
|
1026
1036
|
function init() {
|
|
1027
1037
|
if (settings.autoscale) {
|
|
1028
|
-
on(root, "resize", resizeCanvas)
|
|
1038
|
+
on(root, "resize", resizeCanvas);
|
|
1029
1039
|
}
|
|
1030
1040
|
if (settings.tapEvents) {
|
|
1031
1041
|
const _getXY = (ev) => [
|
|
@@ -1034,190 +1044,190 @@
|
|
|
1034
1044
|
],
|
|
1035
1045
|
_taps = new Map(),
|
|
1036
1046
|
_registerTap = (id, x, y) => {
|
|
1037
|
-
const tap = { x, y, xi: x, yi: y, t: perf.now() }
|
|
1038
|
-
_taps.set(id, tap)
|
|
1039
|
-
return tap
|
|
1047
|
+
const tap = { x, y, xi: x, yi: y, t: perf.now() };
|
|
1048
|
+
_taps.set(id, tap);
|
|
1049
|
+
return tap;
|
|
1040
1050
|
},
|
|
1041
1051
|
_updateTap = (id, x, y) => {
|
|
1042
|
-
const tap = _taps.get(id) || _registerTap(id)
|
|
1043
|
-
tap.x = x
|
|
1044
|
-
tap.y = y
|
|
1052
|
+
const tap = _taps.get(id) || _registerTap(id);
|
|
1053
|
+
tap.x = x;
|
|
1054
|
+
tap.y = y;
|
|
1045
1055
|
},
|
|
1046
|
-
_checkTapped = (tap) => tap && perf.now() - tap.t <= 300
|
|
1047
|
-
let _pressingMouse = false
|
|
1056
|
+
_checkTapped = (tap) => tap && perf.now() - tap.t <= 300;
|
|
1057
|
+
let _pressingMouse = false;
|
|
1048
1058
|
on(_canvas, "mousedown", (ev) => {
|
|
1049
1059
|
if (ev.button === 0) {
|
|
1050
|
-
preventDefault(ev)
|
|
1051
|
-
const [x, y] = _getXY(ev)
|
|
1052
|
-
instance.emit("tap", x, y, 0)
|
|
1053
|
-
_registerTap(0, x, y)
|
|
1054
|
-
_pressingMouse = true
|
|
1060
|
+
preventDefault(ev);
|
|
1061
|
+
const [x, y] = _getXY(ev);
|
|
1062
|
+
instance.emit("tap", x, y, 0);
|
|
1063
|
+
_registerTap(0, x, y);
|
|
1064
|
+
_pressingMouse = true;
|
|
1055
1065
|
}
|
|
1056
|
-
})
|
|
1066
|
+
});
|
|
1057
1067
|
on(_canvas, "mouseup", (ev) => {
|
|
1058
1068
|
if (ev.button === 0) {
|
|
1059
|
-
preventDefault(ev)
|
|
1060
|
-
const tap = _taps.get(0)
|
|
1061
|
-
const [x, y] = _getXY(ev)
|
|
1069
|
+
preventDefault(ev);
|
|
1070
|
+
const tap = _taps.get(0);
|
|
1071
|
+
const [x, y] = _getXY(ev);
|
|
1062
1072
|
if (_checkTapped(tap)) {
|
|
1063
|
-
instance.emit("tapped", tap.xi, tap.yi, 0)
|
|
1073
|
+
instance.emit("tapped", tap.xi, tap.yi, 0);
|
|
1064
1074
|
}
|
|
1065
|
-
instance.emit("untap", x, y, 0)
|
|
1066
|
-
_taps.delete(0)
|
|
1067
|
-
_pressingMouse = false
|
|
1075
|
+
instance.emit("untap", x, y, 0);
|
|
1076
|
+
_taps.delete(0);
|
|
1077
|
+
_pressingMouse = false;
|
|
1068
1078
|
}
|
|
1069
|
-
})
|
|
1079
|
+
});
|
|
1070
1080
|
on(root, "mousemove", (ev) => {
|
|
1071
|
-
preventDefault(ev)
|
|
1072
|
-
const [x, y] = _getXY(ev)
|
|
1073
|
-
instance.def("MX", x)
|
|
1074
|
-
instance.def("MY", y)
|
|
1075
|
-
if (!_pressingMouse) return
|
|
1076
|
-
instance.emit("tapping", x, y, 0)
|
|
1077
|
-
_updateTap(0, x, y)
|
|
1078
|
-
})
|
|
1081
|
+
preventDefault(ev);
|
|
1082
|
+
const [x, y] = _getXY(ev);
|
|
1083
|
+
instance.def("MX", x);
|
|
1084
|
+
instance.def("MY", y);
|
|
1085
|
+
if (!_pressingMouse) return;
|
|
1086
|
+
instance.emit("tapping", x, y, 0);
|
|
1087
|
+
_updateTap(0, x, y);
|
|
1088
|
+
});
|
|
1079
1089
|
on(_canvas, "touchstart", (ev) => {
|
|
1080
|
-
preventDefault(ev)
|
|
1081
|
-
const touches = ev.changedTouches
|
|
1090
|
+
preventDefault(ev);
|
|
1091
|
+
const touches = ev.changedTouches;
|
|
1082
1092
|
for (const touch of touches) {
|
|
1083
|
-
const [x, y] = _getXY(touch)
|
|
1084
|
-
instance.emit("tap", x, y, touch.identifier + 1)
|
|
1085
|
-
_registerTap(touch.identifier + 1, x, y)
|
|
1093
|
+
const [x, y] = _getXY(touch);
|
|
1094
|
+
instance.emit("tap", x, y, touch.identifier + 1);
|
|
1095
|
+
_registerTap(touch.identifier + 1, x, y);
|
|
1086
1096
|
}
|
|
1087
|
-
})
|
|
1097
|
+
});
|
|
1088
1098
|
on(_canvas, "touchmove", (ev) => {
|
|
1089
|
-
preventDefault(ev)
|
|
1090
|
-
const touches = ev.changedTouches
|
|
1099
|
+
preventDefault(ev);
|
|
1100
|
+
const touches = ev.changedTouches;
|
|
1091
1101
|
for (const touch of touches) {
|
|
1092
|
-
const [x, y] = _getXY(touch)
|
|
1093
|
-
instance.emit("tapping", x, y, touch.identifier + 1)
|
|
1094
|
-
_updateTap(touch.identifier + 1, x, y)
|
|
1102
|
+
const [x, y] = _getXY(touch);
|
|
1103
|
+
instance.emit("tapping", x, y, touch.identifier + 1);
|
|
1104
|
+
_updateTap(touch.identifier + 1, x, y);
|
|
1095
1105
|
}
|
|
1096
|
-
})
|
|
1106
|
+
});
|
|
1097
1107
|
const _touchEndHandler = (ev) => {
|
|
1098
|
-
preventDefault(ev)
|
|
1099
|
-
const existing = []
|
|
1108
|
+
preventDefault(ev);
|
|
1109
|
+
const existing = [];
|
|
1100
1110
|
if (ev.targetTouches.length > 0) {
|
|
1101
1111
|
for (const touch of ev.targetTouches) {
|
|
1102
|
-
existing.push(touch.identifier + 1)
|
|
1112
|
+
existing.push(touch.identifier + 1);
|
|
1103
1113
|
}
|
|
1104
1114
|
}
|
|
1105
1115
|
for (const [id, tap] of _taps) {
|
|
1106
|
-
if (existing.includes(id)) continue
|
|
1116
|
+
if (existing.includes(id)) continue;
|
|
1107
1117
|
if (_checkTapped(tap)) {
|
|
1108
|
-
instance.emit("tapped", tap.xi, tap.yi, id)
|
|
1118
|
+
instance.emit("tapped", tap.xi, tap.yi, id);
|
|
1109
1119
|
}
|
|
1110
|
-
instance.emit("untap", tap.x, tap.y, id)
|
|
1111
|
-
_taps.delete(id)
|
|
1120
|
+
instance.emit("untap", tap.x, tap.y, id);
|
|
1121
|
+
_taps.delete(id);
|
|
1112
1122
|
}
|
|
1113
|
-
}
|
|
1114
|
-
on(_canvas, "touchend", _touchEndHandler)
|
|
1115
|
-
on(_canvas, "touchcancel", _touchEndHandler)
|
|
1123
|
+
};
|
|
1124
|
+
on(_canvas, "touchend", _touchEndHandler);
|
|
1125
|
+
on(_canvas, "touchcancel", _touchEndHandler);
|
|
1116
1126
|
on(root, "blur", () => {
|
|
1117
|
-
_pressingMouse = false
|
|
1127
|
+
_pressingMouse = false;
|
|
1118
1128
|
for (const [id, tap] of _taps) {
|
|
1119
|
-
instance.emit("untap", tap.x, tap.y, id)
|
|
1120
|
-
_taps.delete(id)
|
|
1129
|
+
instance.emit("untap", tap.x, tap.y, id);
|
|
1130
|
+
_taps.delete(id);
|
|
1121
1131
|
}
|
|
1122
|
-
})
|
|
1132
|
+
});
|
|
1123
1133
|
}
|
|
1124
1134
|
if (settings.keyboardEvents) {
|
|
1125
|
-
const _keysDown = new Set()
|
|
1126
|
-
const _keysPress = new Set()
|
|
1135
|
+
const _keysDown = new Set();
|
|
1136
|
+
const _keysPress = new Set();
|
|
1127
1137
|
const keyCheck = (keySet, key = "") => {
|
|
1128
|
-
key = lowerCase(key)
|
|
1138
|
+
key = lowerCase(key);
|
|
1129
1139
|
return !key
|
|
1130
1140
|
? keySet.size > 0
|
|
1131
|
-
: keySet.has("space" === key ? " " : key)
|
|
1132
|
-
}
|
|
1133
|
-
let _lastKey = ""
|
|
1141
|
+
: keySet.has("space" === key ? " " : key);
|
|
1142
|
+
};
|
|
1143
|
+
let _lastKey = "";
|
|
1134
1144
|
on(root, "keydown", (event) => {
|
|
1135
|
-
const key = lowerCase(event.key)
|
|
1145
|
+
const key = lowerCase(event.key);
|
|
1136
1146
|
if (!_keysDown.has(key)) {
|
|
1137
|
-
_keysDown.add(key)
|
|
1138
|
-
_keysPress.add(key)
|
|
1139
|
-
_lastKey = key === " " ? "space" : key
|
|
1147
|
+
_keysDown.add(key);
|
|
1148
|
+
_keysPress.add(key);
|
|
1149
|
+
_lastKey = key === " " ? "space" : key;
|
|
1140
1150
|
}
|
|
1141
|
-
})
|
|
1151
|
+
});
|
|
1142
1152
|
on(root, "keyup", (event) => {
|
|
1143
|
-
_keysDown.delete(lowerCase(event.key))
|
|
1144
|
-
})
|
|
1145
|
-
on(root, "blur", () => _keysDown.clear())
|
|
1146
|
-
instance.listen("after:update", () => _keysPress.clear())
|
|
1153
|
+
_keysDown.delete(lowerCase(event.key));
|
|
1154
|
+
});
|
|
1155
|
+
on(root, "blur", () => _keysDown.clear());
|
|
1156
|
+
instance.listen("after:update", () => _keysPress.clear());
|
|
1147
1157
|
instance.def("iskeydown", (key) => {
|
|
1148
1158
|
DEV: assert(
|
|
1149
1159
|
null == key || "string" === typeof key,
|
|
1150
1160
|
loggerPrefix +
|
|
1151
1161
|
"iskeydown() 1st param must be a string or undefined",
|
|
1152
|
-
)
|
|
1153
|
-
return keyCheck(_keysDown, key)
|
|
1154
|
-
})
|
|
1162
|
+
);
|
|
1163
|
+
return keyCheck(_keysDown, key);
|
|
1164
|
+
});
|
|
1155
1165
|
instance.def("iskeypressed", (key) => {
|
|
1156
1166
|
DEV: assert(
|
|
1157
1167
|
null == key || "string" === typeof key,
|
|
1158
1168
|
loggerPrefix +
|
|
1159
1169
|
"iskeypressed() 1st param must be a string or undefined",
|
|
1160
|
-
)
|
|
1161
|
-
return keyCheck(_keysPress, key)
|
|
1162
|
-
})
|
|
1163
|
-
instance.def("lastkey", () => _lastKey)
|
|
1170
|
+
);
|
|
1171
|
+
return keyCheck(_keysPress, key);
|
|
1172
|
+
});
|
|
1173
|
+
instance.def("lastkey", () => _lastKey);
|
|
1164
1174
|
}
|
|
1165
|
-
_initialized = true
|
|
1166
|
-
instance.resume()
|
|
1167
|
-
instance.emit("init", instance)
|
|
1175
|
+
_initialized = true;
|
|
1176
|
+
instance.resume();
|
|
1177
|
+
instance.emit("init", instance);
|
|
1168
1178
|
}
|
|
1169
1179
|
function drawFrame() {
|
|
1170
|
-
_rafid = raf(drawFrame)
|
|
1171
|
-
let now = perf.now()
|
|
1172
|
-
let updated = 0
|
|
1173
|
-
let frameTime = now - _lastFrameTime
|
|
1174
|
-
_lastFrameTime = now
|
|
1175
|
-
_accumulated += frameTime < 100 ? frameTime : _fpsInterval
|
|
1180
|
+
_rafid = raf(drawFrame);
|
|
1181
|
+
let now = perf.now();
|
|
1182
|
+
let updated = 0;
|
|
1183
|
+
let frameTime = now - _lastFrameTime;
|
|
1184
|
+
_lastFrameTime = now;
|
|
1185
|
+
_accumulated += frameTime < 100 ? frameTime : _fpsInterval;
|
|
1176
1186
|
while (_accumulated >= _fpsInterval) {
|
|
1177
|
-
updated
|
|
1178
|
-
_accumulated -= _fpsInterval
|
|
1179
|
-
let dt = (_fpsInterval / 1e3) * _timeScale
|
|
1180
|
-
instance.emit("update", dt, updated)
|
|
1181
|
-
instance.def("T", instance.T + dt)
|
|
1187
|
+
updated++;
|
|
1188
|
+
_accumulated -= _fpsInterval;
|
|
1189
|
+
let dt = (_fpsInterval / 1e3) * _timeScale;
|
|
1190
|
+
instance.emit("update", dt, updated);
|
|
1191
|
+
instance.def("T", instance.T + dt);
|
|
1182
1192
|
}
|
|
1183
1193
|
if (updated) {
|
|
1184
|
-
instance.emit("draw", _ctx)
|
|
1194
|
+
instance.emit("draw", _ctx);
|
|
1185
1195
|
if (updated > 1) {
|
|
1186
|
-
_accumulated = 0
|
|
1196
|
+
_accumulated = 0;
|
|
1187
1197
|
DEV: console.warn(
|
|
1188
1198
|
loggerPrefix +
|
|
1189
1199
|
"the last frame updated " +
|
|
1190
1200
|
updated +
|
|
1191
1201
|
" times. This can drop the FPS if it keeps happening.",
|
|
1192
|
-
)
|
|
1202
|
+
);
|
|
1193
1203
|
}
|
|
1194
1204
|
}
|
|
1195
1205
|
}
|
|
1196
1206
|
function setupCanvas() {
|
|
1197
1207
|
if ("string" === typeof settings.canvas) {
|
|
1198
|
-
_canvas = document.querySelector(settings.canvas)
|
|
1208
|
+
_canvas = document.querySelector(settings.canvas);
|
|
1199
1209
|
DEV: assert(
|
|
1200
1210
|
null != _canvas,
|
|
1201
1211
|
loggerPrefix +
|
|
1202
1212
|
'litecanvas() option "canvas" is an invalid CSS selector',
|
|
1203
|
-
)
|
|
1213
|
+
);
|
|
1204
1214
|
} else {
|
|
1205
|
-
_canvas = settings.canvas
|
|
1215
|
+
_canvas = settings.canvas;
|
|
1206
1216
|
}
|
|
1207
|
-
_canvas = _canvas || document.createElement("canvas")
|
|
1217
|
+
_canvas = _canvas || document.createElement("canvas");
|
|
1208
1218
|
DEV: assert(
|
|
1209
1219
|
"CANVAS" === _canvas.tagName,
|
|
1210
1220
|
loggerPrefix +
|
|
1211
1221
|
'litecanvas() option "canvas" should be a canvas element or string (CSS selector)',
|
|
1212
|
-
)
|
|
1213
|
-
_ctx = _canvas.getContext("2d")
|
|
1214
|
-
on(_canvas, "click", () => focus())
|
|
1215
|
-
resizeCanvas()
|
|
1222
|
+
);
|
|
1223
|
+
_ctx = _canvas.getContext("2d");
|
|
1224
|
+
on(_canvas, "click", () => focus());
|
|
1225
|
+
resizeCanvas();
|
|
1216
1226
|
if (!_canvas.parentNode) {
|
|
1217
|
-
document.body.appendChild(_canvas)
|
|
1227
|
+
document.body.appendChild(_canvas);
|
|
1218
1228
|
}
|
|
1219
|
-
_canvas.style.imageRendering = "pixelated"
|
|
1220
|
-
_canvas.oncontextmenu = () => false
|
|
1229
|
+
_canvas.style.imageRendering = "pixelated";
|
|
1230
|
+
_canvas.oncontextmenu = () => false;
|
|
1221
1231
|
}
|
|
1222
1232
|
function resizeCanvas() {
|
|
1223
1233
|
DEV: assert(
|
|
@@ -1225,85 +1235,85 @@
|
|
|
1225
1235
|
(isNumber(settings.width) && settings.width > 0),
|
|
1226
1236
|
loggerPrefix +
|
|
1227
1237
|
'litecanvas() option "width" should be a positive number when defined',
|
|
1228
|
-
)
|
|
1238
|
+
);
|
|
1229
1239
|
DEV: assert(
|
|
1230
1240
|
null == settings.height ||
|
|
1231
1241
|
(isNumber(settings.height) && settings.height > 0),
|
|
1232
1242
|
loggerPrefix +
|
|
1233
1243
|
'litecanvas() option "height" should be a positive number when defined',
|
|
1234
|
-
)
|
|
1244
|
+
);
|
|
1235
1245
|
DEV: assert(
|
|
1236
1246
|
null == settings.height || (settings.width > 0 && settings.height > 0),
|
|
1237
1247
|
loggerPrefix +
|
|
1238
1248
|
'litecanvas() option "width" is required when the option "height" is defined',
|
|
1239
|
-
)
|
|
1249
|
+
);
|
|
1240
1250
|
const width = settings.width > 0 ? settings.width : innerWidth,
|
|
1241
1251
|
height =
|
|
1242
|
-
settings.width > 0 ? settings.height || settings.width : innerHeight
|
|
1243
|
-
instance.def("W", width)
|
|
1244
|
-
instance.def("H", height)
|
|
1245
|
-
_canvas.width = width
|
|
1246
|
-
_canvas.height = height
|
|
1252
|
+
settings.width > 0 ? settings.height || settings.width : innerHeight;
|
|
1253
|
+
instance.def("W", width);
|
|
1254
|
+
instance.def("H", height);
|
|
1255
|
+
_canvas.width = width;
|
|
1256
|
+
_canvas.height = height;
|
|
1247
1257
|
if (settings.autoscale) {
|
|
1248
|
-
let maxScale = +settings.autoscale
|
|
1258
|
+
let maxScale = +settings.autoscale;
|
|
1249
1259
|
if (!_canvas.style.display) {
|
|
1250
|
-
_canvas.style.display = "block"
|
|
1251
|
-
_canvas.style.margin = "auto"
|
|
1260
|
+
_canvas.style.display = "block";
|
|
1261
|
+
_canvas.style.margin = "auto";
|
|
1252
1262
|
}
|
|
1253
|
-
_canvasScale = math.min(innerWidth / width, innerHeight / height)
|
|
1263
|
+
_canvasScale = math.min(innerWidth / width, innerHeight / height);
|
|
1254
1264
|
_canvasScale =
|
|
1255
|
-
maxScale > 1 && _canvasScale > maxScale ? maxScale : _canvasScale
|
|
1256
|
-
_canvas.style.width = width * _canvasScale + "px"
|
|
1257
|
-
_canvas.style.height = height * _canvasScale + "px"
|
|
1265
|
+
maxScale > 1 && _canvasScale > maxScale ? maxScale : _canvasScale;
|
|
1266
|
+
_canvas.style.width = width * _canvasScale + "px";
|
|
1267
|
+
_canvas.style.height = height * _canvasScale + "px";
|
|
1258
1268
|
}
|
|
1259
|
-
_ctx.imageSmoothingEnabled = false
|
|
1260
|
-
instance.textalign("start", "top")
|
|
1261
|
-
instance.emit("resized", _canvasScale)
|
|
1269
|
+
_ctx.imageSmoothingEnabled = false;
|
|
1270
|
+
instance.textalign("start", "top");
|
|
1271
|
+
instance.emit("resized", _canvasScale);
|
|
1262
1272
|
}
|
|
1263
1273
|
function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
|
|
1264
|
-
if (!_eventListeners[eventName]) return
|
|
1274
|
+
if (!_eventListeners[eventName]) return;
|
|
1265
1275
|
for (const callback of _eventListeners[eventName]) {
|
|
1266
|
-
callback(arg1, arg2, arg3, arg4)
|
|
1276
|
+
callback(arg1, arg2, arg3, arg4);
|
|
1267
1277
|
}
|
|
1268
1278
|
}
|
|
1269
1279
|
function loadPlugin(callback, config) {
|
|
1270
|
-
const pluginData = callback(instance, config)
|
|
1280
|
+
const pluginData = callback(instance, config);
|
|
1271
1281
|
DEV: assert(
|
|
1272
1282
|
null == pluginData || "object" === typeof pluginData,
|
|
1273
1283
|
loggerPrefix +
|
|
1274
1284
|
"litecanvas() plugins should return an object or nothing",
|
|
1275
|
-
)
|
|
1285
|
+
);
|
|
1276
1286
|
for (const key in pluginData) {
|
|
1277
|
-
instance.def(key, pluginData[key])
|
|
1287
|
+
instance.def(key, pluginData[key]);
|
|
1278
1288
|
}
|
|
1279
1289
|
}
|
|
1280
1290
|
function getColor(index) {
|
|
1281
|
-
const i = _colorPaletteState[index] ?? index
|
|
1282
|
-
return _colorPalette[~~i % _colorPalette.length]
|
|
1291
|
+
const i = _colorPaletteState[index] ?? index;
|
|
1292
|
+
return _colorPalette[~~i % _colorPalette.length];
|
|
1283
1293
|
}
|
|
1284
1294
|
if (settings.global) {
|
|
1285
1295
|
if (root.ENGINE) {
|
|
1286
|
-
throw new Error("only one global litecanvas is allowed")
|
|
1296
|
+
throw new Error("only one global litecanvas is allowed");
|
|
1287
1297
|
}
|
|
1288
|
-
Object.assign(root, instance)
|
|
1289
|
-
root.ENGINE = instance
|
|
1298
|
+
Object.assign(root, instance);
|
|
1299
|
+
root.ENGINE = instance;
|
|
1290
1300
|
}
|
|
1291
|
-
DEV: console.info(loggerPrefix + `version ${version} started`)
|
|
1292
|
-
DEV: console.debug(loggerPrefix + `litecanvas() options =`, settings)
|
|
1293
|
-
setupCanvas()
|
|
1294
|
-
const source = settings.loop ? settings.loop : root
|
|
1301
|
+
DEV: console.info(loggerPrefix + `version ${version} started`);
|
|
1302
|
+
DEV: console.debug(loggerPrefix + `litecanvas() options =`, settings);
|
|
1303
|
+
setupCanvas();
|
|
1304
|
+
const source = settings.loop ? settings.loop : root;
|
|
1295
1305
|
for (const event of _coreEvents.split(",")) {
|
|
1296
1306
|
DEV: if (root === source && source[event]) {
|
|
1297
|
-
console.info(loggerPrefix + `using window.${event}()`)
|
|
1307
|
+
console.info(loggerPrefix + `using window.${event}()`);
|
|
1298
1308
|
}
|
|
1299
|
-
if (source[event]) instance.listen(event, source[event])
|
|
1309
|
+
if (source[event]) instance.listen(event, source[event]);
|
|
1300
1310
|
}
|
|
1301
1311
|
if ("loading" === document.readyState) {
|
|
1302
|
-
on(root, "DOMContentLoaded", () => raf(init))
|
|
1312
|
+
on(root, "DOMContentLoaded", () => raf(init));
|
|
1303
1313
|
} else {
|
|
1304
|
-
_rafid = raf(init)
|
|
1314
|
+
_rafid = raf(init);
|
|
1305
1315
|
}
|
|
1306
|
-
return instance
|
|
1316
|
+
return instance;
|
|
1307
1317
|
}
|
|
1308
|
-
window.litecanvas = litecanvas
|
|
1309
|
-
})()
|
|
1318
|
+
window.litecanvas = litecanvas;
|
|
1319
|
+
})();
|