q5 3.9.4 → 4.0.1

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/q5.d.ts CHANGED
@@ -25,8 +25,8 @@ declare global {
25
25
  * @param {object} [opt] [options](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getContextAttributes)
26
26
  * @returns {Promise<HTMLCanvasElement>} created canvas element
27
27
  * @example
28
- * // Canvas2D
29
- * createCanvas(200, 100);
28
+ * // WebGPU
29
+ * await Canvas(200, 100);
30
30
  * background('silver');
31
31
  * circle(0, 0, 80);
32
32
  */
@@ -35,30 +35,27 @@ declare global {
35
35
  /** ⭐
36
36
  * The q5 draw function is run 60 times per second by default.
37
37
  * @example
38
- * function draw() {
38
+ * q5.draw = function () {
39
39
  * background('silver');
40
40
  * circle(mouseX, mouseY, 80);
41
- * }
41
+ * };
42
42
  */
43
43
  function draw(): void;
44
44
 
45
45
  /** ⭐
46
- * Logs a message to the JavaScript console.
46
+ * Logs a message to the JavaScript [console](https://developer.mozilla.org/docs/Web/API/console/log_static).
47
47
  *
48
48
  * To view the console, open your browser's web developer tools
49
49
  * via the keyboard shortcut `Ctrl + Shift + i` or `command + option + i`,
50
50
  * then click the "Console" tab.
51
51
  *
52
- * This is an alias for the standard
53
- * [`console.log`](https://developer.mozilla.org/docs/Web/API/console/log_static) function.
54
- *
55
- * When you're curious about what your code is doing, use `log()`!
52
+ * Use `log` when you're curious about what your code is doing!
56
53
  * @param {*} message
57
54
  * @example
58
- * function draw() {
55
+ * q5.draw = function () {
59
56
  * circle(mouseX, mouseY, 80);
60
57
  * log('The mouse is at:', mouseX, mouseY);
61
- * }
58
+ * };
62
59
  */
63
60
  function log(message: any): void;
64
61
 
@@ -70,8 +67,8 @@ declare global {
70
67
  * @param {number} y y-coordinate
71
68
  * @param {number} diameter diameter of the circle
72
69
  * @example
73
- * createCanvas(200, 100);
74
- * circle(100, 50, 80);
70
+ * await Canvas(200, 100);
71
+ * circle(0, 0, 80);
75
72
  */
76
73
  function circle(x: number, y: number, diameter: number): void;
77
74
 
@@ -80,29 +77,29 @@ declare global {
80
77
  * @param {number} x x-coordinate
81
78
  * @param {number} y y-coordinate
82
79
  * @param {number} width width of the ellipse
83
- * @param {number} [height] height of the ellipse
80
+ * @param {number} height height of the ellipse
84
81
  * @example
85
- * createCanvas(200, 100);
86
- * ellipse(100, 50, 160, 80);
82
+ * await Canvas(200, 100);
83
+ * ellipse(0, 0, 160, 80);
87
84
  */
88
- function ellipse(x: number, y: number, width: number, height?: number): void;
85
+ function ellipse(x: number, y: number, width: number, height: number): void;
89
86
 
90
87
  /** 🧑‍🎨
91
88
  * Draws a rectangle or a rounded rectangle.
92
89
  * @param {number} x x-coordinate
93
90
  * @param {number} y y-coordinate
94
91
  * @param {number} w width of the rectangle
95
- * @param {number} [h] height of the rectangle
92
+ * @param {number} h height of the rectangle
96
93
  * @param {number} [rounded] radius for all corners
97
94
  * @example
98
- * createCanvas(200);
99
- * background(200);
95
+ * await Canvas(200);
96
+ * background(0.8);
100
97
  *
101
- * rect(30, 20, 40, 60);
102
- * rect(80, 70, 40, 60, 10);
103
- * rect(130, 120, 40, 60, 30, 2, 8, 20);
98
+ * rect(-70, -80, 40, 60);
99
+ * rect(-20, -30, 40, 60, 10);
100
+ * rect(30, 20, 40, 60, 30);
104
101
  */
105
- function rect(x: number, y: number, w: number, h?: number, rounded?: number): void;
102
+ function rect(x: number, y: number, w: number, h: number, rounded?: number): void;
106
103
 
107
104
  /** 🧑‍🎨
108
105
  * Draws a square or a rounded square.
@@ -111,12 +108,12 @@ declare global {
111
108
  * @param {number} size size of the sides of the square
112
109
  * @param {number} [rounded] radius for all corners
113
110
  * @example
114
- * createCanvas(200);
115
- * background(200);
111
+ * await Canvas(200);
112
+ * background(0.8);
116
113
  *
117
- * square(30, 30, 40);
118
- * square(80, 80, 40, 10);
119
- * square(130, 130, 40, 30, 2, 8, 20);
114
+ * square(-70, -70, 40);
115
+ * square(-20, -20, 40, 10);
116
+ * square(30, 30, 40, 30);
120
117
  */
121
118
  function square(x: number, y: number, size: number, rounded?: number): void;
122
119
 
@@ -125,12 +122,12 @@ declare global {
125
122
  * @param {number} x x-coordinate
126
123
  * @param {number} y y-coordinate
127
124
  * @example
128
- * createCanvas(200, 100);
125
+ * await Canvas(200, 100);
129
126
  * stroke('white');
130
- * point(75, 50);
127
+ * point(-25, 0);
131
128
  *
132
129
  * strokeWeight(10);
133
- * point(125, 50);
130
+ * point(25, 0);
134
131
  */
135
132
  function point(x: number, y: number): void;
136
133
 
@@ -141,9 +138,9 @@ declare global {
141
138
  * @param {number} x2 x-coordinate of the second point
142
139
  * @param {number} y2 y-coordinate of the second point
143
140
  * @example
144
- * createCanvas(200, 100);
141
+ * await Canvas(200, 100);
145
142
  * stroke('lime');
146
- * line(20, 20, 180, 80);
143
+ * line(-80, -30, 80, 30);
147
144
  */
148
145
  function line(x1: number, y1: number, x2: number, y2: number): void;
149
146
 
@@ -155,17 +152,17 @@ declare global {
155
152
  * @param {number} y2 y-coordinate of the second point
156
153
  * @param {number} r radius of the capsule semi-circle ends
157
154
  * @example
158
- * createCanvas(200, 100);
159
- * background(200);
155
+ * await Canvas(200, 100);
156
+ * background(0.8);
160
157
  * strokeWeight(5);
161
- * capsule(40, 40, 160, 60, 10);
158
+ * capsule(-60, -10, 60, 10, 10);
162
159
  * @example
163
- * function draw() {
164
- * background(200);
160
+ * q5.draw = function () {
161
+ * background(0.8);
165
162
  * fill('cyan');
166
163
  * strokeWeight(10);
167
- * capsule(100, 100, mouseX, mouseY, 20);
168
- * }
164
+ * capsule(0, 0, mouseX, mouseY, 20);
165
+ * };
169
166
  */
170
167
  function capsule(x1: number, y1: number, x2: number, y2: number, r: number): void;
171
168
 
@@ -176,33 +173,33 @@ declare global {
176
173
  * `rect` and `square` are interpreted.
177
174
  * @param {string} mode
178
175
  * @example
179
- * createCanvas(200, 100);
180
- * background(200);
176
+ * await Canvas(200, 100);
177
+ * background(0.8);
181
178
  * rectMode(CORNER);
182
179
  *
183
- * // ( x, y, w, h)
184
- * rect(50, 25, 100, 50);
180
+ * // ( x, y, w, h)
181
+ * rect(-50, -25, 100, 50);
185
182
  * @example
186
- * createCanvas(200, 100);
187
- * background(200);
183
+ * await Canvas(200, 100);
184
+ * background(0.8);
188
185
  * rectMode(CENTER);
189
186
  *
190
- * // ( cX, cY, w, h)
191
- * rect(100, 50, 100, 50);
187
+ * // (cX, cY, w, h)
188
+ * rect(0, 0, 100, 50);
192
189
  * @example
193
- * createCanvas(200, 100);
194
- * background(200);
190
+ * await Canvas(200, 100);
191
+ * background(0.8);
195
192
  * rectMode(RADIUS);
196
193
  *
197
- * // ( cX, cY, rX, rY)
198
- * rect(100, 50, 50, 25);
194
+ * // (cX, cY, rX, rY)
195
+ * rect(0, 0, 50, 25);
199
196
  * @example
200
- * createCanvas(200, 100);
201
- * background(200);
197
+ * await Canvas(200, 100);
198
+ * background(0.8);
202
199
  * rectMode(CORNERS);
203
200
  *
204
- * // ( x1, y1, x2, y2)
205
- * rect(50, 25, 150, 75);
201
+ * // ( x1, y1, x2, y2)
202
+ * rect(-50, -25, 50, 25);
206
203
  */
207
204
  function rectMode(mode: string): void;
208
205
 
@@ -213,33 +210,33 @@ declare global {
213
210
  * `ellipse`, `circle`, and `arc` are interpreted.
214
211
  * @param {string} mode
215
212
  * @example
216
- * createCanvas(200, 100);
217
- * background(200);
213
+ * await Canvas(200, 100);
214
+ * background(0.8);
218
215
  * ellipseMode(CENTER);
219
216
  *
220
- * // ( x, y, w, h)
221
- * ellipse(100, 50, 100, 50);
217
+ * // (x, y, w, h)
218
+ * ellipse(0, 0, 100, 50);
222
219
  * @example
223
- * createCanvas(200, 100);
224
- * background(200);
220
+ * await Canvas(200, 100);
221
+ * background(0.8);
225
222
  * ellipseMode(RADIUS);
226
223
  *
227
- * // ( x, y, rX, rY)
228
- * ellipse(100, 50, 50, 25);
224
+ * // (x, y, rX, rY)
225
+ * ellipse(0, 0, 50, 25);
229
226
  * @example
230
- * createCanvas(200, 100);
231
- * background(200);
227
+ * await Canvas(200, 100);
228
+ * background(0.8);
232
229
  * ellipseMode(CORNER);
233
230
  *
234
- * // (lX, tY, w, h)
235
- * ellipse(50, 25, 100, 50);
231
+ * // ( lX, tY, w, h)
232
+ * ellipse(-50, -25, 100, 50);
236
233
  * @example
237
- * createCanvas(200, 100);
238
- * background(200);
234
+ * await Canvas(200, 100);
235
+ * background(0.8);
239
236
  * ellipseMode(CORNERS);
240
237
  *
241
- * // ( x1, y1, x2, y2)
242
- * ellipse(50, 25, 150, 75);
238
+ * // ( x1, y1, x2, y2)
239
+ * ellipse(-50, -25, 50, 25);
243
240
  */
244
241
  function ellipseMode(mode: string): void;
245
242
 
@@ -267,13 +264,18 @@ declare global {
267
264
  * @param {string} url url of the image to load
268
265
  * @returns {Q5.Image & PromiseLike<Q5.Image>} image
269
266
  * @example
270
- * createCanvas(200);
267
+ * await Canvas(200);
271
268
  *
272
269
  * let logo = loadImage('/q5js_logo.avif');
273
270
  *
274
- * function draw() {
271
+ * q5.draw = function () {
275
272
  * background(logo);
276
- * }
273
+ * };
274
+ * @example
275
+ * await Canvas(200);
276
+ *
277
+ * let logo = await loadImage('/q5js_logo.avif');
278
+ * background(logo);
277
279
  */
278
280
  function loadImage(url: string): Q5.Image & PromiseLike<Q5.Image>;
279
281
 
@@ -289,21 +291,21 @@ declare global {
289
291
  * @param {number} [sw] width of the subsection of the source image
290
292
  * @param {number} [sh] height of the subsection of the source image
291
293
  * @example
292
- * createCanvas(200);
294
+ * await Canvas(200);
293
295
  *
294
- * let logo = loadImage('/q5js_logo.avif');
296
+ * let logo = load('/q5js_logo.avif');
295
297
  *
296
- * function draw() {
297
- * image(logo, 0, 0, 200, 200);
298
- * }
298
+ * q5.draw = function () {
299
+ * image(logo, -100, -100, 200, 200);
300
+ * };
299
301
  * @example
300
- * createCanvas(200);
302
+ * await Canvas(200);
301
303
  *
302
- * let logo = loadImage('/q5js_logo.avif');
304
+ * let logo = load('/q5js_logo.avif');
303
305
  *
304
- * function draw() {
305
- * image(logo, 0, 0, 200, 200, 256, 256, 512, 512);
306
- * }
306
+ * q5.draw = function () {
307
+ * image(logo, -100, -100, 200, 200, 256, 256, 512, 512);
308
+ * };
307
309
  */
308
310
  function image(): void;
309
311
 
@@ -313,35 +315,35 @@ declare global {
313
315
  * Changes how inputs to `image` are interpreted.
314
316
  * @param {string} mode
315
317
  * @example
316
- * createCanvas(200);
317
- * let logo = loadImage('/q5js_logo.avif');
318
+ * await Canvas(200);
319
+ * let logo = load('/q5js_logo.avif');
318
320
  *
319
- * function draw() {
321
+ * q5.draw = function () {
320
322
  * imageMode(CORNER);
321
323
  *
322
- * // ( img, x, y, w, h)
323
- * image(logo, 50, 50, 100, 100);
324
- * }
324
+ * // ( img, x, y, w, h)
325
+ * image(logo, -50, -50, 100, 100);
326
+ * };
325
327
  * @example
326
- * createCanvas(200);
327
- * let logo = loadImage('/q5js_logo.avif');
328
+ * await Canvas(200);
329
+ * let logo = load('/q5js_logo.avif');
328
330
  *
329
- * function draw() {
331
+ * q5.draw = function () {
330
332
  * imageMode(CENTER);
331
333
  *
332
- * // ( img, cX, cY, w, h)
333
- * image(logo, 100, 100, 100, 100);
334
- * }
334
+ * // (img, cX, cY, w, h)
335
+ * image(logo, 0, 0, 100, 100);
336
+ * };
335
337
  * @example
336
- * createCanvas(200);
337
- * let logo = loadImage('/q5js_logo.avif');
338
+ * await Canvas(200);
339
+ * let logo = load('/q5js_logo.avif');
338
340
  *
339
- * function draw() {
341
+ * q5.draw = function () {
340
342
  * imageMode(CORNERS);
341
343
  *
342
- * // ( img, x1, y1, x2, y2)
343
- * image(logo, 50, 50, 100, 100);
344
- * }
344
+ * // ( img, x1, y1, x2, y2)
345
+ * image(logo, -50, -50, 50, 50);
346
+ * };
345
347
  */
346
348
  function imageMode(mode: string): void;
347
349
 
@@ -365,14 +367,12 @@ declare global {
365
367
  * @param {number} w new width
366
368
  * @param {number} h new height
367
369
  * @example
368
- * createCanvas(200);
370
+ * await Canvas(200);
369
371
  *
370
- * let logo = loadImage('/q5js_logo.avif');
372
+ * let logo = await load('/q5js_logo.avif');
371
373
  *
372
- * function setup() {
373
- * logo.resize(128, 128);
374
- * image(logo, 0, 0, 200, 200);
375
- * }
374
+ * logo.resize(128, 128);
375
+ * image(logo, -100, -100, 200, 200);
376
376
  */
377
377
  function resize(w: number, h: number): void;
378
378
 
@@ -387,27 +387,24 @@ declare global {
387
387
  * their actual size. This is the default setting, so running this
388
388
  * function only has an effect if `noSmooth` has been called.
389
389
  * @example
390
- * createCanvas(200);
390
+ * await Canvas(200);
391
+ * smooth();
391
392
  *
392
- * let icon = loadImage('/q5js_icon.png');
393
- *
394
- * function setup() {
395
- * image(icon, 0, 0, 200, 200);
396
- * }
393
+ * let icon = await load('/q5js_icon.png');
394
+ * image(icon, -100, -100, 200, 200);
397
395
  */
398
396
  function smooth(): void;
399
397
 
400
398
  /** 🌆
401
399
  * Disables smooth image rendering for a pixelated look.
400
+ *
401
+ * This setting is applied to images when they're loaded.
402
402
  * @example
403
- * createCanvas(200);
404
- *
405
- * let icon = loadImage('/q5js_icon.png');
403
+ * await Canvas(200);
404
+ * noSmooth();
406
405
  *
407
- * function setup() {
408
- * noSmooth();
409
- * image(icon, 0, 0, 200, 200);
410
- * }
406
+ * let icon = await load('/q5js_icon.png');
407
+ * image(icon, -100, -100, 200, 200);
411
408
  */
412
409
  function noSmooth(): void;
413
410
 
@@ -431,14 +428,12 @@ declare global {
431
428
  * each copy separately.
432
429
  * @param {string | number} color tint color
433
430
  * @example
434
- * createCanvas(200);
431
+ * await Canvas(200);
435
432
  *
436
- * let logo = loadImage('/q5js_logo.avif');
433
+ * let logo = await load('/q5js_logo.avif');
437
434
  *
438
- * function setup() {
439
- * tint(255, 0, 0, 128);
440
- * image(logo, 0, 0, 200, 200);
441
- * }
435
+ * tint(1, 0, 0, 0.5);
436
+ * image(logo, -100, -100, 200, 200);
442
437
  */
443
438
  function tint(color: string | number): void;
444
439
 
@@ -471,14 +466,12 @@ declare global {
471
466
  * @param {number} dw width of the destination region
472
467
  * @param {number} dh height of the destination region
473
468
  * @example
474
- * createCanvas(200);
469
+ * await Canvas(200);
475
470
  *
476
- * let logo = loadImage('/q5js_logo.avif');
471
+ * let logo = await load('/q5js_logo.avif');
477
472
  *
478
- * function setup() {
479
- * logo.inset(256, 256, 512, 512, 0, 0, 256, 256);
480
- * image(logo, 0, 0, 200, 200);
481
- * }
473
+ * logo.inset(256, 256, 512, 512, 0, 0, 256, 256);
474
+ * image(logo, -100, -100, 200, 200);
482
475
  */
483
476
  function inset(sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
484
477
 
@@ -500,24 +493,12 @@ declare global {
500
493
  * @param {number} [h] height of the area, default is 1
501
494
  * @returns {Q5.Image | number[]}
502
495
  * @example
503
- * function draw() {
504
- * background(200);
505
- * noStroke();
506
- * circle(100, 100, frameCount % 200);
496
+ * await Canvas(200);
507
497
  *
508
- * loadPixels();
509
- * let col = get(mouseX, mouseY);
510
- * text(col, mouseX, mouseY);
511
- * }
512
- * @example
513
- * createCanvas(200);
514
- *
515
- * let logo = loadImage('/q5js_logo.avif');
498
+ * let logo = await load('/q5js_logo.avif');
516
499
  *
517
- * function setup() {
518
- * let cropped = logo.get(256, 256, 512, 512);
519
- * image(cropped, 0, 0, 200, 200);
520
- * }
500
+ * let cropped = logo.get(256, 256, 512, 512);
501
+ * image(cropped, -100, -100, 200, 200);
521
502
  */
522
503
  function get(x: number, y: number, w?: number, h?: number): Q5.Image | number[];
523
504
 
@@ -534,13 +515,16 @@ declare global {
534
515
  * @param {number} y
535
516
  * @param {any} val color, canvas, or image
536
517
  * @example
537
- * createCanvas(200);
518
+ * await Canvas(200);
519
+ * noSmooth();
538
520
  * let c = color('lime');
521
+ * let img = createImage(50, 50);
539
522
  *
540
- * function draw() {
541
- * set(random(200), random(200), c);
542
- * updatePixels();
543
- * }
523
+ * q5.draw = function () {
524
+ * img.set(random(50), random(50), c);
525
+ * img.updatePixels();
526
+ * background(img);
527
+ * };
544
528
  */
545
529
  function set(x: number, y: number, val: any): void;
546
530
 
@@ -566,17 +550,18 @@ declare global {
566
550
  *
567
551
  * Not applicable to WebGPU canvases.
568
552
  * @example
553
+ * await Canvas(200);
569
554
  * frameRate(5);
570
- * let icon = loadImage('/q5js_icon.png');
555
+ * let icon = load('/q5js_icon.png');
571
556
  *
572
- * function draw() {
557
+ * q5.draw = function () {
573
558
  * icon.loadPixels();
574
559
  * for (let i = 0; i < icon.pixels.length; i += 16) {
575
- * icon.pixels[i + 1] = random(255);
560
+ * icon.pixels[i + 1] = random(1);
576
561
  * }
577
562
  * icon.updatePixels();
578
563
  * background(icon);
579
- * }
564
+ * };
580
565
  */
581
566
  function loadPixels(): void;
582
567
 
@@ -585,14 +570,18 @@ declare global {
585
570
  *
586
571
  * Not applicable to WebGPU canvases.
587
572
  * @example
588
- * createCanvas(200);
573
+ * await Canvas(200);
574
+ * let c = color('pink');
589
575
  *
590
- * for (let x = 0; x < 200; x += 5) {
591
- * for (let y = 0; y < 200; y += 5) {
592
- * set(x, y, color('pink'));
576
+ * let img = createImage(50, 50);
577
+ * for (let x = 0; x < 50; x += 3) {
578
+ * for (let y = 0; y < 50; y += 3) {
579
+ * img.set(x, y, c);
593
580
  * }
594
581
  * }
595
- * updatePixels();
582
+ * img.updatePixels();
583
+ *
584
+ * background(img);
596
585
  */
597
586
  function updatePixels(): void;
598
587
 
@@ -608,13 +597,10 @@ declare global {
608
597
  * @param {string} type filter type or a CSS filter string
609
598
  * @param {number} [value] optional value, depends on filter type
610
599
  * @example
611
- * createCanvas(200);
612
- * let logo = loadImage('/q5js_logo.avif');
613
- *
614
- * function setup() {
615
- * logo.filter(INVERT);
616
- * image(logo, 0, 0, 200, 200);
617
- * }
600
+ * await Canvas(200);
601
+ * let logo = await load('/q5js_logo.avif');
602
+ * logo.filter(INVERT);
603
+ * image(logo, -100, -100, 200, 200);
618
604
  */
619
605
  function filter(type: string, value?: number): void;
620
606
 
@@ -670,12 +656,22 @@ declare global {
670
656
  /** 🌆
671
657
  * Creates a graphics buffer.
672
658
  *
673
- * Disabled by default in q5 WebGPU.
659
+ * Graphics looping is disabled by default in q5 WebGPU.
674
660
  * See issue [#104](https://github.com/q5js/q5.js/issues/104) for details.
675
661
  * @param {number} w width
676
662
  * @param {number} h height
677
663
  * @param {object} [opt] options
678
664
  * @returns {Q5} a new Q5 graphics buffer
665
+ * @example
666
+ * await Canvas(200);
667
+ *
668
+ * let g = createGraphics(100);
669
+ * g.noLoop();
670
+ * g.stroke('pink');
671
+ * g.fill('red');
672
+ * g.circle(50, 50, 120);
673
+ *
674
+ * image(g, -50, -50, 100, 100);
679
675
  */
680
676
  function createGraphics(w: number, h: number, opt?: any): Q5;
681
677
 
@@ -683,29 +679,26 @@ declare global {
683
679
 
684
680
  /** 📘
685
681
  * Renders text on the canvas.
686
- *
687
- * Text can be positioned with the x and y
688
- * parameters and can optionally be constrained.
689
682
  * @param {string} str string of text to display
690
683
  * @param {number} x x-coordinate of the text's position
691
684
  * @param {number} y y-coordinate of the text's position
692
685
  * @param {number} [wrapWidth] maximum line width in characters
693
686
  * @param {number} [lineLimit] maximum number of lines
694
687
  * @example
695
- * createCanvas(200, 100);
688
+ * await Canvas(200, 100);
696
689
  * background('silver');
697
690
  *
698
691
  * textSize(32);
699
- * text('Hello, world!', 12, 60);
692
+ * text('Hello, world!', -88, 10);
700
693
  * @example
701
- * createCanvas(200);
702
- * background(200);
694
+ * await Canvas(200);
695
+ * background(0.8);
703
696
  * textSize(20);
704
697
  *
705
698
  * let info =
706
- * 'q5.js was designed to make creative coding fun and accessible for a new generation of artists, designers, educators, and beginners.';
699
+ * 'q5.js was designed to make creative coding fun and accessible for artists, designers, educators, and beginners.';
707
700
  *
708
- * text(info, 12, 30, 20, 6);
701
+ * text(info, -88, -70, 20);
709
702
  * //
710
703
  * //
711
704
  */
@@ -714,39 +707,46 @@ declare global {
714
707
  /** 📘
715
708
  * Loads a font from a URL.
716
709
  *
717
- * The font file can be in any format accepted in CSS, such as
718
- * .ttf and .otf files. The first example below loads
719
- * [Robotica](https://www.dafont.com/robotica-courtney.font).
710
+ * The first example below loads [Robotica](https://www.dafont.com/robotica-courtney.font).
720
711
  *
721
- * Also supports loading [Google fonts](https://fonts.google.com/).
722
712
  * The second example loads
723
- * [Pacifico](https://fonts.google.com/specimen/Pacifico).
724
- *
725
- * If no fonts are loaded, the default sans-serif font is used.
713
+ * [Pacifico](https://fonts.google.com/specimen/Pacifico) from [Google fonts](https://fonts.google.com/).
726
714
  *
727
715
  * By default, assets are loaded in parallel before q5 runs `draw`. Use `await` to wait for a font to load.
716
+ *
717
+ * Fonts in [MSDF format](https://github.com/q5js/q5.js/wiki/q5-WebGPU-renderer#text-rendering)
718
+ * with the file ending "-msdf.json" can be used for high performance text rendering. Make your own using the [MSDF font converter](https://msdf-bmfont.donmccurdy.com/).
719
+ *
720
+ * If no fonts are loaded, q5 WebGPU will lazy load the default MSDF font from q5js.org. Until it is loaded, the system's default sans-serif font will be used via `textImage`.
728
721
  * @param {string} url URL of the font to load
729
722
  * @returns {FontFace & PromiseLike<FontFace>} font
730
723
  * @example
731
- * createCanvas(200, 56);
724
+ * await Canvas(200, 56);
732
725
  *
733
- * loadFont('/assets/Robotica.ttf');
726
+ * await loadFont('/assets/Robotica.ttf');
734
727
  *
735
- * function setup() {
736
- * fill('skyblue');
737
- * textSize(64);
738
- * text('Hello!', 2, 54);
739
- * }
728
+ * fill('skyblue');
729
+ * textSize(64);
730
+ * text('Hello!', -98, 24);
740
731
  * @example
741
- * createCanvas(200, 74);
732
+ * await Canvas(200, 74);
742
733
  *
743
734
  * loadFont('fonts.googleapis.com/css2?family=Pacifico');
744
735
  *
745
- * function setup() {
736
+ * q5.draw = function () {
746
737
  * fill('hotpink');
747
738
  * textSize(68);
748
- * text('Hello!', 2, 68);
749
- * }
739
+ * text('Hello!', -98, 31);
740
+ * };
741
+ * //
742
+ * @example
743
+ * await Canvas(200, 74);
744
+ *
745
+ * await loadFont('sans-serif'); // msdf
746
+ *
747
+ * fill('white');
748
+ * textSize(68);
749
+ * text('Hello!', -98, 31);
750
750
  */
751
751
  function loadFont(url: string): FontFace & PromiseLike<FontFace>;
752
752
 
@@ -757,21 +757,19 @@ declare global {
757
757
  * "sans-serif" or the last font loaded.
758
758
  * @param {string} fontName name of the font family or a FontFace object
759
759
  * @example
760
- * createCanvas(200, 160);
761
- * background(200);
760
+ * await Canvas(200, 160);
761
+ * background(0.8);
762
762
  *
763
763
  * textFont('serif');
764
764
  *
765
- * textSize(32);
766
- * text('Hello, world!', 15, 90);
765
+ * text('Hello, world!', -96, 10);
767
766
  * @example
768
- * createCanvas(200);
769
- * background(200);
767
+ * await Canvas(200);
768
+ * background(0.8);
770
769
  *
771
770
  * textFont('monospace');
772
771
  *
773
- * textSize(24);
774
- * text('Hello, world!', 15, 90);
772
+ * text('Hello, world!', -96, 10);
775
773
  */
776
774
  function textFont(fontName: string): void;
777
775
 
@@ -780,12 +778,12 @@ declare global {
780
778
  * @param {number} [size] size of the font in pixels
781
779
  * @returns {number | void} current font size when no argument is provided
782
780
  * @example
783
- * function draw() {
784
- * background(200);
781
+ * q5.draw = function () {
782
+ * background(0.8);
785
783
  *
786
784
  * textSize(abs(mouseX));
787
- * text('A', 10, 190);
788
- * }
785
+ * text('A', -90, 90);
786
+ * };
789
787
  */
790
788
  function textSize(size?: number): number | void;
791
789
 
@@ -794,43 +792,45 @@ declare global {
794
792
  * @param {number} [leading] line height in pixels
795
793
  * @returns {number | void} current line height when no argument is provided
796
794
  * @example
797
- * function draw() {
798
- * background(200);
795
+ * q5.draw = function () {
796
+ * background(0.8);
799
797
  *
800
798
  * textSize(abs(mouseX));
801
- * text('A', 10, 190);
802
- * rect(10, 190, 5, -textLeading());
803
- * }
799
+ * text('A', -90, 90);
800
+ * rect(-90, 90, 5, -textLeading());
801
+ * };
804
802
  */
805
803
  function textLeading(leading?: number): number | void;
806
804
 
807
805
  /** 📘
808
806
  * Sets the current text style.
809
- *
810
- * Not applicable to WebGPU when using MSDF fonts.
807
+ *
808
+ * Not applicable to MSDF fonts.
811
809
  * @param {'normal' | 'italic' | 'bold' | 'bolditalic'} style font style
812
810
  * @example
813
- * createCanvas(200);
814
- * background(200);
811
+ * await Canvas(200);
812
+ * background(0.8);
815
813
  *
816
814
  * textStyle(ITALIC);
817
815
  *
818
816
  * textSize(32);
819
- * text('Hello, world!', 12, 106);
817
+ * text('Hello, world!', -88, 6);
820
818
  */
821
819
  function textStyle(style: 'normal' | 'italic' | 'bold' | 'bolditalic'): void;
822
820
 
823
821
  /** 📘
824
822
  * Sets the horizontal and vertical alignment of text.
823
+ *
824
+ * Alignment constants like `CENTER` can be used with this function.
825
825
  * @param {'left' | 'center' | 'right'} horiz horizontal alignment
826
826
  * @param {'top' | 'middle' | 'bottom' | 'alphabetic'} [vert] vertical alignment
827
827
  * @example
828
- * createCanvas(200);
829
- * background(200);
828
+ * await Canvas(200);
829
+ * background(0.8);
830
830
  * textSize(32);
831
831
  *
832
- * textAlign(CENTER, MIDDLE);
833
- * text('Hello, world!', 100, 100);
832
+ * textAlign(CENTER, CENTER);
833
+ * text('Hello, world!', 0, 0);
834
834
  */
835
835
  function textAlign(horiz: 'left' | 'center' | 'right', vert?: 'top' | 'middle' | 'bottom' | 'alphabetic'): void;
836
836
 
@@ -848,13 +848,13 @@ declare global {
848
848
  * - 900: black/heavy
849
849
  * @param {number | string} weight font weight
850
850
  * @example
851
- * createCanvas(200);
852
- * background(200);
851
+ * await Canvas(200);
852
+ * background(0.8);
853
853
  * textSize(32);
854
- * textAlign(CENTER, MIDDLE);
854
+ * textAlign(CENTER, CENTER);
855
855
  *
856
856
  * textWeight(100);
857
- * text('Hello, world!', 100, 100);
857
+ * text('Hello, world!', 0, 0);
858
858
  */
859
859
  function textWeight(weight: number | string): void;
860
860
 
@@ -863,13 +863,13 @@ declare global {
863
863
  * @param {string} str string to measure
864
864
  * @returns {number} width of the text in pixels
865
865
  * @example
866
- * function draw() {
867
- * background(200);
866
+ * q5.draw = function () {
867
+ * background(0.8);
868
868
  *
869
869
  * textSize(abs(mouseX));
870
- * rect(10, 190, textWidth('A'), -textLeading());
871
- * text('A', 10, 190);
872
- * }
870
+ * rect(-90, 90, textWidth('A'), -textLeading());
871
+ * text('A', -90, 90);
872
+ * };
873
873
  */
874
874
  function textWidth(str: string): number;
875
875
 
@@ -878,13 +878,13 @@ declare global {
878
878
  * @param {string} str string to measure
879
879
  * @returns {number} ascent of the text in pixels
880
880
  * @example
881
- * function draw() {
882
- * background(200);
881
+ * q5.draw = function () {
882
+ * background(0.8);
883
883
  *
884
884
  * textSize(abs(mouseX));
885
- * rect(10, 190, textWidth('A'), -textAscent());
886
- * text('A', 10, 190);
887
- * }
885
+ * rect(-90, 90, textWidth('A'), -textAscent());
886
+ * text('A', -90, 90);
887
+ * };
888
888
  */
889
889
  function textAscent(str: string): number;
890
890
 
@@ -893,12 +893,12 @@ declare global {
893
893
  * @param {string} str string to measure
894
894
  * @returns {number} descent of the text in pixels
895
895
  * @example
896
- * createCanvas(200);
897
- * background(200);
896
+ * await Canvas(200);
897
+ * background(0.8);
898
898
  * textSize(64);
899
899
  *
900
- * rect(0, 100, 200, textDescent('q5'));
901
- * text('q5', 10, 100);
900
+ * rect(-100, 0, 200, textDescent('q5'));
901
+ * text('q5', -90, 0);
902
902
  */
903
903
  function textDescent(str: string): number;
904
904
 
@@ -909,15 +909,15 @@ declare global {
909
909
  * @param {number} [lineLimit] maximum number of lines
910
910
  * @returns {Q5.Image} an image object representing the rendered text
911
911
  * @example
912
- * createCanvas(200);
912
+ * await Canvas(200);
913
913
  * textSize(96);
914
914
  *
915
915
  * let img = createTextImage('🐶');
916
916
  * img.filter(INVERT);
917
917
  *
918
- * function draw() {
919
- * image(img, 55, 10);
920
- * }
918
+ * q5.draw = function () {
919
+ * image(img, -45, -90);
920
+ * };
921
921
  */
922
922
  function createTextImage(str: string, wrapWidth: number, lineLimit: number): Q5.Image;
923
923
 
@@ -929,33 +929,63 @@ declare global {
929
929
  *
930
930
  * The positioning of the image is affected by the current text
931
931
  * alignment and baseline settings.
932
+ *
933
+ * This function can be used to draw emojis, which can
934
+ * not be drawn with MSDF text rendering.
932
935
  *
933
- * In q5 WebGPU, this function is the only way to draw multi-colored
934
- * text, like emojis, and to use fonts that aren't in MSDF format.
935
- * Using this function to draw text that changes every frame has
936
- * a very high performance cost.
936
+ * Using this function to draw text that changes every frame has a
937
+ * very high performance cost.
937
938
  * @param {Q5.Image | string} img image or text
938
939
  * @param {number} x x-coordinate where the image should be placed
939
940
  * @param {number} y y-coordinate where the image should be placed
940
941
  * @example
941
- * createCanvas(200);
942
- * background(200);
942
+ * await Canvas(200);
943
+ * background(0.8);
943
944
  * textSize(96);
944
945
  * textAlign(CENTER, CENTER);
945
946
  *
946
- * textImage('🐶', 100, 100);
947
+ * textImage('🐶', 0, 0);
948
+ */
949
+ function textImage(img: Q5.Image | String, x: number, y: number): void;
950
+
951
+ /** 📘
952
+ * Converts a string of text to an array of points.
953
+ *
954
+ * Samples opaque pixels in a text image made with `createTextImage`.
955
+ *
956
+ * It's influenced by text settings, such as font, size, and alignment.
957
+ *
958
+ * Uses a [Z-order curve](https://wikipedia.org/wiki/Z-order_curve) to improve spatial distribution, which preserves the shape of text better than purely random sampling.
959
+ * @param {string} str string of text
960
+ * @param {number} [x=0] x coordinate of the text position
961
+ * @param {number} [y=0] y coordinate of the text position
962
+ * @param {number} [sampleRate=0.1] lower values increase dithering (1 = all points, 0.1 = ~10% of points)
963
+ * @param {number} [density=1] pixel density of the text
947
964
  * @example
948
- * createCanvas(200);
965
+ * await Canvas(200);
966
+ * textSize(220);
967
+ * textAlign(CENTER, CENTER);
949
968
  *
950
- * loadFont('/assets/Robotica.ttf');
969
+ * let points = textToPoints('5');
951
970
  *
952
- * function setup() {
953
- * background(200);
954
- * textSize(66);
955
- * textImage('Hello!', 0, 0);
971
+ * for (let pt of points) {
972
+ * rect(pt.x, pt.y, 5, 20);
973
+ * }
974
+ * @example
975
+ * await Canvas(200, 296);
976
+ * textSize(340);
977
+ * noFill();
978
+ * stroke(1);
979
+ * strokeWeight(8);
980
+ *
981
+ * let pts = textToPoints('q', -100, 56);
982
+ *
983
+ * strokeWeight(1);
984
+ * for (let pt of pts) {
985
+ * ellipse(pt.x, pt.y, 10, 0.1);
956
986
  * }
957
987
  */
958
- function textImage(img: Q5.Image | String, x: number, y: number): void;
988
+ function textToPoints(str: string, x?: number, y?: number, sampleRate?: number, density?: number): [];
959
989
 
960
990
  /** 📘
961
991
  * Number formatter, can be used to display a number as a string with
@@ -966,11 +996,11 @@ declare global {
966
996
  * @param {number} r number of digits to appear after the decimal point
967
997
  * @returns {string} a string representation of the number, formatted accordingly
968
998
  * @example
969
- * createCanvas(200, 100);
970
- * background(200);
999
+ * await Canvas(200, 100);
1000
+ * background(0.8);
971
1001
  *
972
1002
  * textSize(32);
973
- * text(nf(PI, 4, 5), 10, 60);
1003
+ * text(nf(PI, 4, 5), -90, 10);
974
1004
  */
975
1005
  function nf(num: number, digits: number): string;
976
1006
 
@@ -1014,6 +1044,11 @@ declare global {
1014
1044
  */
1015
1045
  const TOP: 'top';
1016
1046
 
1047
+ /** 📘
1048
+ * Align text to the middle.
1049
+ */
1050
+ const MIDDLE: 'middle';
1051
+
1017
1052
  /** 📘
1018
1053
  * Align text to the bottom.
1019
1054
  */
@@ -1043,21 +1078,21 @@ declare global {
1043
1078
  /** 🖲
1044
1079
  * Current X position of the mouse.
1045
1080
  * @example
1046
- * function draw() {
1047
- * background(200);
1081
+ * q5.draw = function () {
1082
+ * background(0.8);
1048
1083
  * textSize(64);
1049
- * text(round(mouseX), 50, 120);
1050
- * }
1084
+ * text(round(mouseX), -50, 20);
1085
+ * };
1051
1086
  */
1052
1087
  let mouseX: number;
1053
1088
 
1054
1089
  /** 🖲
1055
1090
  * Current Y position of the mouse.
1056
1091
  * @example
1057
- * function draw() {
1058
- * background(200);
1059
- * circle(100, mouseY, 100);
1060
- * }
1092
+ * q5.draw = function () {
1093
+ * background(0.8);
1094
+ * circle(0, mouseY, 100);
1095
+ * };
1061
1096
  */
1062
1097
  let mouseY: number;
1063
1098
 
@@ -1076,47 +1111,47 @@ declare global {
1076
1111
  *
1077
1112
  * The default value is an empty string.
1078
1113
  * @example
1079
- * function draw() {
1080
- * background(200);
1114
+ * q5.draw = function () {
1115
+ * background(0.8);
1081
1116
  * textSize(64);
1082
- * text(mouseButton, 20, 120);
1083
- * }
1117
+ * text(mouseButton, -80, 20);
1118
+ * };
1084
1119
  */
1085
1120
  let mouseButton: string;
1086
1121
 
1087
1122
  /** 🖲
1088
1123
  * True if the mouse is currently pressed, false otherwise.
1089
1124
  * @example
1090
- * function draw() {
1091
- * if (mouseIsPressed) background(100);
1092
- * else background(200);
1093
- * }
1125
+ * q5.draw = function () {
1126
+ * if (mouseIsPressed) background(0.4);
1127
+ * else background(0.8);
1128
+ * };
1094
1129
  */
1095
1130
  let mouseIsPressed: boolean;
1096
1131
 
1097
1132
  /** 🖲
1098
1133
  * Define this function to respond to mouse down events.
1099
1134
  * @example
1100
- * createCanvas(200);
1101
- * let gray = 95;
1135
+ * await Canvas(200);
1136
+ * let gray = 0.4;
1102
1137
  *
1103
- * function mousePressed() {
1104
- * background(gray % 256);
1105
- * gray += 40;
1106
- * }
1138
+ * q5.mousePressed = function () {
1139
+ * background(gray % 1);
1140
+ * gray += 0.1;
1141
+ * };
1107
1142
  */
1108
1143
  function mousePressed(): void;
1109
1144
 
1110
1145
  /** 🖲
1111
1146
  * Define this function to respond to mouse up events.
1112
1147
  * @example
1113
- * createCanvas(200);
1114
- * let gray = 95;
1148
+ * await Canvas(200);
1149
+ * let gray = 0.4;
1115
1150
  *
1116
- * function mouseReleased() {
1117
- * background(gray % 256);
1118
- * gray += 40;
1119
- * }
1151
+ * q5.mouseReleased = function () {
1152
+ * background(gray % 1);
1153
+ * gray += 0.1;
1154
+ * };
1120
1155
  */
1121
1156
  function mouseReleased(): void;
1122
1157
 
@@ -1126,13 +1161,13 @@ declare global {
1126
1161
  * On touchscreen devices this function is not called
1127
1162
  * when the user drags their finger on the screen.
1128
1163
  * @example
1129
- * createCanvas(200);
1130
- * let gray = 95;
1164
+ * await Canvas(200);
1165
+ * let gray = 0.4;
1131
1166
  *
1132
- * function mouseMoved() {
1133
- * background(gray % 256);
1134
- * gray++;
1135
- * }
1167
+ * q5.mouseMoved = function () {
1168
+ * background(gray % 1);
1169
+ * gray += 0.005;
1170
+ * };
1136
1171
  */
1137
1172
  function mouseMoved(): void;
1138
1173
 
@@ -1142,47 +1177,47 @@ declare global {
1142
1177
  * Dragging the mouse is defined as moving the mouse
1143
1178
  * while a mouse button is pressed.
1144
1179
  * @example
1145
- * createCanvas(200);
1146
- * let gray = 95;
1180
+ * await Canvas(200);
1181
+ * let gray = 0.4;
1147
1182
  *
1148
- * function mouseDragged() {
1149
- * background(gray % 256);
1150
- * gray++;
1151
- * }
1183
+ * q5.mouseDragged = function () {
1184
+ * background(gray % 1);
1185
+ * gray += 0.005;
1186
+ * };
1152
1187
  */
1153
1188
  function mouseDragged(): void;
1154
1189
 
1155
1190
  /** 🖲
1156
1191
  * Define this function to respond to mouse double click events.
1157
1192
  * @example
1158
- * createCanvas(200);
1159
- * let gray = 95;
1193
+ * await Canvas(200);
1194
+ * let gray = 0.4;
1160
1195
  *
1161
- * function doubleClicked() {
1162
- * background(gray % 256);
1163
- * gray += 40;
1164
- * }
1196
+ * q5.doubleClicked = function () {
1197
+ * background(gray % 1);
1198
+ * gray += 0.1;
1199
+ * };
1165
1200
  */
1166
1201
  function doubleClicked(): void;
1167
1202
 
1168
1203
  /** 🖲
1169
1204
  * The name of the last key pressed.
1170
1205
  * @example
1171
- * function draw() {
1172
- * background(200);
1206
+ * q5.draw = function () {
1207
+ * background(0.8);
1173
1208
  * textSize(64);
1174
- * text(key, 20, 120);
1175
- * }
1209
+ * text(key, -80, 20);
1210
+ * };
1176
1211
  */
1177
1212
  let key: string;
1178
1213
 
1179
1214
  /** 🖲
1180
1215
  * True if a key is currently pressed, false otherwise.
1181
1216
  * @example
1182
- * function draw() {
1183
- * if (keyIsPressed) background(100);
1184
- * else background(200);
1185
- * }
1217
+ * q5.draw = function () {
1218
+ * if (keyIsPressed) background(0.4);
1219
+ * else background(0.8);
1220
+ * };
1186
1221
  */
1187
1222
  let keyIsPressed: boolean;
1188
1223
 
@@ -1192,39 +1227,39 @@ declare global {
1192
1227
  * @param {string} key key to check
1193
1228
  * @returns {boolean} true if the key is pressed, false otherwise
1194
1229
  * @example
1195
- * function draw() {
1196
- * background(200);
1230
+ * q5.draw = function () {
1231
+ * background(0.8);
1197
1232
  *
1198
1233
  * if (keyIsDown('f') && keyIsDown('j')) {
1199
- * rect(50, 50, 100, 100);
1234
+ * rect(-50, -50, 100, 100);
1200
1235
  * }
1201
- * }
1236
+ * };
1202
1237
  */
1203
1238
  function keyIsDown(key: string): boolean;
1204
1239
 
1205
1240
  /** 🖲
1206
1241
  * Define this function to respond to key down events.
1207
1242
  * @example
1208
- * createCanvas(200);
1243
+ * await Canvas(200);
1244
+ * let gray = 0.4;
1209
1245
  *
1210
- * let gray = 95;
1211
- * function keyPressed() {
1212
- * background(gray % 256);
1213
- * gray += 40;
1214
- * }
1246
+ * q5.keyPressed = function () {
1247
+ * background(gray % 1);
1248
+ * gray += 0.1;
1249
+ * };
1215
1250
  */
1216
1251
  function keyPressed(): void;
1217
1252
 
1218
1253
  /** 🖲
1219
1254
  * Define this function to respond to key up events.
1220
1255
  * @example
1221
- * createCanvas(200);
1256
+ * await Canvas(200);
1257
+ * let gray = 0.4;
1222
1258
  *
1223
- * let gray = 95;
1224
- * function keyReleased() {
1225
- * background(gray % 256);
1226
- * gray += 40;
1227
- * }
1259
+ * q5.keyReleased = function () {
1260
+ * background(gray % 1);
1261
+ * gray += 0.1;
1262
+ * };
1228
1263
  */
1229
1264
  function keyReleased(): void;
1230
1265
 
@@ -1233,12 +1268,12 @@ declare global {
1233
1268
  * browser window. Each touch being an object with
1234
1269
  * `id`, `x`, and `y` properties.
1235
1270
  * @example
1236
- * function draw() {
1237
- * background(200);
1271
+ * q5.draw = function () {
1272
+ * background(0.8);
1238
1273
  * for (let touch of touches) {
1239
1274
  * circle(touch.x, touch.y, 100);
1240
1275
  * }
1241
- * }
1276
+ * };
1242
1277
  */
1243
1278
  let touches: any[];
1244
1279
 
@@ -1249,13 +1284,13 @@ declare global {
1249
1284
  * Return true to enable touch gestures like pinch-to-zoom
1250
1285
  * and scroll, which q5 disables on the canvas by default.
1251
1286
  * @example
1252
- * createCanvas(200);
1287
+ * await Canvas(200);
1288
+ * let gray = 0.4;
1253
1289
  *
1254
- * let gray = 95;
1255
- * function touchStarted() {
1256
- * background(gray % 256);
1257
- * gray += 40;
1258
- * }
1290
+ * q5.touchStarted = function () {
1291
+ * background(gray % 1);
1292
+ * gray += 0.1;
1293
+ * };
1259
1294
  */
1260
1295
  function touchStarted(): void;
1261
1296
 
@@ -1266,13 +1301,13 @@ declare global {
1266
1301
  * Return true to enable touch gestures like pinch-to-zoom
1267
1302
  * and scroll, which q5 disables on the canvas by default.
1268
1303
  * @example
1269
- * createCanvas(200);
1304
+ * await Canvas(200);
1305
+ * let gray = 0.4;
1270
1306
  *
1271
- * let gray = 95;
1272
- * function touchEnded() {
1273
- * background(gray % 256);
1274
- * gray += 40;
1275
- * }
1307
+ * q5.touchEnded = function () {
1308
+ * background(gray % 1);
1309
+ * gray += 0.1;
1310
+ * };
1276
1311
  */
1277
1312
  function touchEnded(): void;
1278
1313
 
@@ -1283,13 +1318,13 @@ declare global {
1283
1318
  * Return true to enable touch gestures like pinch-to-zoom
1284
1319
  * and scroll, which q5 disables on the canvas by default.
1285
1320
  * @example
1286
- * createCanvas(200);
1287
- * let gray = 95;
1321
+ * await Canvas(200);
1322
+ * let gray = 0.4;
1288
1323
  *
1289
- * function touchMoved() {
1290
- * background(gray % 256);
1291
- * gray++;
1292
- * }
1324
+ * q5.touchMoved = function () {
1325
+ * background(gray % 1);
1326
+ * gray += 0.005;
1327
+ * };
1293
1328
  */
1294
1329
  function touchMoved(): void;
1295
1330
 
@@ -1304,13 +1339,13 @@ declare global {
1304
1339
  * The `event` property contains the original
1305
1340
  * [PointerEvent](https://developer.mozilla.org/docs/Web/API/PointerEvent).
1306
1341
  * @example
1307
- * function draw() {
1308
- * background(200);
1342
+ * q5.draw = function () {
1343
+ * background(0.8);
1309
1344
  * for (let pointerID in pointers) {
1310
1345
  * let pointer = pointers[pointerID];
1311
1346
  * circle(pointer.x, pointer.y, 100);
1312
1347
  * }
1313
- * }
1348
+ * };
1314
1349
  */
1315
1350
  let pointers: {};
1316
1351
 
@@ -1322,7 +1357,7 @@ declare global {
1322
1357
  * @param {number} [x] x-coordinate of the cursor's point
1323
1358
  * @param {number} [y] y-coordinate of the cursor's point
1324
1359
  * @example
1325
- * createCanvas(200, 100);
1360
+ * await Canvas(200, 100);
1326
1361
  * cursor('pointer');
1327
1362
  */
1328
1363
  function cursor(name: string, x?: number, y?: number): void;
@@ -1330,7 +1365,7 @@ declare global {
1330
1365
  /** 🖲
1331
1366
  * Hides the cursor within the bounds of the canvas.
1332
1367
  * @example
1333
- * createCanvas(200, 100);
1368
+ * await Canvas(200, 100);
1334
1369
  * noCursor();
1335
1370
  */
1336
1371
  function noCursor(): void;
@@ -1343,15 +1378,15 @@ declare global {
1343
1378
  *
1344
1379
  * Return true to allow the default behavior of scrolling the page.
1345
1380
  * @example
1346
- * let x = (y = 100);
1347
- * function draw() {
1381
+ * let x = (y = 0);
1382
+ * q5.draw = function () {
1348
1383
  * circle(x, y, 10);
1349
- * }
1350
- * function mouseWheel(e) {
1384
+ * };
1385
+ * q5.mouseWheel = function (e) {
1351
1386
  * x += e.deltaX;
1352
1387
  * y += e.deltaY;
1353
1388
  * return false;
1354
- * }
1389
+ * };
1355
1390
  */
1356
1391
  function mouseWheel(event: any): void;
1357
1392
 
@@ -1364,17 +1399,17 @@ declare global {
1364
1399
  * To exit pointer lock mode, call `document.exitPointerLock()`.
1365
1400
  * @param {boolean} unadjustedMovement set to true to disable OS-level mouse acceleration and access raw mouse input
1366
1401
  * @example
1367
- * function draw() {
1368
- * circle(mouseX / 10 + 100, mouseY / 10 + 100, 10);
1369
- * }
1402
+ * q5.draw = function () {
1403
+ * circle(mouseX / 10, mouseY / 10, 10);
1404
+ * };
1370
1405
  *
1371
- * function doubleClicked() {
1406
+ * q5.doubleClicked = function () {
1372
1407
  * if (!document.pointerLockElement) {
1373
1408
  * pointerLock();
1374
1409
  * } else {
1375
1410
  * document.exitPointerLock();
1376
1411
  * }
1377
- * }
1412
+ * };
1378
1413
  */
1379
1414
  function pointerLock(unadjustedMovement: boolean): void;
1380
1415
 
@@ -1390,53 +1425,53 @@ declare global {
1390
1425
  * The [`fill`](https://q5js.org/learn/#fill), [`stroke`](https://q5js.org/learn/#stroke), and [`background`](https://q5js.org/learn/#background)
1391
1426
  * functions accept the same wide range of color representations as this function.
1392
1427
  *
1393
- * The default color format is "integer",
1394
- * so set components to values between 0 and 255.
1428
+ * The default color format is "float", so
1429
+ * set color components to values between 0 and 1.
1395
1430
  *
1396
1431
  * Here are some examples of valid use:
1397
1432
  *
1398
- * - `color(255)` (grayscale)
1399
- * - `color(255, 200)` (grayscale, alpha)
1400
- * - `color(255, 0, 0)` (r, g, b)
1401
- * - `color(255, 0, 0, 10)` (r, g, b, a)
1433
+ * - `color(1)` (grayscale)
1434
+ * - `color(1, 0.8)` (grayscale, alpha)
1435
+ * - `color(1, 0, 0)` (r, g, b)
1436
+ * - `color(1, 0, 0, 0.1)` (r, g, b, a)
1402
1437
  * - `color('red')` (colorName)
1403
1438
  * - `color('#ff0000')` (hexColor)
1404
- * - `color([255, 0, 0])` (colorComponents)
1439
+ * - `color([1, 0, 0])` (colorComponents)
1405
1440
  * @param {string | number | Color | number[]} c0 color or first color component
1406
1441
  * @param {number} [c1] second color component
1407
1442
  * @param {number} [c2] third color component
1408
1443
  * @param {number} [c3] fourth color component (alpha)
1409
1444
  * @returns {Color} a new `Color` object
1410
1445
  * @example
1411
- * createCanvas(200);
1412
- * rect(0, 0, 100, 200);
1446
+ * await Canvas(200);
1447
+ * rect(-100, -100, 100, 200);
1413
1448
  *
1414
1449
  * // ( r, g, b, a)
1415
- * let bottle = color(90, 100, 255, 100);
1450
+ * let bottle = color(0.35, 0.39, 1, 0.4);
1416
1451
  * fill(bottle);
1417
1452
  * stroke(bottle);
1418
1453
  * strokeWeight(30);
1419
- * circle(100, 100, 155);
1454
+ * circle(0, 0, 155);
1420
1455
  * @example
1421
- * createCanvas(200);
1456
+ * await Canvas(200);
1422
1457
  * // (gray, alpha)
1423
- * let c = color(200, 50);
1458
+ * let c = color(0.8, 0.2);
1424
1459
  *
1425
- * function draw() {
1460
+ * q5.draw = function () {
1426
1461
  * background(c);
1427
1462
  * circle(mouseX, mouseY, 50);
1428
- * c.g = (c.g + 1) % 256;
1429
- * }
1463
+ * c.g = (c.g + 0.005) % 1;
1464
+ * };
1430
1465
  * @example
1431
- * createCanvas(200);
1466
+ * await Canvas(200);
1432
1467
  *
1433
- * // (r, g, b, a)
1434
- * let c = color(0, 255, 255, 50);
1468
+ * // (r, g, b, a)
1469
+ * let c = color(0, 1, 1, 0.2);
1435
1470
  *
1436
- * function draw() {
1471
+ * q5.draw = function () {
1437
1472
  * fill(c);
1438
1473
  * circle(mouseX, mouseY, 50);
1439
- * }
1474
+ * };
1440
1475
  */
1441
1476
  function color(c0: string | number | Color | number[], c1?: number, c2?: number, c3?: number): Color;
1442
1477
 
@@ -1446,30 +1481,30 @@ declare global {
1446
1481
  *
1447
1482
  * Color gamut is 'display-p3' by default, if the device supports HDR.
1448
1483
  *
1449
- * The default color mode is RGB in legacy integer format.
1484
+ * The default color mode is RGB in float format.
1450
1485
  * @param {'rgb' | 'oklch' | 'hsl' | 'hsb'} mode color mode
1451
1486
  * @param {1 | 255} format color format (1 for float, 255 for integer)
1452
1487
  * @param {'srgb' | 'display-p3'} [gamut] color gamut
1453
1488
  * @example
1454
- * createCanvas(200);
1489
+ * await Canvas(200);
1455
1490
  *
1456
1491
  * colorMode(RGB, 1);
1457
1492
  * fill(1, 0, 0);
1458
- * rect(0, 0, 66, 200);
1493
+ * rect(-100, -100, 66, 200);
1459
1494
  * fill(0, 1, 0);
1460
- * rect(66, 0, 67, 200);
1495
+ * rect(-34, -100, 67, 200);
1461
1496
  * fill(0, 0, 1);
1462
- * rect(133, 0, 67, 200);
1497
+ * rect(33, -100, 67, 200);
1463
1498
  * @example
1464
- * createCanvas(200);
1499
+ * await Canvas(200);
1465
1500
  *
1466
1501
  * colorMode(OKLCH);
1467
1502
  *
1468
1503
  * fill(0.25, 0.15, 0);
1469
- * rect(0, 0, 100, 200);
1504
+ * rect(-100, -100, 100, 200);
1470
1505
  *
1471
1506
  * fill(0.75, 0.15, 0);
1472
- * rect(100, 0, 100, 200);
1507
+ * rect(0, -100, 100, 200);
1473
1508
  */
1474
1509
  function colorMode(mode: 'rgb' | 'oklch', format: 1 | 255, gamut: 'srgb' | 'display-p3'): void;
1475
1510
 
@@ -1481,11 +1516,11 @@ declare global {
1481
1516
  * rgb colors are mapped to the full P3 gamut, even when they use the
1482
1517
  * legacy integer 0-255 format.
1483
1518
  * @example
1484
- * createCanvas(200, 100);
1519
+ * await Canvas(200, 100);
1485
1520
  *
1486
1521
  * colorMode(RGB);
1487
1522
  *
1488
- * background(255, 0, 0);
1523
+ * background(1, 0, 0);
1489
1524
  */
1490
1525
  const RGB: 'rgb';
1491
1526
 
@@ -1513,18 +1548,18 @@ declare global {
1513
1548
  * - `hue`: 0 to 360
1514
1549
  * - `alpha`: 0 to 1
1515
1550
  * @example
1516
- * createCanvas(200, 100);
1551
+ * await Canvas(200, 100);
1517
1552
  *
1518
1553
  * colorMode(OKLCH);
1519
1554
  *
1520
1555
  * background(0.64, 0.3, 30);
1521
1556
  * @example
1522
- * createCanvas(200);
1557
+ * await Canvas(200);
1523
1558
  * colorMode(OKLCH);
1524
1559
  *
1525
- * function draw() {
1560
+ * q5.draw = function () {
1526
1561
  * background(0.7, 0.16, frameCount % 360);
1527
- * }
1562
+ * };
1528
1563
  */
1529
1564
  const OKLCH: 'oklch';
1530
1565
 
@@ -1548,20 +1583,20 @@ declare global {
1548
1583
  * - `lightness`: 0 to 100
1549
1584
  * - `alpha`: 0 to 1
1550
1585
  * @example
1551
- * createCanvas(200, 100);
1586
+ * await Canvas(200, 100);
1552
1587
  *
1553
1588
  * colorMode(HSL);
1554
1589
  *
1555
1590
  * background(0, 100, 50);
1556
1591
  * @example
1557
- * createCanvas(200, 220);
1592
+ * await Canvas(200, 220);
1558
1593
  * noStroke();
1559
1594
  *
1560
1595
  * colorMode(HSL);
1561
1596
  * for (let h = 0; h < 360; h += 10) {
1562
1597
  * for (let l = 0; l <= 100; l += 10) {
1563
1598
  * fill(h, 100, l);
1564
- * rect(h * (11 / 20), l * 2, 6, 20);
1599
+ * rect(h * (11 / 20) - 100, l * 2 - 110, 6, 20);
1565
1600
  * }
1566
1601
  * }
1567
1602
  */
@@ -1581,20 +1616,20 @@ declare global {
1581
1616
  * - `brightness`: 0 to 100
1582
1617
  * - `alpha`: 0 to 1
1583
1618
  * @example
1584
- * createCanvas(200, 100);
1619
+ * await Canvas(200, 100);
1585
1620
  *
1586
1621
  * colorMode(HSB);
1587
1622
  *
1588
1623
  * background(0, 100, 100);
1589
1624
  * @example
1590
- * createCanvas(200, 220);
1625
+ * await Canvas(200, 220);
1591
1626
  * noStroke();
1592
1627
  *
1593
1628
  * colorMode(HSB);
1594
1629
  * for (let h = 0; h < 360; h += 10) {
1595
1630
  * for (let b = 0; b <= 100; b += 10) {
1596
1631
  * fill(h, 100, b);
1597
- * rect(h * (11 / 20), b * 2, 6, 20);
1632
+ * rect(h * (11 / 20) - 100, b * 2 - 110, 6, 20);
1598
1633
  * }
1599
1634
  * }
1600
1635
  */
@@ -1607,11 +1642,11 @@ declare global {
1607
1642
  * less saturated and darker in this example, as it would on
1608
1643
  * an SDR display.
1609
1644
  * @example
1610
- * createCanvas(200, 100);
1645
+ * await Canvas(200, 100);
1611
1646
  *
1612
- * colorMode(RGB, 255, SRGB);
1647
+ * colorMode(RGB, 1, SRGB);
1613
1648
  *
1614
- * background(255, 0, 0);
1649
+ * background(1, 0, 0);
1615
1650
  */
1616
1651
  const SRGB: 'srgb';
1617
1652
 
@@ -1623,11 +1658,11 @@ declare global {
1623
1658
  * If your display is HDR capable, note that full red appears
1624
1659
  * fully saturated and bright in the following example.
1625
1660
  * @example
1626
- * createCanvas(200, 100);
1661
+ * await Canvas(200, 100);
1627
1662
  *
1628
- * colorMode(RGB, 255, DISPLAY_P3);
1663
+ * colorMode(RGB, 1, DISPLAY_P3);
1629
1664
  *
1630
- * background(255, 0, 0);
1665
+ * background(1, 0, 0);
1631
1666
  */
1632
1667
  const DISPLAY_P3: 'display-p3';
1633
1668
 
@@ -1639,13 +1674,13 @@ declare global {
1639
1674
  * CSS color string, grayscale value, and color component values.
1640
1675
  * @param {Color | Q5.Image} filler a color or image to draw
1641
1676
  * @example
1642
- * createCanvas(200, 100);
1677
+ * await Canvas(200, 100);
1643
1678
  * background('crimson');
1644
1679
  * @example
1645
- * function draw() {
1646
- * background(128, 32);
1680
+ * q5.draw = function () {
1681
+ * background(0.5, 0.2);
1647
1682
  * circle(mouseX, mouseY, 20);
1648
- * }
1683
+ * };
1649
1684
  */
1650
1685
  function background(filler: Color | Q5.Image): void;
1651
1686
 
@@ -1657,9 +1692,6 @@ declare global {
1657
1692
  *
1658
1693
  * Use the `color` function for greater flexibility, it runs
1659
1694
  * this constructor internally.
1660
- *
1661
- * `Color` is not actually a class itself, it's a reference to a
1662
- * Q5 color class based on the color mode, format, and gamut.
1663
1695
  */
1664
1696
  constructor(c0: number, c1: number, c2: number, c3: number);
1665
1697
 
@@ -1695,14 +1727,14 @@ declare global {
1695
1727
  * a `Color` object, grayscale value, or color component values.
1696
1728
  * @param {Color} color fill color
1697
1729
  * @example
1698
- * createCanvas(200);
1699
- * background(200);
1730
+ * await Canvas(200);
1731
+ * background(0.8);
1700
1732
  *
1701
1733
  * fill('red');
1702
- * circle(80, 80, 80);
1734
+ * circle(-20, -20, 80);
1703
1735
  *
1704
1736
  * fill('lime');
1705
- * square(80, 80, 80);
1737
+ * square(-20, -20, 80);
1706
1738
  */
1707
1739
  function fill(color: Color): void;
1708
1740
 
@@ -1714,44 +1746,44 @@ declare global {
1714
1746
  * a `Color` object, grayscale value, or color component values.
1715
1747
  * @param {Color} color stroke color
1716
1748
  * @example
1717
- * createCanvas(200);
1718
- * background(200);
1719
- * fill(36);
1749
+ * await Canvas(200);
1750
+ * background(0.8);
1751
+ * fill(0.14);
1720
1752
  *
1721
1753
  * stroke('red');
1722
- * circle(80, 80, 80);
1754
+ * circle(-20, -20, 80);
1723
1755
  *
1724
1756
  * stroke('lime');
1725
- * square(80, 80, 80);
1757
+ * square(-20, -20, 80);
1726
1758
  */
1727
1759
  function stroke(color: Color): void;
1728
1760
 
1729
1761
  /** 💅
1730
1762
  * After calling this function, drawing will not be filled.
1731
1763
  * @example
1732
- * createCanvas(200);
1733
- * background(200);
1764
+ * await Canvas(200);
1765
+ * background(0.8);
1734
1766
  *
1735
1767
  * noFill();
1736
1768
  *
1737
1769
  * stroke('red');
1738
- * circle(80, 80, 80);
1770
+ * circle(-20, -20, 80);
1739
1771
  * stroke('lime');
1740
- * square(80, 80, 80);
1772
+ * square(-20, -20, 80);
1741
1773
  */
1742
1774
  function noFill(): void;
1743
1775
 
1744
1776
  /** 💅
1745
1777
  * After calling this function, drawing will not have a stroke (outline).
1746
1778
  * @example
1747
- * createCanvas(200);
1748
- * background(200);
1749
- * fill(36);
1779
+ * await Canvas(200);
1780
+ * background(0.8);
1781
+ * fill(0.14);
1750
1782
  * stroke('red');
1751
- * circle(80, 80, 80);
1783
+ * circle(-20, -20, 80);
1752
1784
  *
1753
1785
  * noStroke();
1754
- * square(80, 80, 80);
1786
+ * square(-20, -20, 80);
1755
1787
  */
1756
1788
  function noStroke(): void;
1757
1789
 
@@ -1759,13 +1791,13 @@ declare global {
1759
1791
  * Sets the size of the stroke used for lines and the border around drawings.
1760
1792
  * @param {number} weight size of the stroke in pixels
1761
1793
  * @example
1762
- * createCanvas(200);
1763
- * background(200);
1794
+ * await Canvas(200);
1795
+ * background(0.8);
1764
1796
  * stroke('red');
1765
- * circle(50, 100, 80);
1797
+ * circle(-50, 0, 80);
1766
1798
  *
1767
1799
  * strokeWeight(12);
1768
- * circle(150, 100, 80);
1800
+ * circle(50, 0, 80);
1769
1801
  */
1770
1802
  function strokeWeight(weight: number): void;
1771
1803
 
@@ -1775,14 +1807,14 @@ declare global {
1775
1807
  * In q5 WebGPU this function only affects images.
1776
1808
  * @param {number} alpha opacity level, ranging from 0 to 1
1777
1809
  * @example
1778
- * createCanvas(200);
1779
- * background(200);
1810
+ * await Canvas(200);
1811
+ * background(0.8);
1780
1812
  *
1781
1813
  * opacity(1);
1782
- * circle(80, 80, 80);
1814
+ * circle(-20, -20, 80);
1783
1815
  *
1784
1816
  * opacity(0.2);
1785
- * square(80, 80, 80);
1817
+ * square(-20, -20, 80);
1786
1818
  */
1787
1819
  function opacity(alpha: number): void;
1788
1820
 
@@ -1798,22 +1830,6 @@ declare global {
1798
1830
  *
1799
1831
  * Not available in q5 WebGPU.
1800
1832
  * @param {Color} color shadow color
1801
- * @example
1802
- * createCanvas(200);
1803
- * background(200);
1804
- *
1805
- * noFill();
1806
- * shadow('black');
1807
- * rect(64, 60, 80, 80);
1808
- * @example
1809
- * createCanvas(200);
1810
- * let logo = loadImage('/assets/p5play_logo.webp');
1811
- *
1812
- * function setup() {
1813
- * background(200);
1814
- * shadow(0);
1815
- * image(logo, 36, 36, 128, 128);
1816
- * }
1817
1833
  */
1818
1834
  function shadow(color: string | Color): void;
1819
1835
 
@@ -1821,15 +1837,6 @@ declare global {
1821
1837
  * Disables the shadow effect.
1822
1838
  *
1823
1839
  * Not available in q5 WebGPU.
1824
- * @example
1825
- * createCanvas(200);
1826
- * background(200);
1827
- * noStroke();
1828
- * shadow('black');
1829
- * rect(14, 14, 80, 80);
1830
- *
1831
- * noShadow();
1832
- * rect(104, 104, 80, 80);
1833
1840
  */
1834
1841
  function noShadow(): void;
1835
1842
 
@@ -1842,26 +1849,6 @@ declare global {
1842
1849
  * @param {number} offsetX horizontal offset of the shadow
1843
1850
  * @param {number} offsetY vertical offset of the shadow, defaults to be the same as offsetX
1844
1851
  * @param {number} blur blur radius of the shadow, defaults to 0
1845
- * @example
1846
- * createCanvas(200);
1847
- * noStroke();
1848
- * shadow(50);
1849
- *
1850
- * function draw() {
1851
- * background(200);
1852
- * shadowBox(-20, mouseY, 10);
1853
- * circle(100, 100, 80, 80);
1854
- * }
1855
- * @example
1856
- * createCanvas(200);
1857
- * background(200);
1858
- * noStroke();
1859
- *
1860
- * shadow('aqua');
1861
- * shadowBox(20);
1862
- * rect(50, 50, 100, 100);
1863
- * textSize(64);
1864
- * text('q5', 60, 115);
1865
1852
  */
1866
1853
  function shadowBox(offsetX: number, offsetY: number, blur: number): void;
1867
1854
 
@@ -1878,19 +1865,6 @@ declare global {
1878
1865
  *
1879
1866
  * Not available in q5 WebGPU.
1880
1867
  * @param {CanvasLineCap} val line cap style
1881
- * @example
1882
- * createCanvas(200);
1883
- * background(200);
1884
- * strokeWeight(20);
1885
- *
1886
- * strokeCap(ROUND);
1887
- * line(50, 50, 150, 50);
1888
- *
1889
- * strokeCap(SQUARE);
1890
- * line(50, 100, 150, 100);
1891
- *
1892
- * strokeCap(PROJECT);
1893
- * line(50, 150, 150, 150);
1894
1868
  */
1895
1869
  function strokeCap(val: CanvasLineCap): void;
1896
1870
 
@@ -1899,19 +1873,6 @@ declare global {
1899
1873
  *
1900
1874
  * Not available in q5 WebGPU.
1901
1875
  * @param {CanvasLineJoin} val line join style
1902
- * @example
1903
- * createCanvas(200);
1904
- * background(200);
1905
- * strokeWeight(10);
1906
- *
1907
- * strokeJoin(ROUND);
1908
- * triangle(50, 20, 150, 20, 50, 70);
1909
- *
1910
- * strokeJoin(BEVEL);
1911
- * triangle(150, 50, 50, 100, 150, 150);
1912
- *
1913
- * strokeJoin(MITER);
1914
- * triangle(50, 130, 150, 180, 50, 180);
1915
1876
  */
1916
1877
  function strokeJoin(val: CanvasLineJoin): void;
1917
1878
 
@@ -1939,30 +1900,30 @@ declare global {
1939
1900
  * rect mode, ellipse mode, text size, text align, text baseline, and
1940
1901
  * shadow settings.
1941
1902
  * @example
1942
- * createCanvas(200);
1943
- * background(200);
1903
+ * await Canvas(200);
1904
+ * background(0.8);
1944
1905
  *
1945
1906
  * pushStyles();
1946
1907
  * fill('blue');
1947
- * circle(50, 50, 80);
1908
+ * circle(-50, -50, 80);
1948
1909
  *
1949
1910
  * popStyles();
1950
- * circle(150, 150, 80);
1911
+ * circle(50, 50, 80);
1951
1912
  */
1952
1913
  function pushStyles(): void;
1953
1914
 
1954
1915
  /** 💅
1955
1916
  * Restores the previously saved drawing style settings.
1956
1917
  * @example
1957
- * createCanvas(200);
1958
- * background(200);
1918
+ * await Canvas(200);
1919
+ * background(0.8);
1959
1920
  *
1960
1921
  * pushStyles();
1961
1922
  * fill('blue');
1962
- * circle(50, 50, 80);
1923
+ * circle(-50, -50, 80);
1963
1924
  *
1964
1925
  * popStyles();
1965
- * circle(150, 150, 80);
1926
+ * circle(50, 50, 80);
1966
1927
  */
1967
1928
  function popStyles(): void;
1968
1929
 
@@ -1971,15 +1932,25 @@ declare global {
1971
1932
  *
1972
1933
  * Note that the canvas can only be seen through if it has an alpha channel.
1973
1934
  * @example
1974
- * createCanvas(200, 200, { alpha: true });
1935
+ * await Canvas(200, { alpha: true });
1975
1936
  *
1976
- * function draw() {
1937
+ * q5.draw = function () {
1977
1938
  * clear();
1978
- * circle(frameCount % 200, 100, 80);
1979
- * }
1939
+ * circle((frameCount % 200) - 100, 0, 80);
1940
+ * };
1980
1941
  */
1981
1942
  function clear(): void;
1982
1943
 
1944
+ /** 💅
1945
+ * The 2D rendering context for the canvas.
1946
+ *
1947
+ * You can use it to create [linear gradients](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createLinearGradient), [radial gradients](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/createRadialGradient), [font stretching](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/fontStretch), and
1948
+ * other advanced drawing features.
1949
+ *
1950
+ * Not available in q5 WebGPU.
1951
+ */
1952
+ var ctx: CanvasRenderingContext2D;
1953
+
1983
1954
  /** 💅
1984
1955
  * Checks if a given point is within the current path's fill area.
1985
1956
  *
@@ -2007,12 +1978,12 @@ declare global {
2007
1978
  * @param {number} x translation along the x-axis
2008
1979
  * @param {number} y translation along the y-axis
2009
1980
  * @example
2010
- * function draw() {
2011
- * background(200);
1981
+ * q5.draw = function () {
1982
+ * background(0.8);
2012
1983
  *
2013
- * translate(150, 150);
1984
+ * translate(50, 50);
2014
1985
  * circle(0, 0, 80);
2015
- * }
1986
+ * };
2016
1987
  */
2017
1988
  function translate(x: number, y: number): void;
2018
1989
 
@@ -2020,15 +1991,14 @@ declare global {
2020
1991
  * Rotates the drawing context.
2021
1992
  * @param {number} angle rotation angle in radians
2022
1993
  * @example
2023
- * function draw() {
2024
- * background(200);
1994
+ * q5.draw = function () {
1995
+ * background(0.8);
2025
1996
  *
2026
- * translate(100, 100);
2027
1997
  * rotate(mouseX / 50);
2028
1998
  *
2029
1999
  * rectMode(CENTER);
2030
- * square(0, 0, 50);
2031
- * }
2000
+ * square(0, 0, 120);
2001
+ * };
2032
2002
  */
2033
2003
  function rotate(angle: number): void;
2034
2004
 
@@ -2040,12 +2010,12 @@ declare global {
2040
2010
  * @param {number} x scaling factor along the x-axis
2041
2011
  * @param {number} [y] scaling factor along the y-axis
2042
2012
  * @example
2043
- * function draw() {
2044
- * background(200);
2013
+ * q5.draw = function () {
2014
+ * background(0.8);
2045
2015
  *
2046
2016
  * scale(mouseX / 10);
2047
2017
  * circle(0, 0, 20);
2048
- * }
2018
+ * };
2049
2019
  */
2050
2020
  function scale(x: number, y?: number): void;
2051
2021
 
@@ -2053,13 +2023,13 @@ declare global {
2053
2023
  * Shears the drawing context along the x-axis.
2054
2024
  * @param {number} angle shear angle in radians
2055
2025
  * @example
2056
- * function draw() {
2057
- * background(200);
2026
+ * q5.draw = function () {
2027
+ * background(0.8);
2058
2028
  *
2059
- * translate(25, 60);
2029
+ * translate(-75, -40);
2060
2030
  * shearX(mouseX / 100);
2061
2031
  * square(0, 0, 80);
2062
- * }
2032
+ * };
2063
2033
  */
2064
2034
  function shearX(angle: number): void;
2065
2035
 
@@ -2067,13 +2037,13 @@ declare global {
2067
2037
  * Shears the drawing context along the y-axis.
2068
2038
  * @param {number} angle shear angle in radians
2069
2039
  * @example
2070
- * function draw() {
2071
- * background(200);
2040
+ * q5.draw = function () {
2041
+ * background(0.8);
2072
2042
  *
2073
- * translate(25, 60);
2043
+ * translate(-75, -40);
2074
2044
  * shearY(mouseX / 100);
2075
2045
  * square(0, 0, 80);
2076
- * }
2046
+ * };
2077
2047
  */
2078
2048
  function shearY(angle: number): void;
2079
2049
 
@@ -2081,6 +2051,10 @@ declare global {
2081
2051
  * Applies a transformation matrix.
2082
2052
  *
2083
2053
  * Accepts a 3x3 matrix as either an array or multiple arguments.
2054
+ *
2055
+ * Note that in q5 WebGPU, the identity matrix (default)
2056
+ * has a negative y scale to flip the y-axis to match
2057
+ * the Canvas2D renderer.
2084
2058
  * @param {number} a
2085
2059
  * @param {number} b
2086
2060
  * @param {number} c
@@ -2088,12 +2062,12 @@ declare global {
2088
2062
  * @param {number} e
2089
2063
  * @param {number} f
2090
2064
  * @example
2091
- * function draw() {
2092
- * background(200);
2065
+ * q5.draw = function () {
2066
+ * background(0.8);
2093
2067
  *
2094
- * applyMatrix(2, 1, 1, 1, 100, 100);
2068
+ * applyMatrix(2, -1, 1, -1);
2095
2069
  * circle(0, 0, 80);
2096
- * }
2070
+ * };
2097
2071
  */
2098
2072
  function applyMatrix(a: number, b: number, c: number, d: number, e: number, f: number): void;
2099
2073
 
@@ -2103,10 +2077,10 @@ declare global {
2103
2077
  * q5 runs this function before every time the `draw` function is run,
2104
2078
  * so that transformations don't carry over to the next frame.
2105
2079
  * @example
2106
- * createCanvas(200);
2107
- * background(200);
2080
+ * await Canvas(200);
2081
+ * background(0.8);
2108
2082
  *
2109
- * translate(100, 100);
2083
+ * translate(50, 50);
2110
2084
  * circle(0, 0, 80);
2111
2085
  *
2112
2086
  * resetMatrix();
@@ -2117,9 +2091,8 @@ declare global {
2117
2091
  /** 🦋
2118
2092
  * Saves the current transformation matrix.
2119
2093
  * @example
2120
- * createCanvas(200);
2121
- * background(200);
2122
- * translate(100, 100);
2094
+ * await Canvas(200);
2095
+ * background(0.8);
2123
2096
  *
2124
2097
  * pushMatrix();
2125
2098
  * rotate(QUARTER_PI);
@@ -2133,9 +2106,8 @@ declare global {
2133
2106
  /** 🦋
2134
2107
  * Restores the previously saved transformation matrix.
2135
2108
  * @example
2136
- * createCanvas(200);
2137
- * background(200);
2138
- * translate(100, 100);
2109
+ * await Canvas(200);
2110
+ * background(0.8);
2139
2111
  *
2140
2112
  * pushMatrix();
2141
2113
  * rotate(QUARTER_PI);
@@ -2149,11 +2121,11 @@ declare global {
2149
2121
  /** 🦋
2150
2122
  * Saves the current drawing style settings and transformations.
2151
2123
  * @example
2152
- * createCanvas(200);
2124
+ * await Canvas(200);
2153
2125
  *
2154
2126
  * push();
2155
2127
  * fill('blue');
2156
- * translate(100, 100);
2128
+ * translate(50, 50);
2157
2129
  * circle(0, 0, 80);
2158
2130
  * pop();
2159
2131
  *
@@ -2164,11 +2136,11 @@ declare global {
2164
2136
  /** 🦋
2165
2137
  * Restores the previously saved drawing style settings and transformations.
2166
2138
  * @example
2167
- * createCanvas(200);
2139
+ * await Canvas(200);
2168
2140
  *
2169
2141
  * push();
2170
2142
  * fill('blue');
2171
- * translate(100, 100);
2143
+ * translate(50, 50);
2172
2144
  * circle(0, 0, 80);
2173
2145
  * pop();
2174
2146
  *
@@ -2184,11 +2156,11 @@ declare global {
2184
2156
  * @param {string} renderQuality SMOOTH or PIXELATED
2185
2157
  * @param {number} scale can also be given as a string (for example "x2")
2186
2158
  * @example
2187
- * createCanvas(50, 25);
2159
+ * await Canvas(50, 25);
2188
2160
  *
2189
2161
  * displayMode(CENTER, PIXELATED, 4);
2190
2162
  *
2191
- * circle(25, 12.5, 16);
2163
+ * circle(0, 0, 16);
2192
2164
  */
2193
2165
  function displayMode(mode: string, renderQuality: string, scale: string | number): void;
2194
2166
 
@@ -2223,51 +2195,61 @@ declare global {
2223
2195
  /** 💻
2224
2196
  * The width of the window.
2225
2197
  * @example
2226
- * function draw() {
2227
- * background(200);
2198
+ * q5.draw = function () {
2199
+ * background(0.8);
2228
2200
  * textSize(64);
2229
2201
  * textAlign(CENTER, CENTER);
2230
- * text(windowWidth, 100, 100);
2231
- * }
2202
+ * text(windowWidth, 0, 0);
2203
+ * };
2232
2204
  */
2233
2205
  var windowWidth: number;
2234
2206
 
2235
2207
  /** 💻
2236
2208
  * The height of the window.
2237
2209
  * @example
2238
- * function draw() {
2239
- * background(200);
2210
+ * q5.draw = function () {
2211
+ * background(0.8);
2240
2212
  * textSize(64);
2241
2213
  * textAlign(CENTER, CENTER);
2242
- * text(windowHeight, 100, 100);
2243
- * }
2214
+ * text(windowHeight, 0, 0);
2215
+ * };
2244
2216
  */
2245
2217
  var windowHeight: number;
2246
2218
 
2247
2219
  /** 💻
2248
2220
  * The width of the canvas.
2221
+ * @example
2222
+ * await Canvas(200, 120);
2223
+ * circle(0, 0, width);
2249
2224
  */
2250
2225
  var width: number;
2251
2226
 
2252
2227
  /** 💻
2253
2228
  * The height of the canvas.
2229
+ * @example
2230
+ * await Canvas(200, 80);
2231
+ * circle(0, 0, height);
2254
2232
  */
2255
2233
  var height: number;
2256
2234
 
2257
2235
  /** 💻
2258
2236
  * Half the width of the canvas.
2237
+ * @example
2238
+ * await Canvas(200, 80);
2239
+ * circle(0, 0, halfWidth);
2259
2240
  */
2260
2241
  var halfWidth: number;
2261
2242
 
2262
2243
  /** 💻
2263
2244
  * Half the height of the canvas.
2245
+ * @example
2246
+ * await Canvas(200, 80);
2247
+ * circle(0, 0, halfHeight);
2264
2248
  */
2265
2249
  var halfHeight: number;
2266
2250
 
2267
2251
  /** 💻
2268
2252
  * The canvas element associated with the Q5 instance.
2269
- *
2270
- * If a canvas is not explicitly created with `createCanvas()`, but a q5 function like `draw` or `mousePressed` is defined, a default canvas of size 200x200 will be created automatically.
2271
2253
  */
2272
2254
  var canvas: HTMLCanvasElement;
2273
2255
 
@@ -2276,36 +2258,36 @@ declare global {
2276
2258
  * @param {number} w width of the canvas
2277
2259
  * @param {number} h height of the canvas
2278
2260
  * @example
2279
- * createCanvas(200, 100);
2261
+ * await Canvas(200, 100);
2280
2262
  *
2281
- * function draw() {
2282
- * background(200);
2283
- * }
2263
+ * q5.draw = function () {
2264
+ * background(0.8);
2265
+ * };
2284
2266
  *
2285
- * function mousePressed() {
2267
+ * q5.mousePressed = function () {
2286
2268
  * resizeCanvas(200, 200);
2287
- * }
2269
+ * };
2288
2270
  */
2289
2271
  function resizeCanvas(w: number, h: number): void;
2290
2272
 
2291
2273
  /** 💻
2292
2274
  * The number of frames that have been displayed since the program started.
2293
2275
  * @example
2294
- * function draw() {
2295
- * background(200);
2276
+ * q5.draw = function () {
2277
+ * background(0.8);
2296
2278
  * textSize(64);
2297
- * text(frameCount, 8, 120);
2298
- * }
2279
+ * text(frameCount, -92, 20);
2280
+ * };
2299
2281
  */
2300
2282
  var frameCount: number;
2301
2283
 
2302
2284
  /** 💻
2303
2285
  * Stops the draw loop.
2304
2286
  * @example
2305
- * function draw() {
2306
- * circle(frameCount * 5, 100, 80);
2287
+ * q5.draw = function () {
2288
+ * circle(frameCount * 5 - 100, 0, 80);
2307
2289
  * noLoop();
2308
- * }
2290
+ * };
2309
2291
  */
2310
2292
  function noLoop(): void;
2311
2293
 
@@ -2316,30 +2298,30 @@ declare global {
2316
2298
  * This is an async function.
2317
2299
  * @param {number} [n] number of times to redraw the canvas, default is 1
2318
2300
  * @example
2319
- * createCanvas(200);
2301
+ * await Canvas(200);
2320
2302
  * noLoop();
2321
2303
  *
2322
- * function draw() {
2323
- * circle(frameCount * 5, 100, 80);
2324
- * }
2325
- * function mousePressed() {
2304
+ * q5.draw = function () {
2305
+ * circle(frameCount * 5 - 100, 0, 80);
2306
+ * };
2307
+ * q5.mousePressed = function () {
2326
2308
  * redraw(10);
2327
- * }
2309
+ * };
2328
2310
  */
2329
2311
  function redraw(n?: number): void;
2330
2312
 
2331
2313
  /** 💻
2332
2314
  * Starts the draw loop again if it was stopped.
2333
2315
  * @example
2334
- * createCanvas(200);
2316
+ * await Canvas(200);
2335
2317
  * noLoop();
2336
2318
  *
2337
- * function draw() {
2338
- * circle(frameCount * 5, 100, 80);
2339
- * }
2340
- * function mousePressed() {
2319
+ * q5.draw = function () {
2320
+ * circle(frameCount * 5 - 100, 0, 80);
2321
+ * };
2322
+ * q5.mousePressed = function () {
2341
2323
  * loop();
2342
- * }
2324
+ * };
2343
2325
  */
2344
2326
  function loop(): void;
2345
2327
 
@@ -2353,20 +2335,20 @@ declare global {
2353
2335
  * @param {number} [hertz] target frame rate, default is 60
2354
2336
  * @returns {number} current frame rate
2355
2337
  * @example
2356
- * function draw() {
2357
- * background(200);
2338
+ * q5.draw = function () {
2339
+ * background(0.8);
2358
2340
  *
2359
2341
  * if (mouseIsPressed) frameRate(10);
2360
2342
  * else frameRate(60);
2361
2343
  *
2362
- * circle(frameCount % 200, 100, 80);
2363
- * }
2344
+ * circle((frameCount % 200) - 100, 0, 80);
2345
+ * };
2364
2346
  * @example
2365
- * function draw() {
2366
- * background(200);
2347
+ * q5.draw = function () {
2348
+ * background(0.8);
2367
2349
  * textSize(64);
2368
- * text(round(frameRate()), 65, 120);
2369
- * }
2350
+ * text(round(frameRate()), -35, 20);
2351
+ * };
2370
2352
  */
2371
2353
  function frameRate(hertz?: number): number;
2372
2354
 
@@ -2374,12 +2356,12 @@ declare global {
2374
2356
  * The desired frame rate of the sketch.
2375
2357
  * @returns {number} target frame rate
2376
2358
  * @example
2377
- * function draw() {
2378
- * background(200);
2359
+ * q5.draw = function () {
2360
+ * background(0.8);
2379
2361
  * textSize(64);
2380
2362
  *
2381
- * text(getTargetFrameRate(), 65, 120);
2382
- * }
2363
+ * text(getTargetFrameRate(), -35, 20);
2364
+ * };
2383
2365
  */
2384
2366
  function getTargetFrameRate(): number;
2385
2367
 
@@ -2391,13 +2373,13 @@ declare global {
2391
2373
  * performance analysis.
2392
2374
  * @returns {number} frames per second
2393
2375
  * @example
2394
- * function draw() {
2395
- * background(200);
2376
+ * q5.draw = function () {
2377
+ * background(0.8);
2396
2378
  * frameRate(1);
2397
2379
  * textSize(64);
2398
2380
  *
2399
- * text(getFPS(), 8, 120);
2400
- * }
2381
+ * text(getFPS(), -92, 20);
2382
+ * };
2401
2383
  */
2402
2384
  function getFPS(): number;
2403
2385
 
@@ -2408,15 +2390,6 @@ declare global {
2408
2390
  * to do so at the end of the `draw` function, such as when using
2409
2391
  * addons like p5play that auto-draw to the canvas after the `draw`
2410
2392
  * function is run.
2411
- * @example
2412
- * function draw() {
2413
- * background(200);
2414
- * circle(frameCount % 200, 100, 80);
2415
- * }
2416
- *
2417
- * function postProcess() {
2418
- * filter(INVERT);
2419
- * }
2420
2393
  */
2421
2394
  function postProcess(): void;
2422
2395
 
@@ -2425,10 +2398,10 @@ declare global {
2425
2398
  * @param {number} v pixel density value
2426
2399
  * @returns {number} pixel density
2427
2400
  * @example
2428
- * createCanvas(200, 100);
2429
- * background(200);
2401
+ * await Canvas(200, 100);
2402
+ * background(0.8);
2430
2403
  * pixelDensity(1);
2431
- * circle(100, 50, 80);
2404
+ * circle(0, 0, 80);
2432
2405
  */
2433
2406
  function pixelDensity(v: number): number;
2434
2407
 
@@ -2438,10 +2411,10 @@ declare global {
2438
2411
  * On most modern displays, this value will be 2 or 3.
2439
2412
  * @returns {number} display density
2440
2413
  * @example
2441
- * createCanvas(200, 100);
2442
- * background(200);
2414
+ * await Canvas(200, 100);
2415
+ * background(0.8);
2443
2416
  * textSize(64);
2444
- * text(displayDensity(), 10, 20);
2417
+ * text(displayDensity(), -90, 6);
2445
2418
  */
2446
2419
  function displayDensity(): number;
2447
2420
 
@@ -2456,31 +2429,24 @@ declare global {
2456
2429
  * rates are consistently low, consider reducing the target frame
2457
2430
  * rate instead.
2458
2431
  * @example
2459
- * function draw() {
2460
- * background(200);
2461
- * text(deltaTime, 60, 106);
2462
- * }
2432
+ * q5.draw = function () {
2433
+ * background(0.8);
2434
+ * text(deltaTime, -90, 6);
2435
+ * };
2463
2436
  * @example
2464
- * let x = 0;
2465
- * function draw() {
2466
- * background(200);
2437
+ * let x = -100;
2438
+ * q5.draw = function () {
2439
+ * background(0.8);
2467
2440
  * // simulate frame rate drops
2468
2441
  * frameRate(random(30, 60));
2469
2442
  *
2470
2443
  * x += deltaTime * 0.2;
2471
- * circle(x % 200, 100, 20);
2472
- * }
2444
+ * if (x > 100) x = -100;
2445
+ * circle(x, 0, 20);
2446
+ * };
2473
2447
  */
2474
2448
  var deltaTime: number;
2475
2449
 
2476
- /** 💻
2477
- * The 2D rendering context for the canvas, if using the Canvas2D
2478
- * renderer.
2479
- */
2480
- var ctx: CanvasRenderingContext2D;
2481
-
2482
- var drawingContext: CanvasRenderingContext2D;
2483
-
2484
2450
  // 🧮 math
2485
2451
 
2486
2452
  /** 🧮
@@ -2494,17 +2460,17 @@ declare global {
2494
2460
  * @param {number} [high] upper bound (exclusive)
2495
2461
  * @returns {number | any} a random number or element
2496
2462
  * @example
2497
- * createCanvas(200);
2498
- * background(200);
2463
+ * await Canvas(200);
2464
+ * background(0.8);
2499
2465
  * frameRate(5);
2500
2466
  *
2501
- * function draw() {
2502
- * circle(100, 100, random(20, 200));
2503
- * }
2467
+ * q5.draw = function () {
2468
+ * circle(0, 0, random(200));
2469
+ * };
2504
2470
  * @example
2505
- * function draw() {
2506
- * circle(random(200), random(200), 10);
2507
- * }
2471
+ * q5.draw = function () {
2472
+ * circle(random(-100, 100), random(-10, 10), 10);
2473
+ * };
2508
2474
  */
2509
2475
  function random(low?: number | any[], high?: number): number | any;
2510
2476
 
@@ -2514,21 +2480,20 @@ declare global {
2514
2480
  * Can be used to create a jitter effect (random displacement).
2515
2481
  *
2516
2482
  * Equivalent to `random(-amount, amount)`.
2517
- * @param {number} amount absolute maximum amount of jitter, default is 1
2483
+ * @param {number} [amount] absolute maximum amount of jitter, default is 1
2518
2484
  * @returns {number} random number between -val and val
2519
2485
  * @example
2520
- * function draw() {
2486
+ * q5.draw = function () {
2521
2487
  * circle(mouseX + jit(3), mouseY + jit(3), 5);
2522
- * }
2488
+ * };
2523
2489
  * @example
2524
- * let q = await Q5.WebGPU();
2525
- * createCanvas(200, 100);
2490
+ * await Canvas(200);
2526
2491
  *
2527
- * q.draw = () => {
2492
+ * q5.draw = function () {
2528
2493
  * circle(jit(50), 0, random(50));
2529
2494
  * };
2530
2495
  */
2531
- function jit(amount: number): number;
2496
+ function jit(amount?: number): number;
2532
2497
 
2533
2498
  /** 🧮
2534
2499
  * Generates a noise value based on the x, y, and z inputs.
@@ -2539,20 +2504,31 @@ declare global {
2539
2504
  * @param {number} [z] z-coordinate input
2540
2505
  * @returns {number} a noise value
2541
2506
  * @example
2542
- * function draw() {
2543
- * background(200);
2507
+ * q5.draw = function () {
2508
+ * background(0.8);
2544
2509
  * let n = noise(frameCount * 0.01);
2545
- * circle(100, 100, n * 200);
2546
- * }
2510
+ * circle(0, 0, n * 200);
2511
+ * };
2547
2512
  * @example
2548
- * function draw() {
2549
- * background(200);
2513
+ * q5.draw = function () {
2514
+ * background(0.8);
2550
2515
  * let t = (frameCount + mouseX) * 0.02;
2551
2516
  * for (let x = -5; x < 220; x += 10) {
2552
2517
  * let n = noise(t, x * 0.1);
2553
- * circle(x, 100, n * 40);
2518
+ * circle(x - 100, 0, n * 40);
2554
2519
  * }
2555
- * }
2520
+ * };
2521
+ * @example
2522
+ * q5.draw = function () {
2523
+ * noStroke();
2524
+ * let t = millis() * 0.002;
2525
+ * for (let x = -100; x < 100; x += 5) {
2526
+ * for (let y = -100; y < 100; y += 5) {
2527
+ * fill(noise(t, (mouseX + x) * 0.05, y * 0.05));
2528
+ * square(x, y, 5);
2529
+ * }
2530
+ * }
2531
+ * };
2556
2532
  */
2557
2533
  function noise(x?: number, y?: number, z?: number): number;
2558
2534
 
@@ -2566,14 +2542,13 @@ declare global {
2566
2542
  * @param {number} y2 y-coordinate of the second point
2567
2543
  * @returns {number} distance between the points
2568
2544
  * @example
2569
- * function draw() {
2570
- * background(200);
2571
- * circle(100, 100, 20);
2572
- * circle(mouseX, mouseY, 20);
2545
+ * q5.draw = function () {
2546
+ * background(0.8);
2547
+ * line(0, 0, mouseX, mouseY);
2573
2548
  *
2574
- * let d = dist(100, 100, mouseX, mouseY);
2575
- * text(round(d), 20, 20);
2576
- * }
2549
+ * let d = dist(0, 0, mouseX, mouseY);
2550
+ * text(round(d), -80, -80);
2551
+ * };
2577
2552
  */
2578
2553
  function dist(x1: number, y1: number, x2: number, y2: number): number;
2579
2554
 
@@ -2655,10 +2630,10 @@ declare global {
2655
2630
  * @param {number} [d] number of decimal places to round to
2656
2631
  * @returns {number} rounded number
2657
2632
  * @example
2658
- * createCanvas(200, 100);
2659
- * background(200);
2633
+ * await Canvas(200, 100);
2634
+ * background(0.8);
2660
2635
  * textSize(32);
2661
- * text(round(PI, 5), 10, 60);
2636
+ * text(round(PI, 5), -90, 10);
2662
2637
  */
2663
2638
  function round(n: number, d: number): number;
2664
2639
 
@@ -2667,10 +2642,10 @@ declare global {
2667
2642
  * @param {number} n a number
2668
2643
  * @returns {number} rounded number
2669
2644
  * @example
2670
- * createCanvas(200, 100);
2671
- * background(200);
2645
+ * await Canvas(200, 100);
2646
+ * background(0.8);
2672
2647
  * textSize(32);
2673
- * text(ceil(PI), 10, 60);
2648
+ * text(ceil(PI), -90, 10);
2674
2649
  */
2675
2650
  function ceil(n: number): number;
2676
2651
 
@@ -2679,10 +2654,10 @@ declare global {
2679
2654
  * @param {number} n a number
2680
2655
  * @returns {number} rounded number
2681
2656
  * @example
2682
- * createCanvas(200, 100);
2683
- * background(200);
2657
+ * await Canvas(200, 100);
2658
+ * background(0.8);
2684
2659
  * textSize(32);
2685
- * text(floor(-PI), 10, 60);
2660
+ * text(floor(-PI), -90, 10);
2686
2661
  */
2687
2662
  function floor(n: number): number;
2688
2663
 
@@ -2691,10 +2666,10 @@ declare global {
2691
2666
  * @param {...number} args numbers to compare
2692
2667
  * @returns {number} minimum
2693
2668
  * @example
2694
- * function draw() {
2695
- * background(min(mouseX, 100));
2696
- * circle(min(mouseX, 100), 0, 80);
2697
- * }
2669
+ * q5.draw = function () {
2670
+ * background(min(-mouseX / 100, 0.5));
2671
+ * circle(min(mouseX, 0), 0, 80);
2672
+ * };
2698
2673
  */
2699
2674
  function min(...args: number[]): number;
2700
2675
 
@@ -2703,10 +2678,10 @@ declare global {
2703
2678
  * @param {...number} args numbers to compare
2704
2679
  * @returns {number} maximum
2705
2680
  * @example
2706
- * function draw() {
2707
- * background(max(mouseX, 100));
2708
- * circle(max(mouseX, 100), 0, 80);
2709
- * }
2681
+ * q5.draw = function () {
2682
+ * background(max(-mouseX / 100, 0.5));
2683
+ * circle(max(mouseX, 0), 0, 80);
2684
+ * };
2710
2685
  */
2711
2686
  function max(...args: number[]): number;
2712
2687
 
@@ -2869,14 +2844,14 @@ declare global {
2869
2844
  * @param {string} url sound file
2870
2845
  * @returns {Sound & PromiseLike<Sound>} sound
2871
2846
  * @example
2872
- * createCanvas(200);
2847
+ * await Canvas(200);
2873
2848
  *
2874
2849
  * let sound = loadSound('/assets/jump.wav');
2875
2850
  * sound.volume = 0.3;
2876
2851
  *
2877
- * function mousePressed() {
2852
+ * q5.mousePressed = function () {
2878
2853
  * sound.play();
2879
- * }
2854
+ * };
2880
2855
  */
2881
2856
  function loadSound(url: string): Sound & PromiseLike<Sound>;
2882
2857
 
@@ -2888,14 +2863,14 @@ declare global {
2888
2863
  * Note that audio can only be played after the first user
2889
2864
  * interaction with the page!
2890
2865
  * @example
2891
- * createCanvas(200);
2866
+ * await Canvas(200);
2892
2867
  *
2893
2868
  * let audio = loadAudio('/assets/retro.flac');
2894
2869
  * audio.volume = 0.4;
2895
2870
  *
2896
- * function mousePressed() {
2871
+ * q5.mousePressed = function () {
2897
2872
  * audio.play();
2898
- * }
2873
+ * };
2899
2874
  */
2900
2875
  function loadAudio(url: string): HTMLAudioElement & PromiseLike<HTMLAudioElement>;
2901
2876
 
@@ -2985,7 +2960,7 @@ declare global {
2985
2960
  */
2986
2961
 
2987
2962
  /** 📑
2988
- * Creates a new HTML element and adds it to the page. `createEl` is
2963
+ * Creates a new HTML element and adds it to the page. `createElement` is
2989
2964
  * an alias.
2990
2965
  *
2991
2966
  * Modify the element's CSS [`style`](https://developer.mozilla.org/docs/Web/API/HTMLElement/style) to change its appearance.
@@ -3007,7 +2982,7 @@ declare global {
3007
2982
  * @param {string} [content] content of the element
3008
2983
  * @returns {HTMLElement} element
3009
2984
  * @example
3010
- * createCanvas(200);
2985
+ * await Canvas(200);
3011
2986
  *
3012
2987
  * let el = createEl('div', '*');
3013
2988
  * el.position(50, 50);
@@ -3017,7 +2992,7 @@ declare global {
3017
2992
  * el.style.backgroundColor = 'blue';
3018
2993
  * el.style.color = 'white';
3019
2994
  */
3020
- function createElement(tag: string, content?: string): HTMLElement;
2995
+ function createEl(tag: string, content?: string): HTMLElement;
3021
2996
 
3022
2997
  /** 📑
3023
2998
  * Creates a link element.
@@ -3025,7 +3000,7 @@ declare global {
3025
3000
  * @param {string} [text] text content
3026
3001
  * @param {boolean} [newTab] whether to open the link in a new tab
3027
3002
  * @example
3028
- * createCanvas(200);
3003
+ * await Canvas(200);
3029
3004
  *
3030
3005
  * let link = createA('https://q5js.org', 'q5.js');
3031
3006
  * link.position(16, 42);
@@ -3041,12 +3016,12 @@ declare global {
3041
3016
  * Creates a button element.
3042
3017
  * @param {string} [content] text content
3043
3018
  * @example
3044
- * createCanvas(200, 100);
3019
+ * await Canvas(200, 100);
3045
3020
  *
3046
3021
  * let btn = createButton('Click me!');
3047
3022
  *
3048
3023
  * btn.addEventListener('click', () => {
3049
- * background(random(100, 255));
3024
+ * background(random(0.4, 1));
3050
3025
  * });
3051
3026
  */
3052
3027
  function createButton(content?: string): HTMLButtonElement;
@@ -3060,7 +3035,7 @@ declare global {
3060
3035
  * @param {string} [label] text label placed next to the checkbox
3061
3036
  * @param {boolean} [checked] initial state
3062
3037
  * @example
3063
- * createCanvas(200, 100);
3038
+ * await Canvas(200, 100);
3064
3039
  *
3065
3040
  * let box = createCheckbox('Check me!');
3066
3041
  * box.label.style.color = 'lime';
@@ -3078,14 +3053,14 @@ declare global {
3078
3053
  * Use the `value` property to get or set the color value.
3079
3054
  * @param {string} [value] initial color value
3080
3055
  * @example
3081
- * createCanvas(200, 100);
3056
+ * await Canvas(200, 100);
3082
3057
  *
3083
3058
  * let picker = createColorPicker();
3084
3059
  * picker.value = '#fd7575';
3085
3060
  *
3086
- * function draw() {
3061
+ * q5.draw = function () {
3087
3062
  * background(picker.value);
3088
- * }
3063
+ * };
3089
3064
  */
3090
3065
  function createColorPicker(value?: string): HTMLInputElement;
3091
3066
 
@@ -3093,7 +3068,7 @@ declare global {
3093
3068
  * Creates an image element.
3094
3069
  * @param {string} src url of the image
3095
3070
  * @example
3096
- * createCanvas(200, 100);
3071
+ * await Canvas(200, 100);
3097
3072
  *
3098
3073
  * let img = createImg('/assets/p5play_logo.webp');
3099
3074
  * img.position(0, 0).size(100, 100);
@@ -3112,7 +3087,7 @@ declare global {
3112
3087
  * @param {string} [value] initial value
3113
3088
  * @param {string} [type] text input type, can be 'text', 'password', 'email', 'number', 'range', 'search', 'tel', 'url'
3114
3089
  * @example
3115
- * createCanvas(200, 100);
3090
+ * await Canvas(200, 100);
3116
3091
  * textSize(64);
3117
3092
  *
3118
3093
  * let input = createInput();
@@ -3121,7 +3096,7 @@ declare global {
3121
3096
  *
3122
3097
  * input.addEventListener('input', () => {
3123
3098
  * background('orange');
3124
- * text(input.value, 10, 70);
3099
+ * text(input.value, -90, 30);
3125
3100
  * });
3126
3101
  */
3127
3102
  function createInput(value?: string, type?: string): HTMLInputElement;
@@ -3130,7 +3105,7 @@ declare global {
3130
3105
  * Creates a paragraph element.
3131
3106
  * @param {string} [content] text content
3132
3107
  * @example
3133
- * createCanvas(200, 50);
3108
+ * await Canvas(200, 50);
3134
3109
  * background('coral');
3135
3110
  *
3136
3111
  * let p = createP('Hello, world!');
@@ -3147,16 +3122,17 @@ declare global {
3147
3122
  * Use the `value` property to get or set the value of the selected radio button.
3148
3123
  * @param {string} [groupName]
3149
3124
  * @example
3150
- * createCanvas(200, 160);
3125
+ * await Canvas(200, 160);
3151
3126
  *
3152
3127
  * let radio = createRadio();
3153
- * radio.option('square', '1').option('circle', '2');
3128
+ * radio.option('square', '1');
3129
+ * radio.option('circle', '2');
3154
3130
  *
3155
- * function draw() {
3156
- * background(200);
3157
- * if (radio.value == '1') square(75, 25, 80);
3158
- * if (radio.value == '2') circle(100, 50, 80);
3159
- * }
3131
+ * q5.draw = function () {
3132
+ * background(0.8);
3133
+ * if (radio.value == '1') square(-40, -40, 80);
3134
+ * if (radio.value == '2') circle(0, 0, 80);
3135
+ * };
3160
3136
  */
3161
3137
  function createRadio(groupName?: string): HTMLDivElement;
3162
3138
 
@@ -3175,10 +3151,11 @@ declare global {
3175
3151
  * string or an array of strings.
3176
3152
  * @param {string} [placeholder] optional placeholder text that appears before an option is selected
3177
3153
  * @example
3178
- * createCanvas(200, 100);
3154
+ * await Canvas(200, 100);
3179
3155
  *
3180
3156
  * let sel = createSelect('Select an option');
3181
- * sel.option('Red', '#f55').option('Green', '#5f5');
3157
+ * sel.option('Red', '#f55');
3158
+ * sel.option('Green', '#5f5');
3182
3159
  *
3183
3160
  * sel.addEventListener('change', () => {
3184
3161
  * background(sel.value);
@@ -3197,14 +3174,14 @@ declare global {
3197
3174
  * @param {number} [value] initial value
3198
3175
  * @param {number} [step] step size
3199
3176
  * @example
3200
- * createCanvas(200);
3177
+ * await Canvas(200);
3201
3178
  *
3202
- * let slider = createSlider(0, 255);
3179
+ * let slider = createSlider(0, 1, 0.5, 0.1);
3203
3180
  * slider.position(10, 10).size(180);
3204
3181
  *
3205
- * function draw() {
3182
+ * q5.draw = function () {
3206
3183
  * background(slider.val());
3207
- * }
3184
+ * };
3208
3185
  */
3209
3186
  function createSlider(min: number, max: number, value?: number, step?: number): HTMLInputElement;
3210
3187
 
@@ -3219,25 +3196,25 @@ declare global {
3219
3196
  * @param {string} src url of the video
3220
3197
  * @returns {HTMLVideoElement & PromiseLike<HTMLVideoElement>} a new video element
3221
3198
  * @example
3222
- * createCanvas(1);
3199
+ * await Canvas(1);
3223
3200
  *
3224
3201
  * let vid = createVideo('/assets/apollo4.mp4');
3225
3202
  * vid.size(200, 150);
3226
3203
  * vid.autoplay = vid.muted = vid.loop = true;
3227
3204
  * vid.controls = true;
3228
3205
  * @example
3229
- * createCanvas(200, 150);
3206
+ * await Canvas(200, 150);
3230
3207
  * let vid = createVideo('/assets/apollo4.mp4');
3231
3208
  * vid.hide();
3232
3209
  *
3233
- * function mousePressed() {
3210
+ * q5.mousePressed = function () {
3234
3211
  * vid.currentTime = 0;
3235
3212
  * vid.play();
3236
- * }
3237
- * function draw() {
3238
- * image(vid, 0, 0, 200, 150);
3239
- * filter(HUE_ROTATE, 90);
3240
- * }
3213
+ * };
3214
+ * q5.draw = function () {
3215
+ * rotate(mouseX / 55);
3216
+ * image(vid, -100, -75, 200, 150);
3217
+ * };
3241
3218
  */
3242
3219
  function createVideo(src: string): HTMLVideoElement & PromiseLike<HTMLVideoElement>;
3243
3220
 
@@ -3258,46 +3235,50 @@ declare global {
3258
3235
  * @param {boolean} [flipped] whether to mirror the video vertically, true by default
3259
3236
  * @returns {HTMLVideoElement & PromiseLike<HTMLVideoElement>} a new video element
3260
3237
  * @example
3261
- * function mousePressed() {
3238
+ * q5.mousePressed = function () {
3262
3239
  * let cap = createCapture(VIDEO);
3263
3240
  * cap.size(200, 112.5);
3264
3241
  * canvas.remove();
3265
- * }
3242
+ * };
3266
3243
  * @example
3267
3244
  * let cap;
3268
- * function mousePressed() {
3245
+ * q5.mousePressed = function () {
3269
3246
  * cap = createCapture(VIDEO);
3270
3247
  * cap.hide();
3271
- * }
3248
+ * };
3272
3249
  *
3273
- * function draw() {
3274
- * let y = frameCount % height;
3275
- * image(cap, 0, y, 200, 200);
3276
- * }
3250
+ * q5.draw = function () {
3251
+ * let y = (frameCount % 200) - 100;
3252
+ * image(cap, -100, y, 200, 200);
3253
+ * };
3277
3254
  * @example
3278
- * function mousePressed() {
3255
+ * q5.mousePressed = function () {
3279
3256
  * let cap = createCapture({
3280
3257
  * video: { width: 640, height: 480 }
3281
3258
  * });
3282
3259
  * cap.size(200, 150);
3283
3260
  * canvas.remove();
3284
- * }
3261
+ * };
3285
3262
  */
3286
3263
  function createCapture(type?: string, flipped?: boolean): HTMLVideoElement & PromiseLike<HTMLVideoElement>;
3287
3264
 
3288
3265
  /** 📑
3289
3266
  * Finds the first element in the DOM that matches the given [CSS selector](https://developer.mozilla.org/docs/Learn_web_development/Core/Styling_basics/Basic_selectors).
3267
+ *
3268
+ * Alias for `document.querySelector`.
3290
3269
  * @param {string} selector
3291
3270
  * @returns {HTMLElement} element
3292
3271
  */
3293
- function findElement(selector: string): HTMLElement;
3272
+ function findEl(selector: string): HTMLElement;
3294
3273
 
3295
3274
  /** 📑
3296
3275
  * Finds all elements in the DOM that match the given [CSS selector](https://developer.mozilla.org/docs/Learn_web_development/Core/Styling_basics/Basic_selectors).
3276
+ *
3277
+ * Alias for `document.querySelectorAll`.
3297
3278
  * @param {string} selector
3298
3279
  * @returns {HTMLElement[]} elements
3299
3280
  */
3300
- function findElements(selector: string): HTMLElement[];
3281
+ function findEls(selector: string): HTMLElement[];
3301
3282
 
3302
3283
  // 🎞 record
3303
3284
 
@@ -3321,14 +3302,14 @@ declare global {
3321
3302
  * wiki page.
3322
3303
  * @returns {HTMLElement} a recorder, q5 DOM element
3323
3304
  * @example
3324
- * createCanvas(200);
3305
+ * await Canvas(200);
3325
3306
  *
3326
3307
  * let rec = createRecorder();
3327
3308
  * rec.bitrate = 10;
3328
3309
  *
3329
- * function draw() {
3330
- * circle(mouseX, random(height), 10);
3331
- * }
3310
+ * q5.draw = function () {
3311
+ * circle(mouseX, jit(halfHeight), 10);
3312
+ * };
3332
3313
  */
3333
3314
  function createRecorder(): HTMLElement;
3334
3315
 
@@ -3353,14 +3334,14 @@ declare global {
3353
3334
  * Saves the current recording as a video file.
3354
3335
  * @param {string} fileName
3355
3336
  * @example
3356
- * function draw() {
3357
- * square(mouseX, random(200), 10);
3358
- * }
3337
+ * q5.draw = function () {
3338
+ * square(mouseX, jit(100), 10);
3339
+ * };
3359
3340
  *
3360
- * function mousePressed() {
3341
+ * q5.mousePressed = function () {
3361
3342
  * if (!recording) record();
3362
3343
  * else saveRecording('squares');
3363
- * }
3344
+ * };
3364
3345
  */
3365
3346
  function saveRecording(fileName: string): void;
3366
3347
 
@@ -3381,11 +3362,41 @@ declare global {
3381
3362
  * @param {...string} urls
3382
3363
  * @returns {Promise<any[]>} a promise that resolves with objects
3383
3364
  * @example
3384
- * createCanvas(200);
3365
+ * await Canvas(200);
3366
+ *
3385
3367
  * let logo = load('/q5js_logo.avif');
3386
3368
  *
3387
- * function draw() {
3388
- * image(logo, 0, 0, 200, 200);
3369
+ * q5.draw = function () {
3370
+ * image(logo, -100, -100, 200, 200);
3371
+ * };
3372
+ * @example
3373
+ * await Canvas(200);
3374
+ * background(0.8);
3375
+ *
3376
+ * await load('/assets/Robotica.ttf');
3377
+ *
3378
+ * textSize(28);
3379
+ * text('Hello, world!', -97, 100);
3380
+ * @example
3381
+ * await Canvas(200);
3382
+ *
3383
+ * let [jump, retro] = await load('/assets/jump.wav', '/assets/retro.flac');
3384
+ *
3385
+ * q5.mousePressed = function () {
3386
+ * if (mouseButton == 'left') jump.play();
3387
+ * if (mouseButton == 'right') retro.play();
3388
+ * };
3389
+ * //
3390
+ * @example
3391
+ * await Canvas(200);
3392
+ * background(0.8);
3393
+ * textSize(32);
3394
+ *
3395
+ * let xml = await load('/assets/animals.xml');
3396
+ * let mammals = xml.querySelectorAll('mammal');
3397
+ * let y = -90;
3398
+ * for (let mammal of mammals) {
3399
+ * text(mammal.textContent, -90, (y += 32));
3389
3400
  * }
3390
3401
  */
3391
3402
  function load(...urls: string[]): PromiseLike<any[]>;
@@ -3400,23 +3411,23 @@ declare global {
3400
3411
  * @param {object} [data] canvas, image, or JS object
3401
3412
  * @param {string} [fileName] filename to save as
3402
3413
  * @example
3403
- * createCanvas(200);
3404
- * background(200);
3405
- * circle(100, 100, 50);
3414
+ * await Canvas(200);
3415
+ * background(0.8);
3416
+ * circle(0, 0, 50);
3406
3417
  *
3407
- * function mousePressed() {
3418
+ * q5.mousePressed = function () {
3408
3419
  * save('circle.png');
3409
- * }
3420
+ * };
3410
3421
  * @example
3411
- * createCanvas(200);
3412
- *
3422
+ * await Canvas(200);
3423
+ * background(0.8);
3424
+ * text('save me?', -90, 0);
3413
3425
  * textSize(180);
3414
3426
  * let bolt = createTextImage('⚡️');
3415
- * image(bolt, 16, -56);
3416
3427
  *
3417
- * function mousePressed() {
3428
+ * q5.mousePressed = function () {
3418
3429
  * save(bolt, 'bolt.png');
3419
- * }
3430
+ * };
3420
3431
  */
3421
3432
  function save(data?: object, fileName?: string): void;
3422
3433
 
@@ -3453,6 +3464,17 @@ declare global {
3453
3464
  * Using `await` to get the loaded XML Element is recommended.
3454
3465
  * @param {string} url xml file
3455
3466
  * @returns {Element & PromiseLike<Element>} an object containing the loaded XML Element in a property called `obj.DOM` or use await to get the XML Element directly
3467
+ * @example
3468
+ * await Canvas(200);
3469
+ * background(0.8);
3470
+ * textSize(32);
3471
+ *
3472
+ * let xml = await load('/assets/animals.xml');
3473
+ * let mammals = xml.querySelectorAll('mammal');
3474
+ * let y = -90;
3475
+ * for (let mammal of mammals) {
3476
+ * text(mammal.textContent, -90, (y += 32));
3477
+ * }
3456
3478
  */
3457
3479
  function loadXML(url: string): object & PromiseLike<Element>;
3458
3480
 
@@ -3473,6 +3495,12 @@ declare global {
3473
3495
  * @param {number} num number to format
3474
3496
  * @param {number} digits number of digits to format to
3475
3497
  * @returns {string} formatted number
3498
+ * @example
3499
+ * await Canvas(200, 100);
3500
+ * background(0.8);
3501
+ *
3502
+ * textSize(32);
3503
+ * text(nf(PI, 4, 5), -90, 10);
3476
3504
  */
3477
3505
  function nf(num: number, digits: number): string;
3478
3506
 
@@ -3548,6 +3576,12 @@ declare global {
3548
3576
  * @param {number} x x component of the vector
3549
3577
  * @param {number} y y component of the vector
3550
3578
  * @param {number} [z] optional. The z component of the vector
3579
+ * @example
3580
+ * await Canvas(200);
3581
+ * background(0.8);
3582
+ *
3583
+ * let v = createVector(0, 0);
3584
+ * circle(v.x, v.y, 50);
3551
3585
  */
3552
3586
  constructor(x: number, y: number, z?: number);
3553
3587
 
@@ -3711,18 +3745,20 @@ declare global {
3711
3745
  * @param {number} stop angle to stop the arc
3712
3746
  * @param {number} [mode] shape and stroke style setting, default is `PIE_OPEN` for a pie shape with an unclosed stroke, can be `PIE`, `CHORD`, or `CHORD_OPEN`
3713
3747
  * @example
3714
- * createCanvas(200);
3715
- * background(200);
3748
+ * await Canvas(200);
3749
+ * background(0.8);
3716
3750
  *
3717
- * arc(40, 40, 40, 40, 0.8, -0.8);
3718
- * arc(80, 80, 40, 40, 0.8, -0.8, PIE);
3719
- * arc(120, 120, 40, 40, 0.8, -0.8, CHORD_OPEN);
3720
- * arc(160, 160, 40, 40, 0.8, -0.8, CHORD);
3751
+ * arc(0, 0, 160, 160, 0.8, -0.8);
3721
3752
  */
3722
3753
  function arc(x: number, y: number, w: number, h: number, start: number, stop: number, mode?: number): void;
3723
3754
 
3724
3755
  /** 🖌
3725
3756
  * Draws a curve.
3757
+ * @example
3758
+ * await Canvas(200, 100);
3759
+ * background(0.8);
3760
+ *
3761
+ * curve(-100, -200, -50, 0, 50, 0, 100, -200);
3726
3762
  */
3727
3763
  function curve(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): void;
3728
3764
 
@@ -3731,6 +3767,14 @@ declare global {
3731
3767
  *
3732
3768
  * Only takes effect in q5 WebGPU.
3733
3769
  * @param {number} val curve detail level, default is 20
3770
+ * @example
3771
+ * await Canvas(200);
3772
+ *
3773
+ * curveDetail(4);
3774
+ *
3775
+ * strokeWeight(10);
3776
+ * stroke(0, 1, 1);
3777
+ * curve(-100, -200, -50, 0, 50, 0, 100, -200);
3734
3778
  */
3735
3779
  function curveDetail(val: number): void;
3736
3780
 
@@ -3822,6 +3866,281 @@ declare global {
3822
3866
  */
3823
3867
  function quad(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): void;
3824
3868
 
3869
+ // ⚡ shaders
3870
+
3871
+ /**
3872
+ * Custom shaders written in WGSL (WebGPU Shading Language) can be
3873
+ * used to create advanced visual effects in q5!
3874
+ */
3875
+
3876
+ /** ⚡
3877
+ * Creates a shader that q5 can use to draw shapes.
3878
+ *
3879
+ * Affects the following functions:
3880
+ * `triangle`, `quad`, `plane`,
3881
+ * `curve`, `bezier`, `beginShape`/`endShape`,
3882
+ * and `background` (unless an image is used).
3883
+ *
3884
+ * Use this function to customize a copy of the
3885
+ * [default shapes shader](https://github.com/q5js/q5.js/blob/main/src/shaders/shapes.wgsl).
3886
+ *
3887
+ * For more information on the vertex and fragment function
3888
+ * input parameters, data, and helper functions made available for use
3889
+ * in your custom shader code, read the
3890
+ * ["Custom Shaders in q5 WebGPU"](https://github.com/q5js/q5.js/wiki/Custom-Shaders-in-q5-WebGPU)
3891
+ * wiki page.
3892
+ * @param {string} code WGSL shader code excerpt
3893
+ * @returns {GPUShaderModule} a shader program
3894
+ * @example
3895
+ * await Canvas(200);
3896
+ *
3897
+ * let wobble = createShader(`
3898
+ * @vertex
3899
+ * fn vertexMain(v: VertexParams) -> FragParams {
3900
+ * var vert = transformVertex(v.pos, v.matrixIndex);
3901
+ *
3902
+ * let i = f32(v.vertexIndex) % 4 * 100;
3903
+ * vert.x += cos((q.time + i) * 0.01) * 0.1;
3904
+ *
3905
+ * var f: FragParams;
3906
+ * f.position = vert;
3907
+ * f.color = vec4f(1, 0, 0, 1);
3908
+ * return f;
3909
+ * }`);
3910
+ *
3911
+ * q5.draw = function () {
3912
+ * clear();
3913
+ * shader(wobble);
3914
+ * plane(0, 0, 100);
3915
+ * };
3916
+ * @example
3917
+ * await Canvas(200);
3918
+ *
3919
+ * let stripes = createShader(`
3920
+ * @fragment
3921
+ * fn fragMain(f: FragParams) -> @location(0) vec4f {
3922
+ * let r = cos((q.mouseY + f.position.y) * 0.2);
3923
+ * return vec4(r, 0.0, 1, 1);
3924
+ * }`);
3925
+ *
3926
+ * q5.draw = function () {
3927
+ * shader(stripes);
3928
+ * triangle(-50, -50, 0, 50, 50, -50);
3929
+ * };
3930
+ */
3931
+ function createShader(code: string): GPUShaderModule;
3932
+
3933
+ /** ⚡
3934
+ * A plane is a centered rectangle with no stroke.
3935
+ * @param {number} x center x
3936
+ * @param {number} y center y
3937
+ * @param {number} w width or side length
3938
+ * @param {number} [h] height
3939
+ * @example
3940
+ * await Canvas(200);
3941
+ * plane(0, 0, 100);
3942
+ */
3943
+ function plane(x: number, y: number, w: number, h?: number): void;
3944
+
3945
+ /** ⚡
3946
+ * Applies a shader.
3947
+ * @param {GPUShaderModule} shaderModule a shader program
3948
+ */
3949
+ function shader(shaderModule: GPUShaderModule): void;
3950
+
3951
+ /** ⚡
3952
+ * Make q5 use the default shapes shader.
3953
+ * @example
3954
+ * await Canvas(200);
3955
+ *
3956
+ * let stripes = createShader(`
3957
+ * @fragment
3958
+ * fn fragMain(f: FragParams) -> @location(0) vec4f {
3959
+ * let g = cos((q.mouseY + f.position.y) * 0.05);
3960
+ * return vec4(1, g, 0, 1);
3961
+ * }`);
3962
+ *
3963
+ * q5.draw = function () {
3964
+ * shader(stripes);
3965
+ * background(0);
3966
+ *
3967
+ * resetShader();
3968
+ * triangle(-50, -50, 0, 50, 50, -50);
3969
+ * };
3970
+ */
3971
+ function resetShader(): void;
3972
+
3973
+ /** ⚡
3974
+ * Make q5 use the default frame shader.
3975
+ */
3976
+ function resetFrameShader(): void;
3977
+
3978
+ /** ⚡
3979
+ * Make q5 use the default image shader.
3980
+ */
3981
+ function resetImageShader(): void;
3982
+
3983
+ /** ⚡
3984
+ * Make q5 use the default video shader.
3985
+ */
3986
+ function resetVideoShader(): void;
3987
+
3988
+ /** ⚡
3989
+ * Make q5 use the default text shader.
3990
+ */
3991
+ function resetTextShader(): void;
3992
+
3993
+ /** ⚡
3994
+ * Make q5 use all default shaders.
3995
+ */
3996
+ function resetShaders(): void;
3997
+
3998
+ /** ⚡
3999
+ * Creates a shader that q5 can use to draw frames.
4000
+ *
4001
+ * You must create a canvas before using this function.
4002
+ *
4003
+ * Use this function to customize a copy of the
4004
+ * [default frame shader](https://github.com/q5js/q5.js/blob/main/src/shaders/frame.wgsl).
4005
+ * @example
4006
+ * await Canvas(200);
4007
+ *
4008
+ * let boxy = createFrameShader(`
4009
+ * @fragment
4010
+ * fn fragMain(f: FragParams) -> @location(0) vec4f {
4011
+ * let x = sin(f.texCoord.y * 4 + q.time * 0.002);
4012
+ * let y = cos(f.texCoord.x * 4 + q.time * 0.002);
4013
+ * let uv = f.texCoord + vec2f(x, y);
4014
+ * return textureSample(tex, samp, uv);
4015
+ * }`);
4016
+ *
4017
+ * q5.draw = function () {
4018
+ * stroke(1);
4019
+ * strokeWeight(8);
4020
+ * line(mouseX, mouseY, pmouseX, pmouseY);
4021
+ * mouseIsPressed ? resetShaders() : shader(boxy);
4022
+ * };
4023
+ */
4024
+ function createFrameShader(code: string): GPUShaderModule;
4025
+
4026
+ /** ⚡
4027
+ * Creates a shader that q5 can use to draw images.
4028
+ *
4029
+ * Use this function to customize a copy of the
4030
+ * [default image shader](https://github.com/q5js/q5.js/blob/main/src/shaders/image.wgsl).
4031
+ * @param {string} code WGSL shader code excerpt
4032
+ * @returns {GPUShaderModule} a shader program
4033
+ * @example
4034
+ * await Canvas(200);
4035
+ * imageMode(CENTER);
4036
+ *
4037
+ * let logo = loadImage('/q5js_logo.avif');
4038
+ *
4039
+ * let grate = createImageShader(`
4040
+ * @fragment
4041
+ * fn fragMain(f: FragParams) -> @location(0) vec4f {
4042
+ * var texColor = textureSample(tex, samp, f.texCoord);
4043
+ * texColor.b += (q.mouseX + f.position.x) % 20 / 10;
4044
+ * return texColor;
4045
+ * }`);
4046
+ *
4047
+ * q5.draw = function () {
4048
+ * background(0.7);
4049
+ * shader(grate);
4050
+ * image(logo, 0, 0, 180, 180);
4051
+ * };
4052
+ */
4053
+ function createImageShader(code: string): GPUShaderModule;
4054
+
4055
+ /** ⚡
4056
+ * Creates a shader that q5 can use to draw video frames.
4057
+ *
4058
+ * Use this function to customize a copy of the
4059
+ * [default video shader](https://github.com/q5js/q5.js/blob/main/src/shaders/video.wgsl).
4060
+ * @param {string} code WGSL shader code excerpt
4061
+ * @returns {GPUShaderModule} a shader program
4062
+ * @example
4063
+ * await Canvas(200, 600);
4064
+ *
4065
+ * let vid = createVideo('/assets/apollo4.mp4');
4066
+ * vid.hide();
4067
+ *
4068
+ * let flipper = createVideoShader(`
4069
+ * @vertex
4070
+ * fn vertexMain(v: VertexParams) -> FragParams {
4071
+ * var vert = transformVertex(v.pos, v.matrixIndex);
4072
+ *
4073
+ * var vi = f32(v.vertexIndex);
4074
+ * vert.y *= cos((q.frameCount + vi * 10) * 0.03);
4075
+ *
4076
+ * var f: FragParams;
4077
+ * f.position = vert;
4078
+ * f.texCoord = v.texCoord;
4079
+ * return f;
4080
+ * }
4081
+ *
4082
+ * @fragment
4083
+ * fn fragMain(f: FragParams) -> @location(0) vec4f {
4084
+ * var texColor =
4085
+ * textureSampleBaseClampToEdge(tex, samp, f.texCoord);
4086
+ * texColor.r = 0;
4087
+ * texColor.b *= 2;
4088
+ * return texColor;
4089
+ * }`);
4090
+ *
4091
+ * q5.draw = function () {
4092
+ * clear();
4093
+ * if (mouseIsPressed) vid.play();
4094
+ * shader(flipper);
4095
+ * image(vid, -100, 150, 200, 150);
4096
+ * };
4097
+ */
4098
+ function createVideoShader(code: string): GPUShaderModule;
4099
+
4100
+ /** ⚡
4101
+ * Creates a shader that q5 can use to draw text.
4102
+ *
4103
+ * Use this function to customize a copy of the
4104
+ * [default text shader](https://github.com/q5js/q5.js/blob/main/src/shaders/text.wgsl).
4105
+ * @param {string} code WGSL shader code excerpt
4106
+ * @returns {GPUShaderModule} a shader program
4107
+ * @example
4108
+ * await Canvas(200);
4109
+ * textAlign(CENTER, CENTER);
4110
+ *
4111
+ * let spin = createTextShader(`
4112
+ * @vertex
4113
+ * fn vertexMain(v : VertexParams) -> FragParams {
4114
+ * let char = textChars[v.instanceIndex];
4115
+ * let text = textMetadata[i32(char.w)];
4116
+ * let fontChar = fontChars[i32(char.z)];
4117
+ * let pos = calcPos(v.vertexIndex, char, fontChar, text);
4118
+ *
4119
+ * var vert = transformVertex(pos, text.matrixIndex);
4120
+ *
4121
+ * let i = f32(v.instanceIndex + 1);
4122
+ * vert.y *= cos((q.frameCount - 5 * i) * 0.05);
4123
+ *
4124
+ * var f : FragParams;
4125
+ * f.position = vert;
4126
+ * f.texCoord = calcUV(v.vertexIndex, fontChar);
4127
+ * f.fillColor = colors[i32(text.fillIndex)];
4128
+ * f.strokeColor = colors[i32(text.strokeIndex)];
4129
+ * f.strokeWeight = text.strokeWeight;
4130
+ * f.edge = text.edge;
4131
+ * return f;
4132
+ * }`);
4133
+ *
4134
+ * q5.draw = function () {
4135
+ * clear();
4136
+ * shader(spin);
4137
+ * fill(1, 0, 1);
4138
+ * textSize(32);
4139
+ * text('Hello, World!', 0, 0);
4140
+ * };
4141
+ */
4142
+ function createTextShader(code: string): GPUShaderModule;
4143
+
3825
4144
  // ⚙ advanced
3826
4145
 
3827
4146
  /** ⚙
@@ -3837,16 +4156,18 @@ declare global {
3837
4156
  * Used by the global `Canvas` function.
3838
4157
  * @param {string | Function} [scope]
3839
4158
  * @param {HTMLElement} [parent] element that the canvas will be placed inside
3840
- * @example
3841
- * let q = new Q5('namespace');
3842
- * q.createCanvas(200, 100);
3843
- * q.circle(100, 50, 20);
3844
4159
  */
3845
4160
  constructor(scope?: string | Function, parent?: HTMLElement);
3846
4161
 
3847
4162
  /** ⚙
3848
4163
  * The current minor version of q5.
3849
4164
  * @returns {string} the q5 version
4165
+ * @example
4166
+ * await Canvas(200);
4167
+ * background(0.8);
4168
+ * textSize(64);
4169
+ * textAlign(CENTER, CENTER);
4170
+ * text('v' + Q5.version, 0, 0);
3850
4171
  */
3851
4172
  static version: string;
3852
4173
 
@@ -3925,6 +4246,14 @@ declare global {
3925
4246
 
3926
4247
  /** ⚙
3927
4248
  * Creates a new Q5 instance that uses [q5's WebGPU renderer](https://github.com/q5js/q5.js/wiki/q5-WebGPU-renderer).
4249
+ * @example
4250
+ * let q = await Q5.WebGPU('namespace');
4251
+ * q.Canvas(200, 100);
4252
+ *
4253
+ * q.draw = () => {
4254
+ * q.background(0.8);
4255
+ * q.circle(q.mouseX, 0, 80);
4256
+ * };
3928
4257
  */
3929
4258
  static WebGPU(): Q5;
3930
4259
 
@@ -3935,6 +4264,14 @@ declare global {
3935
4264
  * Inside the function, `this` refers to the Q5 instance.
3936
4265
  * @param {string} lifecycle 'init', 'presetup', 'postsetup', 'predraw', 'postdraw', or 'remove'
3937
4266
  * @param {Function} fn The function to be run at the specified lifecycle phase.
4267
+ * @example
4268
+ * Q5.addHook('predraw', function () {
4269
+ * this.background('cyan');
4270
+ * });
4271
+ *
4272
+ * q5.draw = function () {
4273
+ * circle(mouseX, mouseY, 80);
4274
+ * };
3938
4275
  */
3939
4276
  static addHook(lifecycle: string, fn: Function): void;
3940
4277