q5 4.7.2 → 4.7.4
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 +3 -3
- package/q5.d.ts +11 -10
- package/q5.js +74 -66
- package/q5.pyi +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "q5",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.4",
|
|
4
4
|
"description": "Beginner friendly graphics powered by WebGPU, optimized for interactive art!",
|
|
5
5
|
"author": "quinton-ashley",
|
|
6
6
|
"license": "LGPL-3.0-only",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
],
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"jest-cli": "^29.7.0",
|
|
73
|
-
"jsdom": "^
|
|
73
|
+
"jsdom": "^29.1.1",
|
|
74
74
|
"json2csv": "^6.0.0-alpha.2",
|
|
75
|
-
"skia-canvas": "^
|
|
75
|
+
"skia-canvas": "^3.0.8",
|
|
76
76
|
"terser": "^5.46.1"
|
|
77
77
|
},
|
|
78
78
|
"trustedDependencies": [
|
package/q5.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** @module q5 */
|
|
2
1
|
declare global {
|
|
3
2
|
|
|
4
3
|
// ⭐ core
|
|
@@ -2341,7 +2340,7 @@ declare global {
|
|
|
2341
2340
|
* redraw(10);
|
|
2342
2341
|
* };
|
|
2343
2342
|
*/
|
|
2344
|
-
function redraw(n?: number): void
|
|
2343
|
+
function redraw(n?: number): Promise<void>;
|
|
2345
2344
|
|
|
2346
2345
|
/** 💻
|
|
2347
2346
|
* Starts the draw loop again if it was stopped.
|
|
@@ -2500,6 +2499,8 @@ declare global {
|
|
|
2500
2499
|
*/
|
|
2501
2500
|
const WEBGPU: 'webgpu';
|
|
2502
2501
|
|
|
2502
|
+
function remove(): Promise<void>;
|
|
2503
|
+
|
|
2503
2504
|
// 🧮 math
|
|
2504
2505
|
|
|
2505
2506
|
/** 🧮
|
|
@@ -3398,7 +3399,7 @@ declare global {
|
|
|
3398
3399
|
* else saveRecording('squares');
|
|
3399
3400
|
* };
|
|
3400
3401
|
*/
|
|
3401
|
-
function saveRecording(fileName: string): void
|
|
3402
|
+
function saveRecording(fileName: string): Promise<void>;
|
|
3402
3403
|
|
|
3403
3404
|
/** 🎞
|
|
3404
3405
|
* True if the canvas is currently being recorded.
|
|
@@ -3430,8 +3431,8 @@ declare global {
|
|
|
3430
3431
|
*
|
|
3431
3432
|
* await load('/assets/Robotica.ttf');
|
|
3432
3433
|
*
|
|
3433
|
-
* textSize(
|
|
3434
|
-
* text('Hello
|
|
3434
|
+
* textSize(64);
|
|
3435
|
+
* text('Hello!', -97, 97);
|
|
3435
3436
|
* @example
|
|
3436
3437
|
* await Canvas(200);
|
|
3437
3438
|
*
|
|
@@ -3484,7 +3485,7 @@ declare global {
|
|
|
3484
3485
|
* save(bolt, 'bolt.png');
|
|
3485
3486
|
* };
|
|
3486
3487
|
*/
|
|
3487
|
-
function save(data?: object, fileName?: string): void
|
|
3488
|
+
function save(data?: object, fileName?: string): Promise<void>;
|
|
3488
3489
|
|
|
3489
3490
|
/** 🛠
|
|
3490
3491
|
* Returns the number of milliseconds since the program started.
|
|
@@ -4370,7 +4371,7 @@ declare global {
|
|
|
4370
4371
|
/** ⚙
|
|
4371
4372
|
* The q5 draw function is run 60 times per second by default.
|
|
4372
4373
|
*/
|
|
4373
|
-
static draw(): void
|
|
4374
|
+
static draw(): void | Promise<void>;
|
|
4374
4375
|
|
|
4375
4376
|
/** ⚙
|
|
4376
4377
|
* Runs after each `draw` function call and post-draw q5 addon processes, if any.
|
|
@@ -4380,12 +4381,12 @@ declare global {
|
|
|
4380
4381
|
* addons like q5play that auto-draw to the canvas after the `draw`
|
|
4381
4382
|
* function is run.
|
|
4382
4383
|
*/
|
|
4383
|
-
static postProcess(): void
|
|
4384
|
+
static postProcess(): void | Promise<void>;
|
|
4384
4385
|
//-
|
|
4385
4386
|
static update(): void;
|
|
4386
4387
|
update(): void;
|
|
4387
|
-
draw(): void
|
|
4388
|
-
postProcess(): void
|
|
4388
|
+
draw(): void | Promise<void>;
|
|
4389
|
+
postProcess(): void | Promise<void>;
|
|
4389
4390
|
Canvas: typeof Canvas;
|
|
4390
4391
|
log: typeof log;
|
|
4391
4392
|
circle: typeof circle;
|
package/q5.js
CHANGED
|
@@ -923,35 +923,37 @@ Q5.renderers.c2d.canvas = ($, q) => {
|
|
|
923
923
|
};
|
|
924
924
|
|
|
925
925
|
$.fill = function (c) {
|
|
926
|
-
$.
|
|
926
|
+
$.__doFill = $._fillSet = true;
|
|
927
927
|
if (Q5.Color) {
|
|
928
928
|
if (!c._isColor && (typeof c != 'string' || $._namedColors[c])) {
|
|
929
929
|
c = $.color(...arguments);
|
|
930
930
|
}
|
|
931
|
-
if (c.a <= 0) return ($.
|
|
931
|
+
if (c.a <= 0) return ($.__doFill = false);
|
|
932
932
|
}
|
|
933
933
|
$.ctx.fillStyle = $._fill = c.toString();
|
|
934
934
|
};
|
|
935
935
|
|
|
936
936
|
$.stroke = function (c) {
|
|
937
|
-
$.
|
|
937
|
+
$.__doStroke = $._strokeSet = true;
|
|
938
938
|
if (Q5.Color) {
|
|
939
939
|
if (!c._isColor && (typeof c != 'string' || $._namedColors[c])) {
|
|
940
940
|
c = $.color(...arguments);
|
|
941
941
|
}
|
|
942
|
-
if (c.a <= 0) return ($.
|
|
942
|
+
if (c.a <= 0) return ($.__doStroke = false);
|
|
943
943
|
}
|
|
944
944
|
$.ctx.strokeStyle = $._stroke = c.toString();
|
|
945
945
|
};
|
|
946
946
|
|
|
947
947
|
$.strokeWeight = (n) => {
|
|
948
|
-
if (!n) $.
|
|
949
|
-
else $.
|
|
948
|
+
if (!n) $.__doStroke = false;
|
|
949
|
+
else $.__doStroke = true;
|
|
950
950
|
$.ctx.lineWidth = $._strokeWeight = n || 0.0001;
|
|
951
951
|
};
|
|
952
952
|
|
|
953
|
-
$.noFill = () => ($.
|
|
954
|
-
$.noStroke = () => ($.
|
|
953
|
+
$.noFill = () => ($.__doFill = false);
|
|
954
|
+
$.noStroke = () => ($.__doStroke = false);
|
|
955
|
+
$._doFill = () => ($.__doFill = true);
|
|
956
|
+
$._doStroke = () => ($.__doStroke = true);
|
|
955
957
|
$.opacity = (a) => ($.ctx.globalAlpha = a);
|
|
956
958
|
|
|
957
959
|
$._doShadow = false;
|
|
@@ -1023,8 +1025,8 @@ Q5.renderers.c2d.canvas = ($, q) => {
|
|
|
1023
1025
|
'_fill',
|
|
1024
1026
|
'_stroke',
|
|
1025
1027
|
'_strokeWeight',
|
|
1026
|
-
'
|
|
1027
|
-
'
|
|
1028
|
+
'__doFill',
|
|
1029
|
+
'__doStroke',
|
|
1028
1030
|
'_fillSet',
|
|
1029
1031
|
'_strokeSet',
|
|
1030
1032
|
'_shadow',
|
|
@@ -1082,8 +1084,8 @@ Q5.renderers.c2d.canvas = ($, q) => {
|
|
|
1082
1084
|
};
|
|
1083
1085
|
};
|
|
1084
1086
|
Q5.renderers.c2d.shapes = ($) => {
|
|
1085
|
-
$.
|
|
1086
|
-
$.
|
|
1087
|
+
$.__doStroke = true;
|
|
1088
|
+
$.__doFill = true;
|
|
1087
1089
|
$._strokeSet = false;
|
|
1088
1090
|
$._fillSet = false;
|
|
1089
1091
|
$._ellipseMode = Q5.CENTER;
|
|
@@ -1093,8 +1095,8 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1093
1095
|
let curveBuff = [];
|
|
1094
1096
|
|
|
1095
1097
|
function ink() {
|
|
1096
|
-
if ($.
|
|
1097
|
-
if ($.
|
|
1098
|
+
if ($.__doFill) $.ctx.fill();
|
|
1099
|
+
if ($.__doStroke) $.ctx.stroke();
|
|
1098
1100
|
}
|
|
1099
1101
|
|
|
1100
1102
|
// DRAWING SETTINGS
|
|
@@ -1109,7 +1111,7 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1109
1111
|
// DRAWING
|
|
1110
1112
|
|
|
1111
1113
|
$.line = (x0, y0, x1, y1) => {
|
|
1112
|
-
if ($.
|
|
1114
|
+
if ($.__doStroke) {
|
|
1113
1115
|
$.ctx.beginPath();
|
|
1114
1116
|
$.ctx.moveTo(x0, y0);
|
|
1115
1117
|
$.ctx.lineTo(x1, y1);
|
|
@@ -1137,14 +1139,14 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1137
1139
|
w = Math.abs(w);
|
|
1138
1140
|
h = Math.abs(h);
|
|
1139
1141
|
|
|
1140
|
-
if (!$.
|
|
1142
|
+
if (!$.__doFill && mode == $.PIE_OPEN) mode = $.CHORD_OPEN;
|
|
1141
1143
|
|
|
1142
1144
|
$.ctx.beginPath();
|
|
1143
1145
|
$.ctx.ellipse(x, y, w, h, 0, lo, hi);
|
|
1144
1146
|
if (mode == $.PIE || mode == $.PIE_OPEN) $.ctx.lineTo(x, y);
|
|
1145
|
-
if ($.
|
|
1147
|
+
if ($.__doFill) $.ctx.fill();
|
|
1146
1148
|
|
|
1147
|
-
if ($.
|
|
1149
|
+
if ($.__doStroke) {
|
|
1148
1150
|
if (mode == $.PIE || mode == $.CHORD) $.ctx.closePath();
|
|
1149
1151
|
if (mode != $.PIE_OPEN) return $.ctx.stroke();
|
|
1150
1152
|
|
|
@@ -1198,7 +1200,7 @@ Q5.renderers.c2d.shapes = ($) => {
|
|
|
1198
1200
|
};
|
|
1199
1201
|
|
|
1200
1202
|
$.point = (x, y) => {
|
|
1201
|
-
if ($.
|
|
1203
|
+
if ($.__doStroke) {
|
|
1202
1204
|
if (x.x) {
|
|
1203
1205
|
y = x.y;
|
|
1204
1206
|
x = x.x;
|
|
@@ -2198,7 +2200,7 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
2198
2200
|
let lines = [];
|
|
2199
2201
|
|
|
2200
2202
|
$.text = (str, x, y, w, h) => {
|
|
2201
|
-
if (str === undefined || (!$.
|
|
2203
|
+
if (str === undefined || (!$.__doFill && !$.__doStroke)) return;
|
|
2202
2204
|
str = str.toString();
|
|
2203
2205
|
let ctx = $.ctx;
|
|
2204
2206
|
let img, colorStyle, styleCache, colorCache, recycling;
|
|
@@ -2305,8 +2307,8 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
2305
2307
|
else tX = 0;
|
|
2306
2308
|
|
|
2307
2309
|
ctx.font = $.ctx.font;
|
|
2308
|
-
if ($.
|
|
2309
|
-
if ($.
|
|
2310
|
+
if ($.__doFill && $._fillSet) ctx.fillStyle = $._fill;
|
|
2311
|
+
if ($.__doStroke && $._strokeSet) ctx.strokeStyle = $._stroke;
|
|
2310
2312
|
ctx.lineWidth = $.ctx.lineWidth;
|
|
2311
2313
|
}
|
|
2312
2314
|
|
|
@@ -2318,8 +2320,8 @@ Q5.renderers.c2d.text = ($, q) => {
|
|
|
2318
2320
|
|
|
2319
2321
|
let lineAmount = 0;
|
|
2320
2322
|
for (let line of lines) {
|
|
2321
|
-
if ($.
|
|
2322
|
-
if ($.
|
|
2323
|
+
if ($.__doStroke && $._strokeSet) ctx.strokeText(line, tX, tY);
|
|
2324
|
+
if ($.__doFill) ctx.fillText(line, tX, tY);
|
|
2323
2325
|
tY += leading;
|
|
2324
2326
|
lineAmount++;
|
|
2325
2327
|
if (lineAmount >= h) break;
|
|
@@ -9012,61 +9014,67 @@ Q5.MAX_CHARS = 100000;
|
|
|
9012
9014
|
Q5.MAX_TEXTS = 10000;
|
|
9013
9015
|
|
|
9014
9016
|
Q5.initWebGPU = async () => {
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
}
|
|
9017
|
+
Q5._gpuTask ??= Q5._requestGPU();
|
|
9018
|
+
return Q5._gpuTask;
|
|
9019
|
+
};
|
|
9019
9020
|
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9021
|
+
Q5._requestGPU = async () => {
|
|
9022
|
+
try {
|
|
9023
|
+
if (!navigator.gpu) {
|
|
9024
|
+
console.warn('q5 WebGPU not supported on this browser! Use Google Chrome or Edge.');
|
|
9025
|
+
return false;
|
|
9026
|
+
}
|
|
9023
9027
|
|
|
9024
|
-
|
|
9028
|
+
let adapter = await navigator.gpu.requestAdapter();
|
|
9025
9029
|
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9030
|
+
adapter ??= await navigator.gpu.requestAdapter({
|
|
9031
|
+
featureLevel: 'compatibility'
|
|
9032
|
+
});
|
|
9029
9033
|
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
+
if (!adapter) {
|
|
9035
|
+
console.warn('q5 WebGPU could not start! No appropriate GPUAdapter found, Vulkan may need to be enabled.');
|
|
9036
|
+
return false;
|
|
9037
|
+
}
|
|
9034
9038
|
|
|
9035
|
-
|
|
9039
|
+
let device = await adapter.requestDevice();
|
|
9036
9040
|
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9041
|
+
const vertexStorageLimit =
|
|
9042
|
+
device.limits.maxStorageBuffersInVertexStage ?? device.limits.maxStorageBuffersPerShaderStage;
|
|
9043
|
+
if (vertexStorageLimit < 3) {
|
|
9044
|
+
console.warn('q5 WebGPU requires vertex storage buffers, which are not supported by this device.');
|
|
9045
|
+
return false;
|
|
9046
|
+
}
|
|
9043
9047
|
|
|
9044
|
-
|
|
9045
|
-
|
|
9048
|
+
// Update to fit device limits
|
|
9049
|
+
const maxStorage = device.limits.maxStorageBufferBindingSize;
|
|
9046
9050
|
|
|
9047
|
-
|
|
9048
|
-
|
|
9051
|
+
let min = Math.min,
|
|
9052
|
+
floor = Math.floor;
|
|
9049
9053
|
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9054
|
+
Q5.MAX_TRANSFORMS = min(Q5.MAX_TRANSFORMS, floor(maxStorage / 64));
|
|
9055
|
+
Q5.MAX_RECTS = min(Q5.MAX_RECTS, floor(maxStorage / 64));
|
|
9056
|
+
Q5.MAX_ELLIPSES = min(Q5.MAX_ELLIPSES, floor(maxStorage / 64));
|
|
9057
|
+
Q5.MAX_CHARS = min(Q5.MAX_CHARS, floor(maxStorage / 16));
|
|
9058
|
+
Q5.MAX_TEXTS = min(Q5.MAX_TEXTS, floor(maxStorage / 32));
|
|
9055
9059
|
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
+
device.lost.then((e) => {
|
|
9061
|
+
console.error('WebGPU crashed!');
|
|
9062
|
+
console.error(e);
|
|
9063
|
+
});
|
|
9060
9064
|
|
|
9061
|
-
|
|
9065
|
+
Q5.device = device;
|
|
9062
9066
|
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9067
|
+
if (typeof window == 'object') {
|
|
9068
|
+
window.addEventListener('pagehide', () => {
|
|
9069
|
+
if (device) device.destroy();
|
|
9070
|
+
});
|
|
9071
|
+
}
|
|
9068
9072
|
|
|
9069
|
-
|
|
9073
|
+
return true;
|
|
9074
|
+
} catch (e) {
|
|
9075
|
+
console.warn('q5 WebGPU could not start!', e);
|
|
9076
|
+
return false;
|
|
9077
|
+
}
|
|
9070
9078
|
};
|
|
9071
9079
|
|
|
9072
9080
|
Q5.WebGPU = async function (scope, parent) {
|
package/q5.pyi
CHANGED
|
@@ -4399,11 +4399,11 @@ Each function receives two input parameters:
|
|
|
4399
4399
|
- the q5 instance
|
|
4400
4400
|
- a proxy for editing the q5 instance and corresponding properties of the global scope"""
|
|
4401
4401
|
|
|
4402
|
-
def draw(self) -> None:
|
|
4402
|
+
def draw(self) -> None | object:
|
|
4403
4403
|
"""⚙ The q5 draw function is run 60 times per second by default."""
|
|
4404
4404
|
...
|
|
4405
4405
|
|
|
4406
|
-
def postProcess(self) -> None:
|
|
4406
|
+
def postProcess(self) -> None | object:
|
|
4407
4407
|
"""⚙ Runs after each draw function call and post-draw q5 addon processes, if any.
|
|
4408
4408
|
|
|
4409
4409
|
Useful for adding post-processing effects when it's not possible
|