q5 1.9.2 → 1.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +135 -81
- package/package.json +1 -1
- package/q5.js +424 -547
- package/q5.min.js +1 -1
package/README.md
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
# <img src="q5js_logo.png" height="64"> <img src="q5js_brand.png" height="64">
|
|
2
2
|
|
|
3
|
-
q5.js
|
|
3
|
+
**q5.js** implements all of [p5][]'s 2D drawing, math, and user input functionality.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It's a drop-in replacement that's performance optimized and 23x smaller than p5. q5 even has a few exclusive features: top-level global mode, HDR color support, namespace mode, and text image caching.
|
|
6
6
|
|
|
7
|
-
q5 doesn't include any friendly error messages
|
|
7
|
+
But q5 doesn't include any friendly error messages, so its mainly for people who are already familiar with p5.js or JS programming in general. If you're a beginner, stick with p5 while developing a sketch, then use q5 to share your work.
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
11
|
-
q5 should work with your existing p5.js sketches, no modifications required! If you have any problems though, please [make an issue report
|
|
11
|
+
q5 should work with your existing p5.js sketches, no modifications required! If you have any problems though, please [make an issue report][].
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Or you can use q5.js in your own project by adding this line to your HTML file:
|
|
13
|
+
Use q5.js in your own project by adding this line to your HTML file:
|
|
16
14
|
|
|
17
15
|
```html
|
|
18
16
|
<script src="https://quinton-ashley.github.io/q5.js/q5.js"></script>
|
|
@@ -24,6 +22,8 @@ q5 is also available on [npm](https://www.npmjs.com/package/q5)!
|
|
|
24
22
|
npm install q5
|
|
25
23
|
```
|
|
26
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
27
|
## Support this project 🤝
|
|
28
28
|
|
|
29
29
|
q5 is open source and [multi-licensed](https://github.com/quinton-ashley/p5play-web/blob/main/LICENSING.md). Anyone can use q5 for free under the terms of the AGPLv3. 🎉
|
|
@@ -34,7 +34,7 @@ If you can't afford to pay, you can apply for the free [p5play Novice License](h
|
|
|
34
34
|
|
|
35
35
|
## Using p5 Addon Libraries
|
|
36
36
|
|
|
37
|
-
q5.js is compatible with popular p5 addons and projects that use p5, such as p5play, because it aliases `Q5` to `p5`.
|
|
37
|
+
q5.js is compatible with popular p5 addons and projects that use p5, such as [p5play][], because it aliases `Q5` to `p5`.
|
|
38
38
|
|
|
39
39
|
To use addons, simply load them after q5.js:
|
|
40
40
|
|
|
@@ -47,11 +47,11 @@ To use addons, simply load them after q5.js:
|
|
|
47
47
|
|
|
48
48
|
## New Features: Top-Level Global Mode
|
|
49
49
|
|
|
50
|
-
|
|
50
|
+
> q5.js includes some exclusive features that aren't available in p5.js. Using them is optional!
|
|
51
51
|
|
|
52
|
-
**
|
|
52
|
+
In **p5**, p5 functions can't be used on the file level. Also you must declare a `setup` or `draw` function on the file level for p5 to start running in global mode.
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
**q5** can automatically run in global mode as well, so existing sketches don't require any modification. But if you initialize Q5 at the top of your sketch, the `preload` and `setup` functions become optional.
|
|
55
55
|
|
|
56
56
|
```js
|
|
57
57
|
new Q5();
|
|
@@ -62,82 +62,94 @@ fill(c);
|
|
|
62
62
|
rect(15, 15, 35, 70);
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
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!
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
new Q5();
|
|
67
|
+
## New Features: HDR Color Support
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
Most modern devices support the "display-p3" HDR color space. If a device doesn't support it, q5 will fall back to "srgb".
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
requestAnimationFrame(myLoop);
|
|
74
|
-
rect(15, 15, 35, 70);
|
|
75
|
-
}
|
|
76
|
-
myLoop();
|
|
77
|
-
```
|
|
71
|
+
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.
|
|
78
72
|
|
|
79
|
-
|
|
73
|
+
The [oklch](https://oklch.com/#63.65,0.2872,16.57,100) color format is the best way to work with HDR colors!
|
|
80
74
|
|
|
81
|
-
|
|
75
|
+
https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl
|
|
82
76
|
|
|
83
77
|
```js
|
|
84
|
-
|
|
85
|
-
p.setup = function () {
|
|
86
|
-
p.createCanvas(100, 100);
|
|
87
|
-
};
|
|
88
|
-
p.draw = function () {
|
|
89
|
-
p.background(0);
|
|
90
|
-
};
|
|
91
|
-
};
|
|
78
|
+
colorMode('oklch');
|
|
92
79
|
|
|
93
|
-
|
|
80
|
+
// (lightness, chroma, hue, alpha)
|
|
81
|
+
let c = color(0.637, 0.287, 16.57, 1);
|
|
94
82
|
```
|
|
95
83
|
|
|
96
|
-
|
|
84
|
+
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 the "#RRGGBB" or "#RRGGBBAA" formats.
|
|
97
85
|
|
|
98
|
-
|
|
99
|
-
- Variables inside `sketch` can no longer be accessed via browser console, which makes it less convenient for debugging.
|
|
86
|
+
Use `new Color()` to create color objects without any parsing overhead.
|
|
100
87
|
|
|
101
|
-
|
|
88
|
+
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`.
|
|
102
89
|
|
|
103
|
-
|
|
104
|
-
let q5 = new Q5('namespace');
|
|
90
|
+
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.
|
|
105
91
|
|
|
106
|
-
|
|
107
|
-
q5.createCanvas(100, 100);
|
|
108
|
-
};
|
|
92
|
+
https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages
|
|
109
93
|
|
|
110
|
-
|
|
111
|
-
|
|
94
|
+
## New Features: Customize Canvas Context Attributes
|
|
95
|
+
|
|
96
|
+
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. p5 also doesn't support HDR color spaces or desynchronized rendering.
|
|
97
|
+
|
|
98
|
+
But **q5** has its own defaults:
|
|
99
|
+
|
|
100
|
+
```js
|
|
101
|
+
Q5.canvasOptions = {
|
|
102
|
+
alpha: false,
|
|
103
|
+
desynchronized: true,
|
|
104
|
+
colorSpace: 'display-p3'
|
|
112
105
|
};
|
|
113
106
|
```
|
|
114
107
|
|
|
115
|
-
|
|
108
|
+
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:
|
|
116
109
|
|
|
117
110
|
```js
|
|
118
|
-
|
|
119
|
-
|
|
111
|
+
createCanvas(400, 400, '2d', {
|
|
112
|
+
alpha: true
|
|
113
|
+
});
|
|
114
|
+
```
|
|
120
115
|
|
|
121
|
-
|
|
122
|
-
q5.createCanvas(400, 400);
|
|
123
|
-
};
|
|
116
|
+
## New Features: Namespace Mode
|
|
124
117
|
|
|
125
|
-
|
|
126
|
-
q5.background(100);
|
|
127
|
-
};
|
|
118
|
+
**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][].
|
|
128
119
|
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
```js
|
|
121
|
+
let sketch = (p) => {
|
|
122
|
+
with (p) {
|
|
123
|
+
p.setup = () => {
|
|
124
|
+
createCanvas(400, 400);
|
|
125
|
+
};
|
|
126
|
+
p.draw = () => {
|
|
127
|
+
background(100);
|
|
128
|
+
};
|
|
129
|
+
}
|
|
131
130
|
};
|
|
132
131
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
let myp5 = new p5(sketch);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**q5** introduces "namespace" mode, in addition to the global and instance modes. You can call the namespace variable whatever you like.
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
let q = new Q5('namespace');
|
|
139
|
+
|
|
140
|
+
with (q) {
|
|
141
|
+
q.setup = () => {
|
|
142
|
+
createCanvas(400, 400);
|
|
143
|
+
};
|
|
144
|
+
q.draw = () => {
|
|
145
|
+
background(100);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
136
148
|
```
|
|
137
149
|
|
|
138
150
|
## Motivation: Part 1
|
|
139
151
|
|
|
140
|
-
|
|
152
|
+
> This section was written by @LingDong-, co-creator of q5.
|
|
141
153
|
|
|
142
154
|
After having used many graphics libraries across many different languages, I have found that the Processing/p5.js/Openframeworks system has one huge advantage over others:
|
|
143
155
|
|
|
@@ -153,55 +165,69 @@ In fact, its not uncommon for successful software systems to have multiple imple
|
|
|
153
165
|
|
|
154
166
|
## Motivation: Part 2
|
|
155
167
|
|
|
156
|
-
|
|
168
|
+
> This section was written by @quinton-ashley, co-creator of q5.
|
|
157
169
|
|
|
158
|
-
I thought @LingDong-'s work on q5 and the idea itself had great potential
|
|
170
|
+
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)!
|
|
159
171
|
|
|
160
172
|
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.
|
|
161
173
|
|
|
162
|
-
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 I think some 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! p5.js is 4.3 MB un-minified, q5.js is
|
|
174
|
+
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 I think some 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! p5.js is 4.3 MB un-minified, q5.js is under 70kb.
|
|
163
175
|
|
|
164
176
|
I think it'd be better if the canvas mode, webgl mode, Friendly Error System, and accessibility features of p5 were offered in separate files. Yet, the powers that be at the Processing Foundation have made it clear that they don't want to do that. Instead they insist on adding more accessibility features to the base library, which the majority of people just don't need. So q5 is a good alternative that trims out the fat.
|
|
165
177
|
|
|
166
|
-
Thanks in large part to @LingDong-'s design, q5 is well organized, concise, and utilizes many modern JS features! I think even without documentation, the source code is easier for experienced JS programmers to comprehend.
|
|
178
|
+
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.
|
|
167
179
|
|
|
168
|
-
## More
|
|
180
|
+
## More exclusive features
|
|
169
181
|
|
|
170
|
-
|
|
182
|
+
Features added by @quinton-ashley:
|
|
171
183
|
|
|
172
184
|
- `textCache(true)`: 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.
|
|
173
|
-
- `loadSound()`: Basic sound support in q5.js, returns a Web Audio object. Not as powerful as p5.sound, but it's good enough
|
|
185
|
+
- `loadSound()`: Basic sound support in q5.js, returns a Web Audio object with `setVolume()` and `setLoop()` functions added. Not as powerful as p5.sound, but it's good enough in many cases.
|
|
186
|
+
- `ctx`: an alias for `drawingContext`
|
|
187
|
+
|
|
188
|
+
Features added by @LingDong-:
|
|
189
|
+
|
|
174
190
|
- `randomExponential()` in addition to `randomGaussian()`: a random distribution that resembles exponential decay.
|
|
175
191
|
- `curveAlpha()`: manipulate the `α` parameter of Catmull-Rom curves.
|
|
176
192
|
- `relRotationX`, `relRotationY` and `relRotationZ`: Similar to `rotationX/Y/Z`, but are relative to the orientation of the mobile device.
|
|
177
193
|
|
|
178
194
|
## Cutting room floor
|
|
179
195
|
|
|
180
|
-
**p5.js** has some pretty extensive parsing capabilities. For example, it can parse out a color from strings like `color('hsl(160, 100%, 50%)')
|
|
196
|
+
**p5.js** has some pretty extensive parsing capabilities. For example, it can parse out a color from strings like `color('hsl(160, 100%, 50%)')`. Functions behave sightly differently when under different "modes" and some have secret default settings, such as `arc` and `text`.
|
|
181
197
|
|
|
182
|
-
**q5.js** will only do things when you communicate the command in the simplest way. This means that functions mainly just take numeric inputs.
|
|
198
|
+
**q5.js** will only do things when you communicate the command in the simplest way. This means that functions mainly just take numeric inputs. q5 has almost no overhead between digesting your parameters and putting them into use.
|
|
183
199
|
|
|
184
|
-
##
|
|
200
|
+
## Size Comparison
|
|
185
201
|
|
|
186
|
-
|
|
202
|
+
Unminified:
|
|
187
203
|
|
|
188
|
-
|
|
204
|
+
- p5.js **4300kb** ⚠️
|
|
205
|
+
- p5.sound.js 488kb
|
|
206
|
+
- q5.js 66kb
|
|
189
207
|
|
|
190
|
-
|
|
208
|
+
Minified:
|
|
209
|
+
|
|
210
|
+
- p5.min.js 1000kb
|
|
191
211
|
- p5.sound.min.js 200kb
|
|
212
|
+
- q5.min.js **42kb** 🎉
|
|
192
213
|
|
|
193
|
-
|
|
214
|
+
## Benchmarks
|
|
194
215
|
|
|
195
|
-
|
|
196
|
-
- p5play.min.js 93kb
|
|
216
|
+
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.
|
|
197
217
|
|
|
198
|
-
|
|
218
|
+
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.
|
|
199
219
|
|
|
200
|
-
|
|
220
|
+
Less time (milliseconds) is better.
|
|
201
221
|
|
|
202
|
-
|
|
222
|
+
| Task | p5.js | q5.js |
|
|
223
|
+
| -------------------------------------------------- | ----- | ----- |
|
|
224
|
+
| Generate 100,000 random colors with `color(r,g,b)` | 168ms | 12ms |
|
|
203
225
|
|
|
204
|
-
|
|
226
|
+
## Older Benchmarks
|
|
227
|
+
|
|
228
|
+
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.
|
|
229
|
+
|
|
230
|
+
Higher FPS (frames per second) is better.
|
|
205
231
|
|
|
206
232
|
| Operation on 1024x1024 image | p5.js | q5.js |
|
|
207
233
|
| ---------------------------- | ----- | -------- |
|
|
@@ -213,7 +239,7 @@ p5.js version used is **1.1.9**.
|
|
|
213
239
|
| opaque | 20FPS | 60FPS |
|
|
214
240
|
| erode/dilate | 5FPS | 9FPS |
|
|
215
241
|
|
|
216
|
-
|
|
|
242
|
+
| Task | p5.js | q5.js |
|
|
217
243
|
| --------------------------------------------------- | ----- | ----- |
|
|
218
244
|
| Generating 10,000 `randomGaussian()` sample | 10FPS | 20FPS |
|
|
219
245
|
| Calling `noiseSeed()` 1,000 times | 10FPS | 60FPS |
|
|
@@ -222,7 +248,35 @@ p5.js version used is **1.1.9**.
|
|
|
222
248
|
|
|
223
249
|
<sub>\* Only for browsers that support CanvasRenderingContext2D.filter ([75% of all](https://caniuse.com/#feat=mdn-api_canvasrenderingcontext2d_filter) as of Aug 2020, including Chrome, Firefox and Edge). For those that don't, performance is similar to p5.js, as identical implementations are usually used as fallbacks.</sub>
|
|
224
250
|
|
|
251
|
+
## Contributing
|
|
252
|
+
|
|
225
253
|
Speed is a goal for q5.js, and we would very much like to see the above list grow. If you know how to make something faster, advice/pull requests are very welcome!
|
|
226
254
|
|
|
227
|
-
|
|
228
|
-
|
|
255
|
+
## Licensing
|
|
256
|
+
|
|
257
|
+
q5.js is not affiliated with the Processing Foundation. p5.js is licensed under the LGPLv2, the two small sections of p5.js' code were directly copied into q5.js are credited below. The rest of q5 is a partial re-implementation of the p5.js API. APIs are not copyrightable in the United States, as decided by the Supreme Court in the Oracle v Google case.
|
|
258
|
+
|
|
259
|
+
@LingDong- created the original q5xjs library and licensed it under the MIT license.
|
|
260
|
+
|
|
261
|
+
@quinton-ashley created q5.js (this project) and implemented more of the p5.js API and added several exclusive features. q5.js is licensed under the AGPLv3.
|
|
262
|
+
|
|
263
|
+
## Credits
|
|
264
|
+
|
|
265
|
+
catmullRomSpline:
|
|
266
|
+
https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline
|
|
267
|
+
|
|
268
|
+
ziggurat:
|
|
269
|
+
http://ziggurat.glitch.me/
|
|
270
|
+
|
|
271
|
+
random:
|
|
272
|
+
https://github.com/processing/p5.js/blob/1.1.9/src/math/noise.js
|
|
273
|
+
|
|
274
|
+
Curve query:
|
|
275
|
+
https://github.com/processing/p5.js/blob/1.1.9/src/core/shape/curves.js
|
|
276
|
+
|
|
277
|
+
[p5]: https://p5js.org
|
|
278
|
+
[p5play]: https://p5play.org
|
|
279
|
+
[instance mode]: https://p5js.org/examples/instance-mode-instantiation.html
|
|
280
|
+
[with statement]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with
|
|
281
|
+
[make an issue report]: https://github.com/quinton-ashley/q5.js/issues
|
|
282
|
+
[context attributes]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext#contextattributes
|