litecanvas 0.74.3 → 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 +329 -438
- package/dist/dist.js +38 -438
- package/dist/dist.min.js +1 -1
- package/package.json +10 -7
- package/src/dev.js +0 -1
- package/src/index.js +389 -435
- package/src/zzfx.js +2 -108
package/dist/dist.dev.js
CHANGED
|
@@ -1,27 +1,10 @@
|
|
|
1
1
|
(() => {
|
|
2
2
|
// src/zzfx.js
|
|
3
3
|
var zzfxX = /* @__PURE__ */ new AudioContext();
|
|
4
|
-
var zzfx = (
|
|
5
|
-
let
|
|
6
|
-
e =
|
|
7
|
-
|
|
8
|
-
r *= R;
|
|
9
|
-
t *= R;
|
|
10
|
-
c *= R;
|
|
11
|
-
y *= 500 * d / R ** 3;
|
|
12
|
-
A *= d / R;
|
|
13
|
-
v *= d / R;
|
|
14
|
-
z *= R;
|
|
15
|
-
l = R * l | 0;
|
|
16
|
-
p *= 0.3 * (globalThis.zzfxV || 1);
|
|
17
|
-
for (h = e + m + r + t + c | 0; a < h; k[a++] = f * p)
|
|
18
|
-
++J % (100 * F | 0) || (f = q ? 1 < q ? 2 < q ? 3 < q ? Z(g * g) : M.max(M.min(M.tan(g), 1), -1) : 1 - (2 * g / d % 2 + 2) % 2 : 1 - 4 * M.abs(M.round(g / d) - g / d) : Z(g), f = (l ? 1 - B + B * Z(d * a / l) : 1) * (f < 0 ? -1 : 1) * M.abs(f) ** D * (a < e ? a / e : a < e + m ? 1 - (a - e) / m * (1 - w) : a < e + m + r ? w : a < h - c ? (h - a - c) / t * w : 0), f = c ? f / 2 + (c > a ? 0 : (a < h - c ? 1 : (h - a) / c) * k[a - c | 0] / 2 / p) : f, N ? f = W = S * T + Q * (T = U) + P * (U = f) - Y * V - X * (V = W) : 0), x = (b += u += y) * M.cos(A * H++), g += x + x * E * Z(a ** 5), n && ++n > z && (b += v, C += v, n = 0), !l || ++I % l || (b = C, u = G, n = n || 1);
|
|
19
|
-
p = zzfxX.createBuffer(1, h, R);
|
|
20
|
-
p.getChannelData(0).set(k);
|
|
21
|
-
b = zzfxX.createBufferSource();
|
|
22
|
-
b.buffer = p;
|
|
23
|
-
b.connect(zzfxX.destination);
|
|
24
|
-
b.start();
|
|
4
|
+
var zzfx = (i = 1, d = 0.05, z = 220, e = 0, P = 0, S = 0.1, I = 0, c = 1, T = 0, H = 0, V = 0, J = 0, h = 0, j = 0, K = 0, E = 0, r = 0, B = 1, X = 0, L = 0, D = 0) => {
|
|
5
|
+
let n = Math, t = 2 * n.PI, a = 44100, F = T *= 500 * t / a / a, O = z *= (1 - d + 2 * d * n.random(d = [])) * t / a, x = 0, _ = 0, f = 0, g = 1, $ = 0, l = 0, o = 0, s = D < 0 ? -1 : 1, u = t * s * D * 2 / a, G = n.cos(u), C = n.sin, Q = C(u) / 4, M = 1 + Q, m = -2 * G / M, y = (1 - Q) / M, R = (1 + s * G) / 2 / M, A = -(s + G) / M, v = R, U = 0, W = 0, Y = 0, Z = 0;
|
|
6
|
+
for (e = a * e + 9, X *= a, P *= a, S *= a, r *= a, H *= 500 * t / a ** 3, K *= t / a, V *= t / a, J *= a, h = a * h | 0, i *= 0.3 * (globalThis.zzfxV || 1), s = e + X + P + S + r | 0; f < s; d[f++] = o * i) ++l % (100 * E | 0) || (o = I ? 1 < I ? 2 < I ? 3 < I ? C(x * x) : n.max(n.min(n.tan(x), 1), -1) : 1 - (2 * x / t % 2 + 2) % 2 : 1 - 4 * n.abs(n.round(x / t) - x / t) : C(x), o = (h ? 1 - L + L * C(t * f / h) : 1) * (o < 0 ? -1 : 1) * n.abs(o) ** c * (f < e ? f / e : f < e + X ? 1 - (f - e) / X * (1 - B) : f < e + X + P ? B : f < s - r ? (s - f - r) / S * B : 0), o = r ? o / 2 + (r > f ? 0 : (f < s - r ? 1 : (s - f) / r) * d[f - r | 0] / 2 / i) : o, D && (o = Z = v * U + A * (U = W) + R * (W = o) - y * Y - m * (Y = Z))), u = (z += T += H) * n.cos(K * _++), x += u + u * j * C(f ** 5), g && ++g > J && (z += V, O += V, g = 0), !h || ++$ % h || (z = O, T = F, g = g || 1);
|
|
7
|
+
i = zzfxX.createBuffer(1, s, a), i.getChannelData(0).set(d), z = zzfxX.createBufferSource(), z.buffer = i, z.connect(zzfxX.destination), z.start();
|
|
25
8
|
};
|
|
26
9
|
|
|
27
10
|
// src/palette.js
|
|
@@ -101,13 +84,6 @@
|
|
|
101
84
|
/** @type {number[]} */
|
|
102
85
|
DEFAULT_SFX: [0.5, , 1675, , 0.06, 0.2, 1, 1.8, , , 637, 0.06],
|
|
103
86
|
/** MATH API */
|
|
104
|
-
/**
|
|
105
|
-
* The value of the mathematical constant PI (π).
|
|
106
|
-
* Approximately 3.14159
|
|
107
|
-
*
|
|
108
|
-
* @type {number}
|
|
109
|
-
*/
|
|
110
|
-
PI,
|
|
111
87
|
/**
|
|
112
88
|
* Twice the value of the mathematical constant PI (π).
|
|
113
89
|
* Approximately 6.28318
|
|
@@ -124,7 +100,7 @@
|
|
|
124
100
|
*
|
|
125
101
|
* @type {number}
|
|
126
102
|
*/
|
|
127
|
-
HALF_PI: PI
|
|
103
|
+
HALF_PI: PI / 2,
|
|
128
104
|
/**
|
|
129
105
|
* Calculates a linear (interpolation) value over t%.
|
|
130
106
|
*
|
|
@@ -135,12 +111,10 @@
|
|
|
135
111
|
* @tutorial https://gamedev.net/tutorials/programming/general-and-gameplay-programming/a-brief-introduction-to-lerp-r4954/
|
|
136
112
|
*/
|
|
137
113
|
lerp: (start, end, t) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
143
|
-
return start + t * (end - start);
|
|
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");
|
|
117
|
+
return t * (end - start) + start;
|
|
144
118
|
},
|
|
145
119
|
/**
|
|
146
120
|
* Convert degrees to radians
|
|
@@ -149,9 +123,7 @@
|
|
|
149
123
|
* @returns {number} the value in radians
|
|
150
124
|
*/
|
|
151
125
|
deg2rad: (degs) => {
|
|
152
|
-
|
|
153
|
-
assert(isFinite(degs), "deg2rad: 1st param must be a number");
|
|
154
|
-
}
|
|
126
|
+
DEV: assert(isFinite(degs), "deg2rad: 1st param must be a number");
|
|
155
127
|
return PI / 180 * degs;
|
|
156
128
|
},
|
|
157
129
|
/**
|
|
@@ -161,9 +133,7 @@
|
|
|
161
133
|
* @returns {number} the value in degrees
|
|
162
134
|
*/
|
|
163
135
|
rad2deg: (rads) => {
|
|
164
|
-
|
|
165
|
-
assert(isFinite(rads), "rad2deg: 1st param must be a number");
|
|
166
|
-
}
|
|
136
|
+
DEV: assert(isFinite(rads), "rad2deg: 1st param must be a number");
|
|
167
137
|
return 180 / PI * rads;
|
|
168
138
|
},
|
|
169
139
|
/**
|
|
@@ -175,15 +145,13 @@
|
|
|
175
145
|
* @returns {number}
|
|
176
146
|
*/
|
|
177
147
|
clamp: (value, min, max) => {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
);
|
|
186
|
-
}
|
|
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
|
+
);
|
|
187
155
|
if (value < min) return min;
|
|
188
156
|
if (value > max) return max;
|
|
189
157
|
return value;
|
|
@@ -197,19 +165,17 @@
|
|
|
197
165
|
* @returns {number}
|
|
198
166
|
*/
|
|
199
167
|
wrap: (value, min, max) => {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
);
|
|
212
|
-
}
|
|
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
|
+
);
|
|
213
179
|
return value - (max - min) * Math.floor((value - min) / (max - min));
|
|
214
180
|
},
|
|
215
181
|
/**
|
|
@@ -224,13 +190,11 @@
|
|
|
224
190
|
* @returns {number} the remapped number
|
|
225
191
|
*/
|
|
226
192
|
map(value, start1, stop1, start2, stop2, withinBounds) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
assert(isFinite(stop2), "map: 5th param must be a number");
|
|
233
|
-
}
|
|
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");
|
|
234
198
|
const result = (value - start1) / (stop1 - start1) * (stop2 - start2) + start2;
|
|
235
199
|
return withinBounds ? instance.clamp(result, start2, stop2) : result;
|
|
236
200
|
},
|
|
@@ -245,11 +209,9 @@
|
|
|
245
209
|
* @returns {number} the normalized number.
|
|
246
210
|
*/
|
|
247
211
|
norm: (value, start, stop) => {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
assert(isFinite(stop), "norm: 3rd param must be a number");
|
|
252
|
-
}
|
|
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");
|
|
253
215
|
return instance.map(value, start, stop, 0, 1);
|
|
254
216
|
},
|
|
255
217
|
/** RNG API */
|
|
@@ -262,14 +224,12 @@
|
|
|
262
224
|
* @returns {number} the random number
|
|
263
225
|
*/
|
|
264
226
|
rand: (min = 0, max = 1) => {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
);
|
|
272
|
-
}
|
|
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
|
+
);
|
|
273
233
|
const a = 1664525;
|
|
274
234
|
const c = 1013904223;
|
|
275
235
|
const m = 4294967296;
|
|
@@ -284,14 +244,12 @@
|
|
|
284
244
|
* @returns {number} the random number
|
|
285
245
|
*/
|
|
286
246
|
randi: (min = 0, max = 1) => {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
);
|
|
294
|
-
}
|
|
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
|
+
);
|
|
295
253
|
return Math.floor(instance.rand(min, max + 1));
|
|
296
254
|
},
|
|
297
255
|
/**
|
|
@@ -302,12 +260,10 @@
|
|
|
302
260
|
* @returns {number} the seed state
|
|
303
261
|
*/
|
|
304
262
|
seed: (value) => {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
);
|
|
310
|
-
}
|
|
263
|
+
DEV: assert(
|
|
264
|
+
null == value || isFinite(value) && value >= 0,
|
|
265
|
+
"seed: 1st param must be a positive number or zero"
|
|
266
|
+
);
|
|
311
267
|
return null == value ? _rng_seed : _rng_seed = ~~value;
|
|
312
268
|
},
|
|
313
269
|
/** BASIC GRAPHICS API */
|
|
@@ -317,12 +273,10 @@
|
|
|
317
273
|
* @param {number?} color The background color (index) or null (for transparent)
|
|
318
274
|
*/
|
|
319
275
|
cls(color) {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
);
|
|
325
|
-
}
|
|
276
|
+
DEV: assert(
|
|
277
|
+
null == color || isFinite(color) && color >= 0,
|
|
278
|
+
"cls: 1st param must be a positive number or zero or null"
|
|
279
|
+
);
|
|
326
280
|
if (null == color) {
|
|
327
281
|
_ctx.clearRect(0, 0, _ctx.canvas.width, _ctx.canvas.height);
|
|
328
282
|
} else {
|
|
@@ -346,26 +300,24 @@
|
|
|
346
300
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
347
301
|
*/
|
|
348
302
|
rect(x, y, width, height, color, radii = null) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
);
|
|
368
|
-
}
|
|
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
|
+
);
|
|
369
321
|
_ctx.beginPath();
|
|
370
322
|
_ctx[radii ? "roundRect" : "rect"](
|
|
371
323
|
~~x - _outline_fix,
|
|
@@ -387,26 +339,24 @@
|
|
|
387
339
|
* @param {number|number[]} [radii] A number or list specifying the radii used to draw a rounded-borders rectangle
|
|
388
340
|
*/
|
|
389
341
|
rectfill(x, y, width, height, color, radii = null) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
);
|
|
409
|
-
}
|
|
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
|
+
);
|
|
410
360
|
_ctx.beginPath();
|
|
411
361
|
_ctx[radii ? "roundRect" : "rect"](
|
|
412
362
|
~~x,
|
|
@@ -426,18 +376,16 @@
|
|
|
426
376
|
* @param {number} [color=0] the color index
|
|
427
377
|
*/
|
|
428
378
|
circ(x, y, radius, color) {
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
);
|
|
440
|
-
}
|
|
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
|
+
);
|
|
441
389
|
_ctx.beginPath();
|
|
442
390
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
443
391
|
instance.stroke(color);
|
|
@@ -451,18 +399,16 @@
|
|
|
451
399
|
* @param {number} [color=0] the color index
|
|
452
400
|
*/
|
|
453
401
|
circfill(x, y, radius, color) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
);
|
|
465
|
-
}
|
|
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
|
+
);
|
|
466
412
|
_ctx.beginPath();
|
|
467
413
|
_ctx.arc(~~x, ~~y, ~~radius, 0, TWO_PI);
|
|
468
414
|
instance.fill(color);
|
|
@@ -477,22 +423,20 @@
|
|
|
477
423
|
* @param {number} [color=0] the color index
|
|
478
424
|
*/
|
|
479
425
|
line(x1, y1, x2, y2, color) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
);
|
|
495
|
-
}
|
|
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
|
+
);
|
|
496
440
|
_ctx.beginPath();
|
|
497
441
|
let xfix = _outline_fix !== 0 && ~~x1 === ~~x2 ? 0.5 : 0;
|
|
498
442
|
let yfix = _outline_fix !== 0 && ~~y1 === ~~y2 ? 0.5 : 0;
|
|
@@ -507,12 +451,10 @@
|
|
|
507
451
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth
|
|
508
452
|
*/
|
|
509
453
|
linewidth(value) {
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
);
|
|
515
|
-
}
|
|
454
|
+
DEV: assert(
|
|
455
|
+
isFinite(value) && ~~value > 0,
|
|
456
|
+
"linewidth: 1st param must be a positive number"
|
|
457
|
+
);
|
|
516
458
|
_ctx.lineWidth = ~~value;
|
|
517
459
|
_outline_fix = ~~value % 2 === 0 ? 0 : 0.5;
|
|
518
460
|
},
|
|
@@ -525,13 +467,14 @@
|
|
|
525
467
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset
|
|
526
468
|
*/
|
|
527
469
|
linedash(segments, offset = 0) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
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
|
+
);
|
|
535
478
|
_ctx.setLineDash(segments);
|
|
536
479
|
_ctx.lineDashOffset = offset;
|
|
537
480
|
},
|
|
@@ -546,18 +489,16 @@
|
|
|
546
489
|
* @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
|
|
547
490
|
*/
|
|
548
491
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
);
|
|
560
|
-
}
|
|
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
|
+
);
|
|
561
502
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
562
503
|
_ctx.fillStyle = instance.getcolor(color);
|
|
563
504
|
_ctx.fillText(message, ~~x, ~~y);
|
|
@@ -568,12 +509,10 @@
|
|
|
568
509
|
* @param {string} family
|
|
569
510
|
*/
|
|
570
511
|
textfont(family) {
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
);
|
|
576
|
-
}
|
|
512
|
+
DEV: assert(
|
|
513
|
+
"string" === typeof family,
|
|
514
|
+
"textfont: 1st param must be a string"
|
|
515
|
+
);
|
|
577
516
|
_fontFamily = family;
|
|
578
517
|
},
|
|
579
518
|
/**
|
|
@@ -582,9 +521,7 @@
|
|
|
582
521
|
* @param {number} size
|
|
583
522
|
*/
|
|
584
523
|
textsize(size) {
|
|
585
|
-
|
|
586
|
-
assert(isFinite(size), "textsize: 1st param must be a number");
|
|
587
|
-
}
|
|
524
|
+
DEV: assert(isFinite(size), "textsize: 1st param must be a number");
|
|
588
525
|
_fontSize = size;
|
|
589
526
|
},
|
|
590
527
|
/**
|
|
@@ -596,25 +533,21 @@
|
|
|
596
533
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
597
534
|
*/
|
|
598
535
|
textalign(align, baseline) {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
].includes(baseline),
|
|
615
|
-
"textalign: 2nd param must be a string"
|
|
616
|
-
);
|
|
617
|
-
}
|
|
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
|
+
);
|
|
618
551
|
if (align) _ctx.textAlign = align;
|
|
619
552
|
if (baseline) _ctx.textBaseline = baseline;
|
|
620
553
|
},
|
|
@@ -627,10 +560,8 @@
|
|
|
627
560
|
* @param {OffscreenCanvas|HTMLImageElement|HTMLCanvasElement} source
|
|
628
561
|
*/
|
|
629
562
|
image(x, y, source) {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
assert(isFinite(y), "image: 2nd param must be a number");
|
|
633
|
-
}
|
|
563
|
+
DEV: assert(isFinite(x), "image: 1st param must be a number");
|
|
564
|
+
DEV: assert(isFinite(y), "image: 2nd param must be a number");
|
|
634
565
|
_ctx.drawImage(source, ~~x, ~~y);
|
|
635
566
|
},
|
|
636
567
|
/**
|
|
@@ -646,18 +577,16 @@
|
|
|
646
577
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
647
578
|
*/
|
|
648
579
|
paint(width, height, drawing, options = {}) {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
);
|
|
660
|
-
}
|
|
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
|
+
);
|
|
661
590
|
const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
|
|
662
591
|
canvas.width = width * scale;
|
|
663
592
|
canvas.height = height * scale;
|
|
@@ -691,8 +620,6 @@
|
|
|
691
620
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D
|
|
692
621
|
*/
|
|
693
622
|
ctx(context) {
|
|
694
|
-
if (true) {
|
|
695
|
-
}
|
|
696
623
|
if (context) {
|
|
697
624
|
_ctx = context;
|
|
698
625
|
}
|
|
@@ -717,10 +644,8 @@
|
|
|
717
644
|
* @param {number} y
|
|
718
645
|
*/
|
|
719
646
|
translate: (x, y) => {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
assert(isFinite(y), "translate: 2nd param must be a number");
|
|
723
|
-
}
|
|
647
|
+
DEV: assert(isFinite(x), "translate: 1st param must be a number");
|
|
648
|
+
DEV: assert(isFinite(y), "translate: 2nd param must be a number");
|
|
724
649
|
return _ctx.translate(~~x, ~~y);
|
|
725
650
|
},
|
|
726
651
|
/**
|
|
@@ -730,13 +655,11 @@
|
|
|
730
655
|
* @param {number} [y]
|
|
731
656
|
*/
|
|
732
657
|
scale: (x, y) => {
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
);
|
|
739
|
-
}
|
|
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
|
+
);
|
|
740
663
|
return _ctx.scale(x, y || x);
|
|
741
664
|
},
|
|
742
665
|
/**
|
|
@@ -745,9 +668,7 @@
|
|
|
745
668
|
* @param {number} radians
|
|
746
669
|
*/
|
|
747
670
|
rotate: (radians) => {
|
|
748
|
-
|
|
749
|
-
assert(isFinite(radians), "rotate: 1st param must be a number");
|
|
750
|
-
}
|
|
671
|
+
DEV: assert(isFinite(radians), "rotate: 1st param must be a number");
|
|
751
672
|
return _ctx.rotate(radians);
|
|
752
673
|
},
|
|
753
674
|
/**
|
|
@@ -757,9 +678,7 @@
|
|
|
757
678
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha
|
|
758
679
|
*/
|
|
759
680
|
alpha(value) {
|
|
760
|
-
|
|
761
|
-
assert(isFinite(value), "alpha: 1st param must be a number");
|
|
762
|
-
}
|
|
681
|
+
DEV: assert(isFinite(value), "alpha: 1st param must be a number");
|
|
763
682
|
_ctx.globalAlpha = instance.clamp(value, 0, 1);
|
|
764
683
|
},
|
|
765
684
|
/**
|
|
@@ -772,12 +691,10 @@
|
|
|
772
691
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D
|
|
773
692
|
*/
|
|
774
693
|
path: (arg) => {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
);
|
|
780
|
-
}
|
|
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
|
+
);
|
|
781
698
|
return new Path2D(arg);
|
|
782
699
|
},
|
|
783
700
|
/**
|
|
@@ -787,16 +704,14 @@
|
|
|
787
704
|
* @param {Path2D} [path]
|
|
788
705
|
*/
|
|
789
706
|
fill(color, path) {
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
);
|
|
799
|
-
}
|
|
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
|
+
);
|
|
800
715
|
_ctx.fillStyle = instance.getcolor(color);
|
|
801
716
|
if (path) {
|
|
802
717
|
_ctx.fill(path);
|
|
@@ -811,16 +726,14 @@
|
|
|
811
726
|
* @param {Path2D} [path]
|
|
812
727
|
*/
|
|
813
728
|
stroke(color, path) {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
);
|
|
823
|
-
}
|
|
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
|
+
);
|
|
824
737
|
_ctx.strokeStyle = instance.getcolor(color);
|
|
825
738
|
if (path) {
|
|
826
739
|
_ctx.stroke(path);
|
|
@@ -835,12 +748,10 @@
|
|
|
835
748
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip
|
|
836
749
|
*/
|
|
837
750
|
clip(path) {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
);
|
|
843
|
-
}
|
|
751
|
+
DEV: assert(
|
|
752
|
+
path instanceof Path2D,
|
|
753
|
+
"clip: 1st param must be a Path2D instance"
|
|
754
|
+
);
|
|
844
755
|
_ctx.clip(path);
|
|
845
756
|
},
|
|
846
757
|
/** SOUND API */
|
|
@@ -856,17 +767,15 @@
|
|
|
856
767
|
* @see https://github.com/KilledByAPixel/ZzFX
|
|
857
768
|
*/
|
|
858
769
|
sfx(zzfxParams, pitchSlide = 0, volumeFactor = 1) {
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
);
|
|
869
|
-
}
|
|
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
|
+
);
|
|
870
779
|
if (root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive) {
|
|
871
780
|
return false;
|
|
872
781
|
}
|
|
@@ -886,9 +795,7 @@
|
|
|
886
795
|
* @param {number} value
|
|
887
796
|
*/
|
|
888
797
|
volume(value) {
|
|
889
|
-
|
|
890
|
-
assert(isFinite(value), "volume: 1st param must be a number");
|
|
891
|
-
}
|
|
798
|
+
DEV: assert(isFinite(value), "volume: 1st param must be a number");
|
|
892
799
|
root.zzfxV = value;
|
|
893
800
|
},
|
|
894
801
|
/** UTILS API */
|
|
@@ -906,16 +813,14 @@
|
|
|
906
813
|
* @returns {boolean}
|
|
907
814
|
*/
|
|
908
815
|
colrect: (x1, y1, w1, h1, x2, y2, w2, h2) => {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
assert(isFinite(h2), "colrect: 8th param must be a number");
|
|
918
|
-
}
|
|
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");
|
|
919
824
|
return x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2;
|
|
920
825
|
},
|
|
921
826
|
/**
|
|
@@ -930,14 +835,12 @@
|
|
|
930
835
|
* @returns {boolean}
|
|
931
836
|
*/
|
|
932
837
|
colcirc: (x1, y1, r1, x2, y2, r2) => {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
assert(isFinite(r2), "colcirc: 6th param must be a number");
|
|
940
|
-
}
|
|
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");
|
|
941
844
|
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) <= (r1 + r2) * (r1 + r2);
|
|
942
845
|
},
|
|
943
846
|
/** PLUGINS API */
|
|
@@ -947,16 +850,14 @@
|
|
|
947
850
|
* @param {pluginCallback} callback
|
|
948
851
|
*/
|
|
949
852
|
use(callback, config = {}) {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
);
|
|
959
|
-
}
|
|
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
|
+
);
|
|
960
861
|
_initialized ? loadPlugin(callback, config) : _plugins.push([callback, config]);
|
|
961
862
|
},
|
|
962
863
|
/**
|
|
@@ -967,16 +868,14 @@
|
|
|
967
868
|
* @returns {Function} a function to remove the listener
|
|
968
869
|
*/
|
|
969
870
|
listen(eventName, callback) {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
);
|
|
979
|
-
}
|
|
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
|
+
);
|
|
980
879
|
_events[eventName] = _events[eventName] || /* @__PURE__ */ new Set();
|
|
981
880
|
_events[eventName].add(callback);
|
|
982
881
|
return () => _events[eventName].delete(callback);
|
|
@@ -991,12 +890,10 @@
|
|
|
991
890
|
* @param {*} [arg4] any data to be passed over the listeners
|
|
992
891
|
*/
|
|
993
892
|
emit(eventName, arg1, arg2, arg3, arg4) {
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
);
|
|
999
|
-
}
|
|
893
|
+
DEV: assert(
|
|
894
|
+
"string" === typeof eventName,
|
|
895
|
+
"emit: 1st param must be a string"
|
|
896
|
+
);
|
|
1000
897
|
triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
|
|
1001
898
|
triggerEvent(eventName, arg1, arg2, arg3, arg4);
|
|
1002
899
|
triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
|
|
@@ -1008,12 +905,10 @@
|
|
|
1008
905
|
* @returns {string} the color code
|
|
1009
906
|
*/
|
|
1010
907
|
getcolor: (index) => {
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
);
|
|
1016
|
-
}
|
|
908
|
+
DEV: assert(
|
|
909
|
+
null == index || isFinite(index) && index >= 0,
|
|
910
|
+
"getcolor: 1st param must be a number"
|
|
911
|
+
);
|
|
1017
912
|
return colors[~~index % colors.length];
|
|
1018
913
|
},
|
|
1019
914
|
/**
|
|
@@ -1023,13 +918,12 @@
|
|
|
1023
918
|
* @param {*} value
|
|
1024
919
|
*/
|
|
1025
920
|
setvar(key, value) {
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
}
|
|
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}`);
|
|
1033
927
|
}
|
|
1034
928
|
instance[key] = value;
|
|
1035
929
|
if (_global) {
|
|
@@ -1043,10 +937,8 @@
|
|
|
1043
937
|
* @param {number} height
|
|
1044
938
|
*/
|
|
1045
939
|
resize(width, height) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
assert(isFinite(height), "resize: 2nd param must be a number");
|
|
1049
|
-
}
|
|
940
|
+
DEV: assert(isFinite(width), "resize: 1st param must be a number");
|
|
941
|
+
DEV: assert(isFinite(height), "resize: 2nd param must be a number");
|
|
1050
942
|
instance.setvar("WIDTH", _canvas.width = width);
|
|
1051
943
|
instance.setvar("HEIGHT", _canvas.height = height);
|
|
1052
944
|
pageResized();
|
|
@@ -1059,9 +951,10 @@
|
|
|
1059
951
|
* @param {number} value
|
|
1060
952
|
*/
|
|
1061
953
|
timescale(value) {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
954
|
+
DEV: assert(
|
|
955
|
+
isFinite(value),
|
|
956
|
+
"timescale: 1st param must be a number"
|
|
957
|
+
);
|
|
1065
958
|
_timeScale = value;
|
|
1066
959
|
},
|
|
1067
960
|
/**
|
|
@@ -1070,12 +963,10 @@
|
|
|
1070
963
|
* @param {number} value
|
|
1071
964
|
*/
|
|
1072
965
|
setfps(value) {
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
);
|
|
1078
|
-
}
|
|
966
|
+
DEV: assert(
|
|
967
|
+
isFinite(value) && value >= 1,
|
|
968
|
+
"setfps: 1st param must be a positive number"
|
|
969
|
+
);
|
|
1079
970
|
_deltaTime = 1 / ~~value;
|
|
1080
971
|
},
|
|
1081
972
|
/**
|
|
@@ -1096,24 +987,7 @@
|
|
|
1096
987
|
}
|
|
1097
988
|
}
|
|
1098
989
|
};
|
|
1099
|
-
for (const k of
|
|
1100
|
-
"sin",
|
|
1101
|
-
"cos",
|
|
1102
|
-
"atan2",
|
|
1103
|
-
"hypot",
|
|
1104
|
-
"tan",
|
|
1105
|
-
"abs",
|
|
1106
|
-
"ceil",
|
|
1107
|
-
"round",
|
|
1108
|
-
"floor",
|
|
1109
|
-
"trunc",
|
|
1110
|
-
"min",
|
|
1111
|
-
"max",
|
|
1112
|
-
"pow",
|
|
1113
|
-
"sqrt",
|
|
1114
|
-
"sign",
|
|
1115
|
-
"exp"
|
|
1116
|
-
]) {
|
|
990
|
+
for (const k of "PI,sin,cos,atan2,hypot,tan,abs,ceil,round,floor,trunc,min,max,pow,sqrt,sign,exp".split(",")) {
|
|
1117
991
|
instance[k] = Math[k];
|
|
1118
992
|
}
|
|
1119
993
|
function init() {
|
|
@@ -1148,17 +1022,32 @@
|
|
|
1148
1022
|
const tap = _taps.get(id) || _registerTap(id);
|
|
1149
1023
|
tap.x = x;
|
|
1150
1024
|
tap.y = y;
|
|
1151
|
-
}, _checkTapped = (tap) => tap && performance.now() - tap.ts <= 200;
|
|
1025
|
+
}, _checkTapped = (tap) => tap && performance.now() - tap.ts <= 200, preventDefault = (ev) => ev.preventDefault();
|
|
1152
1026
|
let _pressingMouse = false;
|
|
1153
1027
|
on(_canvas, "mousedown", (ev) => {
|
|
1154
|
-
ev.
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1028
|
+
if (ev.button === 0) {
|
|
1029
|
+
preventDefault(ev);
|
|
1030
|
+
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
1031
|
+
instance.emit("tap", x, y, 0);
|
|
1032
|
+
_registerTap(0, x, y);
|
|
1033
|
+
_pressingMouse = true;
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
on(_canvas, "mouseup", (ev) => {
|
|
1037
|
+
if (ev.button === 0) {
|
|
1038
|
+
preventDefault(ev);
|
|
1039
|
+
const tap = _taps.get(0);
|
|
1040
|
+
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
1041
|
+
if (_checkTapped(tap)) {
|
|
1042
|
+
instance.emit("tapped", tap.startX, tap.startY, 0);
|
|
1043
|
+
}
|
|
1044
|
+
instance.emit("untap", x, y, 0);
|
|
1045
|
+
_taps.delete(0);
|
|
1046
|
+
_pressingMouse = false;
|
|
1047
|
+
}
|
|
1159
1048
|
});
|
|
1160
1049
|
on(_canvas, "mousemove", (ev) => {
|
|
1161
|
-
|
|
1050
|
+
preventDefault(ev);
|
|
1162
1051
|
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
1163
1052
|
instance.setvar("MOUSEX", x);
|
|
1164
1053
|
instance.setvar("MOUSEY", y);
|
|
@@ -1166,19 +1055,8 @@
|
|
|
1166
1055
|
instance.emit("tapping", x, y, 0);
|
|
1167
1056
|
_updateTap(0, x, y);
|
|
1168
1057
|
});
|
|
1169
|
-
on(_canvas, "mouseup", (ev) => {
|
|
1170
|
-
ev.preventDefault();
|
|
1171
|
-
const tap = _taps.get(0);
|
|
1172
|
-
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
1173
|
-
if (_checkTapped(tap)) {
|
|
1174
|
-
instance.emit("tapped", tap.startX, tap.startY, 0);
|
|
1175
|
-
}
|
|
1176
|
-
instance.emit("untap", x, y, 0);
|
|
1177
|
-
_taps.delete(0);
|
|
1178
|
-
_pressingMouse = false;
|
|
1179
|
-
});
|
|
1180
1058
|
on(_canvas, "touchstart", (ev) => {
|
|
1181
|
-
|
|
1059
|
+
preventDefault(ev);
|
|
1182
1060
|
const touches = ev.changedTouches;
|
|
1183
1061
|
for (const touch of touches) {
|
|
1184
1062
|
const [x, y] = _getXY(touch.pageX, touch.pageY);
|
|
@@ -1187,7 +1065,7 @@
|
|
|
1187
1065
|
}
|
|
1188
1066
|
});
|
|
1189
1067
|
on(_canvas, "touchmove", (ev) => {
|
|
1190
|
-
|
|
1068
|
+
preventDefault(ev);
|
|
1191
1069
|
const touches = ev.changedTouches;
|
|
1192
1070
|
for (const touch of touches) {
|
|
1193
1071
|
const [x, y] = _getXY(touch.pageX, touch.pageY);
|
|
@@ -1196,7 +1074,7 @@
|
|
|
1196
1074
|
}
|
|
1197
1075
|
});
|
|
1198
1076
|
const _touchEndHandler = (ev) => {
|
|
1199
|
-
|
|
1077
|
+
preventDefault(ev);
|
|
1200
1078
|
const existing = [];
|
|
1201
1079
|
if (ev.targetTouches.length > 0) {
|
|
1202
1080
|
for (const touch of ev.targetTouches) {
|
|
@@ -1225,12 +1103,10 @@
|
|
|
1225
1103
|
if (settings.keyboardEvents) {
|
|
1226
1104
|
const _keys = /* @__PURE__ */ new Set();
|
|
1227
1105
|
const iskeydown = (key) => {
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
);
|
|
1233
|
-
}
|
|
1106
|
+
DEV: assert(
|
|
1107
|
+
"string" === typeof key,
|
|
1108
|
+
"iskeydown: 1st param must be a string"
|
|
1109
|
+
);
|
|
1234
1110
|
return "any" === key ? _keys.size > 0 : _keys.has(key.toLowerCase());
|
|
1235
1111
|
};
|
|
1236
1112
|
instance.setvar("iskeydown", iskeydown);
|
|
@@ -1263,7 +1139,8 @@
|
|
|
1263
1139
|
}
|
|
1264
1140
|
let updated = 0, frameTime = (now - _lastFrameTime) / 1e3;
|
|
1265
1141
|
_lastFrameTime = now;
|
|
1266
|
-
if (frameTime >
|
|
1142
|
+
if (frameTime > _deltaTime * 30)
|
|
1143
|
+
return console.log("skipping too long frame");
|
|
1267
1144
|
_accumulated += frameTime;
|
|
1268
1145
|
if (!_animated) {
|
|
1269
1146
|
_accumulated = _deltaTime;
|
|
@@ -1283,6 +1160,18 @@
|
|
|
1283
1160
|
}
|
|
1284
1161
|
function setupCanvas() {
|
|
1285
1162
|
_canvas = "string" === typeof _canvas ? document.querySelector(_canvas) : _canvas;
|
|
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
|
+
);
|
|
1286
1175
|
instance.setvar("CANVAS", _canvas);
|
|
1287
1176
|
_ctx = _canvas.getContext("2d");
|
|
1288
1177
|
on(_canvas, "click", () => root.focus());
|
|
@@ -1316,7 +1205,7 @@
|
|
|
1316
1205
|
instance.setvar("CENTERY", instance.HEIGHT / 2);
|
|
1317
1206
|
if (!settings.antialias || settings.pixelart) {
|
|
1318
1207
|
_ctx.imageSmoothingEnabled = false;
|
|
1319
|
-
|
|
1208
|
+
styles.imageRendering = "pixelated";
|
|
1320
1209
|
}
|
|
1321
1210
|
instance.emit("resized", _scale);
|
|
1322
1211
|
if (!_animated) {
|
|
@@ -1331,10 +1220,12 @@
|
|
|
1331
1220
|
}
|
|
1332
1221
|
function loadPlugin(callback, config) {
|
|
1333
1222
|
const pluginData = callback(instance, _helpers, config);
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1223
|
+
DEV: assert(
|
|
1224
|
+
null == pluginData || "object" === typeof pluginData,
|
|
1225
|
+
"Litecanvas plugins should return an object or nothing"
|
|
1226
|
+
);
|
|
1227
|
+
for (const key in pluginData) {
|
|
1228
|
+
instance.setvar(key, pluginData[key]);
|
|
1338
1229
|
}
|
|
1339
1230
|
}
|
|
1340
1231
|
if (_global) {
|