q5 2.26.1 → 2.27.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/deno.json +1 -1
- package/package.json +1 -1
- package/q5.d.ts +227 -36
- package/q5.js +120 -80
- package/q5.min.js +2 -2
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.27
|
|
4
4
|
* @author quinton-ashley
|
|
5
5
|
* @contributors Tezumie, LingDong-
|
|
6
6
|
* @license LGPL-3.0
|
|
@@ -160,7 +160,7 @@ function Q5(scope, parent, renderer) {
|
|
|
160
160
|
};
|
|
161
161
|
|
|
162
162
|
$.frameRate = (hz) => {
|
|
163
|
-
if (hz != $._targetFrameRate) {
|
|
163
|
+
if (hz && hz != $._targetFrameRate) {
|
|
164
164
|
$._targetFrameRate = hz;
|
|
165
165
|
$._targetFrameDuration = 1000 / hz;
|
|
166
166
|
|
|
@@ -256,18 +256,8 @@ function Q5(scope, parent, renderer) {
|
|
|
256
256
|
};
|
|
257
257
|
|
|
258
258
|
let t = globalScope || $;
|
|
259
|
-
$._isTouchAware = t.touchStarted || t.touchMoved || t.touchEnded;
|
|
260
259
|
|
|
261
|
-
|
|
262
|
-
$.preload = t.preload;
|
|
263
|
-
$.setup = t.setup;
|
|
264
|
-
$.draw = t.draw;
|
|
265
|
-
$.postProcess = t.postProcess;
|
|
266
|
-
}
|
|
267
|
-
$.preload ??= () => {};
|
|
268
|
-
$.setup ??= () => {};
|
|
269
|
-
$.draw ??= () => {};
|
|
270
|
-
$.postProcess ??= () => {};
|
|
260
|
+
$._isTouchAware = t.touchStarted || t.touchMoved || t.touchEnded;
|
|
271
261
|
|
|
272
262
|
let userFns = [
|
|
273
263
|
'setup',
|
|
@@ -277,6 +267,7 @@ function Q5(scope, parent, renderer) {
|
|
|
277
267
|
'mouseReleased',
|
|
278
268
|
'mouseDragged',
|
|
279
269
|
'mouseClicked',
|
|
270
|
+
'doubleClicked',
|
|
280
271
|
'mouseWheel',
|
|
281
272
|
'keyPressed',
|
|
282
273
|
'keyReleased',
|
|
@@ -286,12 +277,15 @@ function Q5(scope, parent, renderer) {
|
|
|
286
277
|
'touchEnded',
|
|
287
278
|
'windowResized'
|
|
288
279
|
];
|
|
289
|
-
|
|
290
|
-
|
|
280
|
+
// shim if undefined
|
|
281
|
+
for (let name of userFns) $[name] ??= () => {};
|
|
282
|
+
|
|
283
|
+
function wrapWithFES(fn) {
|
|
284
|
+
if (!t[fn]) $[fn] = () => {};
|
|
291
285
|
else if ($._isGlobal) {
|
|
292
|
-
$[
|
|
286
|
+
$[fn] = (event) => {
|
|
293
287
|
try {
|
|
294
|
-
return t[
|
|
288
|
+
return t[fn](event);
|
|
295
289
|
} catch (e) {
|
|
296
290
|
if ($._fes) $._fes(e);
|
|
297
291
|
throw e;
|
|
@@ -300,28 +294,24 @@ function Q5(scope, parent, renderer) {
|
|
|
300
294
|
}
|
|
301
295
|
}
|
|
302
296
|
|
|
303
|
-
async function
|
|
304
|
-
|
|
297
|
+
async function _start() {
|
|
298
|
+
wrapWithFES('preload');
|
|
299
|
+
$.preload();
|
|
305
300
|
await Promise.all($._preloadPromises);
|
|
306
301
|
if ($._g) await Promise.all($._g._preloadPromises);
|
|
302
|
+
|
|
303
|
+
for (let name of userFns) wrapWithFES(name);
|
|
304
|
+
|
|
305
|
+
$.draw = t.draw || (() => {});
|
|
306
|
+
|
|
307
307
|
millisStart = performance.now();
|
|
308
308
|
await $.setup();
|
|
309
309
|
$._setupDone = true;
|
|
310
|
-
if ($.frameCount) return;
|
|
311
310
|
if ($.ctx === null) $.createCanvas(200, 200);
|
|
311
|
+
if ($.frameCount) return;
|
|
312
312
|
raf($._draw);
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
function _start() {
|
|
316
|
-
try {
|
|
317
|
-
$.preload();
|
|
318
|
-
if (!$._startDone) _setup();
|
|
319
|
-
} catch (e) {
|
|
320
|
-
if ($._fes) $._fes(e);
|
|
321
|
-
throw e;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
315
|
if (autoLoaded) _start();
|
|
326
316
|
else setTimeout(_start, 32);
|
|
327
317
|
}
|
|
@@ -363,7 +353,7 @@ function createCanvas(w, h, opt) {
|
|
|
363
353
|
}
|
|
364
354
|
}
|
|
365
355
|
|
|
366
|
-
Q5.version = Q5.VERSION = '2.
|
|
356
|
+
Q5.version = Q5.VERSION = '2.27';
|
|
367
357
|
|
|
368
358
|
if (typeof document == 'object') {
|
|
369
359
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -430,21 +420,44 @@ Q5.modules.canvas = ($, q) => {
|
|
|
430
420
|
|
|
431
421
|
if ($._scope != 'image') {
|
|
432
422
|
if ($._scope == 'graphics') $._pixelDensity = this._pixelDensity;
|
|
433
|
-
else if (
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
423
|
+
else if (!Q5._server) {
|
|
424
|
+
// the canvas can become detached from the DOM
|
|
425
|
+
// if the innerHTML of one of its parents is edited
|
|
426
|
+
// check if canvas is still attached to the DOM
|
|
427
|
+
let el = c;
|
|
428
|
+
while (el && el.parentElement != document.body) {
|
|
429
|
+
el = el.parentElement;
|
|
430
|
+
}
|
|
431
|
+
if (!el) {
|
|
432
|
+
// reattach canvas to the DOM
|
|
433
|
+
document.getElementById(c.id)?.remove();
|
|
434
|
+
addCanvas();
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (window.IntersectionObserver) {
|
|
438
|
+
let wasObserved = false;
|
|
439
|
+
new IntersectionObserver((e) => {
|
|
440
|
+
let isIntersecting = e[0].isIntersecting;
|
|
441
|
+
|
|
442
|
+
if (!isIntersecting) {
|
|
443
|
+
// the canvas might still be onscreen, just behind other elements
|
|
444
|
+
let r = c.getBoundingClientRect();
|
|
445
|
+
c.visible = r.top < window.innerHeight && r.bottom > 0 && r.left < window.innerWidth && r.right > 0;
|
|
446
|
+
} else c.visible = true;
|
|
447
|
+
|
|
448
|
+
if (!wasObserved) {
|
|
449
|
+
$._wasLooping = $._loop;
|
|
450
|
+
wasObserved = true;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
if (c.visible) {
|
|
454
|
+
if ($._wasLooping && !$._loop) $.loop();
|
|
455
|
+
} else {
|
|
456
|
+
$._wasLooping = $._loop;
|
|
457
|
+
$.noLoop();
|
|
458
|
+
}
|
|
459
|
+
}).observe(c);
|
|
460
|
+
}
|
|
448
461
|
}
|
|
449
462
|
}
|
|
450
463
|
|
|
@@ -609,7 +622,9 @@ Q5.modules.canvas = ($, q) => {
|
|
|
609
622
|
$.popStyles = () => {
|
|
610
623
|
let styles = $._styles.pop();
|
|
611
624
|
for (let s of $._styleNames) $[s] = styles[s];
|
|
612
|
-
|
|
625
|
+
|
|
626
|
+
if ($._webgpu) $.colorMode($._colorMode, $._colorFormat);
|
|
627
|
+
else q.Color = styles.Color;
|
|
613
628
|
};
|
|
614
629
|
|
|
615
630
|
if (window && $._scope != 'graphics') {
|
|
@@ -3091,7 +3106,12 @@ Q5.modules.input = ($, q) => {
|
|
|
3091
3106
|
|
|
3092
3107
|
$._updateMouse = (e) => {
|
|
3093
3108
|
if (e.changedTouches) return;
|
|
3094
|
-
|
|
3109
|
+
|
|
3110
|
+
if (document.pointerLockElement) {
|
|
3111
|
+
// In pointer lock mode, update position based on movement
|
|
3112
|
+
q.mouseX += e.movementX;
|
|
3113
|
+
q.mouseY += e.movementY;
|
|
3114
|
+
} else if (c) {
|
|
3095
3115
|
let rect = c.getBoundingClientRect();
|
|
3096
3116
|
let sx = c.scrollWidth / $.width || 1;
|
|
3097
3117
|
let sy = c.scrollHeight / $.height || 1;
|
|
@@ -3109,10 +3129,8 @@ Q5.modules.input = ($, q) => {
|
|
|
3109
3129
|
q.moveY = e.movementY;
|
|
3110
3130
|
};
|
|
3111
3131
|
|
|
3112
|
-
let pressedInCanvas = 0;
|
|
3113
|
-
|
|
3114
3132
|
$._onmousedown = (e) => {
|
|
3115
|
-
|
|
3133
|
+
if (!c?.visible) return;
|
|
3116
3134
|
$._startAudio();
|
|
3117
3135
|
$._updateMouse(e);
|
|
3118
3136
|
q.mouseIsPressed = true;
|
|
@@ -3127,19 +3145,30 @@ Q5.modules.input = ($, q) => {
|
|
|
3127
3145
|
};
|
|
3128
3146
|
|
|
3129
3147
|
$._onmouseup = (e) => {
|
|
3148
|
+
if (!c?.visible) return;
|
|
3130
3149
|
$._updateMouse(e);
|
|
3131
3150
|
q.mouseIsPressed = false;
|
|
3132
3151
|
$.mouseReleased(e);
|
|
3133
3152
|
};
|
|
3134
3153
|
|
|
3135
3154
|
$._onclick = (e) => {
|
|
3155
|
+
if (!c?.visible) return;
|
|
3136
3156
|
$._updateMouse(e);
|
|
3137
3157
|
q.mouseIsPressed = true;
|
|
3138
3158
|
$.mouseClicked(e);
|
|
3139
3159
|
q.mouseIsPressed = false;
|
|
3140
3160
|
};
|
|
3141
3161
|
|
|
3162
|
+
$._ondblclick = (e) => {
|
|
3163
|
+
if (!c?.visible) return;
|
|
3164
|
+
$._updateMouse(e);
|
|
3165
|
+
q.mouseIsPressed = true;
|
|
3166
|
+
$.doubleClicked(e);
|
|
3167
|
+
q.mouseIsPressed = false;
|
|
3168
|
+
};
|
|
3169
|
+
|
|
3142
3170
|
$._onwheel = (e) => {
|
|
3171
|
+
if (!c?.visible) return;
|
|
3143
3172
|
$._updateMouse(e);
|
|
3144
3173
|
e.delta = e.deltaY;
|
|
3145
3174
|
if ($.mouseWheel(e) == false || $._noScroll) e.preventDefault();
|
|
@@ -3160,10 +3189,10 @@ Q5.modules.input = ($, q) => {
|
|
|
3160
3189
|
$.noCursor = () => ($.canvas.style.cursor = 'none');
|
|
3161
3190
|
$.noScroll = () => ($._noScroll = true);
|
|
3162
3191
|
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3192
|
+
$.requestPointerLock = (unadjustedMovement = false) => {
|
|
3193
|
+
return document.body?.requestPointerLock({ unadjustedMovement });
|
|
3194
|
+
};
|
|
3195
|
+
$.exitPointerLock = () => document.exitPointerLock();
|
|
3167
3196
|
|
|
3168
3197
|
$._onkeydown = (e) => {
|
|
3169
3198
|
if (e.repeat) return;
|
|
@@ -3204,6 +3233,7 @@ Q5.modules.input = ($, q) => {
|
|
|
3204
3233
|
}
|
|
3205
3234
|
|
|
3206
3235
|
$._ontouchstart = (e) => {
|
|
3236
|
+
if (!c?.visible) return;
|
|
3207
3237
|
$._startAudio();
|
|
3208
3238
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
3209
3239
|
if (!$._isTouchAware) {
|
|
@@ -3217,6 +3247,7 @@ Q5.modules.input = ($, q) => {
|
|
|
3217
3247
|
};
|
|
3218
3248
|
|
|
3219
3249
|
$._ontouchmove = (e) => {
|
|
3250
|
+
if (!c?.visible) return;
|
|
3220
3251
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
3221
3252
|
if (!$._isTouchAware) {
|
|
3222
3253
|
q.mouseX = $.touches[0].x;
|
|
@@ -3227,6 +3258,7 @@ Q5.modules.input = ($, q) => {
|
|
|
3227
3258
|
};
|
|
3228
3259
|
|
|
3229
3260
|
$._ontouchend = (e) => {
|
|
3261
|
+
if (!c?.visible) return;
|
|
3230
3262
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
3231
3263
|
if (!$._isTouchAware && !$.touches.length) {
|
|
3232
3264
|
q.mouseIsPressed = false;
|
|
@@ -3235,11 +3267,18 @@ Q5.modules.input = ($, q) => {
|
|
|
3235
3267
|
if (!$.touchEnded(e)) e.preventDefault();
|
|
3236
3268
|
};
|
|
3237
3269
|
|
|
3238
|
-
if (
|
|
3239
|
-
let l =
|
|
3270
|
+
if (window) {
|
|
3271
|
+
let l = window.addEventListener;
|
|
3272
|
+
l('keydown', (e) => $._onkeydown(e), false);
|
|
3273
|
+
l('keyup', (e) => $._onkeyup(e), false);
|
|
3274
|
+
|
|
3240
3275
|
l('mousedown', (e) => $._onmousedown(e));
|
|
3241
|
-
l('
|
|
3276
|
+
l('mousemove', (e) => $._onmousemove(e), false);
|
|
3277
|
+
l('mouseup', (e) => $._onmouseup(e));
|
|
3242
3278
|
l('click', (e) => $._onclick(e));
|
|
3279
|
+
l('dblclick', (e) => $._ondblclick(e));
|
|
3280
|
+
|
|
3281
|
+
if (!c) l('wheel', (e) => $._onwheel(e));
|
|
3243
3282
|
|
|
3244
3283
|
l('touchstart', (e) => $._ontouchstart(e));
|
|
3245
3284
|
l('touchmove', (e) => $._ontouchmove(e));
|
|
@@ -3247,25 +3286,10 @@ Q5.modules.input = ($, q) => {
|
|
|
3247
3286
|
l('touchcancel', (e) => $._ontouchend(e));
|
|
3248
3287
|
}
|
|
3249
3288
|
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
if (!c) {
|
|
3256
|
-
l('mousedown', (e) => $._onmousedown(e));
|
|
3257
|
-
l('wheel', (e) => $._onwheel(e));
|
|
3258
|
-
l('click', (e) => $._onclick(e));
|
|
3259
|
-
}
|
|
3260
|
-
|
|
3261
|
-
l('mousemove', (e) => $._onmousemove(e), false);
|
|
3262
|
-
l('mouseup', (e) => {
|
|
3263
|
-
if (pressedInCanvas > 0) {
|
|
3264
|
-
pressedInCanvas--;
|
|
3265
|
-
$._onmouseup(e);
|
|
3266
|
-
}
|
|
3267
|
-
});
|
|
3268
|
-
}
|
|
3289
|
+
// making the window level event listener for wheel events
|
|
3290
|
+
// not passive would be necessary to be able to use `e.preventDefault`
|
|
3291
|
+
// but browsers warn that it's bad for performance
|
|
3292
|
+
if (c) c.addEventListener('wheel', (e) => $._onwheel(e));
|
|
3269
3293
|
};
|
|
3270
3294
|
Q5.modules.math = ($, q) => {
|
|
3271
3295
|
$.RADIANS = 0;
|
|
@@ -4134,6 +4158,10 @@ Q5.modules.sound = ($, q) => {
|
|
|
4134
4158
|
return Q5.aud.resume();
|
|
4135
4159
|
}
|
|
4136
4160
|
};
|
|
4161
|
+
|
|
4162
|
+
$.outputVolume = (level) => {
|
|
4163
|
+
if (Q5.soundOut) Q5.soundOut.gain.value = level;
|
|
4164
|
+
};
|
|
4137
4165
|
};
|
|
4138
4166
|
|
|
4139
4167
|
if (window.OfflineAudioContext) {
|
|
@@ -4183,6 +4211,7 @@ Q5.Sound = class {
|
|
|
4183
4211
|
source.onended = () => {
|
|
4184
4212
|
if (!this.paused) {
|
|
4185
4213
|
this.ended = true;
|
|
4214
|
+
if (this._onended) this._onended();
|
|
4186
4215
|
this.sources.delete(source);
|
|
4187
4216
|
}
|
|
4188
4217
|
};
|
|
@@ -4278,6 +4307,9 @@ Q5.Sound = class {
|
|
|
4278
4307
|
isLooping() {
|
|
4279
4308
|
return this._loop;
|
|
4280
4309
|
}
|
|
4310
|
+
onended(cb) {
|
|
4311
|
+
this._onended = cb;
|
|
4312
|
+
}
|
|
4281
4313
|
};
|
|
4282
4314
|
Q5.modules.util = ($, q) => {
|
|
4283
4315
|
$._loadFile = (url, cb, type) => {
|
|
@@ -4950,6 +4982,8 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4950
4982
|
createMainView();
|
|
4951
4983
|
};
|
|
4952
4984
|
|
|
4985
|
+
// since these values are checked so often in `addColor`,
|
|
4986
|
+
// they're stored in local variables for better performance
|
|
4953
4987
|
let usingRGB = true,
|
|
4954
4988
|
colorFormat = 1;
|
|
4955
4989
|
|
|
@@ -6021,7 +6055,10 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6021
6055
|
};
|
|
6022
6056
|
|
|
6023
6057
|
let curveSegments = 20;
|
|
6024
|
-
$.curveDetail = (
|
|
6058
|
+
$.curveDetail = (v) => (curveSegments = v);
|
|
6059
|
+
|
|
6060
|
+
let bezierSegments = 20;
|
|
6061
|
+
$.bezierDetail = (v) => (bezierSegments = v);
|
|
6025
6062
|
|
|
6026
6063
|
let shapeVertCount;
|
|
6027
6064
|
let sv = []; // shape vertices
|
|
@@ -6053,7 +6090,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6053
6090
|
let startX = sv[prevIndex];
|
|
6054
6091
|
let startY = sv[prevIndex + 1];
|
|
6055
6092
|
|
|
6056
|
-
let step = 1 /
|
|
6093
|
+
let step = 1 / bezierSegments;
|
|
6057
6094
|
|
|
6058
6095
|
let vx, vy;
|
|
6059
6096
|
let quadratic = arguments.length == 4;
|
|
@@ -6101,6 +6138,9 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6101
6138
|
}
|
|
6102
6139
|
}
|
|
6103
6140
|
|
|
6141
|
+
// Use curveSegments to determine step size
|
|
6142
|
+
let step = 1 / curveSegments;
|
|
6143
|
+
|
|
6104
6144
|
// calculate catmull-rom spline curve points
|
|
6105
6145
|
for (let i = 0; i < points.length - 3; i++) {
|
|
6106
6146
|
let p0 = points[i];
|
|
@@ -6108,7 +6148,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6108
6148
|
let p2 = points[i + 2];
|
|
6109
6149
|
let p3 = points[i + 3];
|
|
6110
6150
|
|
|
6111
|
-
for (let t = 0; t <= 1; t +=
|
|
6151
|
+
for (let t = 0; t <= 1; t += step) {
|
|
6112
6152
|
let t2 = t * t;
|
|
6113
6153
|
let t3 = t2 * t;
|
|
6114
6154
|
|