q5 2.21.5 → 2.22.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -0
- package/deno.json +2 -2
- package/package.json +2 -2
- package/q5.d.ts +140 -48
- package/q5.js +286 -109
- 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.22
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -41,7 +41,8 @@ function Q5(scope, parent, renderer) {
|
|
|
41
41
|
|
|
42
42
|
$.canvas = $.ctx = $.drawingContext = null;
|
|
43
43
|
$.pixels = [];
|
|
44
|
-
let looper = null
|
|
44
|
+
let looper = null,
|
|
45
|
+
useRAF = true;
|
|
45
46
|
|
|
46
47
|
$.frameCount = 0;
|
|
47
48
|
$.deltaTime = 16;
|
|
@@ -83,13 +84,22 @@ function Q5(scope, parent, renderer) {
|
|
|
83
84
|
$._didResize = false;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
if ($._loop)
|
|
87
|
-
|
|
87
|
+
if ($._loop) {
|
|
88
|
+
if (useRAF) looper = raf($._draw);
|
|
89
|
+
else {
|
|
90
|
+
let nextTS = ts + $._targetFrameDuration;
|
|
91
|
+
let frameDelay = nextTS - performance.now();
|
|
92
|
+
while (frameDelay < 0) frameDelay += $._targetFrameDuration;
|
|
93
|
+
log(frameDelay);
|
|
94
|
+
looper = setTimeout(() => $._draw(nextTS), frameDelay);
|
|
95
|
+
}
|
|
96
|
+
} else if ($.frameCount && !$._redraw) return;
|
|
88
97
|
|
|
89
|
-
if (
|
|
90
|
-
let
|
|
91
|
-
if (
|
|
98
|
+
if ($.frameCount && useRAF) {
|
|
99
|
+
let timeSinceLast = ts - $._lastFrameTime;
|
|
100
|
+
if (timeSinceLast < $._targetFrameDuration - 4) return;
|
|
92
101
|
}
|
|
102
|
+
|
|
93
103
|
q.deltaTime = ts - $._lastFrameTime;
|
|
94
104
|
$._frameRate = 1000 / $.deltaTime;
|
|
95
105
|
q.frameCount++;
|
|
@@ -100,7 +110,6 @@ function Q5(scope, parent, renderer) {
|
|
|
100
110
|
try {
|
|
101
111
|
$.draw();
|
|
102
112
|
} catch (e) {
|
|
103
|
-
if (!Q5.disableFriendlyErrors && $._askAI) $._askAI(e);
|
|
104
113
|
if (!Q5.errorTolerant) $.noLoop();
|
|
105
114
|
throw e;
|
|
106
115
|
}
|
|
@@ -117,6 +126,10 @@ function Q5(scope, parent, renderer) {
|
|
|
117
126
|
};
|
|
118
127
|
$.noLoop = () => {
|
|
119
128
|
$._loop = false;
|
|
129
|
+
if (looper) {
|
|
130
|
+
if (useRAF) cancelAnimationFrame(looper);
|
|
131
|
+
else clearTimeout(looper);
|
|
132
|
+
}
|
|
120
133
|
looper = null;
|
|
121
134
|
};
|
|
122
135
|
$.loop = () => {
|
|
@@ -140,6 +153,14 @@ function Q5(scope, parent, renderer) {
|
|
|
140
153
|
if (hz) {
|
|
141
154
|
$._targetFrameRate = hz;
|
|
142
155
|
$._targetFrameDuration = 1000 / hz;
|
|
156
|
+
|
|
157
|
+
if ($._loop && $._setupDone && looper != null) {
|
|
158
|
+
if (useRAF) cancelAnimationFrame(looper);
|
|
159
|
+
else clearTimeout(looper);
|
|
160
|
+
looper = null;
|
|
161
|
+
}
|
|
162
|
+
useRAF = hz <= 60;
|
|
163
|
+
setTimeout(() => $._draw(), $._targetFrameDuration);
|
|
143
164
|
}
|
|
144
165
|
return $._frameRate;
|
|
145
166
|
};
|
|
@@ -243,20 +264,13 @@ function Q5(scope, parent, renderer) {
|
|
|
243
264
|
for (let k of userFns) {
|
|
244
265
|
if (!t[k]) $[k] = () => {};
|
|
245
266
|
else if ($._isGlobal) {
|
|
246
|
-
$[k] = (event) =>
|
|
247
|
-
try {
|
|
248
|
-
return t[k](event);
|
|
249
|
-
} catch (e) {
|
|
250
|
-
if ($._askAI) $._askAI(e);
|
|
251
|
-
throw e;
|
|
252
|
-
}
|
|
253
|
-
};
|
|
267
|
+
$[k] = (event) => t[k](event);
|
|
254
268
|
}
|
|
255
269
|
}
|
|
256
270
|
|
|
257
271
|
async function _setup() {
|
|
258
272
|
$._startDone = true;
|
|
259
|
-
if ($._preloadCount > 0) return raf(_setup);
|
|
273
|
+
if ($._preloadCount > 0 || $._g?._preloadCount > 0) return raf(_setup);
|
|
260
274
|
millisStart = performance.now();
|
|
261
275
|
await $.setup();
|
|
262
276
|
$._setupDone = true;
|
|
@@ -314,7 +328,7 @@ function createCanvas(w, h, opt) {
|
|
|
314
328
|
}
|
|
315
329
|
}
|
|
316
330
|
|
|
317
|
-
Q5.version = Q5.VERSION = '2.
|
|
331
|
+
Q5.version = Q5.VERSION = '2.22';
|
|
318
332
|
|
|
319
333
|
if (typeof document == 'object') {
|
|
320
334
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -407,7 +421,6 @@ Q5.modules.canvas = ($, q) => {
|
|
|
407
421
|
if ($._hooks) {
|
|
408
422
|
for (let m of $._hooks.postCanvas) m();
|
|
409
423
|
}
|
|
410
|
-
if ($._beginRender) $._beginRender();
|
|
411
424
|
|
|
412
425
|
if ($._addEventMethods) $._addEventMethods(c);
|
|
413
426
|
|
|
@@ -514,7 +527,7 @@ Q5.modules.canvas = ($, q) => {
|
|
|
514
527
|
$.pixelDensity = (v) => {
|
|
515
528
|
if (!v || v == $._pixelDensity) return $._pixelDensity;
|
|
516
529
|
$._pixelDensity = v;
|
|
517
|
-
$.
|
|
530
|
+
$._resizeCanvas(c.w, c.h);
|
|
518
531
|
return v;
|
|
519
532
|
};
|
|
520
533
|
|
|
@@ -688,6 +701,22 @@ Q5.renderers.c2d.canvas = ($, q) => {
|
|
|
688
701
|
|
|
689
702
|
if ($._scope == 'image') return;
|
|
690
703
|
|
|
704
|
+
$.background = function (c) {
|
|
705
|
+
$.ctx.save();
|
|
706
|
+
$.ctx.resetTransform();
|
|
707
|
+
$.ctx.globalAlpha = 1;
|
|
708
|
+
if (c.canvas) $.image(c, 0, 0, $.canvas.width, $.canvas.height);
|
|
709
|
+
else {
|
|
710
|
+
if (Q5.Color && !c._q5Color) {
|
|
711
|
+
if (typeof c != 'string') c = $.color(...arguments);
|
|
712
|
+
else if ($._namedColors[c]) c = $.color(...$._namedColors[c]);
|
|
713
|
+
}
|
|
714
|
+
$.ctx.fillStyle = c.toString();
|
|
715
|
+
$.ctx.fillRect(0, 0, $.canvas.width, $.canvas.height);
|
|
716
|
+
}
|
|
717
|
+
$.ctx.restore();
|
|
718
|
+
};
|
|
719
|
+
|
|
691
720
|
$._resizeCanvas = (w, h) => {
|
|
692
721
|
let t = {};
|
|
693
722
|
for (let prop in $.ctx) {
|
|
@@ -868,22 +897,6 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
868
897
|
|
|
869
898
|
// DRAWING
|
|
870
899
|
|
|
871
|
-
$.background = function (c) {
|
|
872
|
-
$.ctx.save();
|
|
873
|
-
$.ctx.resetTransform();
|
|
874
|
-
$.ctx.globalAlpha = 1;
|
|
875
|
-
if (c.canvas) $.image(c, 0, 0, $.canvas.width, $.canvas.height);
|
|
876
|
-
else {
|
|
877
|
-
if (Q5.Color && !c._q5Color) {
|
|
878
|
-
if (typeof c != 'string') c = $.color(...arguments);
|
|
879
|
-
else if ($._namedColors[c]) c = $.color(...$._namedColors[c]);
|
|
880
|
-
}
|
|
881
|
-
$.ctx.fillStyle = c.toString();
|
|
882
|
-
$.ctx.fillRect(0, 0, $.canvas.width, $.canvas.height);
|
|
883
|
-
}
|
|
884
|
-
$.ctx.restore();
|
|
885
|
-
};
|
|
886
|
-
|
|
887
900
|
$.line = (x0, y0, x1, y1) => {
|
|
888
901
|
if ($._doStroke) {
|
|
889
902
|
$._da && ((x0 *= $._da), (y0 *= $._da), (x1 *= $._da), (y1 *= $._da));
|
|
@@ -1217,8 +1230,8 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1217
1230
|
$.erase = function (fillAlpha = 255, strokeAlpha = 255) {
|
|
1218
1231
|
$.ctx.save();
|
|
1219
1232
|
$.ctx.globalCompositeOperation = 'destination-out';
|
|
1220
|
-
$.ctx.fillStyle = `
|
|
1221
|
-
$.ctx.strokeStyle = `
|
|
1233
|
+
$.ctx.fillStyle = `rgb(0 0 0 / ${fillAlpha / 255})`;
|
|
1234
|
+
$.ctx.strokeStyle = `rgb(0 0 0 / ${strokeAlpha / 255})`;
|
|
1222
1235
|
};
|
|
1223
1236
|
|
|
1224
1237
|
$.noErase = function () {
|
|
@@ -1868,7 +1881,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
1868
1881
|
|
|
1869
1882
|
$.createTextImage = (str, w, h) => {
|
|
1870
1883
|
genTextImage = true;
|
|
1871
|
-
img = $.text(str, 0, 0, w, h);
|
|
1884
|
+
let img = $.text(str, 0, 0, w, h);
|
|
1872
1885
|
genTextImage = false;
|
|
1873
1886
|
return img;
|
|
1874
1887
|
};
|
|
@@ -2095,21 +2108,29 @@ Q5.modules.ai = ($) => {
|
|
|
2095
2108
|
};
|
|
2096
2109
|
Q5.modules.color = ($, q) => {
|
|
2097
2110
|
$.RGB = $.RGBA = $._colorMode = 'rgb';
|
|
2098
|
-
$.
|
|
2111
|
+
$.HSL = 'hsl';
|
|
2112
|
+
$.HSB = 'hsb';
|
|
2099
2113
|
$.OKLCH = 'oklch';
|
|
2100
2114
|
|
|
2101
|
-
$.
|
|
2115
|
+
$.SRGB = 'srgb';
|
|
2116
|
+
$.DISPLAY_P3 = 'display-p3';
|
|
2117
|
+
|
|
2118
|
+
$.colorMode = (mode, format, gamut) => {
|
|
2102
2119
|
$._colorMode = mode;
|
|
2103
|
-
let srgb = $.canvas.colorSpace == 'srgb' ||
|
|
2120
|
+
let srgb = $.canvas.colorSpace == 'srgb' || gamut == 'srgb';
|
|
2104
2121
|
format ??= srgb ? 'integer' : 'float';
|
|
2105
2122
|
$._colorFormat = format == 'float' || format == 1 ? 1 : 255;
|
|
2106
2123
|
if (mode == 'oklch') {
|
|
2107
2124
|
q.Color = Q5.ColorOKLCH;
|
|
2125
|
+
} else if (mode == 'hsl') {
|
|
2126
|
+
q.Color = srgb ? Q5.ColorHSL : Q5.ColorHSL_P3;
|
|
2127
|
+
} else if (mode == 'hsb') {
|
|
2128
|
+
q.Color = srgb ? Q5.ColorHSB : Q5.ColorHSB_P3;
|
|
2108
2129
|
} else {
|
|
2109
2130
|
if ($._colorFormat == 255) {
|
|
2110
|
-
q.Color = srgb ? Q5.
|
|
2131
|
+
q.Color = srgb ? Q5.ColorRGB_8 : Q5.ColorRGB_P3_8;
|
|
2111
2132
|
} else {
|
|
2112
|
-
q.Color = srgb ? Q5.
|
|
2133
|
+
q.Color = srgb ? Q5.ColorRGB : Q5.ColorRGB_P3;
|
|
2113
2134
|
}
|
|
2114
2135
|
$._colorMode = 'rgb';
|
|
2115
2136
|
}
|
|
@@ -2203,7 +2224,8 @@ Q5.modules.color = ($, q) => {
|
|
|
2203
2224
|
|
|
2204
2225
|
$.lightness = (c) => {
|
|
2205
2226
|
if (c.l) return c.l;
|
|
2206
|
-
|
|
2227
|
+
let l = (0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * 100;
|
|
2228
|
+
return $._colorFormat == 255 ? l / 255 : l;
|
|
2207
2229
|
};
|
|
2208
2230
|
$.hue = (c) => {
|
|
2209
2231
|
if (c.h) return c.h;
|
|
@@ -2248,6 +2270,12 @@ Q5.Color = class {
|
|
|
2248
2270
|
constructor() {
|
|
2249
2271
|
this._q5Color = true;
|
|
2250
2272
|
}
|
|
2273
|
+
get alpha() {
|
|
2274
|
+
return this.a;
|
|
2275
|
+
}
|
|
2276
|
+
set alpha(v) {
|
|
2277
|
+
this.a = v;
|
|
2278
|
+
}
|
|
2251
2279
|
};
|
|
2252
2280
|
|
|
2253
2281
|
Q5.ColorOKLCH = class extends Q5.Color {
|
|
@@ -2289,15 +2317,9 @@ Q5.ColorOKLCH = class extends Q5.Color {
|
|
|
2289
2317
|
set hue(v) {
|
|
2290
2318
|
this.h = v;
|
|
2291
2319
|
}
|
|
2292
|
-
get alpha() {
|
|
2293
|
-
return this.a;
|
|
2294
|
-
}
|
|
2295
|
-
set alpha(v) {
|
|
2296
|
-
this.a = v;
|
|
2297
|
-
}
|
|
2298
2320
|
};
|
|
2299
2321
|
|
|
2300
|
-
Q5.
|
|
2322
|
+
Q5.ColorRGB = class extends Q5.Color {
|
|
2301
2323
|
constructor(r, g, b, a) {
|
|
2302
2324
|
super();
|
|
2303
2325
|
this.r = r;
|
|
@@ -2317,6 +2339,7 @@ Q5.ColorRGBA = class extends Q5.Color {
|
|
|
2317
2339
|
toString() {
|
|
2318
2340
|
return `color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`;
|
|
2319
2341
|
}
|
|
2342
|
+
|
|
2320
2343
|
get red() {
|
|
2321
2344
|
return this.r;
|
|
2322
2345
|
}
|
|
@@ -2335,22 +2358,16 @@ Q5.ColorRGBA = class extends Q5.Color {
|
|
|
2335
2358
|
set blue(v) {
|
|
2336
2359
|
this.b = v;
|
|
2337
2360
|
}
|
|
2338
|
-
get alpha() {
|
|
2339
|
-
return this.a;
|
|
2340
|
-
}
|
|
2341
|
-
set alpha(v) {
|
|
2342
|
-
this.a = v;
|
|
2343
|
-
}
|
|
2344
2361
|
};
|
|
2345
2362
|
|
|
2346
|
-
Q5.
|
|
2363
|
+
Q5.ColorRGB_P3 = class extends Q5.ColorRGB {
|
|
2347
2364
|
toString() {
|
|
2348
2365
|
return `color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`;
|
|
2349
2366
|
}
|
|
2350
2367
|
};
|
|
2351
2368
|
|
|
2352
|
-
// legacy 8-bit (0-255) integer color format
|
|
2353
|
-
Q5.
|
|
2369
|
+
// legacy 8-bit (0-255) integer color format, srgb color space
|
|
2370
|
+
Q5.ColorRGB_8 = class extends Q5.ColorRGB {
|
|
2354
2371
|
constructor(r, g, b, a) {
|
|
2355
2372
|
super(r, g, b, a ?? 255);
|
|
2356
2373
|
}
|
|
@@ -2373,7 +2390,7 @@ Q5.ColorRGBA_8 = class extends Q5.ColorRGBA {
|
|
|
2373
2390
|
};
|
|
2374
2391
|
|
|
2375
2392
|
// p3 10-bit color in integer color format, for backwards compatibility
|
|
2376
|
-
Q5.
|
|
2393
|
+
Q5.ColorRGB_P3_8 = class extends Q5.ColorRGB_8 {
|
|
2377
2394
|
constructor(r, g, b, a) {
|
|
2378
2395
|
super(r, g, b, a ?? 255);
|
|
2379
2396
|
this._edited = true;
|
|
@@ -2418,6 +2435,159 @@ Q5.ColorRGBA_P3_8 = class extends Q5.ColorRGBA {
|
|
|
2418
2435
|
return this._css;
|
|
2419
2436
|
}
|
|
2420
2437
|
};
|
|
2438
|
+
|
|
2439
|
+
Q5.ColorHSL = class extends Q5.Color {
|
|
2440
|
+
constructor(h, s, l, a) {
|
|
2441
|
+
super();
|
|
2442
|
+
this.h = h;
|
|
2443
|
+
this.s = s;
|
|
2444
|
+
this.l = l;
|
|
2445
|
+
this.a = a ?? 1;
|
|
2446
|
+
}
|
|
2447
|
+
get levels() {
|
|
2448
|
+
return [this.h, this.s, this.l, this.a];
|
|
2449
|
+
}
|
|
2450
|
+
equals(c) {
|
|
2451
|
+
return c && this.h == c.h && this.s == c.s && this.l == c.l && this.a == c.a;
|
|
2452
|
+
}
|
|
2453
|
+
isSameColor(c) {
|
|
2454
|
+
return c && this.h == c.h && this.s == c.s && this.l == c.l;
|
|
2455
|
+
}
|
|
2456
|
+
toString() {
|
|
2457
|
+
return `hsl(${this.h} ${this.s} ${this.l} / ${this.a})`;
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2460
|
+
get hue() {
|
|
2461
|
+
return this.h;
|
|
2462
|
+
}
|
|
2463
|
+
set hue(v) {
|
|
2464
|
+
this.h = v;
|
|
2465
|
+
}
|
|
2466
|
+
get saturation() {
|
|
2467
|
+
return this.s;
|
|
2468
|
+
}
|
|
2469
|
+
set saturation(v) {
|
|
2470
|
+
this.s = v;
|
|
2471
|
+
}
|
|
2472
|
+
get lightness() {
|
|
2473
|
+
return this.l;
|
|
2474
|
+
}
|
|
2475
|
+
set lightness(v) {
|
|
2476
|
+
this.l = v;
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
|
|
2480
|
+
Q5.ColorHSL_P3 = class extends Q5.ColorHSL {
|
|
2481
|
+
toString() {
|
|
2482
|
+
let o = Q5.HSLtoRGB(this.h, this.s, this.l);
|
|
2483
|
+
return `color(display-p3 ${o.join(' ')} / ${this.a})`;
|
|
2484
|
+
}
|
|
2485
|
+
};
|
|
2486
|
+
|
|
2487
|
+
Q5.ColorHSB = class extends Q5.ColorHSL {
|
|
2488
|
+
constructor(h, s, b, a) {
|
|
2489
|
+
super(h, s, b, a);
|
|
2490
|
+
delete this.l;
|
|
2491
|
+
this.b = b;
|
|
2492
|
+
}
|
|
2493
|
+
get levels() {
|
|
2494
|
+
return [this.h, this.s, this.b, this.a];
|
|
2495
|
+
}
|
|
2496
|
+
equals(c) {
|
|
2497
|
+
return c && this.h == c.h && this.s == c.s && this.b == c.b && this.a == c.a;
|
|
2498
|
+
}
|
|
2499
|
+
isSameColor(c) {
|
|
2500
|
+
return c && this.h == c.h && this.s == c.s && this.b == c.b;
|
|
2501
|
+
}
|
|
2502
|
+
toString() {
|
|
2503
|
+
let o = Q5.HSBtoHSL(this.h, this.s, this.b);
|
|
2504
|
+
return `hsl(${o.join(' ')} / ${this.a})`;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
get v() {
|
|
2508
|
+
return this.b;
|
|
2509
|
+
}
|
|
2510
|
+
set v(v) {
|
|
2511
|
+
this.b = v;
|
|
2512
|
+
}
|
|
2513
|
+
get brightness() {
|
|
2514
|
+
return this.b;
|
|
2515
|
+
}
|
|
2516
|
+
set brightness(v) {
|
|
2517
|
+
this.b = v;
|
|
2518
|
+
}
|
|
2519
|
+
get value() {
|
|
2520
|
+
return this.b;
|
|
2521
|
+
}
|
|
2522
|
+
set value(v) {
|
|
2523
|
+
this.b = v;
|
|
2524
|
+
}
|
|
2525
|
+
};
|
|
2526
|
+
|
|
2527
|
+
Q5.ColorHSB_P3 = class extends Q5.ColorHSB {
|
|
2528
|
+
toString() {
|
|
2529
|
+
let o = Q5.HSLtoRGB(...Q5.HSBtoHSL(this.h, this.s, this.b));
|
|
2530
|
+
return `color(display-p3 ${o.join(' ')} / ${this.a})`;
|
|
2531
|
+
}
|
|
2532
|
+
};
|
|
2533
|
+
|
|
2534
|
+
Q5.HSLtoRGB = (h, s, l) => {
|
|
2535
|
+
l /= 100;
|
|
2536
|
+
let m = (s / 100) * Math.min(l, 1 - l);
|
|
2537
|
+
let f = (n, k = (n + h / 30) % 12) => l - m * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
2538
|
+
return [f(0), f(8), f(4)];
|
|
2539
|
+
};
|
|
2540
|
+
|
|
2541
|
+
Q5.HSBtoHSL = (h, s, v, l = v * (1 - s / 200)) => [h, !l || l == 100 ? 0 : ((v - l) / Math.min(l, 100 - l)) * 100, l];
|
|
2542
|
+
|
|
2543
|
+
{
|
|
2544
|
+
const multiplyMatrices = (A, B) => [
|
|
2545
|
+
A[0] * B[0] + A[1] * B[1] + A[2] * B[2],
|
|
2546
|
+
A[3] * B[0] + A[4] * B[1] + A[5] * B[2],
|
|
2547
|
+
A[6] * B[0] + A[7] * B[1] + A[8] * B[2]
|
|
2548
|
+
];
|
|
2549
|
+
|
|
2550
|
+
const oklch2oklab = (l, c, h) => [
|
|
2551
|
+
l,
|
|
2552
|
+
isNaN(h) ? 0 : c * Math.cos((h * Math.PI) / 180),
|
|
2553
|
+
isNaN(h) ? 0 : c * Math.sin((h * Math.PI) / 180)
|
|
2554
|
+
];
|
|
2555
|
+
|
|
2556
|
+
const srgbLinear2rgb = (rgb) =>
|
|
2557
|
+
rgb.map((c) =>
|
|
2558
|
+
Math.max(
|
|
2559
|
+
0,
|
|
2560
|
+
Math.min(1, Math.abs(c) > 0.0031308 ? (c < 0 ? -1 : 1) * (1.055 * Math.abs(c) ** (1 / 2.4) - 0.055) : 12.92 * c)
|
|
2561
|
+
)
|
|
2562
|
+
);
|
|
2563
|
+
|
|
2564
|
+
const oklab2xyz = (lab) => {
|
|
2565
|
+
const LMSg = multiplyMatrices(
|
|
2566
|
+
[
|
|
2567
|
+
1, 0.3963377773761749, 0.2158037573099136, 1, -0.1055613458156586, -0.0638541728258133, 1, -0.0894841775298119,
|
|
2568
|
+
-1.2914855480194092
|
|
2569
|
+
],
|
|
2570
|
+
lab
|
|
2571
|
+
);
|
|
2572
|
+
return multiplyMatrices(
|
|
2573
|
+
[
|
|
2574
|
+
1.2268798758459243, -0.5578149944602171, 0.2813910456659647, -0.0405757452148008, 1.112286803280317,
|
|
2575
|
+
-0.0717110580655164, -0.0763729366746601, -0.4214933324022432, 1.5869240198367816
|
|
2576
|
+
],
|
|
2577
|
+
LMSg.map((val) => val ** 3)
|
|
2578
|
+
);
|
|
2579
|
+
};
|
|
2580
|
+
const xyz2rgbLinear = (xyz) =>
|
|
2581
|
+
multiplyMatrices(
|
|
2582
|
+
[
|
|
2583
|
+
3.2409699419045226, -1.537383177570094, -0.4986107602930034, -0.9692436362808796, 1.8759675015077202,
|
|
2584
|
+
0.04155505740717559, 0.05563007969699366, -0.20397695888897652, 1.0569715142428786
|
|
2585
|
+
],
|
|
2586
|
+
xyz
|
|
2587
|
+
);
|
|
2588
|
+
|
|
2589
|
+
Q5.OKLCHtoRGB = (l, c, h) => srgbLinear2rgb(xyz2rgbLinear(oklab2xyz(oklch2oklab(l, c, h))));
|
|
2590
|
+
}
|
|
2421
2591
|
Q5.modules.display = ($) => {
|
|
2422
2592
|
if (!$.canvas || $._scope == 'graphics') return;
|
|
2423
2593
|
|
|
@@ -4556,9 +4726,11 @@ struct Q5 {
|
|
|
4556
4726
|
$._pipelineConfigs = [];
|
|
4557
4727
|
$._pipelines = [];
|
|
4558
4728
|
$._buffers = [];
|
|
4729
|
+
$._prevFramePL = 0;
|
|
4559
4730
|
$._framePL = 0;
|
|
4560
4731
|
|
|
4561
4732
|
// local variables used for slightly better performance
|
|
4733
|
+
|
|
4562
4734
|
// stores pipeline shifts and vertex counts/image indices
|
|
4563
4735
|
let drawStack = ($.drawStack = []);
|
|
4564
4736
|
|
|
@@ -4595,7 +4767,7 @@ struct Q5 {
|
|
|
4595
4767
|
$.bindGroupLayouts = [mainLayout];
|
|
4596
4768
|
|
|
4597
4769
|
let uniformBuffer = Q5.device.createBuffer({
|
|
4598
|
-
size: 64,
|
|
4770
|
+
size: 64,
|
|
4599
4771
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
4600
4772
|
});
|
|
4601
4773
|
|
|
@@ -4695,7 +4867,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4695
4867
|
fragment: {
|
|
4696
4868
|
module: frameShader,
|
|
4697
4869
|
entryPoint: 'fragMain',
|
|
4698
|
-
targets: [{ format
|
|
4870
|
+
targets: [{ format }]
|
|
4699
4871
|
},
|
|
4700
4872
|
primitive: { topology: 'triangle-strip' },
|
|
4701
4873
|
multisample: { count: 4 }
|
|
@@ -4723,27 +4895,24 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4723
4895
|
createMainView();
|
|
4724
4896
|
};
|
|
4725
4897
|
|
|
4726
|
-
$.pixelDensity = (v) => {
|
|
4727
|
-
if (!v || v == $._pixelDensity) return $._pixelDensity;
|
|
4728
|
-
$._pixelDensity = v;
|
|
4729
|
-
$._setCanvasSize(c.w, c.h);
|
|
4730
|
-
createMainView();
|
|
4731
|
-
return v;
|
|
4732
|
-
};
|
|
4733
|
-
|
|
4734
|
-
// current color index, used to associate a vertex with a color
|
|
4735
4898
|
let addColor = (r, g, b, a = 1) => {
|
|
4736
|
-
if (typeof r == 'string'
|
|
4737
|
-
|
|
4899
|
+
if (typeof r == 'string' || $._colorMode != 'rgb') {
|
|
4900
|
+
r = $.color(r, g, b, a);
|
|
4901
|
+
} else if (b == undefined) {
|
|
4738
4902
|
// grayscale mode `fill(1, 0.5)`
|
|
4739
4903
|
a = g ?? 1;
|
|
4740
4904
|
g = b = r;
|
|
4741
4905
|
}
|
|
4742
4906
|
if (r._q5Color) {
|
|
4743
|
-
|
|
4744
|
-
b =
|
|
4745
|
-
|
|
4746
|
-
|
|
4907
|
+
let c = r;
|
|
4908
|
+
if (c.r) ({ r, g, b, a } = c);
|
|
4909
|
+
else {
|
|
4910
|
+
a = c.a;
|
|
4911
|
+
if (c.c != undefined) c = Q5.OKLCHtoRGB(c.l, c.c, c.h);
|
|
4912
|
+
else if (c.l != undefined) c = Q5.HSLtoRGB(c.h, c.s, c.l);
|
|
4913
|
+
else c = Q5.HSLtoRGB(...Q5.HSBtoHSL(c.h, c.s, c.b));
|
|
4914
|
+
[r, g, b] = c;
|
|
4915
|
+
}
|
|
4747
4916
|
}
|
|
4748
4917
|
|
|
4749
4918
|
let cs = colorStack,
|
|
@@ -4776,7 +4945,6 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4776
4945
|
$._tint = colorIndex;
|
|
4777
4946
|
};
|
|
4778
4947
|
$.opacity = (a) => ($._globalAlpha = a);
|
|
4779
|
-
|
|
4780
4948
|
$.noFill = () => ($._doFill = false);
|
|
4781
4949
|
$.noStroke = () => ($._doStroke = false);
|
|
4782
4950
|
$.noTint = () => ($._tint = 1);
|
|
@@ -4784,6 +4952,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4784
4952
|
$._strokeWeight = 1;
|
|
4785
4953
|
$._hsw = 0.5;
|
|
4786
4954
|
$._scaledSW = 1;
|
|
4955
|
+
|
|
4787
4956
|
$.strokeWeight = (v) => {
|
|
4788
4957
|
v = Math.abs(v);
|
|
4789
4958
|
$._strokeWeight = v;
|
|
@@ -4934,7 +5103,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
4934
5103
|
$._matrixDirty = true;
|
|
4935
5104
|
};
|
|
4936
5105
|
|
|
4937
|
-
//
|
|
5106
|
+
// saves the current matrix state
|
|
4938
5107
|
$._saveMatrix = () => {
|
|
4939
5108
|
transforms.set(matrix, matrices.length * MATRIX_SIZE);
|
|
4940
5109
|
$._matrixIndex = matrices.length;
|
|
@@ -5066,13 +5235,28 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5066
5235
|
};
|
|
5067
5236
|
|
|
5068
5237
|
let shouldClear;
|
|
5238
|
+
|
|
5069
5239
|
$.clear = () => {
|
|
5070
5240
|
shouldClear = true;
|
|
5071
5241
|
};
|
|
5072
5242
|
|
|
5073
|
-
$.
|
|
5074
|
-
|
|
5243
|
+
$.background = (r, g, b, a) => {
|
|
5244
|
+
$.push();
|
|
5245
|
+
$.resetMatrix();
|
|
5246
|
+
if (r.canvas) {
|
|
5247
|
+
let img = r;
|
|
5248
|
+
$._imageMode = 'corner';
|
|
5249
|
+
$.image(img, -c.hw, -c.hh, c.w, c.h);
|
|
5250
|
+
} else {
|
|
5251
|
+
$._rectMode = 'corner';
|
|
5252
|
+
$.fill(r, g, b, a);
|
|
5253
|
+
$._doStroke = false;
|
|
5254
|
+
$.rect(-c.hw, -c.hh, c.w, c.h);
|
|
5255
|
+
}
|
|
5256
|
+
$.pop();
|
|
5257
|
+
};
|
|
5075
5258
|
|
|
5259
|
+
$._beginRender = () => {
|
|
5076
5260
|
// swap the frame textures
|
|
5077
5261
|
const temp = frameA;
|
|
5078
5262
|
frameA = frameB;
|
|
@@ -5103,7 +5287,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5103
5287
|
});
|
|
5104
5288
|
|
|
5105
5289
|
if (!shouldClear) {
|
|
5106
|
-
pass.setPipeline($._pipelines[
|
|
5290
|
+
pass.setPipeline($._pipelines[$._prevFramePL]);
|
|
5107
5291
|
pass.setBindGroup(0, frameBindGroup);
|
|
5108
5292
|
pass.draw(4);
|
|
5109
5293
|
}
|
|
@@ -5120,6 +5304,8 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5120
5304
|
new Float32Array(transformBuffer.getMappedRange()).set(transforms.slice(0, matrices.length * MATRIX_SIZE));
|
|
5121
5305
|
transformBuffer.unmap();
|
|
5122
5306
|
|
|
5307
|
+
$._buffers.push(transformBuffer);
|
|
5308
|
+
|
|
5123
5309
|
let colorsBuffer = Q5.device.createBuffer({
|
|
5124
5310
|
size: colorStackIndex * 4,
|
|
5125
5311
|
usage: GPUBufferUsage.STORAGE,
|
|
@@ -5129,6 +5315,8 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5129
5315
|
new Float32Array(colorsBuffer.getMappedRange()).set(colorStack.slice(0, colorStackIndex));
|
|
5130
5316
|
colorsBuffer.unmap();
|
|
5131
5317
|
|
|
5318
|
+
$._buffers.push(colorsBuffer);
|
|
5319
|
+
|
|
5132
5320
|
$._uniforms = [
|
|
5133
5321
|
$.width,
|
|
5134
5322
|
$.height,
|
|
@@ -5189,7 +5377,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5189
5377
|
pass.setBindGroup(1, $._textureBindGroups[v]);
|
|
5190
5378
|
pass.draw(4, 1, imageVertOffset);
|
|
5191
5379
|
imageVertOffset += 4;
|
|
5192
|
-
} else
|
|
5380
|
+
} else {
|
|
5193
5381
|
// draw a shape
|
|
5194
5382
|
// v is the number of vertices
|
|
5195
5383
|
pass.draw(v, 1, drawVertOffset);
|
|
@@ -5198,7 +5386,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5198
5386
|
}
|
|
5199
5387
|
};
|
|
5200
5388
|
|
|
5201
|
-
$._finishRender = () => {
|
|
5389
|
+
$._finishRender = async () => {
|
|
5202
5390
|
pass.end();
|
|
5203
5391
|
|
|
5204
5392
|
pass = encoder.beginRenderPass({
|
|
@@ -5228,6 +5416,7 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5228
5416
|
pass.end();
|
|
5229
5417
|
|
|
5230
5418
|
Q5.device.queue.submit([encoder.finish()]);
|
|
5419
|
+
$._pass = pass = encoder = null;
|
|
5231
5420
|
|
|
5232
5421
|
// destroy buffers
|
|
5233
5422
|
Q5.device.queue.onSubmittedWorkDone().then(() => {
|
|
@@ -5235,8 +5424,6 @@ fn fragMain(f: FragParams ) -> @location(0) vec4f {
|
|
|
5235
5424
|
$._buffers = [];
|
|
5236
5425
|
});
|
|
5237
5426
|
|
|
5238
|
-
$._pass = pass = encoder = null;
|
|
5239
|
-
|
|
5240
5427
|
// clear the stacks for the next frame
|
|
5241
5428
|
drawStack.splice(0, drawStack.length);
|
|
5242
5429
|
colorIndex = 1;
|
|
@@ -5886,22 +6073,6 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
5886
6073
|
$.endShape(true);
|
|
5887
6074
|
};
|
|
5888
6075
|
|
|
5889
|
-
$.background = (r, g, b, a) => {
|
|
5890
|
-
$.push();
|
|
5891
|
-
$.resetMatrix();
|
|
5892
|
-
if (r.canvas) {
|
|
5893
|
-
let img = r;
|
|
5894
|
-
$._imageMode = 'corner';
|
|
5895
|
-
$.image(img, -c.hw, -c.hh, c.w, c.h);
|
|
5896
|
-
} else {
|
|
5897
|
-
$._rectMode = 'corner';
|
|
5898
|
-
$.fill(r, g, b, a);
|
|
5899
|
-
$._doStroke = false;
|
|
5900
|
-
$.rect(-c.hw, -c.hh, c.w, c.h);
|
|
5901
|
-
}
|
|
5902
|
-
$.pop();
|
|
5903
|
-
};
|
|
5904
|
-
|
|
5905
6076
|
$._hooks.preRender.push(() => {
|
|
5906
6077
|
$._pass.setPipeline($._pipelines[1]);
|
|
5907
6078
|
|
|
@@ -6231,9 +6402,11 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6231
6402
|
|
|
6232
6403
|
$.createGraphics = (w, h, opt) => {
|
|
6233
6404
|
let g = _createGraphics(w, h, opt);
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6405
|
+
if (g.canvas.renderer == 'webgpu') {
|
|
6406
|
+
$._addTexture(g, g._frameA);
|
|
6407
|
+
$._addTexture(g, g._frameB);
|
|
6408
|
+
g._beginRender();
|
|
6409
|
+
}
|
|
6237
6410
|
return g;
|
|
6238
6411
|
};
|
|
6239
6412
|
|
|
@@ -6720,6 +6893,7 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
6720
6893
|
leadPercent = 1.25;
|
|
6721
6894
|
|
|
6722
6895
|
$.textFont = (fontName) => {
|
|
6896
|
+
if (!fontName) return $._font;
|
|
6723
6897
|
if (typeof fontName != 'string') fontName = fontName.family;
|
|
6724
6898
|
let font = fonts[fontName];
|
|
6725
6899
|
if (font) $._font = font;
|
|
@@ -7049,6 +7223,7 @@ Q5.renderers.webgpu.shaders = ($) => {
|
|
|
7049
7223
|
|
|
7050
7224
|
let pl = plCounters[type];
|
|
7051
7225
|
$._pipelines[pl] = Q5.device.createRenderPipeline(config);
|
|
7226
|
+
$._pipelines[pl].shader = shader;
|
|
7052
7227
|
shader.pipelineIndex = pl;
|
|
7053
7228
|
|
|
7054
7229
|
plCounters[type]++;
|
|
@@ -7063,15 +7238,17 @@ Q5.renderers.webgpu.shaders = ($) => {
|
|
|
7063
7238
|
$.createTextShader = (code) => $._createShader(code, 'text');
|
|
7064
7239
|
|
|
7065
7240
|
$.shader = (shader) => {
|
|
7066
|
-
|
|
7241
|
+
if (shader.applyBeforeDraw) $._prevFramePL = shader.pipelineIndex;
|
|
7242
|
+
else $['_' + shader.type + 'PL'] = shader.pipelineIndex;
|
|
7067
7243
|
};
|
|
7068
7244
|
|
|
7069
7245
|
$.resetShader = (type = 'shapes') => {
|
|
7246
|
+
if (type == 'frame') $._prevFramePL = 0;
|
|
7070
7247
|
$['_' + type + 'PL'] = pipelineTypes.indexOf(type);
|
|
7071
7248
|
};
|
|
7072
7249
|
|
|
7073
7250
|
$.resetShaders = () => {
|
|
7074
|
-
$._framePL = 0;
|
|
7251
|
+
$._prevFramePL = $._framePL = 0;
|
|
7075
7252
|
$._shapesPL = 1;
|
|
7076
7253
|
$._imagePL = 2;
|
|
7077
7254
|
$._videoPL = 3;
|