q5 4.7.3 → 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.
Files changed (4) hide show
  1. package/package.json +3 -3
  2. package/q5.d.ts +11 -10
  3. package/q5.js +48 -42
  4. package/q5.pyi +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "q5",
3
- "version": "4.7.3",
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": "^25.0.1",
73
+ "jsdom": "^29.1.1",
74
74
  "json2csv": "^6.0.0-alpha.2",
75
- "skia-canvas": "^1.0.2",
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(28);
3434
- * text('Hello, world!', -97, 100);
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
@@ -9014,61 +9014,67 @@ Q5.MAX_CHARS = 100000;
9014
9014
  Q5.MAX_TEXTS = 10000;
9015
9015
 
9016
9016
  Q5.initWebGPU = async () => {
9017
- if (!navigator.gpu) {
9018
- console.warn('q5 WebGPU not supported on this browser! Use Google Chrome or Edge.');
9019
- return;
9020
- }
9017
+ Q5._gpuTask ??= Q5._requestGPU();
9018
+ return Q5._gpuTask;
9019
+ };
9021
9020
 
9022
- // fn can only be called once
9023
- if (Q5.requestedGPU) return;
9024
- Q5.requestedGPU = true;
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
+ }
9025
9027
 
9026
- let adapter = await navigator.gpu.requestAdapter();
9028
+ let adapter = await navigator.gpu.requestAdapter();
9027
9029
 
9028
- adapter ??= await navigator.gpu.requestAdapter({
9029
- featureLevel: 'compatibility'
9030
- });
9030
+ adapter ??= await navigator.gpu.requestAdapter({
9031
+ featureLevel: 'compatibility'
9032
+ });
9031
9033
 
9032
- if (!adapter) {
9033
- console.warn('q5 WebGPU could not start! No appropriate GPUAdapter found, Vulkan may need to be enabled.');
9034
- return;
9035
- }
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
+ }
9036
9038
 
9037
- let device = await adapter.requestDevice();
9039
+ let device = await adapter.requestDevice();
9038
9040
 
9039
- const vertexStorageLimit =
9040
- device.limits.maxStorageBuffersInVertexStage ?? device.limits.maxStorageBuffersPerShaderStage;
9041
- if (vertexStorageLimit < 3) {
9042
- console.warn('q5 WebGPU requires vertex storage buffers, which are not supported by this device.');
9043
- return;
9044
- }
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
+ }
9045
9047
 
9046
- // Update to fit device limits
9047
- const maxStorage = device.limits.maxStorageBufferBindingSize;
9048
+ // Update to fit device limits
9049
+ const maxStorage = device.limits.maxStorageBufferBindingSize;
9048
9050
 
9049
- let min = Math.min,
9050
- floor = Math.floor;
9051
+ let min = Math.min,
9052
+ floor = Math.floor;
9051
9053
 
9052
- Q5.MAX_TRANSFORMS = min(Q5.MAX_TRANSFORMS, floor(maxStorage / 64));
9053
- Q5.MAX_RECTS = min(Q5.MAX_RECTS, floor(maxStorage / 64));
9054
- Q5.MAX_ELLIPSES = min(Q5.MAX_ELLIPSES, floor(maxStorage / 64));
9055
- Q5.MAX_CHARS = min(Q5.MAX_CHARS, floor(maxStorage / 16));
9056
- Q5.MAX_TEXTS = min(Q5.MAX_TEXTS, floor(maxStorage / 32));
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));
9057
9059
 
9058
- device.lost.then((e) => {
9059
- console.error('WebGPU crashed!');
9060
- console.error(e);
9061
- });
9060
+ device.lost.then((e) => {
9061
+ console.error('WebGPU crashed!');
9062
+ console.error(e);
9063
+ });
9062
9064
 
9063
- Q5.device = device;
9065
+ Q5.device = device;
9064
9066
 
9065
- if (typeof window == 'object') {
9066
- window.addEventListener('pagehide', () => {
9067
- if (device) device.destroy();
9068
- });
9069
- }
9067
+ if (typeof window == 'object') {
9068
+ window.addEventListener('pagehide', () => {
9069
+ if (device) device.destroy();
9070
+ });
9071
+ }
9070
9072
 
9071
- return true;
9073
+ return true;
9074
+ } catch (e) {
9075
+ console.warn('q5 WebGPU could not start!', e);
9076
+ return false;
9077
+ }
9072
9078
  };
9073
9079
 
9074
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