q5 2.9.21 → 2.9.22
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/package.json +1 -1
- package/q5.js +110 -17
- package/q5.min.js +1 -1
- package/src/q5-2d-canvas.js +8 -2
- package/src/q5-2d-drawing.js +20 -7
- package/src/q5-2d-image.js +1 -0
- package/src/q5-2d-text.js +7 -0
- package/src/q5-canvas.js +6 -5
- package/src/q5-color.js +5 -0
- package/src/q5-input.js +12 -0
- package/src/q5-math.js +10 -3
- package/src/q5-record.js +2 -0
- package/src/q5-vector.js +33 -0
- package/src/q5-webgpu-canvas.js +3 -0
- package/src/q5-webgpu-text.js +5 -0
package/q5.js
CHANGED
|
@@ -462,7 +462,7 @@ Q5.modules.canvas = ($, q) => {
|
|
|
462
462
|
return g;
|
|
463
463
|
};
|
|
464
464
|
|
|
465
|
-
|
|
465
|
+
async function saveFile(data, name, ext) {
|
|
466
466
|
name = name || 'untitled';
|
|
467
467
|
ext = ext || 'png';
|
|
468
468
|
if (ext == 'jpg' || ext == 'png' || ext == 'webp') {
|
|
@@ -490,18 +490,19 @@ Q5.modules.canvas = ($, q) => {
|
|
|
490
490
|
a.download = name + '.' + ext;
|
|
491
491
|
a.click();
|
|
492
492
|
URL.revokeObjectURL(a.href);
|
|
493
|
-
}
|
|
493
|
+
}
|
|
494
|
+
|
|
494
495
|
$.save = (a, b, c) => {
|
|
495
496
|
if (!a || (typeof a == 'string' && (!b || (!c && b.length < 5)))) {
|
|
496
497
|
c = b;
|
|
497
498
|
b = a;
|
|
498
499
|
a = $.canvas;
|
|
499
500
|
}
|
|
500
|
-
if (c) return
|
|
501
|
+
if (c) return saveFile(a, b, c);
|
|
501
502
|
if (b) {
|
|
502
503
|
b = b.split('.');
|
|
503
|
-
|
|
504
|
-
} else
|
|
504
|
+
saveFile(a, b[0], b.at(-1));
|
|
505
|
+
} else saveFile(a);
|
|
505
506
|
};
|
|
506
507
|
|
|
507
508
|
$._setCanvasSize = (w, h) => {
|
|
@@ -716,7 +717,7 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
716
717
|
}
|
|
717
718
|
$.ctx.fillStyle = $._fill = c.toString();
|
|
718
719
|
};
|
|
719
|
-
|
|
720
|
+
|
|
720
721
|
$.stroke = function (c) {
|
|
721
722
|
$._doStroke = $._strokeSet = true;
|
|
722
723
|
if (Q5.Color) {
|
|
@@ -728,13 +729,15 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
728
729
|
}
|
|
729
730
|
$.ctx.strokeStyle = $._stroke = c.toString();
|
|
730
731
|
};
|
|
732
|
+
|
|
731
733
|
$.strokeWeight = (n) => {
|
|
732
734
|
if (!n) $._doStroke = false;
|
|
733
735
|
if ($._da) n *= $._da;
|
|
734
736
|
$.ctx.lineWidth = $._strokeWeight = n || 0.0001;
|
|
735
737
|
};
|
|
736
|
-
$.noStroke = () => ($._doStroke = false);
|
|
737
738
|
|
|
739
|
+
$.noFill = () => ($._doFill = false);
|
|
740
|
+
$.noStroke = () => ($._doStroke = false);
|
|
738
741
|
$.opacity = (a) => ($.ctx.globalAlpha = a);
|
|
739
742
|
|
|
740
743
|
// DRAWING MATRIX
|
|
@@ -746,10 +749,12 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
746
749
|
}
|
|
747
750
|
$.ctx.translate(x, y);
|
|
748
751
|
};
|
|
752
|
+
|
|
749
753
|
$.rotate = (r) => {
|
|
750
754
|
if ($._angleMode) r = $.radians(r);
|
|
751
755
|
$.ctx.rotate(r);
|
|
752
756
|
};
|
|
757
|
+
|
|
753
758
|
$.scale = (x, y) => {
|
|
754
759
|
if (x.x) {
|
|
755
760
|
y = x.y;
|
|
@@ -758,9 +763,11 @@ Q5.renderers.q2d.canvas = ($, q) => {
|
|
|
758
763
|
y ??= x;
|
|
759
764
|
$.ctx.scale(x, y);
|
|
760
765
|
};
|
|
766
|
+
|
|
761
767
|
$.applyMatrix = (a, b, c, d, e, f) => $.ctx.transform(a, b, c, d, e, f);
|
|
762
768
|
$.shearX = (ang) => $.ctx.transform(1, 0, $.tan(ang), 1, 0, 0);
|
|
763
769
|
$.shearY = (ang) => $.ctx.transform(1, $.tan(ang), 0, 1, 0, 0);
|
|
770
|
+
|
|
764
771
|
$.resetMatrix = () => {
|
|
765
772
|
if ($.ctx) {
|
|
766
773
|
$.ctx.resetTransform();
|
|
@@ -852,12 +859,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
852
859
|
|
|
853
860
|
$.line = (x0, y0, x1, y1) => {
|
|
854
861
|
if ($._doStroke) {
|
|
855
|
-
|
|
856
|
-
x0 *= $._da;
|
|
857
|
-
y0 *= $._da;
|
|
858
|
-
x1 *= $._da;
|
|
859
|
-
y1 *= $._da;
|
|
860
|
-
}
|
|
862
|
+
$._da && ((x0 *= $._da), (y0 *= $._da), (x1 *= $._da), (y1 *= $._da));
|
|
861
863
|
$.ctx.beginPath();
|
|
862
864
|
$.ctx.moveTo(x0, y0);
|
|
863
865
|
$.ctx.lineTo(x1, y1);
|
|
@@ -897,6 +899,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
897
899
|
$.ctx.stroke();
|
|
898
900
|
}
|
|
899
901
|
}
|
|
902
|
+
|
|
900
903
|
$.arc = (x, y, w, h, start, stop, mode) => {
|
|
901
904
|
if (start == stop) return $.ellipse(x, y, w, h);
|
|
902
905
|
|
|
@@ -906,7 +909,6 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
906
909
|
w *= $._da;
|
|
907
910
|
h *= $._da;
|
|
908
911
|
}
|
|
909
|
-
|
|
910
912
|
mode ??= $.PIE_OPEN;
|
|
911
913
|
|
|
912
914
|
if ($._ellipseMode == $.CENTER) {
|
|
@@ -925,6 +927,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
925
927
|
$.ctx.ellipse(x, y, w / 2, h / 2, 0, 0, $.TAU);
|
|
926
928
|
ink();
|
|
927
929
|
}
|
|
930
|
+
|
|
928
931
|
$.ellipse = (x, y, w, h) => {
|
|
929
932
|
h ??= w;
|
|
930
933
|
if ($._da) {
|
|
@@ -943,6 +946,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
943
946
|
ellipse((x + w) / 2, (y + h) / 2, w - x, h - y);
|
|
944
947
|
}
|
|
945
948
|
};
|
|
949
|
+
|
|
946
950
|
$.circle = (x, y, d) => {
|
|
947
951
|
if ($._ellipseMode == $.CENTER) {
|
|
948
952
|
if ($._da) {
|
|
@@ -984,6 +988,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
984
988
|
$.ctx.rect(x, y, w, h);
|
|
985
989
|
ink();
|
|
986
990
|
}
|
|
991
|
+
|
|
987
992
|
function roundedRect(x, y, w, h, tl, tr, br, bl) {
|
|
988
993
|
if (tl === undefined) {
|
|
989
994
|
return rect(x, y, w, h);
|
|
@@ -1016,6 +1021,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1016
1021
|
roundedRect(x, y, w - x, h - y, tl, tr, br, bl);
|
|
1017
1022
|
}
|
|
1018
1023
|
};
|
|
1024
|
+
|
|
1019
1025
|
$.square = (x, y, s, tl, tr, br, bl) => {
|
|
1020
1026
|
return $.rect(x, y, s, s, tl, tr, br, bl);
|
|
1021
1027
|
};
|
|
@@ -1025,15 +1031,18 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1025
1031
|
$.ctx.beginPath();
|
|
1026
1032
|
firstVertex = true;
|
|
1027
1033
|
};
|
|
1034
|
+
|
|
1028
1035
|
$.beginContour = () => {
|
|
1029
1036
|
$.ctx.closePath();
|
|
1030
1037
|
curveBuff.length = 0;
|
|
1031
1038
|
firstVertex = true;
|
|
1032
1039
|
};
|
|
1040
|
+
|
|
1033
1041
|
$.endContour = () => {
|
|
1034
1042
|
curveBuff.length = 0;
|
|
1035
1043
|
firstVertex = true;
|
|
1036
1044
|
};
|
|
1045
|
+
|
|
1037
1046
|
$.vertex = (x, y) => {
|
|
1038
1047
|
if ($._da) {
|
|
1039
1048
|
x *= $._da;
|
|
@@ -1047,6 +1056,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1047
1056
|
}
|
|
1048
1057
|
firstVertex = false;
|
|
1049
1058
|
};
|
|
1059
|
+
|
|
1050
1060
|
$.bezierVertex = (cp1x, cp1y, cp2x, cp2y, x, y) => {
|
|
1051
1061
|
if ($._da) {
|
|
1052
1062
|
cp1x *= $._da;
|
|
@@ -1059,6 +1069,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1059
1069
|
curveBuff.length = 0;
|
|
1060
1070
|
$.ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
|
|
1061
1071
|
};
|
|
1072
|
+
|
|
1062
1073
|
$.quadraticVertex = (cp1x, cp1y, x, y) => {
|
|
1063
1074
|
if ($._da) {
|
|
1064
1075
|
cp1x *= $._da;
|
|
@@ -1069,12 +1080,14 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1069
1080
|
curveBuff.length = 0;
|
|
1070
1081
|
$.ctx.quadraticCurveTo(cp1x, cp1y, x, y);
|
|
1071
1082
|
};
|
|
1083
|
+
|
|
1072
1084
|
$.bezier = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
1073
1085
|
$.beginShape();
|
|
1074
1086
|
$.vertex(x1, y1);
|
|
1075
1087
|
$.bezierVertex(x2, y2, x3, y3, x4, y4);
|
|
1076
1088
|
$.endShape();
|
|
1077
1089
|
};
|
|
1090
|
+
|
|
1078
1091
|
$.triangle = (x1, y1, x2, y2, x3, y3) => {
|
|
1079
1092
|
$.beginShape();
|
|
1080
1093
|
$.vertex(x1, y1);
|
|
@@ -1082,6 +1095,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1082
1095
|
$.vertex(x3, y3);
|
|
1083
1096
|
$.endShape($.CLOSE);
|
|
1084
1097
|
};
|
|
1098
|
+
|
|
1085
1099
|
$.quad = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
1086
1100
|
$.beginShape();
|
|
1087
1101
|
$.vertex(x1, y1);
|
|
@@ -1090,6 +1104,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1090
1104
|
$.vertex(x4, y4);
|
|
1091
1105
|
$.endShape($.CLOSE);
|
|
1092
1106
|
};
|
|
1107
|
+
|
|
1093
1108
|
$.endShape = (close) => {
|
|
1094
1109
|
curveBuff.length = 0;
|
|
1095
1110
|
if (close) $.ctx.closePath();
|
|
@@ -1120,6 +1135,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1120
1135
|
}
|
|
1121
1136
|
$.ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, p2[0], p2[1]);
|
|
1122
1137
|
};
|
|
1138
|
+
|
|
1123
1139
|
$.curve = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
1124
1140
|
$.beginShape();
|
|
1125
1141
|
$.curveVertex(x1, y1);
|
|
@@ -1128,6 +1144,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1128
1144
|
$.curveVertex(x4, y4);
|
|
1129
1145
|
$.endShape();
|
|
1130
1146
|
};
|
|
1147
|
+
|
|
1131
1148
|
$.curvePoint = (a, b, c, d, t) => {
|
|
1132
1149
|
const t3 = t * t * t,
|
|
1133
1150
|
t2 = t * t,
|
|
@@ -1137,6 +1154,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1137
1154
|
f4 = 0.5 * t3 - 0.5 * t2;
|
|
1138
1155
|
return a * f1 + b * f2 + c * f3 + d * f4;
|
|
1139
1156
|
};
|
|
1157
|
+
|
|
1140
1158
|
$.bezierPoint = (a, b, c, d, t) => {
|
|
1141
1159
|
const adjustedT = 1 - t;
|
|
1142
1160
|
return (
|
|
@@ -1146,6 +1164,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1146
1164
|
Math.pow(t, 3) * d
|
|
1147
1165
|
);
|
|
1148
1166
|
};
|
|
1167
|
+
|
|
1149
1168
|
$.curveTangent = (a, b, c, d, t) => {
|
|
1150
1169
|
const t2 = t * t,
|
|
1151
1170
|
f1 = (-3 * t2) / 2 + 2 * t - 0.5,
|
|
@@ -1154,6 +1173,7 @@ Q5.renderers.q2d.drawing = ($) => {
|
|
|
1154
1173
|
f4 = (3 * t2) / 2 - t;
|
|
1155
1174
|
return a * f1 + b * f2 + c * f3 + d * f4;
|
|
1156
1175
|
};
|
|
1176
|
+
|
|
1157
1177
|
$.bezierTangent = (a, b, c, d, t) => {
|
|
1158
1178
|
const adjustedT = 1 - t;
|
|
1159
1179
|
return (
|
|
@@ -1271,6 +1291,7 @@ Q5.renderers.q2d.image = ($, q) => {
|
|
|
1271
1291
|
};
|
|
1272
1292
|
|
|
1273
1293
|
$.imageMode = (mode) => ($._imageMode = mode);
|
|
1294
|
+
|
|
1274
1295
|
$.image = (img, dx, dy, dw, dh, sx = 0, sy = 0, sw, sh) => {
|
|
1275
1296
|
if (!img) return;
|
|
1276
1297
|
let drawable = img?.canvas || img;
|
|
@@ -1512,6 +1533,7 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1512
1533
|
fontMod = true;
|
|
1513
1534
|
styleHash = -1;
|
|
1514
1535
|
};
|
|
1536
|
+
|
|
1515
1537
|
$.textSize = (x) => {
|
|
1516
1538
|
if (x == undefined || x == $._textSize) return $._textSize;
|
|
1517
1539
|
if ($._da) x *= $._da;
|
|
@@ -1523,12 +1545,14 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1523
1545
|
leadDiff = leading - x;
|
|
1524
1546
|
}
|
|
1525
1547
|
};
|
|
1548
|
+
|
|
1526
1549
|
$.textStyle = (x) => {
|
|
1527
1550
|
if (!x || x == emphasis) return emphasis;
|
|
1528
1551
|
emphasis = x;
|
|
1529
1552
|
fontMod = true;
|
|
1530
1553
|
styleHash = -1;
|
|
1531
1554
|
};
|
|
1555
|
+
|
|
1532
1556
|
$.textLeading = (x) => {
|
|
1533
1557
|
leadingSet = true;
|
|
1534
1558
|
if (x == undefined || x == leading) return leading;
|
|
@@ -1537,6 +1561,7 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1537
1561
|
leadDiff = x - $._textSize;
|
|
1538
1562
|
styleHash = -1;
|
|
1539
1563
|
};
|
|
1564
|
+
|
|
1540
1565
|
$.textAlign = (horiz, vert) => {
|
|
1541
1566
|
$.ctx.textAlign = $._textAlign = horiz;
|
|
1542
1567
|
if (vert) {
|
|
@@ -1566,6 +1591,7 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1566
1591
|
if (enable !== undefined) useCache = enable;
|
|
1567
1592
|
return useCache;
|
|
1568
1593
|
};
|
|
1594
|
+
|
|
1569
1595
|
$.createTextImage = (str, w, h) => {
|
|
1570
1596
|
genTextImage = true;
|
|
1571
1597
|
img = $.text(str, 0, 0, w, h);
|
|
@@ -1574,6 +1600,7 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1574
1600
|
};
|
|
1575
1601
|
|
|
1576
1602
|
let lines = [];
|
|
1603
|
+
|
|
1577
1604
|
$.text = (str, x, y, w, h) => {
|
|
1578
1605
|
if (str === undefined || (!$._doFill && !$._doStroke)) return;
|
|
1579
1606
|
str = str.toString();
|
|
@@ -1699,6 +1726,7 @@ Q5.renderers.q2d.text = ($, q) => {
|
|
|
1699
1726
|
$.textImage(img, x, y);
|
|
1700
1727
|
}
|
|
1701
1728
|
};
|
|
1729
|
+
|
|
1702
1730
|
$.textImage = (img, x, y) => {
|
|
1703
1731
|
if (typeof img == 'string') img = $.createTextImage(img);
|
|
1704
1732
|
|
|
@@ -1942,6 +1970,7 @@ Q5.Color = class {
|
|
|
1942
1970
|
this._q5Color = true;
|
|
1943
1971
|
}
|
|
1944
1972
|
};
|
|
1973
|
+
|
|
1945
1974
|
Q5.ColorOKLCH = class extends Q5.Color {
|
|
1946
1975
|
constructor(l, c, h, a) {
|
|
1947
1976
|
super();
|
|
@@ -1954,6 +1983,7 @@ Q5.ColorOKLCH = class extends Q5.Color {
|
|
|
1954
1983
|
return `oklch(${this.l} ${this.c} ${this.h} / ${this.a})`;
|
|
1955
1984
|
}
|
|
1956
1985
|
};
|
|
1986
|
+
|
|
1957
1987
|
Q5.ColorRGBA = class extends Q5.Color {
|
|
1958
1988
|
constructor(r, g, b, a) {
|
|
1959
1989
|
super();
|
|
@@ -1969,11 +1999,13 @@ Q5.ColorRGBA = class extends Q5.Color {
|
|
|
1969
1999
|
return `color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`;
|
|
1970
2000
|
}
|
|
1971
2001
|
};
|
|
2002
|
+
|
|
1972
2003
|
Q5.ColorRGBA_P3 = class extends Q5.ColorRGBA {
|
|
1973
2004
|
toString() {
|
|
1974
2005
|
return `color(display-p3 ${this.r} ${this.g} ${this.b} / ${this.a})`;
|
|
1975
2006
|
}
|
|
1976
2007
|
};
|
|
2008
|
+
|
|
1977
2009
|
// legacy 8-bit (0-255) integer color format
|
|
1978
2010
|
Q5.ColorRGBA_8 = class extends Q5.ColorRGBA {
|
|
1979
2011
|
constructor(r, g, b, a) {
|
|
@@ -1998,6 +2030,7 @@ Q5.ColorRGBA_8 = class extends Q5.ColorRGBA {
|
|
|
1998
2030
|
return `rgb(${this.r} ${this.g} ${this.b} / ${this.a / 255})`;
|
|
1999
2031
|
}
|
|
2000
2032
|
};
|
|
2033
|
+
|
|
2001
2034
|
// p3 10-bit color in integer color format, for backwards compatibility
|
|
2002
2035
|
Q5.ColorRGBA_P3_8 = class extends Q5.ColorRGBA {
|
|
2003
2036
|
constructor(r, g, b, a) {
|
|
@@ -2206,6 +2239,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2206
2239
|
q.moveX = e.movementX;
|
|
2207
2240
|
q.moveY = e.movementY;
|
|
2208
2241
|
};
|
|
2242
|
+
|
|
2209
2243
|
$._onmousedown = (e) => {
|
|
2210
2244
|
$._startAudio();
|
|
2211
2245
|
$._updateMouse(e);
|
|
@@ -2213,22 +2247,26 @@ Q5.modules.input = ($, q) => {
|
|
|
2213
2247
|
q.mouseButton = mouseBtns[e.button];
|
|
2214
2248
|
$.mousePressed(e);
|
|
2215
2249
|
};
|
|
2250
|
+
|
|
2216
2251
|
$._onmousemove = (e) => {
|
|
2217
2252
|
$._updateMouse(e);
|
|
2218
2253
|
if ($.mouseIsPressed) $.mouseDragged(e);
|
|
2219
2254
|
else $.mouseMoved(e);
|
|
2220
2255
|
};
|
|
2256
|
+
|
|
2221
2257
|
$._onmouseup = (e) => {
|
|
2222
2258
|
$._updateMouse(e);
|
|
2223
2259
|
q.mouseIsPressed = false;
|
|
2224
2260
|
$.mouseReleased(e);
|
|
2225
2261
|
};
|
|
2262
|
+
|
|
2226
2263
|
$._onclick = (e) => {
|
|
2227
2264
|
$._updateMouse(e);
|
|
2228
2265
|
q.mouseIsPressed = true;
|
|
2229
2266
|
$.mouseClicked(e);
|
|
2230
2267
|
q.mouseIsPressed = false;
|
|
2231
2268
|
};
|
|
2269
|
+
|
|
2232
2270
|
$._onwheel = (e) => {
|
|
2233
2271
|
$._updateMouse(e);
|
|
2234
2272
|
e.delta = e.deltaY;
|
|
@@ -2246,9 +2284,11 @@ Q5.modules.input = ($, q) => {
|
|
|
2246
2284
|
}
|
|
2247
2285
|
$.canvas.style.cursor = name + pfx;
|
|
2248
2286
|
};
|
|
2287
|
+
|
|
2249
2288
|
$.noCursor = () => {
|
|
2250
2289
|
$.canvas.style.cursor = 'none';
|
|
2251
2290
|
};
|
|
2291
|
+
|
|
2252
2292
|
if (window) {
|
|
2253
2293
|
$.requestPointerLock = document.body?.requestPointerLock;
|
|
2254
2294
|
$.exitPointerLock = document.exitPointerLock;
|
|
@@ -2264,6 +2304,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2264
2304
|
$.keyPressed(e);
|
|
2265
2305
|
if (e.key.length == 1) $.keyTyped(e);
|
|
2266
2306
|
};
|
|
2307
|
+
|
|
2267
2308
|
$._onkeyup = (e) => {
|
|
2268
2309
|
q.keyIsPressed = false;
|
|
2269
2310
|
q.key = e.key;
|
|
@@ -2271,6 +2312,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2271
2312
|
keysHeld[$.keyCode] = keysHeld[$.key.toLowerCase()] = false;
|
|
2272
2313
|
$.keyReleased(e);
|
|
2273
2314
|
};
|
|
2315
|
+
|
|
2274
2316
|
$.keyIsDown = (v) => !!keysHeld[typeof v == 'string' ? v.toLowerCase() : v];
|
|
2275
2317
|
|
|
2276
2318
|
function getTouchInfo(touch) {
|
|
@@ -2283,6 +2325,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2283
2325
|
id: touch.identifier
|
|
2284
2326
|
};
|
|
2285
2327
|
}
|
|
2328
|
+
|
|
2286
2329
|
$._ontouchstart = (e) => {
|
|
2287
2330
|
$._startAudio();
|
|
2288
2331
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
@@ -2295,6 +2338,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2295
2338
|
}
|
|
2296
2339
|
if (!$.touchStarted(e)) e.preventDefault();
|
|
2297
2340
|
};
|
|
2341
|
+
|
|
2298
2342
|
$._ontouchmove = (e) => {
|
|
2299
2343
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
2300
2344
|
if (!$._isTouchAware) {
|
|
@@ -2304,6 +2348,7 @@ Q5.modules.input = ($, q) => {
|
|
|
2304
2348
|
}
|
|
2305
2349
|
if (!$.touchMoved(e)) e.preventDefault();
|
|
2306
2350
|
};
|
|
2351
|
+
|
|
2307
2352
|
$._ontouchend = (e) => {
|
|
2308
2353
|
q.touches = [...e.touches].map(getTouchInfo);
|
|
2309
2354
|
if (!$._isTouchAware && !$.touches.length) {
|
|
@@ -2375,13 +2420,15 @@ Q5.modules.math = ($, q) => {
|
|
|
2375
2420
|
return Math.min(Math.max(val, ostop), ostart);
|
|
2376
2421
|
}
|
|
2377
2422
|
};
|
|
2378
|
-
|
|
2379
|
-
$.constrain = (x, lo, hi) => Math.min(Math.max(x, lo), hi);
|
|
2423
|
+
|
|
2380
2424
|
$.dist = function () {
|
|
2381
2425
|
let a = arguments;
|
|
2382
2426
|
if (a.length == 4) return Math.hypot(a[0] - a[2], a[1] - a[3]);
|
|
2383
2427
|
else return Math.hypot(a[0] - a[3], a[1] - a[4], a[2] - a[5]);
|
|
2384
2428
|
};
|
|
2429
|
+
|
|
2430
|
+
$.lerp = (a, b, t) => a * (1 - t) + b * t;
|
|
2431
|
+
$.constrain = (x, lo, hi) => Math.min(Math.max(x, lo), hi);
|
|
2385
2432
|
$.norm = (value, start, stop) => $.map(value, start, stop, 0, 1);
|
|
2386
2433
|
$.sq = (x) => x * x;
|
|
2387
2434
|
$.fract = (x) => x - Math.floor(x);
|
|
@@ -2402,7 +2449,6 @@ Q5.modules.math = ($, q) => {
|
|
|
2402
2449
|
let a = Math.atan(x);
|
|
2403
2450
|
return !angleMode ? a : a * RADTODEG;
|
|
2404
2451
|
};
|
|
2405
|
-
|
|
2406
2452
|
$.atan2 = (y, x) => {
|
|
2407
2453
|
let a = Math.atan2(y, x);
|
|
2408
2454
|
return !angleMode ? a : a * RADTODEG;
|
|
@@ -2426,6 +2472,7 @@ Q5.modules.math = ($, q) => {
|
|
|
2426
2472
|
}
|
|
2427
2473
|
};
|
|
2428
2474
|
}
|
|
2475
|
+
|
|
2429
2476
|
function shr3() {
|
|
2430
2477
|
let jsr, seed;
|
|
2431
2478
|
let m = 4294967295;
|
|
@@ -2444,6 +2491,7 @@ Q5.modules.math = ($, q) => {
|
|
|
2444
2491
|
}
|
|
2445
2492
|
};
|
|
2446
2493
|
}
|
|
2494
|
+
|
|
2447
2495
|
let rng1 = shr3();
|
|
2448
2496
|
rng1.setSeed();
|
|
2449
2497
|
|
|
@@ -2460,6 +2508,7 @@ Q5.modules.math = ($, q) => {
|
|
|
2460
2508
|
return a[Math.trunc(a.length * rng1.rand())];
|
|
2461
2509
|
}
|
|
2462
2510
|
};
|
|
2511
|
+
|
|
2463
2512
|
$.randomGenerator = (method) => {
|
|
2464
2513
|
if (method == $.LCG) rng1 = lcg();
|
|
2465
2514
|
else if (method == $.SHR3) rng1 = shr3();
|
|
@@ -2615,13 +2664,16 @@ Q5.modules.math = ($, q) => {
|
|
|
2615
2664
|
q.Noise = Q5[mode[0].toUpperCase() + mode.slice(1) + 'Noise'];
|
|
2616
2665
|
_noise = null;
|
|
2617
2666
|
};
|
|
2667
|
+
|
|
2618
2668
|
$.noiseSeed = (seed) => {
|
|
2619
2669
|
_noise = new $.Noise(seed);
|
|
2620
2670
|
};
|
|
2671
|
+
|
|
2621
2672
|
$.noise = (x = 0, y = 0, z = 0) => {
|
|
2622
2673
|
_noise ??= new $.Noise();
|
|
2623
2674
|
return _noise.noise(x, y, z);
|
|
2624
2675
|
};
|
|
2676
|
+
|
|
2625
2677
|
$.noiseDetail = (lod, falloff) => {
|
|
2626
2678
|
_noise ??= new $.Noise();
|
|
2627
2679
|
if (lod > 0) _noise.octaves = lod;
|
|
@@ -2857,15 +2909,18 @@ Q5.Vector = class {
|
|
|
2857
2909
|
this._cn = null;
|
|
2858
2910
|
this._cnsq = null;
|
|
2859
2911
|
}
|
|
2912
|
+
|
|
2860
2913
|
set(x, y, z) {
|
|
2861
2914
|
this.x = x?.x || x || 0;
|
|
2862
2915
|
this.y = x?.y || y || 0;
|
|
2863
2916
|
this.z = x?.z || z || 0;
|
|
2864
2917
|
return this;
|
|
2865
2918
|
}
|
|
2919
|
+
|
|
2866
2920
|
copy() {
|
|
2867
2921
|
return new Q5.Vector(this.x, this.y, this.z);
|
|
2868
2922
|
}
|
|
2923
|
+
|
|
2869
2924
|
_arg2v(x, y, z) {
|
|
2870
2925
|
if (x?.x !== undefined) return x;
|
|
2871
2926
|
if (y !== undefined) {
|
|
@@ -2873,10 +2928,12 @@ Q5.Vector = class {
|
|
|
2873
2928
|
}
|
|
2874
2929
|
return { x: x, y: x, z: x };
|
|
2875
2930
|
}
|
|
2931
|
+
|
|
2876
2932
|
_calcNorm() {
|
|
2877
2933
|
this._cnsq = this.x * this.x + this.y * this.y + this.z * this.z;
|
|
2878
2934
|
this._cn = Math.sqrt(this._cnsq);
|
|
2879
2935
|
}
|
|
2936
|
+
|
|
2880
2937
|
add() {
|
|
2881
2938
|
let u = this._arg2v(...arguments);
|
|
2882
2939
|
this.x += u.x;
|
|
@@ -2884,6 +2941,7 @@ Q5.Vector = class {
|
|
|
2884
2941
|
this.z += u.z;
|
|
2885
2942
|
return this;
|
|
2886
2943
|
}
|
|
2944
|
+
|
|
2887
2945
|
rem() {
|
|
2888
2946
|
let u = this._arg2v(...arguments);
|
|
2889
2947
|
this.x %= u.x;
|
|
@@ -2891,6 +2949,7 @@ Q5.Vector = class {
|
|
|
2891
2949
|
this.z %= u.z;
|
|
2892
2950
|
return this;
|
|
2893
2951
|
}
|
|
2952
|
+
|
|
2894
2953
|
sub() {
|
|
2895
2954
|
let u = this._arg2v(...arguments);
|
|
2896
2955
|
this.x -= u.x;
|
|
@@ -2898,6 +2957,7 @@ Q5.Vector = class {
|
|
|
2898
2957
|
this.z -= u.z;
|
|
2899
2958
|
return this;
|
|
2900
2959
|
}
|
|
2960
|
+
|
|
2901
2961
|
mult() {
|
|
2902
2962
|
let u = this._arg2v(...arguments);
|
|
2903
2963
|
this.x *= u.x;
|
|
@@ -2905,6 +2965,7 @@ Q5.Vector = class {
|
|
|
2905
2965
|
this.z *= u.z;
|
|
2906
2966
|
return this;
|
|
2907
2967
|
}
|
|
2968
|
+
|
|
2908
2969
|
div() {
|
|
2909
2970
|
let u = this._arg2v(...arguments);
|
|
2910
2971
|
if (u.x) this.x /= u.x;
|
|
@@ -2915,18 +2976,22 @@ Q5.Vector = class {
|
|
|
2915
2976
|
else this.z = 0;
|
|
2916
2977
|
return this;
|
|
2917
2978
|
}
|
|
2979
|
+
|
|
2918
2980
|
mag() {
|
|
2919
2981
|
this._calcNorm();
|
|
2920
2982
|
return this._cn;
|
|
2921
2983
|
}
|
|
2984
|
+
|
|
2922
2985
|
magSq() {
|
|
2923
2986
|
this._calcNorm();
|
|
2924
2987
|
return this._cnsq;
|
|
2925
2988
|
}
|
|
2989
|
+
|
|
2926
2990
|
dot() {
|
|
2927
2991
|
let u = this._arg2v(...arguments);
|
|
2928
2992
|
return this.x * u.x + this.y * u.y + this.z * u.z;
|
|
2929
2993
|
}
|
|
2994
|
+
|
|
2930
2995
|
dist() {
|
|
2931
2996
|
let u = this._arg2v(...arguments);
|
|
2932
2997
|
let x = this.x - u.x;
|
|
@@ -2934,6 +2999,7 @@ Q5.Vector = class {
|
|
|
2934
2999
|
let z = this.z - u.z;
|
|
2935
3000
|
return Math.sqrt(x * x + y * y + z * z);
|
|
2936
3001
|
}
|
|
3002
|
+
|
|
2937
3003
|
cross() {
|
|
2938
3004
|
let u = this._arg2v(...arguments);
|
|
2939
3005
|
let x = this.y * u.z - this.z * u.y;
|
|
@@ -2944,6 +3010,7 @@ Q5.Vector = class {
|
|
|
2944
3010
|
this.z = z;
|
|
2945
3011
|
return this;
|
|
2946
3012
|
}
|
|
3013
|
+
|
|
2947
3014
|
normalize() {
|
|
2948
3015
|
this._calcNorm();
|
|
2949
3016
|
let n = this._cn;
|
|
@@ -2956,6 +3023,7 @@ Q5.Vector = class {
|
|
|
2956
3023
|
this._cnsq = 1;
|
|
2957
3024
|
return this;
|
|
2958
3025
|
}
|
|
3026
|
+
|
|
2959
3027
|
limit(m) {
|
|
2960
3028
|
this._calcNorm();
|
|
2961
3029
|
let n = this._cn;
|
|
@@ -2969,6 +3037,7 @@ Q5.Vector = class {
|
|
|
2969
3037
|
}
|
|
2970
3038
|
return this;
|
|
2971
3039
|
}
|
|
3040
|
+
|
|
2972
3041
|
setMag(m) {
|
|
2973
3042
|
this._calcNorm();
|
|
2974
3043
|
let n = this._cn;
|
|
@@ -2980,15 +3049,18 @@ Q5.Vector = class {
|
|
|
2980
3049
|
this._cnsq = m * m;
|
|
2981
3050
|
return this;
|
|
2982
3051
|
}
|
|
3052
|
+
|
|
2983
3053
|
heading() {
|
|
2984
3054
|
return this._$.atan2(this.y, this.x);
|
|
2985
3055
|
}
|
|
3056
|
+
|
|
2986
3057
|
setHeading(ang) {
|
|
2987
3058
|
let mag = this.mag();
|
|
2988
3059
|
this.x = mag * this._$.cos(ang);
|
|
2989
3060
|
this.y = mag * this._$.sin(ang);
|
|
2990
3061
|
return this;
|
|
2991
3062
|
}
|
|
3063
|
+
|
|
2992
3064
|
rotate(ang) {
|
|
2993
3065
|
let costh = this._$.cos(ang);
|
|
2994
3066
|
let sinth = this._$.sin(ang);
|
|
@@ -2998,12 +3070,14 @@ Q5.Vector = class {
|
|
|
2998
3070
|
this.y = vy;
|
|
2999
3071
|
return this;
|
|
3000
3072
|
}
|
|
3073
|
+
|
|
3001
3074
|
angleBetween() {
|
|
3002
3075
|
let u = this._arg2v(...arguments);
|
|
3003
3076
|
let o = Q5.Vector.cross(this, u);
|
|
3004
3077
|
let ang = this._$.atan2(o.mag(), this.dot(u));
|
|
3005
3078
|
return ang * Math.sign(o.z || 1);
|
|
3006
3079
|
}
|
|
3080
|
+
|
|
3007
3081
|
lerp() {
|
|
3008
3082
|
let args = [...arguments];
|
|
3009
3083
|
let amt = args.at(-1);
|
|
@@ -3014,6 +3088,7 @@ Q5.Vector = class {
|
|
|
3014
3088
|
this.z += (u.z - this.z) * amt;
|
|
3015
3089
|
return this;
|
|
3016
3090
|
}
|
|
3091
|
+
|
|
3017
3092
|
slerp() {
|
|
3018
3093
|
let args = [...arguments];
|
|
3019
3094
|
let amt = args.at(-1);
|
|
@@ -3052,17 +3127,21 @@ Q5.Vector = class {
|
|
|
3052
3127
|
this.z = this.z * cosMultiplier + ey.z * sinMultiplier;
|
|
3053
3128
|
return this;
|
|
3054
3129
|
}
|
|
3130
|
+
|
|
3055
3131
|
reflect(n) {
|
|
3056
3132
|
n.normalize();
|
|
3057
3133
|
return this.sub(n.mult(2 * this.dot(n)));
|
|
3058
3134
|
}
|
|
3135
|
+
|
|
3059
3136
|
array() {
|
|
3060
3137
|
return [this.x, this.y, this.z];
|
|
3061
3138
|
}
|
|
3139
|
+
|
|
3062
3140
|
equals(u, epsilon) {
|
|
3063
3141
|
epsilon ??= Number.EPSILON || 0;
|
|
3064
3142
|
return Math.abs(u.x - this.x) < epsilon && Math.abs(u.y - this.y) < epsilon && Math.abs(u.z - this.z) < epsilon;
|
|
3065
3143
|
}
|
|
3144
|
+
|
|
3066
3145
|
fromAngle(th, l) {
|
|
3067
3146
|
if (l === undefined) l = 1;
|
|
3068
3147
|
this._cn = l;
|
|
@@ -3072,6 +3151,7 @@ Q5.Vector = class {
|
|
|
3072
3151
|
this.z = 0;
|
|
3073
3152
|
return this;
|
|
3074
3153
|
}
|
|
3154
|
+
|
|
3075
3155
|
fromAngles(th, ph, l) {
|
|
3076
3156
|
if (l === undefined) l = 1;
|
|
3077
3157
|
this._cn = l;
|
|
@@ -3085,18 +3165,22 @@ Q5.Vector = class {
|
|
|
3085
3165
|
this.z = l * sinth * cosph;
|
|
3086
3166
|
return this;
|
|
3087
3167
|
}
|
|
3168
|
+
|
|
3088
3169
|
random2D() {
|
|
3089
3170
|
this._cn = this._cnsq = 1;
|
|
3090
3171
|
return this.fromAngle(Math.random() * Math.PI * 2);
|
|
3091
3172
|
}
|
|
3173
|
+
|
|
3092
3174
|
random3D() {
|
|
3093
3175
|
this._cn = this._cnsq = 1;
|
|
3094
3176
|
return this.fromAngles(Math.random() * Math.PI * 2, Math.random() * Math.PI * 2);
|
|
3095
3177
|
}
|
|
3178
|
+
|
|
3096
3179
|
toString() {
|
|
3097
3180
|
return `[${this.x}, ${this.y}, ${this.z}]`;
|
|
3098
3181
|
}
|
|
3099
3182
|
};
|
|
3183
|
+
|
|
3100
3184
|
Q5.Vector.add = (v, u) => v.copy().add(u);
|
|
3101
3185
|
Q5.Vector.cross = (v, u) => v.copy().cross(u);
|
|
3102
3186
|
Q5.Vector.dist = (v, u) => Math.hypot(v.x - u.x, v.y - u.y, v.z - u.z);
|
|
@@ -3113,6 +3197,7 @@ Q5.Vector.mult = (v, u) => v.copy().mult(u);
|
|
|
3113
3197
|
Q5.Vector.normalize = (v) => v.copy().normalize();
|
|
3114
3198
|
Q5.Vector.rem = (v, u) => v.copy().rem(u);
|
|
3115
3199
|
Q5.Vector.sub = (v, u) => v.copy().sub(u);
|
|
3200
|
+
|
|
3116
3201
|
for (let k of ['fromAngle', 'fromAngles', 'random2D', 'random3D']) {
|
|
3117
3202
|
Q5.Vector[k] = (u, v, t) => new Q5.Vector()[k](u, v, t);
|
|
3118
3203
|
}
|
|
@@ -3432,6 +3517,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3432
3517
|
if ($._matrixDirty) $._saveMatrix();
|
|
3433
3518
|
$._transformIndexStack.push($._transformIndex);
|
|
3434
3519
|
};
|
|
3520
|
+
|
|
3435
3521
|
$.popMatrix = () => {
|
|
3436
3522
|
if (!$._transformIndexStack.length) {
|
|
3437
3523
|
return console.warn('Matrix index stack is empty!');
|
|
@@ -3447,6 +3533,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3447
3533
|
$.pushMatrix();
|
|
3448
3534
|
$.pushStyles();
|
|
3449
3535
|
};
|
|
3536
|
+
|
|
3450
3537
|
$.pop = () => {
|
|
3451
3538
|
$.popMatrix();
|
|
3452
3539
|
$.popStyles();
|
|
@@ -3528,6 +3615,7 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
3528
3615
|
}
|
|
3529
3616
|
|
|
3530
3617
|
$._blendMode = 'normal';
|
|
3618
|
+
|
|
3531
3619
|
$.blendMode = (mode) => {
|
|
3532
3620
|
if (mode == $._blendMode) return;
|
|
3533
3621
|
if (mode == 'source-over') mode = 'normal';
|
|
@@ -4537,6 +4625,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
4537
4625
|
mipmapFilter: 'linear',
|
|
4538
4626
|
maxAnisotropy: 16
|
|
4539
4627
|
});
|
|
4628
|
+
|
|
4540
4629
|
let fontBindGroupLayout = Q5.device.createBindGroupLayout({
|
|
4541
4630
|
label: 'MSDF font group layout',
|
|
4542
4631
|
entries: [
|
|
@@ -4574,6 +4663,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
4574
4663
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
4575
4664
|
multisample: { count: 4 }
|
|
4576
4665
|
};
|
|
4666
|
+
|
|
4577
4667
|
$._pipelines[2] = Q5.device.createRenderPipeline($._pipelineConfigs[2]);
|
|
4578
4668
|
|
|
4579
4669
|
class MsdfFont {
|
|
@@ -4722,6 +4812,7 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
4722
4812
|
$.textFont = (fontName) => {
|
|
4723
4813
|
$._font = fonts[fontName];
|
|
4724
4814
|
};
|
|
4815
|
+
|
|
4725
4816
|
$.textSize = (size) => {
|
|
4726
4817
|
$._textSize = size;
|
|
4727
4818
|
if (!leadingSet) {
|
|
@@ -4729,12 +4820,14 @@ fn fragmentMain(input : VertexOutput) -> @location(0) vec4f {
|
|
|
4729
4820
|
leadDiff = leading - size;
|
|
4730
4821
|
}
|
|
4731
4822
|
};
|
|
4823
|
+
|
|
4732
4824
|
$.textLeading = (lineHeight) => {
|
|
4733
4825
|
$._font.lineHeight = leading = lineHeight;
|
|
4734
4826
|
leadDiff = leading - $._textSize;
|
|
4735
4827
|
leadPercent = leading / $._textSize;
|
|
4736
4828
|
leadingSet = true;
|
|
4737
4829
|
};
|
|
4830
|
+
|
|
4738
4831
|
$.textAlign = (horiz, vert) => {
|
|
4739
4832
|
$._textAlign = horiz;
|
|
4740
4833
|
if (vert) $._textBaseline = vert;
|