q5 3.9.1 → 4.0.0

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
@@ -9,6 +9,8 @@ declare global {
9
9
  *
10
10
  * On these Learn pages, you can experiment with editing the
11
11
  * interactive mini examples. Have fun! 😎
12
+ *
13
+ * [![](/assets/Authored-By-Humans-Not-By-AI-Badge.png)](https://notbyai.fyi/)
12
14
  */
13
15
 
14
16
  /** ⭐
@@ -23,40 +25,37 @@ declare global {
23
25
  * @param {object} [opt] [options](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getContextAttributes)
24
26
  * @returns {Promise<HTMLCanvasElement>} created canvas element
25
27
  * @example
26
- * // Canvas2D
27
- * createCanvas(200, 100);
28
+ * // WebGPU
29
+ * await Canvas(200, 100);
28
30
  * background('silver');
29
31
  * circle(0, 0, 80);
30
32
  */
31
- function Canvas(w?: number, h?: number, options?: CanvasRenderingContext2DSettings): Promise<HTMLCanvasElement>;
33
+ function Canvas(w?: number, h?: number, options?: object): Promise<HTMLCanvasElement>;
32
34
 
33
35
  /** ⭐
34
36
  * The q5 draw function is run 60 times per second by default.
35
37
  * @example
36
- * function draw() {
38
+ * q5.draw = function () {
37
39
  * background('silver');
38
40
  * circle(mouseX, mouseY, 80);
39
- * }
41
+ * };
40
42
  */
41
43
  function draw(): void;
42
44
 
43
45
  /** ⭐
44
- * 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).
45
47
  *
46
48
  * To view the console, open your browser's web developer tools
47
49
  * via the keyboard shortcut `Ctrl + Shift + i` or `command + option + i`,
48
50
  * then click the "Console" tab.
49
51
  *
50
- * This is an alias for the standard
51
- * [`console.log`](https://developer.mozilla.org/docs/Web/API/console/log_static) function.
52
- *
53
- * 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!
54
53
  * @param {*} message
55
54
  * @example
56
- * function draw() {
55
+ * q5.draw = function () {
57
56
  * circle(mouseX, mouseY, 80);
58
57
  * log('The mouse is at:', mouseX, mouseY);
59
- * }
58
+ * };
60
59
  */
61
60
  function log(message: any): void;
62
61
 
@@ -68,8 +67,8 @@ declare global {
68
67
  * @param {number} y y-coordinate
69
68
  * @param {number} diameter diameter of the circle
70
69
  * @example
71
- * createCanvas(200, 100);
72
- * circle(100, 50, 80);
70
+ * await Canvas(200, 100);
71
+ * circle(0, 0, 80);
73
72
  */
74
73
  function circle(x: number, y: number, diameter: number): void;
75
74
 
@@ -78,29 +77,29 @@ declare global {
78
77
  * @param {number} x x-coordinate
79
78
  * @param {number} y y-coordinate
80
79
  * @param {number} width width of the ellipse
81
- * @param {number} [height] height of the ellipse
80
+ * @param {number} height height of the ellipse
82
81
  * @example
83
- * createCanvas(200, 100);
84
- * ellipse(100, 50, 160, 80);
82
+ * await Canvas(200, 100);
83
+ * ellipse(0, 0, 160, 80);
85
84
  */
86
- function ellipse(x: number, y: number, width: number, height?: number): void;
85
+ function ellipse(x: number, y: number, width: number, height: number): void;
87
86
 
88
87
  /** 🧑‍🎨
89
88
  * Draws a rectangle or a rounded rectangle.
90
89
  * @param {number} x x-coordinate
91
90
  * @param {number} y y-coordinate
92
91
  * @param {number} w width of the rectangle
93
- * @param {number} [h] height of the rectangle
92
+ * @param {number} h height of the rectangle
94
93
  * @param {number} [rounded] radius for all corners
95
94
  * @example
96
- * createCanvas(200);
97
- * background(200);
95
+ * await Canvas(200);
96
+ * background(0.8);
98
97
  *
99
- * rect(30, 20, 40, 60);
100
- * rect(80, 70, 40, 60, 10);
101
- * 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);
102
101
  */
103
- 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;
104
103
 
105
104
  /** 🧑‍🎨
106
105
  * Draws a square or a rounded square.
@@ -109,12 +108,12 @@ declare global {
109
108
  * @param {number} size size of the sides of the square
110
109
  * @param {number} [rounded] radius for all corners
111
110
  * @example
112
- * createCanvas(200);
113
- * background(200);
111
+ * await Canvas(200);
112
+ * background(0.8);
114
113
  *
115
- * square(30, 30, 40);
116
- * square(80, 80, 40, 10);
117
- * 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);
118
117
  */
119
118
  function square(x: number, y: number, size: number, rounded?: number): void;
120
119
 
@@ -123,12 +122,12 @@ declare global {
123
122
  * @param {number} x x-coordinate
124
123
  * @param {number} y y-coordinate
125
124
  * @example
126
- * createCanvas(200, 100);
125
+ * await Canvas(200, 100);
127
126
  * stroke('white');
128
- * point(75, 50);
127
+ * point(-25, 0);
129
128
  *
130
129
  * strokeWeight(10);
131
- * point(125, 50);
130
+ * point(25, 0);
132
131
  */
133
132
  function point(x: number, y: number): void;
134
133
 
@@ -139,9 +138,9 @@ declare global {
139
138
  * @param {number} x2 x-coordinate of the second point
140
139
  * @param {number} y2 y-coordinate of the second point
141
140
  * @example
142
- * createCanvas(200, 100);
141
+ * await Canvas(200, 100);
143
142
  * stroke('lime');
144
- * line(20, 20, 180, 80);
143
+ * line(-80, -30, 80, 30);
145
144
  */
146
145
  function line(x1: number, y1: number, x2: number, y2: number): void;
147
146
 
@@ -153,17 +152,17 @@ declare global {
153
152
  * @param {number} y2 y-coordinate of the second point
154
153
  * @param {number} r radius of the capsule semi-circle ends
155
154
  * @example
156
- * createCanvas(200, 100);
157
- * background(200);
155
+ * await Canvas(200, 100);
156
+ * background(0.8);
158
157
  * strokeWeight(5);
159
- * capsule(40, 40, 160, 60, 10);
158
+ * capsule(-60, -10, 60, 10, 10);
160
159
  * @example
161
- * function draw() {
162
- * background(200);
160
+ * q5.draw = function () {
161
+ * background(0.8);
163
162
  * fill('cyan');
164
163
  * strokeWeight(10);
165
- * capsule(100, 100, mouseX, mouseY, 20);
166
- * }
164
+ * capsule(0, 0, mouseX, mouseY, 20);
165
+ * };
167
166
  */
168
167
  function capsule(x1: number, y1: number, x2: number, y2: number, r: number): void;
169
168
 
@@ -174,33 +173,33 @@ declare global {
174
173
  * `rect` and `square` are interpreted.
175
174
  * @param {string} mode
176
175
  * @example
177
- * createCanvas(200, 100);
178
- * background(200);
176
+ * await Canvas(200, 100);
177
+ * background(0.8);
179
178
  * rectMode(CORNER);
180
179
  *
181
- * // ( x, y, w, h)
182
- * rect(50, 25, 100, 50);
180
+ * // ( x, y, w, h)
181
+ * rect(-50, -25, 100, 50);
183
182
  * @example
184
- * createCanvas(200, 100);
185
- * background(200);
183
+ * await Canvas(200, 100);
184
+ * background(0.8);
186
185
  * rectMode(CENTER);
187
186
  *
188
- * // ( cX, cY, w, h)
189
- * rect(100, 50, 100, 50);
187
+ * // (cX, cY, w, h)
188
+ * rect(0, 0, 100, 50);
190
189
  * @example
191
- * createCanvas(200, 100);
192
- * background(200);
190
+ * await Canvas(200, 100);
191
+ * background(0.8);
193
192
  * rectMode(RADIUS);
194
193
  *
195
- * // ( cX, cY, rX, rY)
196
- * rect(100, 50, 50, 25);
194
+ * // (cX, cY, rX, rY)
195
+ * rect(0, 0, 50, 25);
197
196
  * @example
198
- * createCanvas(200, 100);
199
- * background(200);
197
+ * await Canvas(200, 100);
198
+ * background(0.8);
200
199
  * rectMode(CORNERS);
201
200
  *
202
- * // ( x1, y1, x2, y2)
203
- * rect(50, 25, 150, 75);
201
+ * // ( x1, y1, x2, y2)
202
+ * rect(-50, -25, 50, 25);
204
203
  */
205
204
  function rectMode(mode: string): void;
206
205
 
@@ -211,33 +210,33 @@ declare global {
211
210
  * `ellipse`, `circle`, and `arc` are interpreted.
212
211
  * @param {string} mode
213
212
  * @example
214
- * createCanvas(200, 100);
215
- * background(200);
213
+ * await Canvas(200, 100);
214
+ * background(0.8);
216
215
  * ellipseMode(CENTER);
217
216
  *
218
- * // ( x, y, w, h)
219
- * ellipse(100, 50, 100, 50);
217
+ * // (x, y, w, h)
218
+ * ellipse(0, 0, 100, 50);
220
219
  * @example
221
- * createCanvas(200, 100);
222
- * background(200);
220
+ * await Canvas(200, 100);
221
+ * background(0.8);
223
222
  * ellipseMode(RADIUS);
224
223
  *
225
- * // ( x, y, rX, rY)
226
- * ellipse(100, 50, 50, 25);
224
+ * // (x, y, rX, rY)
225
+ * ellipse(0, 0, 50, 25);
227
226
  * @example
228
- * createCanvas(200, 100);
229
- * background(200);
227
+ * await Canvas(200, 100);
228
+ * background(0.8);
230
229
  * ellipseMode(CORNER);
231
230
  *
232
- * // (lX, tY, w, h)
233
- * ellipse(50, 25, 100, 50);
231
+ * // ( lX, tY, w, h)
232
+ * ellipse(-50, -25, 100, 50);
234
233
  * @example
235
- * createCanvas(200, 100);
236
- * background(200);
234
+ * await Canvas(200, 100);
235
+ * background(0.8);
237
236
  * ellipseMode(CORNERS);
238
237
  *
239
- * // ( x1, y1, x2, y2)
240
- * ellipse(50, 25, 150, 75);
238
+ * // ( x1, y1, x2, y2)
239
+ * ellipse(-50, -25, 50, 25);
241
240
  */
242
241
  function ellipseMode(mode: string): void;
243
242
 
@@ -265,13 +264,18 @@ declare global {
265
264
  * @param {string} url url of the image to load
266
265
  * @returns {Q5.Image & PromiseLike<Q5.Image>} image
267
266
  * @example
268
- * createCanvas(200);
267
+ * await Canvas(200);
269
268
  *
270
269
  * let logo = loadImage('/q5js_logo.avif');
271
270
  *
272
- * function draw() {
271
+ * q5.draw = function () {
273
272
  * background(logo);
274
- * }
273
+ * };
274
+ * @example
275
+ * await Canvas(200);
276
+ *
277
+ * let logo = await loadImage('/q5js_logo.avif');
278
+ * background(logo);
275
279
  */
276
280
  function loadImage(url: string): Q5.Image & PromiseLike<Q5.Image>;
277
281
 
@@ -287,21 +291,21 @@ declare global {
287
291
  * @param {number} [sw] width of the subsection of the source image
288
292
  * @param {number} [sh] height of the subsection of the source image
289
293
  * @example
290
- * createCanvas(200);
294
+ * await Canvas(200);
291
295
  *
292
- * let logo = loadImage('/q5js_logo.avif');
296
+ * let logo = load('/q5js_logo.avif');
293
297
  *
294
- * function draw() {
295
- * image(logo, 0, 0, 200, 200);
296
- * }
298
+ * q5.draw = function () {
299
+ * image(logo, -100, -100, 200, 200);
300
+ * };
297
301
  * @example
298
- * createCanvas(200);
302
+ * await Canvas(200);
299
303
  *
300
- * let logo = loadImage('/q5js_logo.avif');
304
+ * let logo = load('/q5js_logo.avif');
301
305
  *
302
- * function draw() {
303
- * image(logo, 0, 0, 200, 200, 256, 256, 512, 512);
304
- * }
306
+ * q5.draw = function () {
307
+ * image(logo, -100, -100, 200, 200, 256, 256, 512, 512);
308
+ * };
305
309
  */
306
310
  function image(): void;
307
311
 
@@ -311,35 +315,35 @@ declare global {
311
315
  * Changes how inputs to `image` are interpreted.
312
316
  * @param {string} mode
313
317
  * @example
314
- * createCanvas(200);
315
- * let logo = loadImage('/q5js_logo.avif');
318
+ * await Canvas(200);
319
+ * let logo = load('/q5js_logo.avif');
316
320
  *
317
- * function draw() {
321
+ * q5.draw = function () {
318
322
  * imageMode(CORNER);
319
323
  *
320
- * // ( img, x, y, w, h)
321
- * image(logo, 50, 50, 100, 100);
322
- * }
324
+ * // ( img, x, y, w, h)
325
+ * image(logo, -50, -50, 100, 100);
326
+ * };
323
327
  * @example
324
- * createCanvas(200);
325
- * let logo = loadImage('/q5js_logo.avif');
328
+ * await Canvas(200);
329
+ * let logo = load('/q5js_logo.avif');
326
330
  *
327
- * function draw() {
331
+ * q5.draw = function () {
328
332
  * imageMode(CENTER);
329
333
  *
330
- * // ( img, cX, cY, w, h)
331
- * image(logo, 100, 100, 100, 100);
332
- * }
334
+ * // (img, cX, cY, w, h)
335
+ * image(logo, 0, 0, 100, 100);
336
+ * };
333
337
  * @example
334
- * createCanvas(200);
335
- * let logo = loadImage('/q5js_logo.avif');
338
+ * await Canvas(200);
339
+ * let logo = load('/q5js_logo.avif');
336
340
  *
337
- * function draw() {
341
+ * q5.draw = function () {
338
342
  * imageMode(CORNERS);
339
343
  *
340
- * // ( img, x1, y1, x2, y2)
341
- * image(logo, 50, 50, 100, 100);
342
- * }
344
+ * // ( img, x1, y1, x2, y2)
345
+ * image(logo, -50, -50, 50, 50);
346
+ * };
343
347
  */
344
348
  function imageMode(mode: string): void;
345
349
 
@@ -363,14 +367,12 @@ declare global {
363
367
  * @param {number} w new width
364
368
  * @param {number} h new height
365
369
  * @example
366
- * createCanvas(200);
370
+ * await Canvas(200);
367
371
  *
368
- * let logo = loadImage('/q5js_logo.avif');
372
+ * let logo = await load('/q5js_logo.avif');
369
373
  *
370
- * function setup() {
371
- * logo.resize(128, 128);
372
- * image(logo, 0, 0, 200, 200);
373
- * }
374
+ * logo.resize(128, 128);
375
+ * image(logo, -100, -100, 200, 200);
374
376
  */
375
377
  function resize(w: number, h: number): void;
376
378
 
@@ -385,27 +387,24 @@ declare global {
385
387
  * their actual size. This is the default setting, so running this
386
388
  * function only has an effect if `noSmooth` has been called.
387
389
  * @example
388
- * createCanvas(200);
390
+ * await Canvas(200);
391
+ * smooth();
389
392
  *
390
- * let icon = loadImage('/q5js_icon.png');
391
- *
392
- * function setup() {
393
- * image(icon, 0, 0, 200, 200);
394
- * }
393
+ * let icon = await load('/q5js_icon.png');
394
+ * image(icon, -100, -100, 200, 200);
395
395
  */
396
396
  function smooth(): void;
397
397
 
398
398
  /** 🌆
399
399
  * Disables smooth image rendering for a pixelated look.
400
+ *
401
+ * This setting is applied to images when they're loaded.
400
402
  * @example
401
- * createCanvas(200);
402
- *
403
- * let icon = loadImage('/q5js_icon.png');
403
+ * await Canvas(200);
404
+ * noSmooth();
404
405
  *
405
- * function setup() {
406
- * noSmooth();
407
- * image(icon, 0, 0, 200, 200);
408
- * }
406
+ * let icon = await load('/q5js_icon.png');
407
+ * image(icon, -100, -100, 200, 200);
409
408
  */
410
409
  function noSmooth(): void;
411
410
 
@@ -429,14 +428,12 @@ declare global {
429
428
  * each copy separately.
430
429
  * @param {string | number} color tint color
431
430
  * @example
432
- * createCanvas(200);
431
+ * await Canvas(200);
433
432
  *
434
- * let logo = loadImage('/q5js_logo.avif');
433
+ * let logo = await load('/q5js_logo.avif');
435
434
  *
436
- * function setup() {
437
- * tint(255, 0, 0, 128);
438
- * image(logo, 0, 0, 200, 200);
439
- * }
435
+ * tint(1, 0, 0, 0.5);
436
+ * image(logo, -100, -100, 200, 200);
440
437
  */
441
438
  function tint(color: string | number): void;
442
439
 
@@ -469,14 +466,12 @@ declare global {
469
466
  * @param {number} dw width of the destination region
470
467
  * @param {number} dh height of the destination region
471
468
  * @example
472
- * createCanvas(200);
469
+ * await Canvas(200);
473
470
  *
474
- * let logo = loadImage('/q5js_logo.avif');
471
+ * let logo = await load('/q5js_logo.avif');
475
472
  *
476
- * function setup() {
477
- * logo.inset(256, 256, 512, 512, 0, 0, 256, 256);
478
- * image(logo, 0, 0, 200, 200);
479
- * }
473
+ * logo.inset(256, 256, 512, 512, 0, 0, 256, 256);
474
+ * image(logo, -100, -100, 200, 200);
480
475
  */
481
476
  function inset(sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
482
477
 
@@ -498,24 +493,12 @@ declare global {
498
493
  * @param {number} [h] height of the area, default is 1
499
494
  * @returns {Q5.Image | number[]}
500
495
  * @example
501
- * function draw() {
502
- * background(200);
503
- * noStroke();
504
- * circle(100, 100, frameCount % 200);
496
+ * await Canvas(200);
505
497
  *
506
- * loadPixels();
507
- * let col = get(mouseX, mouseY);
508
- * text(col, mouseX, mouseY);
509
- * }
510
- * @example
511
- * createCanvas(200);
512
- *
513
- * let logo = loadImage('/q5js_logo.avif');
498
+ * let logo = await load('/q5js_logo.avif');
514
499
  *
515
- * function setup() {
516
- * let cropped = logo.get(256, 256, 512, 512);
517
- * image(cropped, 0, 0, 200, 200);
518
- * }
500
+ * let cropped = logo.get(256, 256, 512, 512);
501
+ * image(cropped, -100, -100, 200, 200);
519
502
  */
520
503
  function get(x: number, y: number, w?: number, h?: number): Q5.Image | number[];
521
504
 
@@ -532,13 +515,16 @@ declare global {
532
515
  * @param {number} y
533
516
  * @param {any} val color, canvas, or image
534
517
  * @example
535
- * createCanvas(200);
518
+ * await Canvas(200);
519
+ * noSmooth();
536
520
  * let c = color('lime');
521
+ * let img = createImage(50, 50);
537
522
  *
538
- * function draw() {
539
- * set(random(200), random(200), c);
540
- * updatePixels();
541
- * }
523
+ * q5.draw = function () {
524
+ * img.set(random(50), random(50), c);
525
+ * img.updatePixels();
526
+ * background(img);
527
+ * };
542
528
  */
543
529
  function set(x: number, y: number, val: any): void;
544
530
 
@@ -564,17 +550,18 @@ declare global {
564
550
  *
565
551
  * Not applicable to WebGPU canvases.
566
552
  * @example
553
+ * await Canvas(200);
567
554
  * frameRate(5);
568
- * let icon = loadImage('/q5js_icon.png');
555
+ * let icon = load('/q5js_icon.png');
569
556
  *
570
- * function draw() {
557
+ * q5.draw = function () {
571
558
  * icon.loadPixels();
572
559
  * for (let i = 0; i < icon.pixels.length; i += 16) {
573
- * icon.pixels[i + 1] = random(255);
560
+ * icon.pixels[i + 1] = random(1);
574
561
  * }
575
562
  * icon.updatePixels();
576
563
  * background(icon);
577
- * }
564
+ * };
578
565
  */
579
566
  function loadPixels(): void;
580
567
 
@@ -583,14 +570,18 @@ declare global {
583
570
  *
584
571
  * Not applicable to WebGPU canvases.
585
572
  * @example
586
- * createCanvas(200);
573
+ * await Canvas(200);
574
+ * let c = color('pink');
587
575
  *
588
- * for (let x = 0; x < 200; x += 5) {
589
- * for (let y = 0; y < 200; y += 5) {
590
- * 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);
591
580
  * }
592
581
  * }
593
- * updatePixels();
582
+ * img.updatePixels();
583
+ *
584
+ * background(img);
594
585
  */
595
586
  function updatePixels(): void;
596
587
 
@@ -606,13 +597,10 @@ declare global {
606
597
  * @param {string} type filter type or a CSS filter string
607
598
  * @param {number} [value] optional value, depends on filter type
608
599
  * @example
609
- * createCanvas(200);
610
- * let logo = loadImage('/q5js_logo.avif');
611
- *
612
- * function setup() {
613
- * logo.filter(INVERT);
614
- * image(logo, 0, 0, 200, 200);
615
- * }
600
+ * await Canvas(200);
601
+ * let logo = await load('/q5js_logo.avif');
602
+ * logo.filter(INVERT);
603
+ * image(logo, -100, -100, 200, 200);
616
604
  */
617
605
  function filter(type: string, value?: number): void;
618
606
 
@@ -668,12 +656,22 @@ declare global {
668
656
  /** 🌆
669
657
  * Creates a graphics buffer.
670
658
  *
671
- * Disabled by default in q5 WebGPU.
659
+ * Graphics looping is disabled by default in q5 WebGPU.
672
660
  * See issue [#104](https://github.com/q5js/q5.js/issues/104) for details.
673
661
  * @param {number} w width
674
662
  * @param {number} h height
675
663
  * @param {object} [opt] options
676
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);
677
675
  */
678
676
  function createGraphics(w: number, h: number, opt?: any): Q5;
679
677
 
@@ -681,29 +679,26 @@ declare global {
681
679
 
682
680
  /** 📘
683
681
  * Renders text on the canvas.
684
- *
685
- * Text can be positioned with the x and y
686
- * parameters and can optionally be constrained.
687
682
  * @param {string} str string of text to display
688
683
  * @param {number} x x-coordinate of the text's position
689
684
  * @param {number} y y-coordinate of the text's position
690
685
  * @param {number} [wrapWidth] maximum line width in characters
691
686
  * @param {number} [lineLimit] maximum number of lines
692
687
  * @example
693
- * createCanvas(200, 100);
688
+ * await Canvas(200, 100);
694
689
  * background('silver');
695
690
  *
696
691
  * textSize(32);
697
- * text('Hello, world!', 12, 60);
692
+ * text('Hello, world!', -88, 10);
698
693
  * @example
699
- * createCanvas(200);
700
- * background(200);
694
+ * await Canvas(200);
695
+ * background(0.8);
701
696
  * textSize(20);
702
697
  *
703
698
  * let info =
704
- * '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.';
705
700
  *
706
- * text(info, 12, 30, 20, 6);
701
+ * text(info, -88, -70, 20);
707
702
  * //
708
703
  * //
709
704
  */
@@ -712,39 +707,46 @@ declare global {
712
707
  /** 📘
713
708
  * Loads a font from a URL.
714
709
  *
715
- * The font file can be in any format accepted in CSS, such as
716
- * .ttf and .otf files. The first example below loads
717
- * [Robotica](https://www.dafont.com/robotica-courtney.font).
710
+ * The first example below loads [Robotica](https://www.dafont.com/robotica-courtney.font).
718
711
  *
719
- * Also supports loading [Google fonts](https://fonts.google.com/).
720
712
  * The second example loads
721
- * [Pacifico](https://fonts.google.com/specimen/Pacifico).
722
- *
723
- * 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/).
724
714
  *
725
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`.
726
721
  * @param {string} url URL of the font to load
727
722
  * @returns {FontFace & PromiseLike<FontFace>} font
728
723
  * @example
729
- * createCanvas(200, 56);
724
+ * await Canvas(200, 56);
730
725
  *
731
- * loadFont('/assets/Robotica.ttf');
726
+ * await loadFont('/assets/Robotica.ttf');
732
727
  *
733
- * function setup() {
734
- * fill('skyblue');
735
- * textSize(64);
736
- * text('Hello!', 2, 54);
737
- * }
728
+ * fill('skyblue');
729
+ * textSize(64);
730
+ * text('Hello!', -98, 24);
738
731
  * @example
739
- * createCanvas(200, 74);
732
+ * await Canvas(200, 74);
740
733
  *
741
734
  * loadFont('fonts.googleapis.com/css2?family=Pacifico');
742
735
  *
743
- * function setup() {
736
+ * q5.draw = function () {
744
737
  * fill('hotpink');
745
738
  * textSize(68);
746
- * text('Hello!', 2, 68);
747
- * }
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);
748
750
  */
749
751
  function loadFont(url: string): FontFace & PromiseLike<FontFace>;
750
752
 
@@ -755,21 +757,19 @@ declare global {
755
757
  * "sans-serif" or the last font loaded.
756
758
  * @param {string} fontName name of the font family or a FontFace object
757
759
  * @example
758
- * createCanvas(200, 160);
759
- * background(200);
760
+ * await Canvas(200, 160);
761
+ * background(0.8);
760
762
  *
761
763
  * textFont('serif');
762
764
  *
763
- * textSize(32);
764
- * text('Hello, world!', 15, 90);
765
+ * text('Hello, world!', -96, 10);
765
766
  * @example
766
- * createCanvas(200);
767
- * background(200);
767
+ * await Canvas(200);
768
+ * background(0.8);
768
769
  *
769
770
  * textFont('monospace');
770
771
  *
771
- * textSize(24);
772
- * text('Hello, world!', 15, 90);
772
+ * text('Hello, world!', -96, 10);
773
773
  */
774
774
  function textFont(fontName: string): void;
775
775
 
@@ -778,12 +778,12 @@ declare global {
778
778
  * @param {number} [size] size of the font in pixels
779
779
  * @returns {number | void} current font size when no argument is provided
780
780
  * @example
781
- * function draw() {
782
- * background(200);
781
+ * q5.draw = function () {
782
+ * background(0.8);
783
783
  *
784
784
  * textSize(abs(mouseX));
785
- * text('A', 10, 190);
786
- * }
785
+ * text('A', -90, 90);
786
+ * };
787
787
  */
788
788
  function textSize(size?: number): number | void;
789
789
 
@@ -792,43 +792,45 @@ declare global {
792
792
  * @param {number} [leading] line height in pixels
793
793
  * @returns {number | void} current line height when no argument is provided
794
794
  * @example
795
- * function draw() {
796
- * background(200);
795
+ * q5.draw = function () {
796
+ * background(0.8);
797
797
  *
798
798
  * textSize(abs(mouseX));
799
- * text('A', 10, 190);
800
- * rect(10, 190, 5, -textLeading());
801
- * }
799
+ * text('A', -90, 90);
800
+ * rect(-90, 90, 5, -textLeading());
801
+ * };
802
802
  */
803
803
  function textLeading(leading?: number): number | void;
804
804
 
805
805
  /** 📘
806
806
  * Sets the current text style.
807
- *
808
- * Not applicable to WebGPU when using MSDF fonts.
807
+ *
808
+ * Not applicable to MSDF fonts.
809
809
  * @param {'normal' | 'italic' | 'bold' | 'bolditalic'} style font style
810
810
  * @example
811
- * createCanvas(200);
812
- * background(200);
811
+ * await Canvas(200);
812
+ * background(0.8);
813
813
  *
814
814
  * textStyle(ITALIC);
815
815
  *
816
816
  * textSize(32);
817
- * text('Hello, world!', 12, 106);
817
+ * text('Hello, world!', -88, 6);
818
818
  */
819
819
  function textStyle(style: 'normal' | 'italic' | 'bold' | 'bolditalic'): void;
820
820
 
821
821
  /** 📘
822
822
  * Sets the horizontal and vertical alignment of text.
823
+ *
824
+ * Alignment constants like `CENTER` can be used with this function.
823
825
  * @param {'left' | 'center' | 'right'} horiz horizontal alignment
824
826
  * @param {'top' | 'middle' | 'bottom' | 'alphabetic'} [vert] vertical alignment
825
827
  * @example
826
- * createCanvas(200);
827
- * background(200);
828
+ * await Canvas(200);
829
+ * background(0.8);
828
830
  * textSize(32);
829
831
  *
830
- * textAlign(CENTER, MIDDLE);
831
- * text('Hello, world!', 100, 100);
832
+ * textAlign(CENTER, CENTER);
833
+ * text('Hello, world!', 0, 0);
832
834
  */
833
835
  function textAlign(horiz: 'left' | 'center' | 'right', vert?: 'top' | 'middle' | 'bottom' | 'alphabetic'): void;
834
836
 
@@ -846,13 +848,13 @@ declare global {
846
848
  * - 900: black/heavy
847
849
  * @param {number | string} weight font weight
848
850
  * @example
849
- * createCanvas(200);
850
- * background(200);
851
+ * await Canvas(200);
852
+ * background(0.8);
851
853
  * textSize(32);
852
- * textAlign(CENTER, MIDDLE);
854
+ * textAlign(CENTER, CENTER);
853
855
  *
854
856
  * textWeight(100);
855
- * text('Hello, world!', 100, 100);
857
+ * text('Hello, world!', 0, 0);
856
858
  */
857
859
  function textWeight(weight: number | string): void;
858
860
 
@@ -861,13 +863,13 @@ declare global {
861
863
  * @param {string} str string to measure
862
864
  * @returns {number} width of the text in pixels
863
865
  * @example
864
- * function draw() {
865
- * background(200);
866
+ * q5.draw = function () {
867
+ * background(0.8);
866
868
  *
867
869
  * textSize(abs(mouseX));
868
- * rect(10, 190, textWidth('A'), -textLeading());
869
- * text('A', 10, 190);
870
- * }
870
+ * rect(-90, 90, textWidth('A'), -textLeading());
871
+ * text('A', -90, 90);
872
+ * };
871
873
  */
872
874
  function textWidth(str: string): number;
873
875
 
@@ -876,13 +878,13 @@ declare global {
876
878
  * @param {string} str string to measure
877
879
  * @returns {number} ascent of the text in pixels
878
880
  * @example
879
- * function draw() {
880
- * background(200);
881
+ * q5.draw = function () {
882
+ * background(0.8);
881
883
  *
882
884
  * textSize(abs(mouseX));
883
- * rect(10, 190, textWidth('A'), -textAscent());
884
- * text('A', 10, 190);
885
- * }
885
+ * rect(-90, 90, textWidth('A'), -textAscent());
886
+ * text('A', -90, 90);
887
+ * };
886
888
  */
887
889
  function textAscent(str: string): number;
888
890
 
@@ -891,12 +893,12 @@ declare global {
891
893
  * @param {string} str string to measure
892
894
  * @returns {number} descent of the text in pixels
893
895
  * @example
894
- * createCanvas(200);
895
- * background(200);
896
+ * await Canvas(200);
897
+ * background(0.8);
896
898
  * textSize(64);
897
899
  *
898
- * rect(0, 100, 200, textDescent('q5'));
899
- * text('q5', 10, 100);
900
+ * rect(-100, 0, 200, textDescent('q5'));
901
+ * text('q5', -90, 0);
900
902
  */
901
903
  function textDescent(str: string): number;
902
904
 
@@ -907,15 +909,15 @@ declare global {
907
909
  * @param {number} [lineLimit] maximum number of lines
908
910
  * @returns {Q5.Image} an image object representing the rendered text
909
911
  * @example
910
- * createCanvas(200);
912
+ * await Canvas(200);
911
913
  * textSize(96);
912
914
  *
913
915
  * let img = createTextImage('🐶');
914
916
  * img.filter(INVERT);
915
917
  *
916
- * function draw() {
917
- * image(img, 55, 10);
918
- * }
918
+ * q5.draw = function () {
919
+ * image(img, -45, -90);
920
+ * };
919
921
  */
920
922
  function createTextImage(str: string, wrapWidth: number, lineLimit: number): Q5.Image;
921
923
 
@@ -927,33 +929,63 @@ declare global {
927
929
  *
928
930
  * The positioning of the image is affected by the current text
929
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.
930
935
  *
931
- * In q5 WebGPU, this function is the only way to draw multi-colored
932
- * text, like emojis, and to use fonts that aren't in MSDF format.
933
- * Using this function to draw text that changes every frame has
934
- * a very high performance cost.
936
+ * Using this function to draw text that changes every frame has a
937
+ * very high performance cost.
935
938
  * @param {Q5.Image | string} img image or text
936
939
  * @param {number} x x-coordinate where the image should be placed
937
940
  * @param {number} y y-coordinate where the image should be placed
938
941
  * @example
939
- * createCanvas(200);
940
- * background(200);
942
+ * await Canvas(200);
943
+ * background(0.8);
941
944
  * textSize(96);
942
945
  * textAlign(CENTER, CENTER);
943
946
  *
944
- * 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
945
964
  * @example
946
- * createCanvas(200);
965
+ * await Canvas(200);
966
+ * textSize(220);
967
+ * textAlign(CENTER, CENTER);
968
+ *
969
+ * let points = textToPoints('5');
970
+ *
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);
947
980
  *
948
- * loadFont('/assets/Robotica.ttf');
981
+ * let pts = textToPoints('q', -100, 56);
949
982
  *
950
- * function setup() {
951
- * background(200);
952
- * textSize(66);
953
- * textImage('Hello!', 0, 0);
983
+ * strokeWeight(1);
984
+ * for (let pt of pts) {
985
+ * ellipse(pt.x, pt.y, 10, 0.1);
954
986
  * }
955
987
  */
956
- function textImage(img: Q5.Image | String, x: number, y: number): void;
988
+ function textToPoints(str: string, x?: number, y?: number, sampleRate?: number, density?: number): [];
957
989
 
958
990
  /** 📘
959
991
  * Number formatter, can be used to display a number as a string with
@@ -964,11 +996,11 @@ declare global {
964
996
  * @param {number} r number of digits to appear after the decimal point
965
997
  * @returns {string} a string representation of the number, formatted accordingly
966
998
  * @example
967
- * createCanvas(200, 100);
968
- * background(200);
999
+ * await Canvas(200, 100);
1000
+ * background(0.8);
969
1001
  *
970
1002
  * textSize(32);
971
- * text(nf(PI, 4, 5), 10, 60);
1003
+ * text(nf(PI, 4, 5), -90, 10);
972
1004
  */
973
1005
  function nf(num: number, digits: number): string;
974
1006
 
@@ -1012,6 +1044,11 @@ declare global {
1012
1044
  */
1013
1045
  const TOP: 'top';
1014
1046
 
1047
+ /** 📘
1048
+ * Align text to the middle.
1049
+ */
1050
+ const MIDDLE: 'middle';
1051
+
1015
1052
  /** 📘
1016
1053
  * Align text to the bottom.
1017
1054
  */
@@ -1041,21 +1078,21 @@ declare global {
1041
1078
  /** 🖲
1042
1079
  * Current X position of the mouse.
1043
1080
  * @example
1044
- * function draw() {
1045
- * background(200);
1081
+ * q5.draw = function () {
1082
+ * background(0.8);
1046
1083
  * textSize(64);
1047
- * text(round(mouseX), 50, 120);
1048
- * }
1084
+ * text(round(mouseX), -50, 20);
1085
+ * };
1049
1086
  */
1050
1087
  let mouseX: number;
1051
1088
 
1052
1089
  /** 🖲
1053
1090
  * Current Y position of the mouse.
1054
1091
  * @example
1055
- * function draw() {
1056
- * background(200);
1057
- * circle(100, mouseY, 100);
1058
- * }
1092
+ * q5.draw = function () {
1093
+ * background(0.8);
1094
+ * circle(0, mouseY, 100);
1095
+ * };
1059
1096
  */
1060
1097
  let mouseY: number;
1061
1098
 
@@ -1074,47 +1111,47 @@ declare global {
1074
1111
  *
1075
1112
  * The default value is an empty string.
1076
1113
  * @example
1077
- * function draw() {
1078
- * background(200);
1114
+ * q5.draw = function () {
1115
+ * background(0.8);
1079
1116
  * textSize(64);
1080
- * text(mouseButton, 20, 120);
1081
- * }
1117
+ * text(mouseButton, -80, 20);
1118
+ * };
1082
1119
  */
1083
1120
  let mouseButton: string;
1084
1121
 
1085
1122
  /** 🖲
1086
1123
  * True if the mouse is currently pressed, false otherwise.
1087
1124
  * @example
1088
- * function draw() {
1089
- * if (mouseIsPressed) background(100);
1090
- * else background(200);
1091
- * }
1125
+ * q5.draw = function () {
1126
+ * if (mouseIsPressed) background(0.4);
1127
+ * else background(0.8);
1128
+ * };
1092
1129
  */
1093
1130
  let mouseIsPressed: boolean;
1094
1131
 
1095
1132
  /** 🖲
1096
1133
  * Define this function to respond to mouse down events.
1097
1134
  * @example
1098
- * createCanvas(200);
1099
- * let gray = 95;
1135
+ * await Canvas(200);
1136
+ * let gray = 0.4;
1100
1137
  *
1101
- * function mousePressed() {
1102
- * background(gray % 256);
1103
- * gray += 40;
1104
- * }
1138
+ * q5.mousePressed = function () {
1139
+ * background(gray % 1);
1140
+ * gray += 0.1;
1141
+ * };
1105
1142
  */
1106
1143
  function mousePressed(): void;
1107
1144
 
1108
1145
  /** 🖲
1109
1146
  * Define this function to respond to mouse up events.
1110
1147
  * @example
1111
- * createCanvas(200);
1112
- * let gray = 95;
1148
+ * await Canvas(200);
1149
+ * let gray = 0.4;
1113
1150
  *
1114
- * function mouseReleased() {
1115
- * background(gray % 256);
1116
- * gray += 40;
1117
- * }
1151
+ * q5.mouseReleased = function () {
1152
+ * background(gray % 1);
1153
+ * gray += 0.1;
1154
+ * };
1118
1155
  */
1119
1156
  function mouseReleased(): void;
1120
1157
 
@@ -1124,13 +1161,13 @@ declare global {
1124
1161
  * On touchscreen devices this function is not called
1125
1162
  * when the user drags their finger on the screen.
1126
1163
  * @example
1127
- * createCanvas(200);
1128
- * let gray = 95;
1164
+ * await Canvas(200);
1165
+ * let gray = 0.4;
1129
1166
  *
1130
- * function mouseMoved() {
1131
- * background(gray % 256);
1132
- * gray++;
1133
- * }
1167
+ * q5.mouseMoved = function () {
1168
+ * background(gray % 1);
1169
+ * gray += 0.005;
1170
+ * };
1134
1171
  */
1135
1172
  function mouseMoved(): void;
1136
1173
 
@@ -1140,47 +1177,47 @@ declare global {
1140
1177
  * Dragging the mouse is defined as moving the mouse
1141
1178
  * while a mouse button is pressed.
1142
1179
  * @example
1143
- * createCanvas(200);
1144
- * let gray = 95;
1180
+ * await Canvas(200);
1181
+ * let gray = 0.4;
1145
1182
  *
1146
- * function mouseDragged() {
1147
- * background(gray % 256);
1148
- * gray++;
1149
- * }
1183
+ * q5.mouseDragged = function () {
1184
+ * background(gray % 1);
1185
+ * gray += 0.005;
1186
+ * };
1150
1187
  */
1151
1188
  function mouseDragged(): void;
1152
1189
 
1153
1190
  /** 🖲
1154
1191
  * Define this function to respond to mouse double click events.
1155
1192
  * @example
1156
- * createCanvas(200);
1157
- * let gray = 95;
1193
+ * await Canvas(200);
1194
+ * let gray = 0.4;
1158
1195
  *
1159
- * function doubleClicked() {
1160
- * background(gray % 256);
1161
- * gray += 40;
1162
- * }
1196
+ * q5.doubleClicked = function () {
1197
+ * background(gray % 1);
1198
+ * gray += 0.1;
1199
+ * };
1163
1200
  */
1164
1201
  function doubleClicked(): void;
1165
1202
 
1166
1203
  /** 🖲
1167
1204
  * The name of the last key pressed.
1168
1205
  * @example
1169
- * function draw() {
1170
- * background(200);
1206
+ * q5.draw = function () {
1207
+ * background(0.8);
1171
1208
  * textSize(64);
1172
- * text(key, 20, 120);
1173
- * }
1209
+ * text(key, -80, 20);
1210
+ * };
1174
1211
  */
1175
1212
  let key: string;
1176
1213
 
1177
1214
  /** 🖲
1178
1215
  * True if a key is currently pressed, false otherwise.
1179
1216
  * @example
1180
- * function draw() {
1181
- * if (keyIsPressed) background(100);
1182
- * else background(200);
1183
- * }
1217
+ * q5.draw = function () {
1218
+ * if (keyIsPressed) background(0.4);
1219
+ * else background(0.8);
1220
+ * };
1184
1221
  */
1185
1222
  let keyIsPressed: boolean;
1186
1223
 
@@ -1190,39 +1227,39 @@ declare global {
1190
1227
  * @param {string} key key to check
1191
1228
  * @returns {boolean} true if the key is pressed, false otherwise
1192
1229
  * @example
1193
- * function draw() {
1194
- * background(200);
1230
+ * q5.draw = function () {
1231
+ * background(0.8);
1195
1232
  *
1196
1233
  * if (keyIsDown('f') && keyIsDown('j')) {
1197
- * rect(50, 50, 100, 100);
1234
+ * rect(-50, -50, 100, 100);
1198
1235
  * }
1199
- * }
1236
+ * };
1200
1237
  */
1201
1238
  function keyIsDown(key: string): boolean;
1202
1239
 
1203
1240
  /** 🖲
1204
1241
  * Define this function to respond to key down events.
1205
1242
  * @example
1206
- * createCanvas(200);
1243
+ * await Canvas(200);
1244
+ * let gray = 0.4;
1207
1245
  *
1208
- * let gray = 95;
1209
- * function keyPressed() {
1210
- * background(gray % 256);
1211
- * gray += 40;
1212
- * }
1246
+ * q5.keyPressed = function () {
1247
+ * background(gray % 1);
1248
+ * gray += 0.1;
1249
+ * };
1213
1250
  */
1214
1251
  function keyPressed(): void;
1215
1252
 
1216
1253
  /** 🖲
1217
1254
  * Define this function to respond to key up events.
1218
1255
  * @example
1219
- * createCanvas(200);
1256
+ * await Canvas(200);
1257
+ * let gray = 0.4;
1220
1258
  *
1221
- * let gray = 95;
1222
- * function keyReleased() {
1223
- * background(gray % 256);
1224
- * gray += 40;
1225
- * }
1259
+ * q5.keyReleased = function () {
1260
+ * background(gray % 1);
1261
+ * gray += 0.1;
1262
+ * };
1226
1263
  */
1227
1264
  function keyReleased(): void;
1228
1265
 
@@ -1231,12 +1268,12 @@ declare global {
1231
1268
  * browser window. Each touch being an object with
1232
1269
  * `id`, `x`, and `y` properties.
1233
1270
  * @example
1234
- * function draw() {
1235
- * background(200);
1271
+ * q5.draw = function () {
1272
+ * background(0.8);
1236
1273
  * for (let touch of touches) {
1237
1274
  * circle(touch.x, touch.y, 100);
1238
1275
  * }
1239
- * }
1276
+ * };
1240
1277
  */
1241
1278
  let touches: any[];
1242
1279
 
@@ -1247,13 +1284,13 @@ declare global {
1247
1284
  * Return true to enable touch gestures like pinch-to-zoom
1248
1285
  * and scroll, which q5 disables on the canvas by default.
1249
1286
  * @example
1250
- * createCanvas(200);
1287
+ * await Canvas(200);
1288
+ * let gray = 0.4;
1251
1289
  *
1252
- * let gray = 95;
1253
- * function touchStarted() {
1254
- * background(gray % 256);
1255
- * gray += 40;
1256
- * }
1290
+ * q5.touchStarted = function () {
1291
+ * background(gray % 1);
1292
+ * gray += 0.1;
1293
+ * };
1257
1294
  */
1258
1295
  function touchStarted(): void;
1259
1296
 
@@ -1264,13 +1301,13 @@ declare global {
1264
1301
  * Return true to enable touch gestures like pinch-to-zoom
1265
1302
  * and scroll, which q5 disables on the canvas by default.
1266
1303
  * @example
1267
- * createCanvas(200);
1304
+ * await Canvas(200);
1305
+ * let gray = 0.4;
1268
1306
  *
1269
- * let gray = 95;
1270
- * function touchEnded() {
1271
- * background(gray % 256);
1272
- * gray += 40;
1273
- * }
1307
+ * q5.touchEnded = function () {
1308
+ * background(gray % 1);
1309
+ * gray += 0.1;
1310
+ * };
1274
1311
  */
1275
1312
  function touchEnded(): void;
1276
1313
 
@@ -1281,13 +1318,13 @@ declare global {
1281
1318
  * Return true to enable touch gestures like pinch-to-zoom
1282
1319
  * and scroll, which q5 disables on the canvas by default.
1283
1320
  * @example
1284
- * createCanvas(200);
1285
- * let gray = 95;
1321
+ * await Canvas(200);
1322
+ * let gray = 0.4;
1286
1323
  *
1287
- * function touchMoved() {
1288
- * background(gray % 256);
1289
- * gray++;
1290
- * }
1324
+ * q5.touchMoved = function () {
1325
+ * background(gray % 1);
1326
+ * gray += 0.005;
1327
+ * };
1291
1328
  */
1292
1329
  function touchMoved(): void;
1293
1330
 
@@ -1302,13 +1339,13 @@ declare global {
1302
1339
  * The `event` property contains the original
1303
1340
  * [PointerEvent](https://developer.mozilla.org/docs/Web/API/PointerEvent).
1304
1341
  * @example
1305
- * function draw() {
1306
- * background(200);
1342
+ * q5.draw = function () {
1343
+ * background(0.8);
1307
1344
  * for (let pointerID in pointers) {
1308
1345
  * let pointer = pointers[pointerID];
1309
1346
  * circle(pointer.x, pointer.y, 100);
1310
1347
  * }
1311
- * }
1348
+ * };
1312
1349
  */
1313
1350
  let pointers: {};
1314
1351
 
@@ -1320,7 +1357,7 @@ declare global {
1320
1357
  * @param {number} [x] x-coordinate of the cursor's point
1321
1358
  * @param {number} [y] y-coordinate of the cursor's point
1322
1359
  * @example
1323
- * createCanvas(200, 100);
1360
+ * await Canvas(200, 100);
1324
1361
  * cursor('pointer');
1325
1362
  */
1326
1363
  function cursor(name: string, x?: number, y?: number): void;
@@ -1328,7 +1365,7 @@ declare global {
1328
1365
  /** 🖲
1329
1366
  * Hides the cursor within the bounds of the canvas.
1330
1367
  * @example
1331
- * createCanvas(200, 100);
1368
+ * await Canvas(200, 100);
1332
1369
  * noCursor();
1333
1370
  */
1334
1371
  function noCursor(): void;
@@ -1341,15 +1378,15 @@ declare global {
1341
1378
  *
1342
1379
  * Return true to allow the default behavior of scrolling the page.
1343
1380
  * @example
1344
- * let x = (y = 100);
1345
- * function draw() {
1381
+ * let x = (y = 0);
1382
+ * q5.draw = function () {
1346
1383
  * circle(x, y, 10);
1347
- * }
1348
- * function mouseWheel(e) {
1384
+ * };
1385
+ * q5.mouseWheel = function (e) {
1349
1386
  * x += e.deltaX;
1350
1387
  * y += e.deltaY;
1351
1388
  * return false;
1352
- * }
1389
+ * };
1353
1390
  */
1354
1391
  function mouseWheel(event: any): void;
1355
1392
 
@@ -1362,17 +1399,17 @@ declare global {
1362
1399
  * To exit pointer lock mode, call `document.exitPointerLock()`.
1363
1400
  * @param {boolean} unadjustedMovement set to true to disable OS-level mouse acceleration and access raw mouse input
1364
1401
  * @example
1365
- * function draw() {
1366
- * circle(mouseX / 10 + 100, mouseY / 10 + 100, 10);
1367
- * }
1402
+ * q5.draw = function () {
1403
+ * circle(mouseX / 10, mouseY / 10, 10);
1404
+ * };
1368
1405
  *
1369
- * function doubleClicked() {
1406
+ * q5.doubleClicked = function () {
1370
1407
  * if (!document.pointerLockElement) {
1371
1408
  * pointerLock();
1372
1409
  * } else {
1373
1410
  * document.exitPointerLock();
1374
1411
  * }
1375
- * }
1412
+ * };
1376
1413
  */
1377
1414
  function pointerLock(unadjustedMovement: boolean): void;
1378
1415
 
@@ -1388,53 +1425,53 @@ declare global {
1388
1425
  * The [`fill`](https://q5js.org/learn/#fill), [`stroke`](https://q5js.org/learn/#stroke), and [`background`](https://q5js.org/learn/#background)
1389
1426
  * functions accept the same wide range of color representations as this function.
1390
1427
  *
1391
- * The default color format is "integer",
1392
- * 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.
1393
1430
  *
1394
1431
  * Here are some examples of valid use:
1395
1432
  *
1396
- * - `color(255)` (grayscale)
1397
- * - `color(255, 200)` (grayscale, alpha)
1398
- * - `color(255, 0, 0)` (r, g, b)
1399
- * - `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)
1400
1437
  * - `color('red')` (colorName)
1401
1438
  * - `color('#ff0000')` (hexColor)
1402
- * - `color([255, 0, 0])` (colorComponents)
1439
+ * - `color([1, 0, 0])` (colorComponents)
1403
1440
  * @param {string | number | Color | number[]} c0 color or first color component
1404
1441
  * @param {number} [c1] second color component
1405
1442
  * @param {number} [c2] third color component
1406
1443
  * @param {number} [c3] fourth color component (alpha)
1407
1444
  * @returns {Color} a new `Color` object
1408
1445
  * @example
1409
- * createCanvas(200);
1410
- * rect(0, 0, 100, 200);
1446
+ * await Canvas(200);
1447
+ * rect(-100, -100, 100, 200);
1411
1448
  *
1412
1449
  * // ( r, g, b, a)
1413
- * let bottle = color(90, 100, 255, 100);
1450
+ * let bottle = color(0.35, 0.39, 1, 0.4);
1414
1451
  * fill(bottle);
1415
1452
  * stroke(bottle);
1416
1453
  * strokeWeight(30);
1417
- * circle(100, 100, 155);
1454
+ * circle(0, 0, 155);
1418
1455
  * @example
1419
- * createCanvas(200);
1456
+ * await Canvas(200);
1420
1457
  * // (gray, alpha)
1421
- * let c = color(200, 50);
1458
+ * let c = color(0.8, 0.2);
1422
1459
  *
1423
- * function draw() {
1460
+ * q5.draw = function () {
1424
1461
  * background(c);
1425
1462
  * circle(mouseX, mouseY, 50);
1426
- * c.g = (c.g + 1) % 256;
1427
- * }
1463
+ * c.g = (c.g + 0.005) % 1;
1464
+ * };
1428
1465
  * @example
1429
- * createCanvas(200);
1466
+ * await Canvas(200);
1430
1467
  *
1431
- * // (r, g, b, a)
1432
- * let c = color(0, 255, 255, 50);
1468
+ * // (r, g, b, a)
1469
+ * let c = color(0, 1, 1, 0.2);
1433
1470
  *
1434
- * function draw() {
1471
+ * q5.draw = function () {
1435
1472
  * fill(c);
1436
1473
  * circle(mouseX, mouseY, 50);
1437
- * }
1474
+ * };
1438
1475
  */
1439
1476
  function color(c0: string | number | Color | number[], c1?: number, c2?: number, c3?: number): Color;
1440
1477
 
@@ -1444,30 +1481,30 @@ declare global {
1444
1481
  *
1445
1482
  * Color gamut is 'display-p3' by default, if the device supports HDR.
1446
1483
  *
1447
- * The default color mode is RGB in legacy integer format.
1484
+ * The default color mode is RGB in float format.
1448
1485
  * @param {'rgb' | 'oklch' | 'hsl' | 'hsb'} mode color mode
1449
1486
  * @param {1 | 255} format color format (1 for float, 255 for integer)
1450
1487
  * @param {'srgb' | 'display-p3'} [gamut] color gamut
1451
1488
  * @example
1452
- * createCanvas(200);
1489
+ * await Canvas(200);
1453
1490
  *
1454
1491
  * colorMode(RGB, 1);
1455
1492
  * fill(1, 0, 0);
1456
- * rect(0, 0, 66, 200);
1493
+ * rect(-100, -100, 66, 200);
1457
1494
  * fill(0, 1, 0);
1458
- * rect(66, 0, 67, 200);
1495
+ * rect(-34, -100, 67, 200);
1459
1496
  * fill(0, 0, 1);
1460
- * rect(133, 0, 67, 200);
1497
+ * rect(33, -100, 67, 200);
1461
1498
  * @example
1462
- * createCanvas(200);
1499
+ * await Canvas(200);
1463
1500
  *
1464
1501
  * colorMode(OKLCH);
1465
1502
  *
1466
1503
  * fill(0.25, 0.15, 0);
1467
- * rect(0, 0, 100, 200);
1504
+ * rect(-100, -100, 100, 200);
1468
1505
  *
1469
1506
  * fill(0.75, 0.15, 0);
1470
- * rect(100, 0, 100, 200);
1507
+ * rect(0, -100, 100, 200);
1471
1508
  */
1472
1509
  function colorMode(mode: 'rgb' | 'oklch', format: 1 | 255, gamut: 'srgb' | 'display-p3'): void;
1473
1510
 
@@ -1479,11 +1516,11 @@ declare global {
1479
1516
  * rgb colors are mapped to the full P3 gamut, even when they use the
1480
1517
  * legacy integer 0-255 format.
1481
1518
  * @example
1482
- * createCanvas(200, 100);
1519
+ * await Canvas(200, 100);
1483
1520
  *
1484
1521
  * colorMode(RGB);
1485
1522
  *
1486
- * background(255, 0, 0);
1523
+ * background(1, 0, 0);
1487
1524
  */
1488
1525
  const RGB: 'rgb';
1489
1526
 
@@ -1511,18 +1548,18 @@ declare global {
1511
1548
  * - `hue`: 0 to 360
1512
1549
  * - `alpha`: 0 to 1
1513
1550
  * @example
1514
- * createCanvas(200, 100);
1551
+ * await Canvas(200, 100);
1515
1552
  *
1516
1553
  * colorMode(OKLCH);
1517
1554
  *
1518
1555
  * background(0.64, 0.3, 30);
1519
1556
  * @example
1520
- * createCanvas(200);
1557
+ * await Canvas(200);
1521
1558
  * colorMode(OKLCH);
1522
1559
  *
1523
- * function draw() {
1560
+ * q5.draw = function () {
1524
1561
  * background(0.7, 0.16, frameCount % 360);
1525
- * }
1562
+ * };
1526
1563
  */
1527
1564
  const OKLCH: 'oklch';
1528
1565
 
@@ -1546,20 +1583,20 @@ declare global {
1546
1583
  * - `lightness`: 0 to 100
1547
1584
  * - `alpha`: 0 to 1
1548
1585
  * @example
1549
- * createCanvas(200, 100);
1586
+ * await Canvas(200, 100);
1550
1587
  *
1551
1588
  * colorMode(HSL);
1552
1589
  *
1553
1590
  * background(0, 100, 50);
1554
1591
  * @example
1555
- * createCanvas(200, 220);
1592
+ * await Canvas(200, 220);
1556
1593
  * noStroke();
1557
1594
  *
1558
1595
  * colorMode(HSL);
1559
1596
  * for (let h = 0; h < 360; h += 10) {
1560
1597
  * for (let l = 0; l <= 100; l += 10) {
1561
1598
  * fill(h, 100, l);
1562
- * rect(h * (11 / 20), l * 2, 6, 20);
1599
+ * rect(h * (11 / 20) - 100, l * 2 - 110, 6, 20);
1563
1600
  * }
1564
1601
  * }
1565
1602
  */
@@ -1579,20 +1616,20 @@ declare global {
1579
1616
  * - `brightness`: 0 to 100
1580
1617
  * - `alpha`: 0 to 1
1581
1618
  * @example
1582
- * createCanvas(200, 100);
1619
+ * await Canvas(200, 100);
1583
1620
  *
1584
1621
  * colorMode(HSB);
1585
1622
  *
1586
1623
  * background(0, 100, 100);
1587
1624
  * @example
1588
- * createCanvas(200, 220);
1625
+ * await Canvas(200, 220);
1589
1626
  * noStroke();
1590
1627
  *
1591
1628
  * colorMode(HSB);
1592
1629
  * for (let h = 0; h < 360; h += 10) {
1593
1630
  * for (let b = 0; b <= 100; b += 10) {
1594
1631
  * fill(h, 100, b);
1595
- * rect(h * (11 / 20), b * 2, 6, 20);
1632
+ * rect(h * (11 / 20) - 100, b * 2 - 110, 6, 20);
1596
1633
  * }
1597
1634
  * }
1598
1635
  */
@@ -1605,11 +1642,11 @@ declare global {
1605
1642
  * less saturated and darker in this example, as it would on
1606
1643
  * an SDR display.
1607
1644
  * @example
1608
- * createCanvas(200, 100);
1645
+ * await Canvas(200, 100);
1609
1646
  *
1610
- * colorMode(RGB, 255, SRGB);
1647
+ * colorMode(RGB, 1, SRGB);
1611
1648
  *
1612
- * background(255, 0, 0);
1649
+ * background(1, 0, 0);
1613
1650
  */
1614
1651
  const SRGB: 'srgb';
1615
1652
 
@@ -1621,11 +1658,11 @@ declare global {
1621
1658
  * If your display is HDR capable, note that full red appears
1622
1659
  * fully saturated and bright in the following example.
1623
1660
  * @example
1624
- * createCanvas(200, 100);
1661
+ * await Canvas(200, 100);
1625
1662
  *
1626
- * colorMode(RGB, 255, DISPLAY_P3);
1663
+ * colorMode(RGB, 1, DISPLAY_P3);
1627
1664
  *
1628
- * background(255, 0, 0);
1665
+ * background(1, 0, 0);
1629
1666
  */
1630
1667
  const DISPLAY_P3: 'display-p3';
1631
1668
 
@@ -1637,13 +1674,13 @@ declare global {
1637
1674
  * CSS color string, grayscale value, and color component values.
1638
1675
  * @param {Color | Q5.Image} filler a color or image to draw
1639
1676
  * @example
1640
- * createCanvas(200, 100);
1677
+ * await Canvas(200, 100);
1641
1678
  * background('crimson');
1642
1679
  * @example
1643
- * function draw() {
1644
- * background(128, 32);
1680
+ * q5.draw = function () {
1681
+ * background(0.5, 0.2);
1645
1682
  * circle(mouseX, mouseY, 20);
1646
- * }
1683
+ * };
1647
1684
  */
1648
1685
  function background(filler: Color | Q5.Image): void;
1649
1686
 
@@ -1655,9 +1692,6 @@ declare global {
1655
1692
  *
1656
1693
  * Use the `color` function for greater flexibility, it runs
1657
1694
  * this constructor internally.
1658
- *
1659
- * `Color` is not actually a class itself, it's a reference to a
1660
- * Q5 color class based on the color mode, format, and gamut.
1661
1695
  */
1662
1696
  constructor(c0: number, c1: number, c2: number, c3: number);
1663
1697
 
@@ -1693,14 +1727,14 @@ declare global {
1693
1727
  * a `Color` object, grayscale value, or color component values.
1694
1728
  * @param {Color} color fill color
1695
1729
  * @example
1696
- * createCanvas(200);
1697
- * background(200);
1730
+ * await Canvas(200);
1731
+ * background(0.8);
1698
1732
  *
1699
1733
  * fill('red');
1700
- * circle(80, 80, 80);
1734
+ * circle(-20, -20, 80);
1701
1735
  *
1702
1736
  * fill('lime');
1703
- * square(80, 80, 80);
1737
+ * square(-20, -20, 80);
1704
1738
  */
1705
1739
  function fill(color: Color): void;
1706
1740
 
@@ -1712,44 +1746,44 @@ declare global {
1712
1746
  * a `Color` object, grayscale value, or color component values.
1713
1747
  * @param {Color} color stroke color
1714
1748
  * @example
1715
- * createCanvas(200);
1716
- * background(200);
1717
- * fill(36);
1749
+ * await Canvas(200);
1750
+ * background(0.8);
1751
+ * fill(0.14);
1718
1752
  *
1719
1753
  * stroke('red');
1720
- * circle(80, 80, 80);
1754
+ * circle(-20, -20, 80);
1721
1755
  *
1722
1756
  * stroke('lime');
1723
- * square(80, 80, 80);
1757
+ * square(-20, -20, 80);
1724
1758
  */
1725
1759
  function stroke(color: Color): void;
1726
1760
 
1727
1761
  /** 💅
1728
1762
  * After calling this function, drawing will not be filled.
1729
1763
  * @example
1730
- * createCanvas(200);
1731
- * background(200);
1764
+ * await Canvas(200);
1765
+ * background(0.8);
1732
1766
  *
1733
1767
  * noFill();
1734
1768
  *
1735
1769
  * stroke('red');
1736
- * circle(80, 80, 80);
1770
+ * circle(-20, -20, 80);
1737
1771
  * stroke('lime');
1738
- * square(80, 80, 80);
1772
+ * square(-20, -20, 80);
1739
1773
  */
1740
1774
  function noFill(): void;
1741
1775
 
1742
1776
  /** 💅
1743
1777
  * After calling this function, drawing will not have a stroke (outline).
1744
1778
  * @example
1745
- * createCanvas(200);
1746
- * background(200);
1747
- * fill(36);
1779
+ * await Canvas(200);
1780
+ * background(0.8);
1781
+ * fill(0.14);
1748
1782
  * stroke('red');
1749
- * circle(80, 80, 80);
1783
+ * circle(-20, -20, 80);
1750
1784
  *
1751
1785
  * noStroke();
1752
- * square(80, 80, 80);
1786
+ * square(-20, -20, 80);
1753
1787
  */
1754
1788
  function noStroke(): void;
1755
1789
 
@@ -1757,13 +1791,13 @@ declare global {
1757
1791
  * Sets the size of the stroke used for lines and the border around drawings.
1758
1792
  * @param {number} weight size of the stroke in pixels
1759
1793
  * @example
1760
- * createCanvas(200);
1761
- * background(200);
1794
+ * await Canvas(200);
1795
+ * background(0.8);
1762
1796
  * stroke('red');
1763
- * circle(50, 100, 80);
1797
+ * circle(-50, 0, 80);
1764
1798
  *
1765
1799
  * strokeWeight(12);
1766
- * circle(150, 100, 80);
1800
+ * circle(50, 0, 80);
1767
1801
  */
1768
1802
  function strokeWeight(weight: number): void;
1769
1803
 
@@ -1773,14 +1807,14 @@ declare global {
1773
1807
  * In q5 WebGPU this function only affects images.
1774
1808
  * @param {number} alpha opacity level, ranging from 0 to 1
1775
1809
  * @example
1776
- * createCanvas(200);
1777
- * background(200);
1810
+ * await Canvas(200);
1811
+ * background(0.8);
1778
1812
  *
1779
1813
  * opacity(1);
1780
- * circle(80, 80, 80);
1814
+ * circle(-20, -20, 80);
1781
1815
  *
1782
1816
  * opacity(0.2);
1783
- * square(80, 80, 80);
1817
+ * square(-20, -20, 80);
1784
1818
  */
1785
1819
  function opacity(alpha: number): void;
1786
1820
 
@@ -1796,22 +1830,6 @@ declare global {
1796
1830
  *
1797
1831
  * Not available in q5 WebGPU.
1798
1832
  * @param {Color} color shadow color
1799
- * @example
1800
- * createCanvas(200);
1801
- * background(200);
1802
- *
1803
- * noFill();
1804
- * shadow('black');
1805
- * rect(64, 60, 80, 80);
1806
- * @example
1807
- * createCanvas(200);
1808
- * let logo = loadImage('/assets/p5play_logo.webp');
1809
- *
1810
- * function setup() {
1811
- * background(200);
1812
- * shadow(0);
1813
- * image(logo, 36, 36, 128, 128);
1814
- * }
1815
1833
  */
1816
1834
  function shadow(color: string | Color): void;
1817
1835
 
@@ -1819,15 +1837,6 @@ declare global {
1819
1837
  * Disables the shadow effect.
1820
1838
  *
1821
1839
  * Not available in q5 WebGPU.
1822
- * @example
1823
- * createCanvas(200);
1824
- * background(200);
1825
- * noStroke();
1826
- * shadow('black');
1827
- * rect(14, 14, 80, 80);
1828
- *
1829
- * noShadow();
1830
- * rect(104, 104, 80, 80);
1831
1840
  */
1832
1841
  function noShadow(): void;
1833
1842
 
@@ -1840,26 +1849,6 @@ declare global {
1840
1849
  * @param {number} offsetX horizontal offset of the shadow
1841
1850
  * @param {number} offsetY vertical offset of the shadow, defaults to be the same as offsetX
1842
1851
  * @param {number} blur blur radius of the shadow, defaults to 0
1843
- * @example
1844
- * createCanvas(200);
1845
- * noStroke();
1846
- * shadow(50);
1847
- *
1848
- * function draw() {
1849
- * background(200);
1850
- * shadowBox(-20, mouseY, 10);
1851
- * circle(100, 100, 80, 80);
1852
- * }
1853
- * @example
1854
- * createCanvas(200);
1855
- * background(200);
1856
- * noStroke();
1857
- *
1858
- * shadow('aqua');
1859
- * shadowBox(20);
1860
- * rect(50, 50, 100, 100);
1861
- * textSize(64);
1862
- * text('q5', 60, 115);
1863
1852
  */
1864
1853
  function shadowBox(offsetX: number, offsetY: number, blur: number): void;
1865
1854
 
@@ -1876,19 +1865,6 @@ declare global {
1876
1865
  *
1877
1866
  * Not available in q5 WebGPU.
1878
1867
  * @param {CanvasLineCap} val line cap style
1879
- * @example
1880
- * createCanvas(200);
1881
- * background(200);
1882
- * strokeWeight(20);
1883
- *
1884
- * strokeCap(ROUND);
1885
- * line(50, 50, 150, 50);
1886
- *
1887
- * strokeCap(SQUARE);
1888
- * line(50, 100, 150, 100);
1889
- *
1890
- * strokeCap(PROJECT);
1891
- * line(50, 150, 150, 150);
1892
1868
  */
1893
1869
  function strokeCap(val: CanvasLineCap): void;
1894
1870
 
@@ -1897,19 +1873,6 @@ declare global {
1897
1873
  *
1898
1874
  * Not available in q5 WebGPU.
1899
1875
  * @param {CanvasLineJoin} val line join style
1900
- * @example
1901
- * createCanvas(200);
1902
- * background(200);
1903
- * strokeWeight(10);
1904
- *
1905
- * strokeJoin(ROUND);
1906
- * triangle(50, 20, 150, 20, 50, 70);
1907
- *
1908
- * strokeJoin(BEVEL);
1909
- * triangle(150, 50, 50, 100, 150, 150);
1910
- *
1911
- * strokeJoin(MITER);
1912
- * triangle(50, 130, 150, 180, 50, 180);
1913
1876
  */
1914
1877
  function strokeJoin(val: CanvasLineJoin): void;
1915
1878
 
@@ -1937,30 +1900,30 @@ declare global {
1937
1900
  * rect mode, ellipse mode, text size, text align, text baseline, and
1938
1901
  * shadow settings.
1939
1902
  * @example
1940
- * createCanvas(200);
1941
- * background(200);
1903
+ * await Canvas(200);
1904
+ * background(0.8);
1942
1905
  *
1943
1906
  * pushStyles();
1944
1907
  * fill('blue');
1945
- * circle(50, 50, 80);
1908
+ * circle(-50, -50, 80);
1946
1909
  *
1947
1910
  * popStyles();
1948
- * circle(150, 150, 80);
1911
+ * circle(50, 50, 80);
1949
1912
  */
1950
1913
  function pushStyles(): void;
1951
1914
 
1952
1915
  /** 💅
1953
1916
  * Restores the previously saved drawing style settings.
1954
1917
  * @example
1955
- * createCanvas(200);
1956
- * background(200);
1918
+ * await Canvas(200);
1919
+ * background(0.8);
1957
1920
  *
1958
1921
  * pushStyles();
1959
1922
  * fill('blue');
1960
- * circle(50, 50, 80);
1923
+ * circle(-50, -50, 80);
1961
1924
  *
1962
1925
  * popStyles();
1963
- * circle(150, 150, 80);
1926
+ * circle(50, 50, 80);
1964
1927
  */
1965
1928
  function popStyles(): void;
1966
1929
 
@@ -1968,18 +1931,26 @@ declare global {
1968
1931
  * Clears the canvas, making every pixel completely transparent.
1969
1932
  *
1970
1933
  * Note that the canvas can only be seen through if it has an alpha channel.
1971
- *
1972
- * #### webgpu
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
 
@@ -2826,6 +2801,22 @@ declare global {
2826
2801
  */
2827
2802
  const QUARTER_PI: number;
2828
2803
 
2804
+ function sin(angle: number): number;
2805
+
2806
+ function cos(angle: number): number;
2807
+
2808
+ function tan(angle: number): number;
2809
+
2810
+ function mag(val1: number, val2: number): number;
2811
+
2812
+ function asin(n: number): number;
2813
+
2814
+ function acos(n: number): number;
2815
+
2816
+ function atan(n: number): number;
2817
+
2818
+ function atan2(y: number, x: number): number;
2819
+
2829
2820
  // 🔊 sound
2830
2821
 
2831
2822
  /**
@@ -2853,14 +2844,14 @@ declare global {
2853
2844
  * @param {string} url sound file
2854
2845
  * @returns {Sound & PromiseLike<Sound>} sound
2855
2846
  * @example
2856
- * createCanvas(200);
2847
+ * await Canvas(200);
2857
2848
  *
2858
2849
  * let sound = loadSound('/assets/jump.wav');
2859
2850
  * sound.volume = 0.3;
2860
2851
  *
2861
- * function mousePressed() {
2852
+ * q5.mousePressed = function () {
2862
2853
  * sound.play();
2863
- * }
2854
+ * };
2864
2855
  */
2865
2856
  function loadSound(url: string): Sound & PromiseLike<Sound>;
2866
2857
 
@@ -2872,14 +2863,14 @@ declare global {
2872
2863
  * Note that audio can only be played after the first user
2873
2864
  * interaction with the page!
2874
2865
  * @example
2875
- * createCanvas(200);
2866
+ * await Canvas(200);
2876
2867
  *
2877
2868
  * let audio = loadAudio('/assets/retro.flac');
2878
2869
  * audio.volume = 0.4;
2879
2870
  *
2880
- * function mousePressed() {
2871
+ * q5.mousePressed = function () {
2881
2872
  * audio.play();
2882
- * }
2873
+ * };
2883
2874
  */
2884
2875
  function loadAudio(url: string): HTMLAudioElement & PromiseLike<HTMLAudioElement>;
2885
2876
 
@@ -2969,7 +2960,7 @@ declare global {
2969
2960
  */
2970
2961
 
2971
2962
  /** 📑
2972
- * 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
2973
2964
  * an alias.
2974
2965
  *
2975
2966
  * Modify the element's CSS [`style`](https://developer.mozilla.org/docs/Web/API/HTMLElement/style) to change its appearance.
@@ -2991,7 +2982,7 @@ declare global {
2991
2982
  * @param {string} [content] content of the element
2992
2983
  * @returns {HTMLElement} element
2993
2984
  * @example
2994
- * createCanvas(200);
2985
+ * await Canvas(200);
2995
2986
  *
2996
2987
  * let el = createEl('div', '*');
2997
2988
  * el.position(50, 50);
@@ -3001,7 +2992,7 @@ declare global {
3001
2992
  * el.style.backgroundColor = 'blue';
3002
2993
  * el.style.color = 'white';
3003
2994
  */
3004
- function createElement(tag: string, content?: string): HTMLElement;
2995
+ function createEl(tag: string, content?: string): HTMLElement;
3005
2996
 
3006
2997
  /** 📑
3007
2998
  * Creates a link element.
@@ -3009,7 +3000,7 @@ declare global {
3009
3000
  * @param {string} [text] text content
3010
3001
  * @param {boolean} [newTab] whether to open the link in a new tab
3011
3002
  * @example
3012
- * createCanvas(200);
3003
+ * await Canvas(200);
3013
3004
  *
3014
3005
  * let link = createA('https://q5js.org', 'q5.js');
3015
3006
  * link.position(16, 42);
@@ -3025,12 +3016,12 @@ declare global {
3025
3016
  * Creates a button element.
3026
3017
  * @param {string} [content] text content
3027
3018
  * @example
3028
- * createCanvas(200, 100);
3019
+ * await Canvas(200, 100);
3029
3020
  *
3030
3021
  * let btn = createButton('Click me!');
3031
3022
  *
3032
3023
  * btn.addEventListener('click', () => {
3033
- * background(random(100, 255));
3024
+ * background(random(0.4, 1));
3034
3025
  * });
3035
3026
  */
3036
3027
  function createButton(content?: string): HTMLButtonElement;
@@ -3044,7 +3035,7 @@ declare global {
3044
3035
  * @param {string} [label] text label placed next to the checkbox
3045
3036
  * @param {boolean} [checked] initial state
3046
3037
  * @example
3047
- * createCanvas(200, 100);
3038
+ * await Canvas(200, 100);
3048
3039
  *
3049
3040
  * let box = createCheckbox('Check me!');
3050
3041
  * box.label.style.color = 'lime';
@@ -3062,14 +3053,14 @@ declare global {
3062
3053
  * Use the `value` property to get or set the color value.
3063
3054
  * @param {string} [value] initial color value
3064
3055
  * @example
3065
- * createCanvas(200, 100);
3056
+ * await Canvas(200, 100);
3066
3057
  *
3067
3058
  * let picker = createColorPicker();
3068
3059
  * picker.value = '#fd7575';
3069
3060
  *
3070
- * function draw() {
3061
+ * q5.draw = function () {
3071
3062
  * background(picker.value);
3072
- * }
3063
+ * };
3073
3064
  */
3074
3065
  function createColorPicker(value?: string): HTMLInputElement;
3075
3066
 
@@ -3077,7 +3068,7 @@ declare global {
3077
3068
  * Creates an image element.
3078
3069
  * @param {string} src url of the image
3079
3070
  * @example
3080
- * createCanvas(200, 100);
3071
+ * await Canvas(200, 100);
3081
3072
  *
3082
3073
  * let img = createImg('/assets/p5play_logo.webp');
3083
3074
  * img.position(0, 0).size(100, 100);
@@ -3096,7 +3087,7 @@ declare global {
3096
3087
  * @param {string} [value] initial value
3097
3088
  * @param {string} [type] text input type, can be 'text', 'password', 'email', 'number', 'range', 'search', 'tel', 'url'
3098
3089
  * @example
3099
- * createCanvas(200, 100);
3090
+ * await Canvas(200, 100);
3100
3091
  * textSize(64);
3101
3092
  *
3102
3093
  * let input = createInput();
@@ -3105,7 +3096,7 @@ declare global {
3105
3096
  *
3106
3097
  * input.addEventListener('input', () => {
3107
3098
  * background('orange');
3108
- * text(input.value, 10, 70);
3099
+ * text(input.value, -90, 30);
3109
3100
  * });
3110
3101
  */
3111
3102
  function createInput(value?: string, type?: string): HTMLInputElement;
@@ -3114,7 +3105,7 @@ declare global {
3114
3105
  * Creates a paragraph element.
3115
3106
  * @param {string} [content] text content
3116
3107
  * @example
3117
- * createCanvas(200, 50);
3108
+ * await Canvas(200, 50);
3118
3109
  * background('coral');
3119
3110
  *
3120
3111
  * let p = createP('Hello, world!');
@@ -3131,16 +3122,17 @@ declare global {
3131
3122
  * Use the `value` property to get or set the value of the selected radio button.
3132
3123
  * @param {string} [groupName]
3133
3124
  * @example
3134
- * createCanvas(200, 160);
3125
+ * await Canvas(200, 160);
3135
3126
  *
3136
3127
  * let radio = createRadio();
3137
- * radio.option('square', '1').option('circle', '2');
3128
+ * radio.option('square', '1');
3129
+ * radio.option('circle', '2');
3138
3130
  *
3139
- * function draw() {
3140
- * background(200);
3141
- * if (radio.value == '1') square(75, 25, 80);
3142
- * if (radio.value == '2') circle(100, 50, 80);
3143
- * }
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
+ * };
3144
3136
  */
3145
3137
  function createRadio(groupName?: string): HTMLDivElement;
3146
3138
 
@@ -3159,10 +3151,11 @@ declare global {
3159
3151
  * string or an array of strings.
3160
3152
  * @param {string} [placeholder] optional placeholder text that appears before an option is selected
3161
3153
  * @example
3162
- * createCanvas(200, 100);
3154
+ * await Canvas(200, 100);
3163
3155
  *
3164
3156
  * let sel = createSelect('Select an option');
3165
- * sel.option('Red', '#f55').option('Green', '#5f5');
3157
+ * sel.option('Red', '#f55');
3158
+ * sel.option('Green', '#5f5');
3166
3159
  *
3167
3160
  * sel.addEventListener('change', () => {
3168
3161
  * background(sel.value);
@@ -3181,14 +3174,14 @@ declare global {
3181
3174
  * @param {number} [value] initial value
3182
3175
  * @param {number} [step] step size
3183
3176
  * @example
3184
- * createCanvas(200);
3177
+ * await Canvas(200);
3185
3178
  *
3186
- * let slider = createSlider(0, 255);
3179
+ * let slider = createSlider(0, 1, 0.5, 0.1);
3187
3180
  * slider.position(10, 10).size(180);
3188
3181
  *
3189
- * function draw() {
3182
+ * q5.draw = function () {
3190
3183
  * background(slider.val());
3191
- * }
3184
+ * };
3192
3185
  */
3193
3186
  function createSlider(min: number, max: number, value?: number, step?: number): HTMLInputElement;
3194
3187
 
@@ -3203,25 +3196,25 @@ declare global {
3203
3196
  * @param {string} src url of the video
3204
3197
  * @returns {HTMLVideoElement & PromiseLike<HTMLVideoElement>} a new video element
3205
3198
  * @example
3206
- * createCanvas(1);
3199
+ * await Canvas(1);
3207
3200
  *
3208
3201
  * let vid = createVideo('/assets/apollo4.mp4');
3209
3202
  * vid.size(200, 150);
3210
3203
  * vid.autoplay = vid.muted = vid.loop = true;
3211
3204
  * vid.controls = true;
3212
3205
  * @example
3213
- * createCanvas(200, 150);
3206
+ * await Canvas(200, 150);
3214
3207
  * let vid = createVideo('/assets/apollo4.mp4');
3215
3208
  * vid.hide();
3216
3209
  *
3217
- * function mousePressed() {
3210
+ * q5.mousePressed = function () {
3218
3211
  * vid.currentTime = 0;
3219
3212
  * vid.play();
3220
- * }
3221
- * function draw() {
3222
- * image(vid, 0, 0, 200, 150);
3223
- * filter(HUE_ROTATE, 90);
3224
- * }
3213
+ * };
3214
+ * q5.draw = function () {
3215
+ * rotate(mouseX / 55);
3216
+ * image(vid, -100, -75, 200, 150);
3217
+ * };
3225
3218
  */
3226
3219
  function createVideo(src: string): HTMLVideoElement & PromiseLike<HTMLVideoElement>;
3227
3220
 
@@ -3242,46 +3235,50 @@ declare global {
3242
3235
  * @param {boolean} [flipped] whether to mirror the video vertically, true by default
3243
3236
  * @returns {HTMLVideoElement & PromiseLike<HTMLVideoElement>} a new video element
3244
3237
  * @example
3245
- * function mousePressed() {
3238
+ * q5.mousePressed = function () {
3246
3239
  * let cap = createCapture(VIDEO);
3247
3240
  * cap.size(200, 112.5);
3248
3241
  * canvas.remove();
3249
- * }
3242
+ * };
3250
3243
  * @example
3251
3244
  * let cap;
3252
- * function mousePressed() {
3245
+ * q5.mousePressed = function () {
3253
3246
  * cap = createCapture(VIDEO);
3254
3247
  * cap.hide();
3255
- * }
3248
+ * };
3256
3249
  *
3257
- * function draw() {
3258
- * let y = frameCount % height;
3259
- * image(cap, 0, y, 200, 200);
3260
- * }
3250
+ * q5.draw = function () {
3251
+ * let y = (frameCount % 200) - 100;
3252
+ * image(cap, -100, y, 200, 200);
3253
+ * };
3261
3254
  * @example
3262
- * function mousePressed() {
3255
+ * q5.mousePressed = function () {
3263
3256
  * let cap = createCapture({
3264
3257
  * video: { width: 640, height: 480 }
3265
3258
  * });
3266
3259
  * cap.size(200, 150);
3267
3260
  * canvas.remove();
3268
- * }
3261
+ * };
3269
3262
  */
3270
3263
  function createCapture(type?: string, flipped?: boolean): HTMLVideoElement & PromiseLike<HTMLVideoElement>;
3271
3264
 
3272
3265
  /** 📑
3273
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`.
3274
3269
  * @param {string} selector
3275
3270
  * @returns {HTMLElement} element
3276
3271
  */
3277
- function findElement(selector: string): HTMLElement;
3272
+ function findEl(selector: string): HTMLElement;
3278
3273
 
3279
3274
  /** 📑
3280
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`.
3281
3278
  * @param {string} selector
3282
3279
  * @returns {HTMLElement[]} elements
3283
3280
  */
3284
- function findElements(selector: string): HTMLElement[];
3281
+ function findEls(selector: string): HTMLElement[];
3285
3282
 
3286
3283
  // 🎞 record
3287
3284
 
@@ -3305,14 +3302,14 @@ declare global {
3305
3302
  * wiki page.
3306
3303
  * @returns {HTMLElement} a recorder, q5 DOM element
3307
3304
  * @example
3308
- * createCanvas(200);
3305
+ * await Canvas(200);
3309
3306
  *
3310
3307
  * let rec = createRecorder();
3311
3308
  * rec.bitrate = 10;
3312
3309
  *
3313
- * function draw() {
3314
- * circle(mouseX, random(height), 10);
3315
- * }
3310
+ * q5.draw = function () {
3311
+ * circle(mouseX, jit(halfHeight), 10);
3312
+ * };
3316
3313
  */
3317
3314
  function createRecorder(): HTMLElement;
3318
3315
 
@@ -3337,14 +3334,14 @@ declare global {
3337
3334
  * Saves the current recording as a video file.
3338
3335
  * @param {string} fileName
3339
3336
  * @example
3340
- * function draw() {
3341
- * square(mouseX, random(200), 10);
3342
- * }
3337
+ * q5.draw = function () {
3338
+ * square(mouseX, jit(100), 10);
3339
+ * };
3343
3340
  *
3344
- * function mousePressed() {
3341
+ * q5.mousePressed = function () {
3345
3342
  * if (!recording) record();
3346
3343
  * else saveRecording('squares');
3347
- * }
3344
+ * };
3348
3345
  */
3349
3346
  function saveRecording(fileName: string): void;
3350
3347
 
@@ -3365,11 +3362,41 @@ declare global {
3365
3362
  * @param {...string} urls
3366
3363
  * @returns {Promise<any[]>} a promise that resolves with objects
3367
3364
  * @example
3368
- * createCanvas(200);
3365
+ * await Canvas(200);
3366
+ *
3369
3367
  * let logo = load('/q5js_logo.avif');
3370
3368
  *
3371
- * function draw() {
3372
- * 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));
3373
3400
  * }
3374
3401
  */
3375
3402
  function load(...urls: string[]): PromiseLike<any[]>;
@@ -3384,23 +3411,23 @@ declare global {
3384
3411
  * @param {object} [data] canvas, image, or JS object
3385
3412
  * @param {string} [fileName] filename to save as
3386
3413
  * @example
3387
- * createCanvas(200);
3388
- * background(200);
3389
- * circle(100, 100, 50);
3414
+ * await Canvas(200);
3415
+ * background(0.8);
3416
+ * circle(0, 0, 50);
3390
3417
  *
3391
- * function mousePressed() {
3418
+ * q5.mousePressed = function () {
3392
3419
  * save('circle.png');
3393
- * }
3420
+ * };
3394
3421
  * @example
3395
- * createCanvas(200);
3396
- *
3422
+ * await Canvas(200);
3423
+ * background(0.8);
3424
+ * text('save me?', -90, 0);
3397
3425
  * textSize(180);
3398
3426
  * let bolt = createTextImage('⚡️');
3399
- * image(bolt, 16, -56);
3400
3427
  *
3401
- * function mousePressed() {
3428
+ * q5.mousePressed = function () {
3402
3429
  * save(bolt, 'bolt.png');
3403
- * }
3430
+ * };
3404
3431
  */
3405
3432
  function save(data?: object, fileName?: string): void;
3406
3433
 
@@ -3437,6 +3464,17 @@ declare global {
3437
3464
  * Using `await` to get the loaded XML Element is recommended.
3438
3465
  * @param {string} url xml file
3439
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
+ * }
3440
3478
  */
3441
3479
  function loadXML(url: string): object & PromiseLike<Element>;
3442
3480
 
@@ -3457,6 +3495,12 @@ declare global {
3457
3495
  * @param {number} num number to format
3458
3496
  * @param {number} digits number of digits to format to
3459
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);
3460
3504
  */
3461
3505
  function nf(num: number, digits: number): string;
3462
3506
 
@@ -3532,6 +3576,12 @@ declare global {
3532
3576
  * @param {number} x x component of the vector
3533
3577
  * @param {number} y y component of the vector
3534
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);
3535
3585
  */
3536
3586
  constructor(x: number, y: number, z?: number);
3537
3587
 
@@ -3695,18 +3745,20 @@ declare global {
3695
3745
  * @param {number} stop angle to stop the arc
3696
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`
3697
3747
  * @example
3698
- * createCanvas(200);
3699
- * background(200);
3748
+ * await Canvas(200);
3749
+ * background(0.8);
3700
3750
  *
3701
- * arc(40, 40, 40, 40, 0.8, -0.8);
3702
- * arc(80, 80, 40, 40, 0.8, -0.8, PIE);
3703
- * arc(120, 120, 40, 40, 0.8, -0.8, CHORD_OPEN);
3704
- * arc(160, 160, 40, 40, 0.8, -0.8, CHORD);
3751
+ * arc(0, 0, 160, 160, 0.8, -0.8);
3705
3752
  */
3706
3753
  function arc(x: number, y: number, w: number, h: number, start: number, stop: number, mode?: number): void;
3707
3754
 
3708
3755
  /** 🖌
3709
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);
3710
3762
  */
3711
3763
  function curve(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): void;
3712
3764
 
@@ -3715,6 +3767,14 @@ declare global {
3715
3767
  *
3716
3768
  * Only takes effect in q5 WebGPU.
3717
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);
3718
3778
  */
3719
3779
  function curveDetail(val: number): void;
3720
3780
 
@@ -3806,6 +3866,281 @@ declare global {
3806
3866
  */
3807
3867
  function quad(x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x4: number, y4: number): void;
3808
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
+
3809
4144
  // ⚙ advanced
3810
4145
 
3811
4146
  /** ⚙
@@ -3821,16 +4156,18 @@ declare global {
3821
4156
  * Used by the global `Canvas` function.
3822
4157
  * @param {string | Function} [scope]
3823
4158
  * @param {HTMLElement} [parent] element that the canvas will be placed inside
3824
- * @example
3825
- * let q = new Q5('namespace');
3826
- * q.createCanvas(200, 100);
3827
- * q.circle(100, 50, 20);
3828
4159
  */
3829
4160
  constructor(scope?: string | Function, parent?: HTMLElement);
3830
4161
 
3831
4162
  /** ⚙
3832
4163
  * The current minor version of q5.
3833
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);
3834
4171
  */
3835
4172
  static version: string;
3836
4173
 
@@ -3909,6 +4246,14 @@ declare global {
3909
4246
 
3910
4247
  /** ⚙
3911
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
+ * };
3912
4257
  */
3913
4258
  static WebGPU(): Q5;
3914
4259
 
@@ -3919,6 +4264,14 @@ declare global {
3919
4264
  * Inside the function, `this` refers to the Q5 instance.
3920
4265
  * @param {string} lifecycle 'init', 'presetup', 'postsetup', 'predraw', 'postdraw', or 'remove'
3921
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
+ * };
3922
4275
  */
3923
4276
  static addHook(lifecycle: string, fn: Function): void;
3924
4277