q5 4.7.3 → 4.7.5
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 +3 -3
- package/q5.d.ts +11 -10
- package/q5.js +58 -50
- package/q5.pyi +2 -2
package/deno.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "q5",
|
|
3
|
-
"version": "4.7.
|
|
3
|
+
"version": "4.7.5",
|
|
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
|
@@ -5420,6 +5420,8 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
5420
5420
|
|
|
5421
5421
|
if ($.colorMode) $.colorMode('rgb', 1);
|
|
5422
5422
|
|
|
5423
|
+
const CANVAS_FORMAT = navigator.gpu.getPreferredCanvasFormat();
|
|
5424
|
+
|
|
5423
5425
|
$._baseShaderCode = /* wgsl */ `
|
|
5424
5426
|
struct Q5 {
|
|
5425
5427
|
width: f32,
|
|
@@ -6608,7 +6610,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
6608
6610
|
fragment: {
|
|
6609
6611
|
module: shapesShader,
|
|
6610
6612
|
entryPoint: 'fragMain',
|
|
6611
|
-
targets: [{ format:
|
|
6613
|
+
targets: [{ format: CANVAS_FORMAT, blend: $.blendConfigs['source-over'] }]
|
|
6612
6614
|
},
|
|
6613
6615
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
6614
6616
|
multisample: { count: 4 }
|
|
@@ -7170,7 +7172,7 @@ fn vertexMain(v: VertexParams) -> FragParams {
|
|
|
7170
7172
|
entryPoint: 'fragMain',
|
|
7171
7173
|
targets: [
|
|
7172
7174
|
{
|
|
7173
|
-
format:
|
|
7175
|
+
format: CANVAS_FORMAT,
|
|
7174
7176
|
blend: $.blendConfigs['source-over']
|
|
7175
7177
|
}
|
|
7176
7178
|
]
|
|
@@ -7532,7 +7534,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7532
7534
|
entryPoint: 'fragMain',
|
|
7533
7535
|
targets: [
|
|
7534
7536
|
{
|
|
7535
|
-
format:
|
|
7537
|
+
format: CANVAS_FORMAT,
|
|
7536
7538
|
blend: $.blendConfigs['source-over']
|
|
7537
7539
|
}
|
|
7538
7540
|
]
|
|
@@ -7805,7 +7807,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7805
7807
|
fragment: {
|
|
7806
7808
|
module: imageShader,
|
|
7807
7809
|
entryPoint: 'fragMain',
|
|
7808
|
-
targets: [{ format:
|
|
7810
|
+
targets: [{ format: CANVAS_FORMAT, blend: $.blendConfigs['source-over'] }]
|
|
7809
7811
|
},
|
|
7810
7812
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
7811
7813
|
multisample: { count: 4 }
|
|
@@ -7824,7 +7826,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7824
7826
|
fragment: {
|
|
7825
7827
|
module: videoShader,
|
|
7826
7828
|
entryPoint: 'fragMain',
|
|
7827
|
-
targets: [{ format:
|
|
7829
|
+
targets: [{ format: CANVAS_FORMAT, blend: $.blendConfigs['source-over'] }]
|
|
7828
7830
|
},
|
|
7829
7831
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
7830
7832
|
multisample: { count: 4 }
|
|
@@ -7922,7 +7924,7 @@ fn fragMain(f: FragParams) -> @location(0) vec4f {
|
|
|
7922
7924
|
|
|
7923
7925
|
texture = Q5.device.createTexture({
|
|
7924
7926
|
size: textureSize,
|
|
7925
|
-
format:
|
|
7927
|
+
format: CANVAS_FORMAT,
|
|
7926
7928
|
usage:
|
|
7927
7929
|
GPUTextureUsage.TEXTURE_BINDING |
|
|
7928
7930
|
GPUTextureUsage.COPY_SRC |
|
|
@@ -8294,7 +8296,7 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
8294
8296
|
fragment: {
|
|
8295
8297
|
module: textShader,
|
|
8296
8298
|
entryPoint: 'fragMain',
|
|
8297
|
-
targets: [{ format:
|
|
8299
|
+
targets: [{ format: CANVAS_FORMAT, blend: $.blendConfigs['source-over'] }]
|
|
8298
8300
|
},
|
|
8299
8301
|
primitive: { topology: 'triangle-strip', stripIndexFormat: 'uint32' },
|
|
8300
8302
|
multisample: { count: 4 }
|
|
@@ -8858,7 +8860,7 @@ fn fragMain(f : FragParams) -> @location(0) vec4f {
|
|
|
8858
8860
|
entryPoint: 'fragMain',
|
|
8859
8861
|
targets: [
|
|
8860
8862
|
{
|
|
8861
|
-
format:
|
|
8863
|
+
format: CANVAS_FORMAT,
|
|
8862
8864
|
blend: $.blendConfigs[blend]
|
|
8863
8865
|
}
|
|
8864
8866
|
]
|
|
@@ -9014,61 +9016,67 @@ Q5.MAX_CHARS = 100000;
|
|
|
9014
9016
|
Q5.MAX_TEXTS = 10000;
|
|
9015
9017
|
|
|
9016
9018
|
Q5.initWebGPU = async () => {
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
}
|
|
9019
|
+
Q5._gpuTask ??= Q5._requestGPU();
|
|
9020
|
+
return Q5._gpuTask;
|
|
9021
|
+
};
|
|
9021
9022
|
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9023
|
+
Q5._requestGPU = async () => {
|
|
9024
|
+
try {
|
|
9025
|
+
if (!navigator.gpu) {
|
|
9026
|
+
console.warn('q5 WebGPU not supported on this browser! Use Google Chrome or Edge.');
|
|
9027
|
+
return false;
|
|
9028
|
+
}
|
|
9025
9029
|
|
|
9026
|
-
|
|
9030
|
+
let adapter = await navigator.gpu.requestAdapter();
|
|
9027
9031
|
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9032
|
+
adapter ??= await navigator.gpu.requestAdapter({
|
|
9033
|
+
featureLevel: 'compatibility'
|
|
9034
|
+
});
|
|
9031
9035
|
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
+
if (!adapter) {
|
|
9037
|
+
console.warn('q5 WebGPU could not start! No appropriate GPUAdapter found, Vulkan may need to be enabled.');
|
|
9038
|
+
return false;
|
|
9039
|
+
}
|
|
9036
9040
|
|
|
9037
|
-
|
|
9041
|
+
let device = await adapter.requestDevice();
|
|
9038
9042
|
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9043
|
+
const vertexStorageLimit =
|
|
9044
|
+
device.limits.maxStorageBuffersInVertexStage ?? device.limits.maxStorageBuffersPerShaderStage;
|
|
9045
|
+
if (vertexStorageLimit < 3) {
|
|
9046
|
+
console.warn('q5 WebGPU requires vertex storage buffers, which are not supported by this device.');
|
|
9047
|
+
return false;
|
|
9048
|
+
}
|
|
9045
9049
|
|
|
9046
|
-
|
|
9047
|
-
|
|
9050
|
+
// Update to fit device limits
|
|
9051
|
+
const maxStorage = device.limits.maxStorageBufferBindingSize;
|
|
9048
9052
|
|
|
9049
|
-
|
|
9050
|
-
|
|
9053
|
+
let min = Math.min,
|
|
9054
|
+
floor = Math.floor;
|
|
9051
9055
|
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9056
|
+
Q5.MAX_TRANSFORMS = min(Q5.MAX_TRANSFORMS, floor(maxStorage / 64));
|
|
9057
|
+
Q5.MAX_RECTS = min(Q5.MAX_RECTS, floor(maxStorage / 64));
|
|
9058
|
+
Q5.MAX_ELLIPSES = min(Q5.MAX_ELLIPSES, floor(maxStorage / 64));
|
|
9059
|
+
Q5.MAX_CHARS = min(Q5.MAX_CHARS, floor(maxStorage / 16));
|
|
9060
|
+
Q5.MAX_TEXTS = min(Q5.MAX_TEXTS, floor(maxStorage / 32));
|
|
9057
9061
|
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
+
device.lost.then((e) => {
|
|
9063
|
+
console.error('WebGPU crashed!');
|
|
9064
|
+
console.error(e);
|
|
9065
|
+
});
|
|
9062
9066
|
|
|
9063
|
-
|
|
9067
|
+
Q5.device = device;
|
|
9064
9068
|
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9069
|
+
if (typeof window == 'object') {
|
|
9070
|
+
window.addEventListener('pagehide', () => {
|
|
9071
|
+
if (device) device.destroy();
|
|
9072
|
+
});
|
|
9073
|
+
}
|
|
9070
9074
|
|
|
9071
|
-
|
|
9075
|
+
return true;
|
|
9076
|
+
} catch (e) {
|
|
9077
|
+
console.warn('q5 WebGPU could not start!', e);
|
|
9078
|
+
return false;
|
|
9079
|
+
}
|
|
9072
9080
|
};
|
|
9073
9081
|
|
|
9074
9082
|
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
|