q5 2.5.4 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -337
- package/package.json +2 -2
- package/q5.d.ts +81 -20
- package/q5.js +620 -530
- package/q5.min.js +2 -2
- package/src/q5-2d-canvas.js +2 -4
- package/src/q5-core.js +2 -2
- package/src/q5-util.js +1 -1
- package/src/q5-webgpu-canvas.js +195 -55
- package/src/q5-webgpu-drawing.js +298 -291
- package/src/q5-webgpu-image.js +25 -38
- package/src/q5-webgpu-text.js +95 -137
- package/src/readme.md +27 -59
package/README.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# <img src="q5js_logo.webp" height="64"> <img src="q5js_brand.webp" height="64">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[**q5.js**](https://q5js.org) is a spiritual successor to the [p5.js][] and [Processing Java][] graphics libraries.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The q5 team aims to make creative coding even more fun and accessible for a new generation of artists, designers, educators, and beginners!
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
If you're already familiar with p5, you'll find yourself right at home with q5. It's also compatible with popular addons, including [p5.sound][] and [p5play][].
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## No Installation Required
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Try out the [q5.js template sketch](https://aijs.io/editor?user=quinton-ashley&project=logoSpin) for the Aijs online code editor.
|
|
12
12
|
|
|
13
13
|
Use q5.js in your own project by adding this line to your HTML file:
|
|
14
14
|
|
|
@@ -22,17 +22,9 @@ q5 is also available on [npm](https://www.npmjs.com/package/q5)!
|
|
|
22
22
|
npm install q5
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Or try out the [q5.js template sketch](https://editor.p5js.org/quinton-ashley/sketches/8SEtLEDl9) for the online p5.js Web Editor.
|
|
26
|
-
|
|
27
|
-
## Support this project 🤝
|
|
28
|
-
|
|
29
|
-
q5 is open source. Anyone can use q5 for free under the terms of the LGPL, just like p5.js. 🎉
|
|
30
|
-
|
|
31
|
-
If you'd like to support this project, please donate via [GitHub Sponsors](https://github.com/sponsors/quinton-ashley) or [Patreon](https://www.patreon.com/p5play).
|
|
32
|
-
|
|
33
25
|
## Using p5 Addon Libraries
|
|
34
26
|
|
|
35
|
-
q5
|
|
27
|
+
q5 is compatible with popular p5 addons and projects that use p5, such as [p5play][], because it aliases `Q5` to `p5`.
|
|
36
28
|
|
|
37
29
|
To use addons, simply load them after q5.js:
|
|
38
30
|
|
|
@@ -43,295 +35,28 @@ To use addons, simply load them after q5.js:
|
|
|
43
35
|
<script src="https://p5play.org/v3/p5play.js"></script>
|
|
44
36
|
```
|
|
45
37
|
|
|
46
|
-
##
|
|
38
|
+
## Documentation
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
Documentation pages are coming to q5js.org soon! For now check out the [q5.d.ts](q5.d.ts) file.
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
See the [wiki](https://github.com/q5js/q5.js/wiki) for extended documentation of q5's exclusive features.
|
|
51
43
|
|
|
52
|
-
|
|
44
|
+
Use the [q5.d.ts](q5.d.ts) file in Visual Studio Code to get autocompletion and inline hover-over documentation. Simply add this `jsconfig.json` file to your project folder:
|
|
53
45
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Why not ask ChatGPT 4o? It excels at identifying the most common errors that beginners make: typos, missing syntax, incorrect arguments, and more.
|
|
63
|
-
|
|
64
|
-
q5 creates error reports that can be sent to an AI just by clicking a link! Users can also run the `askAI()` function before a line of code that isn't working as expected. 🤖
|
|
65
|
-
|
|
66
|
-
```js
|
|
67
|
-
function draw() {
|
|
68
|
-
askAI();
|
|
69
|
-
text('Hello!');
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"compilerOptions": {
|
|
49
|
+
"target": "ESNext"
|
|
50
|
+
},
|
|
51
|
+
"include": ["*.js", "**/*.js", "node_modules/q5/q5.d.ts"]
|
|
70
52
|
}
|
|
71
53
|
```
|
|
72
54
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
ChatGPT 4o excels at identifying the most common errors that beginners make: typos, missing syntax, incorrect arguments, and more.
|
|
76
|
-
|
|
77
|
-
This feature can be disabled by setting `Q5.disableFriendlyErrors = true;`, though unlike in p5 this doesn't provide a performance boost from disabling argument validation because q5 mostly doesn't have any already.
|
|
78
|
-
|
|
79
|
-
q5 can catch errors in q5 function like `draw` and continue looping if you set `Q5.errorTolerant = true;`.
|
|
80
|
-
|
|
81
|
-
## Top-Level Global Mode
|
|
82
|
-
|
|
83
|
-
In **p5**, functions like `rect` can't be used on the file level. They must be called from within p5 functions like `setup` and `draw`.
|
|
84
|
-
|
|
85
|
-
In **q5**, existing p5 2D sketches don't require any modification. But if you initialize Q5 at the top of your sketch, the `preload` and `setup` functions become optional.
|
|
86
|
-
|
|
87
|
-
```js
|
|
88
|
-
new Q5();
|
|
89
|
-
|
|
90
|
-
noStroke();
|
|
91
|
-
let c = color(0, 126, 255, 102);
|
|
92
|
-
fill(c);
|
|
93
|
-
rect(15, 15, 35, 70);
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
This is great because you don't have to declare variables on the file level and then define them in `preload` or `setup`. You can declare and define them at the same time!
|
|
97
|
-
|
|
98
|
-
```js
|
|
99
|
-
new Q5();
|
|
100
|
-
|
|
101
|
-
let cow = loadImage('cow.png');
|
|
102
|
-
|
|
103
|
-
preload();
|
|
104
|
-
|
|
105
|
-
function setup() {
|
|
106
|
-
image(cow, 0, 0);
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Note that if you use `loadImage` on the file level, q5 will wait to run `setup` and `draw` until the image loads. Optionally if you forgo defining `preload`, you can run it to signify that the sketch can start once loading is complete. Otherwise q5 will auto-start the sketch after 32ms of delay, this ensures code after `new Q5()` is run before the sketch starts.
|
|
111
|
-
|
|
112
|
-
## HDR Color Support
|
|
113
|
-
|
|
114
|
-
Most modern devices support the "display-p3" HDR color space. If a device doesn't support it, q5 will fall back to "srgb".
|
|
115
|
-
|
|
116
|
-
In **q5**, `colorMode` accepts 'rgb', 'srgb', and 'oklch'. The default mode is 'rgb', which upgrades rgb colors to HDR on supported displays. Specifying 'srgb' on an HDR capable device enables sRGB gamut correction for rgb colors.
|
|
117
|
-
|
|
118
|
-
The [oklch](https://oklch.com/#63.65,0.2872,16.57,100) color format is the best way to work with HDR colors!
|
|
119
|
-
|
|
120
|
-
https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl
|
|
121
|
-
|
|
122
|
-
```js
|
|
123
|
-
colorMode('oklch');
|
|
124
|
-
|
|
125
|
-
// (lightness, chroma, hue, alpha)
|
|
126
|
-
let c = color(0.637, 0.287, 16.57, 1);
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
The `color` function doesn't accept percentages so you'll have to convert those to decimal values. Also its string parsing capability is limited to simple named colors and the hex "#RRGGBB" or "#RRGGBBAA" formats.
|
|
130
|
-
|
|
131
|
-
Use `new Color()` to create color objects without any parsing overhead.
|
|
132
|
-
|
|
133
|
-
q5 also exposes color components as single letter properties of `Color` objects. For example, you can easily change the red of rgb colors like this `c.r = 128` or the hue of oklch colors like this `c.h = 180`.
|
|
134
|
-
|
|
135
|
-
Support for the HSV color format was removed in q5 v1.9.3 because color experts thought HSV was flawed, outdated, and ought to be abandoned way back in 1997! oklch is superior in every way.
|
|
136
|
-
|
|
137
|
-
https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages
|
|
138
|
-
|
|
139
|
-
## Customize Canvas Context Attributes
|
|
140
|
-
|
|
141
|
-
In **p5**, you're stuck with the default [canvas context attributes][], which can't be changed. So the canvas must have an alpha layer, even if you don't need one. HDR color space and [desynchronized rendering][] are not supported.
|
|
142
|
-
|
|
143
|
-
But **q5** has its own defaults:
|
|
144
|
-
|
|
145
|
-
```js
|
|
146
|
-
Q5.canvasOptions = {
|
|
147
|
-
alpha: false,
|
|
148
|
-
desynchronized: false,
|
|
149
|
-
colorSpace: 'display-p3'
|
|
150
|
-
};
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
The "display-p3" color space will be used by default on supported devices, falling back to "srgb".
|
|
154
|
-
|
|
155
|
-
The `Q5.canvasOptions` object can be overridden, which will effect all q5 instances. You can also override any of these defaults by passing an options object as the fourth parameter to the `createCanvas()` function:
|
|
156
|
-
|
|
157
|
-
```js
|
|
158
|
-
createCanvas(400, 400, '2d', {
|
|
159
|
-
alpha: true
|
|
160
|
-
});
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Namespace Mode
|
|
164
|
-
|
|
165
|
-
**p5**'s [instance mode][] enables multiple sketches to run on one page. To avoid needing to preface every p5 function with `p.` you can use a JS [with statement][].
|
|
166
|
-
|
|
167
|
-
```js
|
|
168
|
-
let sketch = (p) => {
|
|
169
|
-
with (p) {
|
|
170
|
-
p.setup = () => {
|
|
171
|
-
createCanvas(400, 400);
|
|
172
|
-
};
|
|
173
|
-
p.draw = () => {
|
|
174
|
-
background(100);
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
let myp5 = new p5(sketch);
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**q5** introduces "namespace" mode, in addition to the global and instance modes. You can call the namespace variable whatever you like.
|
|
183
|
-
|
|
184
|
-
```js
|
|
185
|
-
let q = new Q5('namespace');
|
|
186
|
-
|
|
187
|
-
with (q) {
|
|
188
|
-
q.setup = () => {
|
|
189
|
-
createCanvas(400, 400);
|
|
190
|
-
};
|
|
191
|
-
q.draw = () => {
|
|
192
|
-
background(100);
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
## Dimension Agnostic
|
|
198
|
-
|
|
199
|
-
In **p5** the only way to do dimension agnostic sketches is to set variables to percentages of the canvas' width and height but this is cumbersome and makes code look messy.
|
|
200
|
-
|
|
201
|
-
In **q5**, @Tezumie added a new feature called `flexibleCanvas`. It takes a unit as input, then any position coordinates or dimensions you use will be scaled based on that unit.
|
|
202
|
-
|
|
203
|
-
In this example, the rect will appear in the middle of the canvas.
|
|
204
|
-
|
|
205
|
-
```js
|
|
206
|
-
new Q5();
|
|
207
|
-
createCanvas(1000, 1000);
|
|
208
|
-
|
|
209
|
-
flexibleCanvas(400);
|
|
210
|
-
rect(100, 100, 200, 200);
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
## Frame your Art
|
|
214
|
-
|
|
215
|
-
The `displayMode` function lets you customize how your canvas is presented.
|
|
216
|
-
|
|
217
|
-
```js
|
|
218
|
-
displayMode(mode, renderQuality, displayScale);
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Display modes:
|
|
222
|
-
|
|
223
|
-
"normal": no styling to canvas or its parent element
|
|
224
|
-
"centered": canvas will be centered horizontally and vertically within its parent and if it's display size is bigger than its parent it will not clip
|
|
225
|
-
"maxed": canvas will fill the parent element, same as fullscreen for a global mode canvas inside a `main` element
|
|
226
|
-
"fullscreen": canvas will fill the screen with letterboxing to persevere its aspect ratio, like css object-fit contain
|
|
227
|
-
|
|
228
|
-
Render qualities:
|
|
229
|
-
|
|
230
|
-
"default": pixelDensity set to displayDensity
|
|
231
|
-
"pixelated": pixelDensity set to 1 and various css styles are applied to the canvas to make it render without image smoothing
|
|
232
|
-
|
|
233
|
-
displayScale:
|
|
234
|
-
|
|
235
|
-
Can be given as a string "x2" or a number. This can be used to make small canvases appear larger.
|
|
236
|
-
|
|
237
|
-
## Node.js Usage
|
|
238
|
-
|
|
239
|
-
> Node.js support was recently added, please [make an issue report][] if you encounter any problems.
|
|
240
|
-
|
|
241
|
-
If you're not interested in rendering to a canvas, q5.js can be used in node.js without any additional dependencies. Just use `noCanvas()` in your sketch and don't call any drawing functions that require a canvas.
|
|
242
|
-
|
|
243
|
-
If you want to render to a canvas, you'll need to install the `canvas` and `jsdom` packages.
|
|
244
|
-
|
|
245
|
-
```bash
|
|
246
|
-
npm install canvas jsdom
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
q5 will automatically load and configure `canvas` and `jsdom` if they are installed. `Q5`, `cairoCanvas`, and `JSDOM` will be added to the global scope by `require('q5')`.
|
|
250
|
-
|
|
251
|
-
In node.js, q5's automatic global mode is disabled. To use global mode you need to assign q5 user defined functions like `draw` and `setup` to the `global` object then call `new Q5()`. q5 will add q5 variables and functions to the `global` object, just like it adds them to the `window` object in the browser.
|
|
252
|
-
|
|
253
|
-
## Modular Use
|
|
254
|
-
|
|
255
|
-
**p5.js** is nearly 5MB in size. This is mainly [due to the inclusion of the webgl render and the dependencies corejs and opentype](https://github.com/processing/p5.js/issues/6776#issuecomment-1918238317). If 2d rendering is all a sketch needs, p5 wastes user bandwidth and is slower to load, parse, and run.
|
|
256
|
-
|
|
257
|
-
**q5.js** (the default bundle) is 70x smaller than p5, which is already great for typical use. For extremely lightweight use you can load a subset of scripts from the `src` folder, just be sure to load `src/q5-core.js` first.
|
|
258
|
-
|
|
259
|
-
## Motivation: Part 1
|
|
260
|
-
|
|
261
|
-
> This section was written by @LingDong-
|
|
262
|
-
|
|
263
|
-
After having used many graphics libraries across many different languages, I have found that the Processing system has one huge advantage over others:
|
|
264
|
-
|
|
265
|
-
It gets stuff drawn onto the screen quick and easy!
|
|
266
|
-
|
|
267
|
-
This might sound silly, but it actually means a lot for people concerned with creative expression. The easier it is to try things out, before one's time and patience is up, the greater chance that you'll get something nice in the end. Therefore, although you can theoretically achieve the exact same result in any decent graphics system, the tool does matter in practice. Artists want more time to spend actually working on how their piece looks, instead of wondering why the computer doesn't work as intended.
|
|
268
|
-
|
|
269
|
-
At [Carnegie Mellon University](https://www.cmu.edu/cfa/studio/index.html), where I studied computational art, p5.js is taught as _the_ framework for the web, and its been a great introduction. However, due to some of the ways in which p5.js is implemented, I found myself using it less and less as I made more and more projects. Lately, I've found that I'll reach directly for the standard JavaScript/Web APIs instead of p5.js. I sometimes think of this as shedding the training wheels on one's bicycle. But I missed the artist-centered logic of the p5 interface! I started thinking, "Is there a better way?"
|
|
270
|
-
|
|
271
|
-
Just to clarify, I think the official p5.js implementation is perfectly justified for its philosophy and suitability for its intended purpose, but my own needs are different enough that I think they justify another implementation instead of pull requests to the official one.
|
|
272
|
-
|
|
273
|
-
In fact, its not uncommon for successful software systems to have multiple implementations of the same spec (think: compilers of C, implementations of SQL, and engines of JavaScript). This allows the user to choose a backend that best suits their goals or needs. When one is using p5.js (or Processing or OpenFrameworks), what one is really using is the same set of commands, the intuitive way of describing drawings, that empowers creative expression. The actual way these commands are implemented internally is incidental; it should be possible to swap internal implementations as necessary.
|
|
274
|
-
|
|
275
|
-
## Motivation: Part 2
|
|
276
|
-
|
|
277
|
-
> This section was written by @quinton-ashley
|
|
278
|
-
|
|
279
|
-
I thought @LingDong-'s work on q5 and the idea itself had great potential, so I decided to implement more of the p5.js API. My main goal was to make it work with [p5play](https://p5play.org)!
|
|
280
|
-
|
|
281
|
-
An increase in performance of even a few frames per second can make a significant difference in the user experience of a work of interactive art or a game, especially on mobile devices.
|
|
282
|
-
|
|
283
|
-
I was also interested in working on q5 because for a lot of p5.js users, the library itself is a black box. Even as an expert JS programmer and someone who teaches CS for a living, I still find myself scratching my head when I look at the p5.js source code. p5 was initially released 10 years ago and bad design choices were made due to JS limitations at the time. It's also become an absolutely massive library, with literally over 100,000 lines of code and documentation!
|
|
284
|
-
|
|
285
|
-
Thanks in large part to @LingDong-'s design, q5 is well organized, concise, and utilizes many modern JS features! I think even without inline documentation, the source code is easier for experienced JS programmers to comprehend.
|
|
286
|
-
|
|
287
|
-
I also started working on q5 because unfortunately I had a bad experience with The Processing Foundation. Simple bug fixes I contributed to p5.js all took over 5 months to be released. That's unacceptable given how well funded TPF is. I began to see p5play solely relying on p5.js as a liability. So being able to provide q5 as an alternative became a priority for me.
|
|
288
|
-
|
|
289
|
-
I think the problem is that management takes exorbitant salaries, 76% of the [annual budget](https://processingfoundation.report/), yet many of them still work [other full time jobs](https://www.linkedin.com/in/edsaber/). They seem to expect that just because p5.js is open source that volunteers will do most of the dev work. 🕵️
|
|
290
|
-
|
|
291
|
-
When criticized, TPF staff play the victim, silence dissent, and badmouth former contributors, regardless of how much time and effort they've donated to TPF projects. This behavior is inexcusable. Its driving away the people who made Processing and p5 great. 🚪
|
|
292
|
-
|
|
293
|
-
In October 2023, The Processing Foundation's co-founder, Ben Fry, resigned and publicly criticized management for [squandering millions of dollars in donations](https://x.com/ben_fry/status/1709400641456501020). I agree with Ben and I hope that TPF will hire full time developers to work on p5.js in the future. The summer 2024 pro5 grants are a great step in the right direction.
|
|
294
|
-
|
|
295
|
-
## Motivation: Part 3
|
|
296
|
-
|
|
297
|
-
> This section was written by @Tezumie
|
|
298
|
-
|
|
299
|
-
My journey into contributing to q5.js began with a deep passion for creative coding. I initially built my own library, T5.js, from scratch to learn more about the inner workings of a creative coding library. This project was driven by my desire to understand and enhance the process of creating visual art through code.
|
|
300
|
-
|
|
301
|
-
The q5.js team took notice of my work on T5.js and reached out to suggest we combine our efforts to further develop q5. We shared similar goals: minimizing the size of the library, optimizing performance, and adding much-needed functionalities that p5.js had yet to implement.
|
|
302
|
-
|
|
303
|
-
One of the aspects I love most about q5.js is its compatibility with p5.js add-ons, something my custom T5.js project lacked. Working with Quinton and the team has allowed me to get creative with new functionalities in q5 as well. We've collaborated on several features, such as FlexibleCanvas, which enables projects to be dimension-agnostic.
|
|
304
|
-
|
|
305
|
-
I genuinely love creative coding and engage with it every day, giving me a deep insight into the needs and potential improvements for a library like q5. My hope is to bring this knowledge and enthusiasm to our work on q5, continually advancing the library to better serve the creative coding community.
|
|
306
|
-
|
|
307
|
-
## More exclusive features
|
|
308
|
-
|
|
309
|
-
Features added by @quinton-ashley:
|
|
310
|
-
|
|
311
|
-
- `inFill`: Check if a point is inside the fill of a previously drawn shape.
|
|
312
|
-
- `async setup()`: enables users to await loading images and sounds before `draw` is called, though loading in parallel with `preload` is still more efficient.
|
|
313
|
-
- `image.trim()`: removes transparent pixels from the edges of an image.
|
|
314
|
-
- `opacity(globalAlpha)`: set the opacity multiplier for anything subsequently drawn to the canvas in a range between 0 (transparent) and 1 (opaque).
|
|
315
|
-
- `textCache(enabled)`: Text image caching is enabled by default. Rotated text is only rendered once, and then cached as an image. This can result in ridiculously high 90x performance boosts for text-heavy sketches. Users don't need to change their code, the `text` function can be used as normal, q5 takes care of everything behind the scenes.
|
|
316
|
-
- `createImage`, `loadImage`, and `createGraphics`: as a last parameter to these functions, `opt` (options) object, users can specify canvas context attributes for an image or graphic. `opt.alpha` is set to true by default.
|
|
317
|
-
- `loadSound(file)`: Returns a Web Audio object with some basic functions added for changing the volume, setting the panning, and checking if the sound is loaded. Good enough in most cases.
|
|
318
|
-
- `ctx`: an instance level alias for `drawingContext`
|
|
319
|
-
|
|
320
|
-
Features added by @LingDong-:
|
|
321
|
-
|
|
322
|
-
- `randomExponential()` in addition to `randomGaussian()`: a random distribution that resembles exponential decay.
|
|
323
|
-
- `curveAlpha()`: manipulate the `α` parameter of Catmull-Rom curves.
|
|
324
|
-
- `relRotationX`, `relRotationY` and `relRotationZ`: Similar to `rotationX/Y/Z`, but are relative to the orientation of the mobile device.
|
|
55
|
+
## Support this project 🤝
|
|
325
56
|
|
|
326
|
-
|
|
57
|
+
q5 is open source and anyone can use it for free under the terms of the LGPL (just like p5.js). 🎉
|
|
327
58
|
|
|
328
|
-
|
|
329
|
-
- `loadImage` and other loading functions don't support a failure callback. If the image fails to load, q5 will throw an error.
|
|
330
|
-
- `colorMode` supports 'rgb', 'srgb', and 'oklch'. Other color modes, like hsv, are so outdated they're obsolete.
|
|
331
|
-
- `color` function only accepts numeric input, hex, and common named colors. It doesn't parse strings like `color('hsl(160, 100%, 50%)')`.
|
|
332
|
-
- `fill`, `stroke`, and `background` can accept any CSS color string.
|
|
333
|
-
- `noise` function's default noise algorithm is perlin noise. p5's default noise is called "blocky" noise in q5 and using it requires loading the src/q5-noisier.js module.
|
|
334
|
-
- `tint` doesn't change the opacity of an image, instead the tint's alpha value specifies how strong the tint should be. To dynamically change the opacity of anything drawn to the canvas, use `opacity(globalAlpha)`.
|
|
59
|
+
We need your support though! If you enjoy using q5.js, please donate via [GitHub Sponsors](https://github.com/sponsors/quinton-ashley) or [Patreon](https://www.patreon.com/p5play).
|
|
335
60
|
|
|
336
61
|
## Size Comparison
|
|
337
62
|
|
|
@@ -347,52 +72,23 @@ Minified:
|
|
|
347
72
|
- p5.sound.min.js 200kb
|
|
348
73
|
- q5.min.js **70kb** 🎉
|
|
349
74
|
|
|
350
|
-
##
|
|
351
|
-
|
|
352
|
-
q5.js has a significant speed advantage in imaging operations because it uses hardware accelerated Canvas APIs whenever possible, instead of going pixel by pixel. Most other functionalities have very marginal speed improvements (or none at all when parameter validation overhead is negligible). The operations with important performance differences are listed below.
|
|
353
|
-
|
|
354
|
-
The following benchmarks are generated with Google Chrome 120, on a MacBook Air M1 2020. q5.js v1.9.3 vs p5.js v1.9.0.
|
|
355
|
-
|
|
356
|
-
Less time (milliseconds) is better.
|
|
357
|
-
|
|
358
|
-
| Task | p5.js | q5.js |
|
|
359
|
-
| ------------------------------------------------- | ----- | ----- |
|
|
360
|
-
| Generate 10,000 random colors with `color(r,g,b)` | 33ms | 3ms |
|
|
361
|
-
|
|
362
|
-
## Older Benchmarks
|
|
363
|
-
|
|
364
|
-
The following benchmarks are generated with Google Chrome 84, on an old-ish MacBook Pro 2015 (with lots of apps and tabs running); Performance varies depending on software and hardware. p5.js version used is v1.1.9.
|
|
365
|
-
|
|
366
|
-
Higher FPS (frames per second) is better.
|
|
75
|
+
## Modular Use
|
|
367
76
|
|
|
368
|
-
|
|
369
|
-
| ---------------------------- | ----- | -------- |
|
|
370
|
-
| tinting | 20FPS | 35FPS |
|
|
371
|
-
| blurring(11px) | 0FPS | 40FPS \* |
|
|
372
|
-
| thresholding | 10FPS | 40FPS \* |
|
|
373
|
-
| grayscaling | 10FPS | 50FPS \* |
|
|
374
|
-
| inverting | 10FPS | 50FPS \* |
|
|
375
|
-
| opaque | 20FPS | 60FPS |
|
|
376
|
-
| erode/dilate | 5FPS | 9FPS |
|
|
77
|
+
**p5.js** is nearly 5MB in size. This is mainly due to lengthy JSDoc comments, [the WebGL render, and the dependencies corejs and opentype](https://github.com/processing/p5.js/issues/6776#issuecomment-1918238317). If 2d rendering is all a sketch needs, p5 wastes user bandwidth and is slower to load, parse, and run.
|
|
377
78
|
|
|
378
|
-
|
|
379
|
-
| --------------------------------------------------- | ----- | ----- |
|
|
380
|
-
| Generating 10,000 `randomGaussian()` sample | 10FPS | 20FPS |
|
|
381
|
-
| Calling `noiseSeed()` 1,000 times | 10FPS | 60FPS |
|
|
382
|
-
| Generate 10,000 (random) colors with `color(r,g,b)` | 5FPS | 60FPS |
|
|
383
|
-
| Rotate a `Vector` 1,000,000 times | 13FPS | 60FPS |
|
|
79
|
+
**q5.js** (the default bundle) is 98% smaller than p5, which is already great for typical use. For extremely lightweight use you can load a subset of scripts from the `src` folder.
|
|
384
80
|
|
|
385
|
-
|
|
81
|
+
See the [src/readme.md](src/readme.md) for more info on modular use.
|
|
386
82
|
|
|
387
83
|
## Contributing
|
|
388
84
|
|
|
389
|
-
Please comment on issues before
|
|
85
|
+
Please report issues or comment on existing issues before working on a pull request.
|
|
390
86
|
|
|
391
87
|
Check out the [q5 planning board](https://github.com/orgs/q5js/projects/1/views/1).
|
|
392
88
|
|
|
393
89
|
If the q5 project is successful, all contributing developers will be paid for their work. The project will be run as a [worker co-op](https://en.wikipedia.org/wiki/Worker_cooperative).
|
|
394
90
|
|
|
395
|
-
Contributors must agree to the [code of conduct](CODE_OF_CONDUCT.md)
|
|
91
|
+
Contributors must agree to the [code of conduct](CODE_OF_CONDUCT.md).
|
|
396
92
|
|
|
397
93
|
## Licensing
|
|
398
94
|
|
|
@@ -400,14 +96,14 @@ q5.js was created by the q5 team and is licensed under the LGPLv3. q5 is not aff
|
|
|
400
96
|
|
|
401
97
|
@LingDong- created the original q5xjs library which is Unlicense licensed.
|
|
402
98
|
|
|
403
|
-
p5.js is licensed under the LGPLv2,
|
|
99
|
+
p5.js is licensed under the LGPLv2, small sections of p5' code directly copied into q5 are credited below. The rest of q5 is a new implementation of part of the p5 API. APIs are not copyrightable in the United States, as decided by the Supreme Court in the Google v Oracle case.
|
|
404
100
|
|
|
405
101
|
## Credits
|
|
406
102
|
|
|
407
|
-
|
|
103
|
+
webgpu msdf text rendering:
|
|
408
104
|
https://webgpu.github.io/webgpu-samples/?sample=textRenderingMsdf
|
|
409
105
|
|
|
410
|
-
|
|
106
|
+
webgpu blendMode:
|
|
411
107
|
https://webgpufundamentals.org/webgpu/lessons/webgpu-transparency.html
|
|
412
108
|
|
|
413
109
|
catmullRomSpline:
|
|
@@ -426,9 +122,7 @@ Curve query:
|
|
|
426
122
|
https://github.com/processing/p5.js/blob/1.1.9/src/core/shape/curves.js
|
|
427
123
|
|
|
428
124
|
[p5]: https://p5js.org
|
|
125
|
+
[p5.js]: https://p5js.org
|
|
126
|
+
[Processing Java]: https://processing.org
|
|
127
|
+
[p5.sound]: https://archive.p5js.org/reference/#/libraries/p5.sound
|
|
429
128
|
[p5play]: https://p5play.org
|
|
430
|
-
[instance mode]: https://p5js.org/examples/instance-mode-instantiation.html
|
|
431
|
-
[with statement]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
|
|
432
|
-
[make an issue report]: https://github.com/quinton-ashley/q5.js/issues
|
|
433
|
-
[canvas context attributes]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
|
|
434
|
-
[desynchronized rendering]: https://github.com/whatwg/html/issues/5466
|
package/package.json
CHANGED
package/q5.d.ts
CHANGED
|
@@ -127,12 +127,15 @@ declare global {
|
|
|
127
127
|
|
|
128
128
|
/** ⭐️
|
|
129
129
|
* The desired frame rate of the sketch.
|
|
130
|
-
* @returns target frame rate
|
|
130
|
+
* @returns target frame rate
|
|
131
131
|
*/
|
|
132
132
|
function getTargetFrameRate(): number;
|
|
133
133
|
|
|
134
134
|
/** ⭐️
|
|
135
|
-
*
|
|
135
|
+
* Gets the current FPS, in terms of how many frames could be generated
|
|
136
|
+
* in one second, which can be higher than the target frame rate. Useful
|
|
137
|
+
* for analyzing performance.
|
|
138
|
+
* @returns frames per second
|
|
136
139
|
*/
|
|
137
140
|
function getFPS(): number;
|
|
138
141
|
|
|
@@ -144,7 +147,7 @@ declare global {
|
|
|
144
147
|
|
|
145
148
|
/** ⭐️
|
|
146
149
|
* Prints a message to the JavaScript console.
|
|
147
|
-
* @param message The message to print
|
|
150
|
+
* @param message The message to print
|
|
148
151
|
*/
|
|
149
152
|
function print(message: any): void;
|
|
150
153
|
|
|
@@ -184,8 +187,8 @@ declare global {
|
|
|
184
187
|
function createCanvas(w: number, h: number, options?: CanvasRenderingContext2DSettings): HTMLCanvasElement;
|
|
185
188
|
|
|
186
189
|
/** ⬜️
|
|
187
|
-
* Any position coordinates or dimensions you use will be scaled based
|
|
188
|
-
* provided to this function.
|
|
190
|
+
* Any position coordinates or dimensions you use will be scaled based
|
|
191
|
+
* on the unit provided to this function.
|
|
189
192
|
* @param unit
|
|
190
193
|
* @example
|
|
191
194
|
* new Q5();
|
|
@@ -377,6 +380,54 @@ declare global {
|
|
|
377
380
|
|
|
378
381
|
// 🧑🎨 drawing
|
|
379
382
|
|
|
383
|
+
/** 🧑🎨
|
|
384
|
+
* Sets the global composite operation for the canvas context.
|
|
385
|
+
* @param x - The composite operation to set.
|
|
386
|
+
*/
|
|
387
|
+
function blendMode(x: string): void;
|
|
388
|
+
|
|
389
|
+
/** 🧑🎨
|
|
390
|
+
* Ses the line cap style for the canvas context.
|
|
391
|
+
* @param x - The line cap style to set ('butt', 'round', 'square').
|
|
392
|
+
*/
|
|
393
|
+
function strokeCap(x: CanvasLineCap): void;
|
|
394
|
+
|
|
395
|
+
/** 🧑🎨
|
|
396
|
+
* Sets the line join style for the canvas context.
|
|
397
|
+
* @param x - The line join style to set ('round', 'bevel', 'miter').
|
|
398
|
+
*/
|
|
399
|
+
function strokeJoin(x: CanvasLineJoin): void;
|
|
400
|
+
|
|
401
|
+
/** 🧑🎨
|
|
402
|
+
* Sets the ellipse mode.
|
|
403
|
+
* @param x - The ellipse mode to set.
|
|
404
|
+
*/
|
|
405
|
+
function ellipseMode(x: string): void;
|
|
406
|
+
|
|
407
|
+
/** 🧑🎨
|
|
408
|
+
* Sets the rectangle mode.
|
|
409
|
+
* @param x - The rectangle mode to set.
|
|
410
|
+
*/
|
|
411
|
+
function rectMode(x: string): void;
|
|
412
|
+
|
|
413
|
+
/** 🧑🎨
|
|
414
|
+
* Sets the curve detail level.
|
|
415
|
+
* @param x - The curve detail level to set.
|
|
416
|
+
*/
|
|
417
|
+
function curveDetail(x: number): void;
|
|
418
|
+
|
|
419
|
+
/** 🧑🎨
|
|
420
|
+
* Sets the curve alpha value.
|
|
421
|
+
* @param x - The curve alpha value to set.
|
|
422
|
+
*/
|
|
423
|
+
function curveAlpha(x: number): void;
|
|
424
|
+
|
|
425
|
+
/** 🧑🎨
|
|
426
|
+
* Sets the curve tightness value.
|
|
427
|
+
* @param x - The curve tightness value to set.
|
|
428
|
+
*/
|
|
429
|
+
function curveTightness(x: number): void;
|
|
430
|
+
|
|
380
431
|
/** 🧑🎨
|
|
381
432
|
* Draws over the entire canvas with a color or image.
|
|
382
433
|
* @param color
|
|
@@ -605,9 +656,9 @@ declare global {
|
|
|
605
656
|
|
|
606
657
|
/** 🌆
|
|
607
658
|
* Displays a region of the image on another region of the image.
|
|
608
|
-
*
|
|
659
|
+
*
|
|
609
660
|
* Can be used to create a detail inset, aka a magnifying glass effect.
|
|
610
|
-
*
|
|
661
|
+
*
|
|
611
662
|
* @param srcX - x-coordinate of the source region
|
|
612
663
|
* @param srcY - y-coordinate of the source region
|
|
613
664
|
* @param srcW - width of the source region
|
|
@@ -630,8 +681,8 @@ declare global {
|
|
|
630
681
|
*
|
|
631
682
|
* Or if width and height are both 1, returns the color of the pixel at
|
|
632
683
|
* the given coordinates in `[R, G, B, A]` array format.
|
|
633
|
-
*
|
|
634
|
-
* To edit the color value of multiple pixels, it's faster to use
|
|
684
|
+
*
|
|
685
|
+
* To edit the color value of multiple pixels, it's faster to use
|
|
635
686
|
* `loadPixels` and `updatePixels`.
|
|
636
687
|
* @param x
|
|
637
688
|
* @param y
|
|
@@ -643,8 +694,8 @@ declare global {
|
|
|
643
694
|
|
|
644
695
|
/** 🌆
|
|
645
696
|
* Sets a pixel's color in the image or canvas.
|
|
646
|
-
*
|
|
647
|
-
* Or if a canvas or image is provided, it's drawn on top of the
|
|
697
|
+
*
|
|
698
|
+
* Or if a canvas or image is provided, it's drawn on top of the
|
|
648
699
|
* destination image or canvas ignoring its tint setting.
|
|
649
700
|
* @param x
|
|
650
701
|
* @param y
|
|
@@ -939,13 +990,14 @@ declare global {
|
|
|
939
990
|
|
|
940
991
|
/** ✨
|
|
941
992
|
* Run this function before a line of code that isn't working as expected.
|
|
993
|
+
* @param question - optional question to ask the AI
|
|
942
994
|
* @example
|
|
943
995
|
* function draw() {
|
|
944
996
|
* askAI();
|
|
945
997
|
* text('Hello!');
|
|
946
998
|
* }
|
|
947
999
|
*/
|
|
948
|
-
function askAI(): void;
|
|
1000
|
+
function askAI(question?: string): void;
|
|
949
1001
|
|
|
950
1002
|
// 🎨 color
|
|
951
1003
|
|
|
@@ -1259,18 +1311,27 @@ declare global {
|
|
|
1259
1311
|
// 🛠️ utilities
|
|
1260
1312
|
|
|
1261
1313
|
/** 🛠️
|
|
1262
|
-
* Loads a text file from the specified path
|
|
1263
|
-
* @param path -
|
|
1264
|
-
* @param cb -
|
|
1314
|
+
* Loads a text file from the specified path. Result is one string.
|
|
1315
|
+
* @param path - the path to the text file
|
|
1316
|
+
* @param cb - a callback function that is run when the file is loaded
|
|
1317
|
+
*/
|
|
1318
|
+
function loadText(path: string, cb: (result: string) => void): void;
|
|
1319
|
+
|
|
1320
|
+
/** 🛠️
|
|
1321
|
+
* Loads a JSON file from the specified path. Result depends on the
|
|
1322
|
+
* JSON file's contents, but is typically an object or array.
|
|
1323
|
+
* @param path - the path to the JSON file
|
|
1324
|
+
* @param cb - a callback function that is run when the file is loaded
|
|
1265
1325
|
*/
|
|
1266
|
-
function
|
|
1326
|
+
function loadJSON(path: string, cb: (result: any) => void): void;
|
|
1267
1327
|
|
|
1268
1328
|
/** 🛠️
|
|
1269
|
-
* Loads a
|
|
1270
|
-
*
|
|
1271
|
-
* @param
|
|
1329
|
+
* Loads a CSV file from the specified path. Result is an array
|
|
1330
|
+
* of objects.
|
|
1331
|
+
* @param path - the path to the CSV file
|
|
1332
|
+
* @param cb - a callback function that is run when the file is loaded
|
|
1272
1333
|
*/
|
|
1273
|
-
function
|
|
1334
|
+
function loadCSV(path: string, cb: (result: object[]) => void): void;
|
|
1274
1335
|
|
|
1275
1336
|
/** 🛠️
|
|
1276
1337
|
* Stores an item in localStorage.
|