q5 2.7.6 → 2.9.0
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/.prettierignore +1 -0
- package/package.json +1 -1
- package/q5.d.ts +260 -155
- package/q5.js +122 -77
- package/q5.min.js +2 -2
- package/q5js_icon.png +0 -0
- package/src/q5-2d-canvas.js +8 -2
- package/src/q5-2d-drawing.js +14 -13
- package/src/q5-2d-image.js +18 -10
- package/src/q5-ai.js +3 -2
- package/src/q5-canvas.js +19 -0
- package/src/q5-core.js +8 -1
- package/src/q5-display.js +2 -2
- package/src/q5-math.js +1 -1
- package/src/q5-webgpu-canvas.js +2 -2
- package/src/q5-webgpu-drawing.js +40 -39
- package/src/q5-webgpu-image.js +8 -6
package/q5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* q5.js
|
|
3
|
-
* @version 2.
|
|
3
|
+
* @version 2.9
|
|
4
4
|
* @author quinton-ashley, Tezumie, and LingDong-
|
|
5
5
|
* @license LGPL-3.0
|
|
6
6
|
* @class Q5
|
|
@@ -290,6 +290,13 @@ if (Q5._nodejs) global.p5 ??= global.Q5 = Q5;
|
|
|
290
290
|
else if (typeof window == 'object') window.p5 ??= window.Q5 = Q5;
|
|
291
291
|
else global.window = 0;
|
|
292
292
|
|
|
293
|
+
function createCanvas(w, h, opt) {
|
|
294
|
+
if (!Q5._hasGlobal) {
|
|
295
|
+
let q = new Q5();
|
|
296
|
+
q.createCanvas(w, h, opt);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
293
300
|
if (typeof document == 'object') {
|
|
294
301
|
document.addEventListener('DOMContentLoaded', () => {
|
|
295
302
|
if (!Q5._hasGlobal) new Q5('auto');
|
|
@@ -486,6 +493,8 @@ Q5.modules.canvas = ($, q) => {
|
|
|
486
493
|
c.h = h = Math.ceil(h);
|
|
487
494
|
c.hw = w / 2;
|
|
488
495
|
c.hh = h / 2;
|
|
496
|
+
|
|
497
|
+
// changes the actual size of the canvas
|
|
489
498
|
c.width = Math.ceil(w * $._pixelDensity);
|
|
490
499
|
c.height = Math.ceil(h * $._pixelDensity);
|
|
491
500
|
|
|
@@ -498,6 +507,17 @@ Q5.modules.canvas = ($, q) => {
|
|
|
498
507
|
else $._adjustDisplay();
|
|
499
508
|
};
|
|
500
509
|
|
|
510
|
+
$._setImageSize = (w, h) => {
|
|
511
|
+
q.width = c.w = w;
|
|
512
|
+
q.height = c.h = h;
|
|
513
|
+
c.hw = w / 2;
|
|
514
|
+
c.hh = h / 2;
|
|
515
|
+
|
|
516
|
+
// changes the actual size of the canvas
|
|
517
|
+
c.width = Math.ceil(w * $._pixelDensity);
|
|
518
|
+
c.height = Math.ceil(h * $._pixelDensity);
|
|
519
|
+
};
|
|
520
|
+
|
|
501
521
|
if ($._scope == 'image') return;
|
|
502
522
|
|
|
503
523
|
if (c && $._scope != 'graphics') {
|
|
@@ -552,6 +572,12 @@ Q5.modules.canvas = ($, q) => {
|
|
|
552
572
|
return v;
|
|
553
573
|
};
|
|
554
574
|
|
|
575
|
+
$.defaultImageScale = (scale) => {
|
|
576
|
+
if (!scale) return $._defaultImageScale;
|
|
577
|
+
return ($._defaultImageScale = scale);
|
|
578
|
+
};
|
|
579
|
+
$.defaultImageScale(0.5);
|
|
580
|
+
|
|
555
581
|
$.flexibleCanvas = (unit = 400) => {
|
|
556
582
|
if (unit) {
|
|
557
583
|
$._da = c.width / (unit * $._pixelDensity);
|
|
@@ -705,6 +731,10 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
705
731
|
$.ctx.rotate(r);
|
|
706
732
|
};
|
|
707
733
|
$.scale = (x, y) => {
|
|
734
|
+
if (x.x) {
|
|
735
|
+
y = x.y;
|
|
736
|
+
x = x.x;
|
|
737
|
+
}
|
|
708
738
|
y ??= x;
|
|
709
739
|
$.ctx.scale(x, y);
|
|
710
740
|
};
|
|
@@ -712,8 +742,10 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
712
742
|
$.shearX = (ang) => $.ctx.transform(1, 0, $.tan(ang), 1, 0, 0);
|
|
713
743
|
$.shearY = (ang) => $.ctx.transform(1, $.tan(ang), 0, 1, 0, 0);
|
|
714
744
|
$.resetMatrix = () => {
|
|
715
|
-
$.ctx
|
|
716
|
-
|
|
745
|
+
if ($.ctx) {
|
|
746
|
+
$.ctx.resetTransform();
|
|
747
|
+
$.scale($._pixelDensity);
|
|
748
|
+
}
|
|
717
749
|
};
|
|
718
750
|
|
|
719
751
|
$.pushMatrix = () => $.ctx.save();
|
|
@@ -776,6 +808,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
776
808
|
$.background = function (c) {
|
|
777
809
|
$.ctx.save();
|
|
778
810
|
$.ctx.resetTransform();
|
|
811
|
+
$.ctx.globalAlpha = 1;
|
|
779
812
|
if (c.canvas) $.image(c, 0, 0, $.canvas.width, $.canvas.height);
|
|
780
813
|
else {
|
|
781
814
|
if (Q5.Color && !c._q5Color) {
|
|
@@ -888,20 +921,20 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
888
921
|
} else $.ellipse(x, y, d, d);
|
|
889
922
|
};
|
|
890
923
|
$.point = (x, y) => {
|
|
891
|
-
if (
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
924
|
+
if ($._doStroke) {
|
|
925
|
+
if (x.x) {
|
|
926
|
+
y = x.y;
|
|
927
|
+
x = x.x;
|
|
928
|
+
}
|
|
929
|
+
if ($._da) {
|
|
930
|
+
x *= $._da;
|
|
931
|
+
y *= $._da;
|
|
932
|
+
}
|
|
933
|
+
$.ctx.beginPath();
|
|
934
|
+
$.ctx.moveTo(x, y);
|
|
935
|
+
$.ctx.lineTo(x, y);
|
|
936
|
+
$.ctx.stroke();
|
|
898
937
|
}
|
|
899
|
-
$.ctx.save();
|
|
900
|
-
$.ctx.beginPath();
|
|
901
|
-
$.ctx.arc(x, y, $.ctx.lineWidth / 2, 0, $.TAU);
|
|
902
|
-
$.ctx.fillStyle = $.ctx.strokeStyle;
|
|
903
|
-
$.ctx.fill();
|
|
904
|
-
$.ctx.restore();
|
|
905
938
|
};
|
|
906
939
|
function rect(x, y, w, h) {
|
|
907
940
|
if ($._da) {
|
|
@@ -1218,9 +1251,15 @@ Q5.renderers.q2d.image = ($, q) => {
|
|
|
1218
1251
|
opt = typeof last == 'object' ? last : null;
|
|
1219
1252
|
|
|
1220
1253
|
let g = $.createImage(1, 1, opt);
|
|
1254
|
+
let pd = (g._pixelDensity = opt?.pixelDensity || 1);
|
|
1221
1255
|
|
|
1222
1256
|
function loaded(img) {
|
|
1223
|
-
g.
|
|
1257
|
+
g.canvas.defaultWidth = img.width * $._defaultImageScale;
|
|
1258
|
+
g.canvas.defaultHeight = img.height * $._defaultImageScale;
|
|
1259
|
+
g.naturalWidth = img.naturalWidth;
|
|
1260
|
+
g.naturalHeight = img.naturalHeight;
|
|
1261
|
+
g._setImageSize(Math.ceil(g.naturalWidth / pd), Math.ceil(g.naturalHeight / pd));
|
|
1262
|
+
|
|
1224
1263
|
g.ctx.drawImage(img, 0, 0);
|
|
1225
1264
|
q._preloadCount--;
|
|
1226
1265
|
if (cb) cb(g);
|
|
@@ -1237,7 +1276,7 @@ Q5.renderers.q2d.image = ($, q) => {
|
|
|
1237
1276
|
let img = new window.Image();
|
|
1238
1277
|
img.src = url;
|
|
1239
1278
|
img.crossOrigin = 'Anonymous';
|
|
1240
|
-
img._pixelDensity =
|
|
1279
|
+
img._pixelDensity = pd;
|
|
1241
1280
|
img.onload = () => loaded(img);
|
|
1242
1281
|
img.onerror = (e) => {
|
|
1243
1282
|
q._preloadCount--;
|
|
@@ -1254,8 +1293,9 @@ Q5.renderers.q2d.image = ($, q) => {
|
|
|
1254
1293
|
if (Q5._createNodeJSCanvas) {
|
|
1255
1294
|
drawable = drawable.context.canvas;
|
|
1256
1295
|
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1296
|
+
|
|
1297
|
+
dw ??= drawable.defaultWidth || drawable.width || img.videoWidth;
|
|
1298
|
+
dh ??= drawable.defaultHeight || drawable.height || img.videoHeight;
|
|
1259
1299
|
if ($._imageMode == 'center') {
|
|
1260
1300
|
dx -= dw * 0.5;
|
|
1261
1301
|
dy -= dh * 0.5;
|
|
@@ -1316,15 +1356,16 @@ Q5.renderers.q2d.image = ($, q) => {
|
|
|
1316
1356
|
|
|
1317
1357
|
if ($._scope == 'image') {
|
|
1318
1358
|
$.resize = (w, h) => {
|
|
1319
|
-
let
|
|
1359
|
+
let c = $.canvas;
|
|
1360
|
+
let o = new $._OffscreenCanvas(c.width, c.height);
|
|
1320
1361
|
let tmpCtx = o.getContext('2d', {
|
|
1321
|
-
colorSpace:
|
|
1362
|
+
colorSpace: c.colorSpace
|
|
1322
1363
|
});
|
|
1323
|
-
tmpCtx.drawImage(
|
|
1324
|
-
$.
|
|
1364
|
+
tmpCtx.drawImage(c, 0, 0);
|
|
1365
|
+
$._setImageSize(w, h);
|
|
1325
1366
|
|
|
1326
|
-
$.ctx.clearRect(0, 0,
|
|
1327
|
-
$.ctx.drawImage(o, 0, 0,
|
|
1367
|
+
$.ctx.clearRect(0, 0, c.width, c.height);
|
|
1368
|
+
$.ctx.drawImage(o, 0, 0, c.width, c.height);
|
|
1328
1369
|
};
|
|
1329
1370
|
}
|
|
1330
1371
|
|
|
@@ -1721,8 +1762,9 @@ Q5.modules.ai = ($) => {
|
|
|
1721
1762
|
}
|
|
1722
1763
|
while (stackLines[idx].indexOf('q5') >= 0) idx++;
|
|
1723
1764
|
|
|
1724
|
-
let
|
|
1725
|
-
|
|
1765
|
+
let errFile = stackLines[idx].split(sep).at(-1);
|
|
1766
|
+
if (errFile.startsWith('blob:')) errFile = errFile.slice(5);
|
|
1767
|
+
let parts = errFile.split(':');
|
|
1726
1768
|
let lineNum = parseInt(parts.at(-2));
|
|
1727
1769
|
if (askAI) lineNum++;
|
|
1728
1770
|
parts[3] = parts[3].split(')')[0];
|
|
@@ -2085,7 +2127,7 @@ main {
|
|
|
2085
2127
|
if ($.noSmooth) $.noSmooth();
|
|
2086
2128
|
if ($.textFont) $.textFont('monospace');
|
|
2087
2129
|
}
|
|
2088
|
-
if (c.displayMode == 'normal') {
|
|
2130
|
+
if (c.displayMode == 'default' || c.displayMode == 'normal') {
|
|
2089
2131
|
p.classList.remove('q5-centered', 'q5-maxed', 'q5-fullscreen');
|
|
2090
2132
|
s.width = c.w * c.displayScale + 'px';
|
|
2091
2133
|
s.height = c.h * c.displayScale + 'px';
|
|
@@ -2110,7 +2152,7 @@ main {
|
|
|
2110
2152
|
}
|
|
2111
2153
|
};
|
|
2112
2154
|
|
|
2113
|
-
$.displayMode = (displayMode = 'normal', renderQuality = '
|
|
2155
|
+
$.displayMode = (displayMode = 'normal', renderQuality = 'smooth', displayScale = 1) => {
|
|
2114
2156
|
if (typeof displayScale == 'string') {
|
|
2115
2157
|
displayScale = parseFloat(displayScale.slice(1));
|
|
2116
2158
|
}
|
|
@@ -2313,7 +2355,7 @@ Q5.modules.math = ($, q) => {
|
|
|
2313
2355
|
$.abs = Math.abs;
|
|
2314
2356
|
$.ceil = Math.ceil;
|
|
2315
2357
|
$.exp = Math.exp;
|
|
2316
|
-
$.floor = Math.floor;
|
|
2358
|
+
$.floor = $.int = Math.floor;
|
|
2317
2359
|
$.loge = Math.log;
|
|
2318
2360
|
$.mag = Math.hypot;
|
|
2319
2361
|
$.max = Math.max;
|
|
@@ -3590,8 +3632,8 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3590
3632
|
// v is the texture index
|
|
3591
3633
|
pass.setBindGroup(2, $._textureBindGroups[v]);
|
|
3592
3634
|
}
|
|
3593
|
-
pass.draw(
|
|
3594
|
-
imageVertOffset +=
|
|
3635
|
+
pass.draw(4, 1, imageVertOffset);
|
|
3636
|
+
imageVertOffset += 4;
|
|
3595
3637
|
} else if (curPipelineIndex == 2) {
|
|
3596
3638
|
let o = drawStack[i + 2];
|
|
3597
3639
|
pass.setBindGroup(2, $._fonts[o].bindGroup);
|
|
@@ -3746,29 +3788,6 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
3746
3788
|
vertIndex = i;
|
|
3747
3789
|
};
|
|
3748
3790
|
|
|
3749
|
-
const addTri = (x1, y1, x2, y2, x3, y3, ci, ti) => {
|
|
3750
|
-
let v = vertexStack,
|
|
3751
|
-
i = vertIndex;
|
|
3752
|
-
|
|
3753
|
-
v[i++] = x1;
|
|
3754
|
-
v[i++] = y1;
|
|
3755
|
-
v[i++] = ci;
|
|
3756
|
-
v[i++] = ti;
|
|
3757
|
-
|
|
3758
|
-
v[i++] = x2;
|
|
3759
|
-
v[i++] = y2;
|
|
3760
|
-
v[i++] = ci;
|
|
3761
|
-
v[i++] = ti;
|
|
3762
|
-
|
|
3763
|
-
v[i++] = x3;
|
|
3764
|
-
v[i++] = y3;
|
|
3765
|
-
v[i++] = ci;
|
|
3766
|
-
v[i++] = ti;
|
|
3767
|
-
|
|
3768
|
-
vertIndex = i;
|
|
3769
|
-
drawStack.push(0, 3);
|
|
3770
|
-
};
|
|
3771
|
-
|
|
3772
3791
|
const addRect = (x1, y1, x2, y2, x3, y3, x4, y4, ci, ti) => {
|
|
3773
3792
|
let v = vertexStack,
|
|
3774
3793
|
i = vertIndex;
|
|
@@ -3852,21 +3871,40 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
3852
3871
|
if ($._doStroke) {
|
|
3853
3872
|
ci = $._strokeIndex;
|
|
3854
3873
|
|
|
3855
|
-
//
|
|
3874
|
+
// stroke weight adjustment
|
|
3856
3875
|
let sw = $._strokeWeight / 2;
|
|
3857
|
-
let to = t + sw,
|
|
3858
|
-
bo = b - sw,
|
|
3859
|
-
lo = l - sw,
|
|
3860
|
-
ro = r + sw;
|
|
3861
|
-
|
|
3862
|
-
// stroke is simply a bigger rectangle drawn first
|
|
3863
|
-
addRect(lo, to, ro, to, ro, bo, lo, bo, ci, ti);
|
|
3864
3876
|
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3877
|
+
if ($._doFill) {
|
|
3878
|
+
// existing behavior: draw stroke as one big rectangle
|
|
3879
|
+
let to = t + sw,
|
|
3880
|
+
bo = b - sw,
|
|
3881
|
+
lo = l - sw,
|
|
3882
|
+
ro = r + sw;
|
|
3883
|
+
|
|
3884
|
+
// draw stroke rectangle
|
|
3885
|
+
addRect(lo, to, ro, to, ro, bo, lo, bo, ci, ti);
|
|
3886
|
+
|
|
3887
|
+
// adjust inner rectangle coordinates
|
|
3888
|
+
t -= sw;
|
|
3889
|
+
b += sw;
|
|
3890
|
+
l += sw;
|
|
3891
|
+
r -= sw;
|
|
3892
|
+
} else {
|
|
3893
|
+
// new behavior: draw stroke as four rectangles (sides)
|
|
3894
|
+
let lsw = l - sw,
|
|
3895
|
+
rsw = r + sw,
|
|
3896
|
+
tsw = t + sw,
|
|
3897
|
+
bsw = b - sw,
|
|
3898
|
+
lpsw = l + sw,
|
|
3899
|
+
rpsw = r - sw,
|
|
3900
|
+
tpsw = t - sw,
|
|
3901
|
+
bpsw = b + sw;
|
|
3902
|
+
|
|
3903
|
+
addRect(lsw, tpsw, rsw, tpsw, rsw, tsw, lsw, tsw, ci, ti); // top
|
|
3904
|
+
addRect(lsw, bsw, rsw, bsw, rsw, bpsw, lsw, bpsw, ci, ti); // bottom
|
|
3905
|
+
addRect(lsw, tsw, lpsw, tsw, lpsw, bsw, lsw, bsw, ci, ti); // left
|
|
3906
|
+
addRect(rpsw, tsw, rsw, tsw, rsw, bsw, rpsw, bsw, ci, ti); // right
|
|
3907
|
+
}
|
|
3870
3908
|
}
|
|
3871
3909
|
|
|
3872
3910
|
if ($._doFill) {
|
|
@@ -4041,11 +4079,16 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
|
|
|
4041
4079
|
$.vertex(x1, y1);
|
|
4042
4080
|
$.vertex(x2, y2);
|
|
4043
4081
|
$.vertex(x3, y3);
|
|
4044
|
-
$.endShape();
|
|
4082
|
+
$.endShape(true);
|
|
4045
4083
|
};
|
|
4046
4084
|
|
|
4047
4085
|
$.quad = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
4048
|
-
|
|
4086
|
+
$.beginShape();
|
|
4087
|
+
$.vertex(x1, y1);
|
|
4088
|
+
$.vertex(x2, y2);
|
|
4089
|
+
$.vertex(x3, y3);
|
|
4090
|
+
$.vertex(x4, y4);
|
|
4091
|
+
$.endShape(true);
|
|
4049
4092
|
};
|
|
4050
4093
|
|
|
4051
4094
|
$.background = (r, g, b, a) => {
|
|
@@ -4178,7 +4221,7 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4178
4221
|
entryPoint: 'fragmentMain',
|
|
4179
4222
|
targets: [{ format: 'bgra8unorm', blend: $.blendConfigs.normal }]
|
|
4180
4223
|
},
|
|
4181
|
-
primitive: { topology: 'triangle-
|
|
4224
|
+
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
4182
4225
|
multisample: { count: 4 }
|
|
4183
4226
|
};
|
|
4184
4227
|
|
|
@@ -4210,7 +4253,6 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4210
4253
|
{
|
|
4211
4254
|
texture,
|
|
4212
4255
|
colorSpace: $.canvas.colorSpace
|
|
4213
|
-
// premultipliedAlpha: true
|
|
4214
4256
|
},
|
|
4215
4257
|
textureSize
|
|
4216
4258
|
);
|
|
@@ -4242,6 +4284,11 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4242
4284
|
const img = new Image();
|
|
4243
4285
|
img.crossOrigin = 'Anonymous';
|
|
4244
4286
|
img.onload = () => {
|
|
4287
|
+
// calculate the default width and height that the image
|
|
4288
|
+
// should be drawn at if the user doesn't specify a display size
|
|
4289
|
+
img.defaultWidth = img.width * $._defaultImageScale;
|
|
4290
|
+
img.defaultHeight = img.height * $._defaultImageScale;
|
|
4291
|
+
|
|
4245
4292
|
$._createTexture(img);
|
|
4246
4293
|
q._preloadCount--;
|
|
4247
4294
|
};
|
|
@@ -4258,8 +4305,8 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4258
4305
|
if ($._matrixDirty) $._saveMatrix();
|
|
4259
4306
|
let ti = $._transformIndex;
|
|
4260
4307
|
|
|
4261
|
-
w ??= img.
|
|
4262
|
-
h ??= img.
|
|
4308
|
+
w ??= img.defaultWidth;
|
|
4309
|
+
h ??= img.defaultHeight;
|
|
4263
4310
|
|
|
4264
4311
|
let [l, r, t, b] = $._calcBox(x, y, w, h, $._imageMode);
|
|
4265
4312
|
|
|
@@ -4268,8 +4315,6 @@ fn fragmentMain(@location(0) texCoord: vec2f) -> @location(0) vec4f {
|
|
|
4268
4315
|
l, t, 0, 0, ti,
|
|
4269
4316
|
r, t, 1, 0, ti,
|
|
4270
4317
|
l, b, 0, 1, ti,
|
|
4271
|
-
r, t, 1, 0, ti,
|
|
4272
|
-
l, b, 0, 1, ti,
|
|
4273
4318
|
r, b, 1, 1, ti
|
|
4274
4319
|
);
|
|
4275
4320
|
|