q5 2.10.2 → 2.10.5

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.
@@ -1,53 +1,52 @@
1
1
  /* software implementation of image filters */
2
2
  Q5.renderers.q2d.soft_filters = ($) => {
3
- let tmpBuf = null;
3
+ let u = null; // uint8 temporary buffer
4
4
 
5
- function ensureTmpBuf() {
5
+ function ensureBuf() {
6
6
  let l = $.canvas.width * $.canvas.height * 4;
7
- if (!tmpBuf || tmpBuf.length != l) {
8
- tmpBuf = new Uint8ClampedArray(l);
9
- }
7
+ if (!u || u.length != l) u = new Uint8ClampedArray(l);
10
8
  }
11
9
 
12
10
  function initSoftFilters() {
13
11
  $._filters = [];
14
- $._filters[Q5.THRESHOLD] = (data, thresh) => {
12
+ $._filters[Q5.THRESHOLD] = (d, thresh) => {
15
13
  if (thresh === undefined) thresh = 127.5;
16
14
  else thresh *= 255;
17
- for (let i = 0; i < data.length; i += 4) {
18
- const gray = 0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2];
19
- data[i] = data[i + 1] = data[i + 2] = gray >= thresh ? 255 : 0;
15
+ for (let i = 0; i < d.length; i += 4) {
16
+ const gray = 0.2126 * d[i] + 0.7152 * d[i + 1] + 0.0722 * d[i + 2];
17
+ d[i] = d[i + 1] = d[i + 2] = gray >= thresh ? 255 : 0;
20
18
  }
21
19
  };
22
- $._filters[Q5.GRAY] = (data) => {
23
- for (let i = 0; i < data.length; i += 4) {
24
- const gray = 0.2126 * data[i] + 0.7152 * data[i + 1] + 0.0722 * data[i + 2];
25
- data[i] = data[i + 1] = data[i + 2] = gray;
20
+ $._filters[Q5.GRAY] = (d) => {
21
+ for (let i = 0; i < d.length; i += 4) {
22
+ const gray = 0.2126 * d[i] + 0.7152 * d[i + 1] + 0.0722 * d[i + 2];
23
+ d[i] = d[i + 1] = d[i + 2] = gray;
26
24
  }
27
25
  };
28
- $._filters[Q5.OPAQUE] = (data) => {
29
- for (let i = 0; i < data.length; i += 4) {
30
- data[i + 3] = 255;
26
+ $._filters[Q5.OPAQUE] = (d) => {
27
+ for (let i = 0; i < d.length; i += 4) {
28
+ d[i + 3] = 255;
31
29
  }
32
30
  };
33
- $._filters[Q5.INVERT] = (data) => {
34
- for (let i = 0; i < data.length; i += 4) {
35
- data[i] = 255 - data[i];
36
- data[i + 1] = 255 - data[i + 1];
37
- data[i + 2] = 255 - data[i + 2];
31
+ $._filters[Q5.INVERT] = (d) => {
32
+ for (let i = 0; i < d.length; i += 4) {
33
+ d[i] = 255 - d[i];
34
+ d[i + 1] = 255 - d[i + 1];
35
+ d[i + 2] = 255 - d[i + 2];
38
36
  }
39
37
  };
40
- $._filters[Q5.POSTERIZE] = (data, lvl = 4) => {
38
+ $._filters[Q5.POSTERIZE] = (d, lvl = 4) => {
41
39
  let lvl1 = lvl - 1;
42
- for (let i = 0; i < data.length; i += 4) {
43
- data[i] = (((data[i] * lvl) >> 8) * 255) / lvl1;
44
- data[i + 1] = (((data[i + 1] * lvl) >> 8) * 255) / lvl1;
45
- data[i + 2] = (((data[i + 2] * lvl) >> 8) * 255) / lvl1;
40
+ for (let i = 0; i < d.length; i += 4) {
41
+ d[i] = (((d[i] * lvl) >> 8) * 255) / lvl1;
42
+ d[i + 1] = (((d[i + 1] * lvl) >> 8) * 255) / lvl1;
43
+ d[i + 2] = (((d[i + 2] * lvl) >> 8) * 255) / lvl1;
46
44
  }
47
45
  };
48
- $._filters[Q5.DILATE] = (data) => {
49
- ensureTmpBuf();
50
- tmpBuf.set(data);
46
+ $._filters[Q5.DILATE] = (d, func) => {
47
+ func ??= Math.max;
48
+ ensureBuf();
49
+ u.set(d);
51
50
  let [w, h] = [$.canvas.width, $.canvas.height];
52
51
  for (let i = 0; i < h; i++) {
53
52
  for (let j = 0; j < w; j++) {
@@ -61,55 +60,25 @@ Q5.renderers.q2d.soft_filters = ($) => {
61
60
  let kt = k + t;
62
61
  let kb = k + b;
63
62
  let ko = k + oi;
64
- data[oi + oj + k] = Math.max(
65
- /*tmpBuf[kt+l],*/ tmpBuf[kt + oj] /*tmpBuf[kt+r],*/,
66
- tmpBuf[ko + l],
67
- tmpBuf[ko + oj],
68
- tmpBuf[ko + r],
69
- /*tmpBuf[kb+l],*/ tmpBuf[kb + oj] /*tmpBuf[kb+r],*/
70
- );
63
+ d[oi + oj + k] = func(u[kt + oj], u[ko + l], u[ko + oj], u[ko + r], u[kb + oj]);
71
64
  }
72
65
  }
73
66
  }
74
67
  };
75
- $._filters[Q5.ERODE] = (data) => {
76
- ensureTmpBuf();
77
- tmpBuf.set(data);
78
- let [w, h] = [$.canvas.width, $.canvas.height];
79
- for (let i = 0; i < h; i++) {
80
- for (let j = 0; j < w; j++) {
81
- let l = 4 * Math.max(j - 1, 0);
82
- let r = 4 * Math.min(j + 1, w - 1);
83
- let t = 4 * Math.max(i - 1, 0) * w;
84
- let b = 4 * Math.min(i + 1, h - 1) * w;
85
- let oi = 4 * i * w;
86
- let oj = 4 * j;
87
- for (let k = 0; k < 4; k++) {
88
- let kt = k + t;
89
- let kb = k + b;
90
- let ko = k + oi;
91
- data[oi + oj + k] = Math.min(
92
- /*tmpBuf[kt+l],*/ tmpBuf[kt + oj] /*tmpBuf[kt+r],*/,
93
- tmpBuf[ko + l],
94
- tmpBuf[ko + oj],
95
- tmpBuf[ko + r],
96
- /*tmpBuf[kb+l],*/ tmpBuf[kb + oj] /*tmpBuf[kb+r],*/
97
- );
98
- }
99
- }
100
- }
68
+ $._filters[Q5.ERODE] = (d) => {
69
+ $._filters[Q5.DILATE](d, Math.min);
101
70
  };
102
- $._filters[Q5.BLUR] = (data, rad) => {
103
- rad = rad || 1;
104
- rad = Math.floor(rad * $._pixelDensity);
105
- ensureTmpBuf();
106
- tmpBuf.set(data);
71
+ $._filters[Q5.BLUR] = (d, r) => {
72
+ r = r || 1;
73
+ r = Math.floor(r * $._pixelDensity);
74
+ ensureBuf();
75
+ u.set(d);
107
76
 
108
- let ksize = rad * 2 + 1;
77
+ let ksize = r * 2 + 1;
109
78
 
110
- function gauss1d(ksize) {
79
+ function gauss(ksize) {
111
80
  let im = new Float32Array(ksize);
112
- let sigma = 0.3 * rad + 0.8;
81
+ let sigma = 0.3 * r + 0.8;
113
82
  let ss2 = sigma * sigma * 2;
114
83
  for (let i = 0; i < ksize; i++) {
115
84
  let x = i - ksize / 2;
@@ -119,7 +88,7 @@ Q5.renderers.q2d.soft_filters = ($) => {
119
88
  return im;
120
89
  }
121
90
 
122
- let kern = gauss1d(ksize);
91
+ let kern = gauss(ksize);
123
92
  let [w, h] = [$.canvas.width, $.canvas.height];
124
93
  for (let i = 0; i < h; i++) {
125
94
  for (let j = 0; j < w; j++) {
@@ -128,21 +97,21 @@ Q5.renderers.q2d.soft_filters = ($) => {
128
97
  s2 = 0,
129
98
  s3 = 0;
130
99
  for (let k = 0; k < ksize; k++) {
131
- let jk = Math.min(Math.max(j - rad + k, 0), w - 1);
100
+ let jk = Math.min(Math.max(j - r + k, 0), w - 1);
132
101
  let idx = 4 * (i * w + jk);
133
- s0 += tmpBuf[idx] * kern[k];
134
- s1 += tmpBuf[idx + 1] * kern[k];
135
- s2 += tmpBuf[idx + 2] * kern[k];
136
- s3 += tmpBuf[idx + 3] * kern[k];
102
+ s0 += u[idx] * kern[k];
103
+ s1 += u[idx + 1] * kern[k];
104
+ s2 += u[idx + 2] * kern[k];
105
+ s3 += u[idx + 3] * kern[k];
137
106
  }
138
107
  let idx = 4 * (i * w + j);
139
- data[idx] = s0;
140
- data[idx + 1] = s1;
141
- data[idx + 2] = s2;
142
- data[idx + 3] = s3;
108
+ d[idx] = s0;
109
+ d[idx + 1] = s1;
110
+ d[idx + 2] = s2;
111
+ d[idx + 3] = s3;
143
112
  }
144
113
  }
145
- tmpBuf.set(data);
114
+ u.set(d);
146
115
  for (let i = 0; i < h; i++) {
147
116
  for (let j = 0; j < w; j++) {
148
117
  let s0 = 0,
@@ -150,18 +119,18 @@ Q5.renderers.q2d.soft_filters = ($) => {
150
119
  s2 = 0,
151
120
  s3 = 0;
152
121
  for (let k = 0; k < ksize; k++) {
153
- let ik = Math.min(Math.max(i - rad + k, 0), h - 1);
122
+ let ik = Math.min(Math.max(i - r + k, 0), h - 1);
154
123
  let idx = 4 * (ik * w + j);
155
- s0 += tmpBuf[idx] * kern[k];
156
- s1 += tmpBuf[idx + 1] * kern[k];
157
- s2 += tmpBuf[idx + 2] * kern[k];
158
- s3 += tmpBuf[idx + 3] * kern[k];
124
+ s0 += u[idx] * kern[k];
125
+ s1 += u[idx + 1] * kern[k];
126
+ s2 += u[idx + 2] * kern[k];
127
+ s3 += u[idx + 3] * kern[k];
159
128
  }
160
129
  let idx = 4 * (i * w + j);
161
- data[idx] = s0;
162
- data[idx + 1] = s1;
163
- data[idx + 2] = s2;
164
- data[idx + 3] = s3;
130
+ d[idx] = s0;
131
+ d[idx + 1] = s1;
132
+ d[idx + 2] = s2;
133
+ d[idx + 3] = s3;
165
134
  }
166
135
  }
167
136
  };
package/src/q5-canvas.js CHANGED
@@ -292,6 +292,7 @@ Q5.modules.canvas = ($, q) => {
292
292
  $._styleNames = [
293
293
  '_fill',
294
294
  '_stroke',
295
+ '_strokeWeight',
295
296
  '_doStroke',
296
297
  '_doFill',
297
298
  '_strokeSet',
package/src/q5-color.js CHANGED
@@ -1,5 +1,6 @@
1
1
  Q5.modules.color = ($, q) => {
2
2
  $.RGB = $.RGBA = $._colorMode = 'rgb';
3
+ $.SRGB = 'srgb';
3
4
  $.OKLCH = 'oklch';
4
5
 
5
6
  $.colorMode = (mode, format) => {
@@ -10,7 +11,6 @@ Q5.modules.color = ($, q) => {
10
11
  if (mode == 'oklch') {
11
12
  q.Color = Q5.ColorOKLCH;
12
13
  } else {
13
- let srgb = $.canvas.colorSpace == 'srgb';
14
14
  if ($._colorFormat == 255) {
15
15
  q.Color = srgb ? Q5.ColorRGBA_8 : Q5.ColorRGBA_P3_8;
16
16
  } else {
@@ -94,10 +94,12 @@ Q5.modules.color = ($, q) => {
94
94
  return new C(c0, c1, c2, c3);
95
95
  };
96
96
 
97
+ // deprecated
97
98
  $.red = (c) => c.r;
98
99
  $.green = (c) => c.g;
99
100
  $.blue = (c) => c.b;
100
101
  $.alpha = (c) => c.a;
102
+
101
103
  $.lightness = (c) => {
102
104
  if (c.l) return c.l;
103
105
  return ((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * 100) / 255;
@@ -155,9 +157,43 @@ Q5.ColorOKLCH = class extends Q5.Color {
155
157
  this.h = h;
156
158
  this.a = a ?? 1;
157
159
  }
160
+ get levels() {
161
+ return [this.l, this.c, this.h, this.a];
162
+ }
163
+ equals(c) {
164
+ return c && this.l == c.l && this.c == c.c && this.h == c.h && this.a == c.a;
165
+ }
166
+ isSameColor(c) {
167
+ return c && this.l == c.l && this.c == c.c && this.h == c.h;
168
+ }
158
169
  toString() {
159
170
  return `oklch(${this.l} ${this.c} ${this.h} / ${this.a})`;
160
171
  }
172
+
173
+ get lightness() {
174
+ return this.l;
175
+ }
176
+ set lightness(v) {
177
+ this.l = v;
178
+ }
179
+ get chroma() {
180
+ return this.c;
181
+ }
182
+ set chroma(v) {
183
+ this.c = v;
184
+ }
185
+ get hue() {
186
+ return this.h;
187
+ }
188
+ set hue(v) {
189
+ this.h = v;
190
+ }
191
+ get alpha() {
192
+ return this.a;
193
+ }
194
+ set alpha(v) {
195
+ this.a = v;
196
+ }
161
197
  };
162
198
 
163
199
  Q5.ColorRGBA = class extends Q5.Color {
@@ -171,9 +207,39 @@ Q5.ColorRGBA = class extends Q5.Color {
171
207
  get levels() {
172
208
  return [this.r, this.g, this.b, this.a];
173
209
  }
210
+ equals(c) {
211
+ return c && this.r == c.r && this.g == c.g && this.b == c.b && this.a == c.a;
212
+ }
213
+ isSameColor(c) {
214
+ return c && this.r == c.r && this.g == c.g && this.b == c.b;
215
+ }
174
216
  toString() {
175
217
  return `color(srgb ${this.r} ${this.g} ${this.b} / ${this.a})`;
176
218
  }
219
+ get red() {
220
+ return this.r;
221
+ }
222
+ set red(v) {
223
+ this.r = v;
224
+ }
225
+ get green() {
226
+ return this.g;
227
+ }
228
+ set green(v) {
229
+ this.g = v;
230
+ }
231
+ get blue() {
232
+ return this.b;
233
+ }
234
+ set blue(v) {
235
+ this.b = v;
236
+ }
237
+ get alpha() {
238
+ return this.a;
239
+ }
240
+ set alpha(v) {
241
+ this.a = v;
242
+ }
177
243
  };
178
244
 
179
245
  Q5.ColorRGBA_P3 = class extends Q5.ColorRGBA {
@@ -187,6 +253,7 @@ Q5.ColorRGBA_8 = class extends Q5.ColorRGBA {
187
253
  constructor(r, g, b, a) {
188
254
  super(r, g, b, a ?? 255);
189
255
  }
256
+ // deprecated set functions for backwards compatibility
190
257
  setRed(v) {
191
258
  this.r = v;
192
259
  }
@@ -199,9 +266,6 @@ Q5.ColorRGBA_8 = class extends Q5.ColorRGBA {
199
266
  setAlpha(v) {
200
267
  this.a = v;
201
268
  }
202
- get levels() {
203
- return [this.r, this.g, this.b, this.a];
204
- }
205
269
  toString() {
206
270
  return `rgb(${this.r} ${this.g} ${this.b} / ${this.a / 255})`;
207
271
  }
package/src/q5-core.js CHANGED
@@ -143,15 +143,16 @@ function Q5(scope, parent, renderer) {
143
143
  $.getTargetFrameRate = () => $._targetFrameRate || 60;
144
144
  $.getFPS = () => $._fps;
145
145
 
146
+ // shims for compatibility with p5.js libraries
146
147
  $.Element = function (a) {
147
148
  this.elt = a;
148
149
  };
149
150
  $._elements = [];
151
+ $.describe = () => {};
150
152
 
151
153
  $.TWO_PI = $.TAU = Math.PI * 2;
152
154
 
153
155
  $.log = $.print = console.log;
154
- $.describe = () => {};
155
156
 
156
157
  for (let m in Q5.modules) {
157
158
  Q5.modules[m]($, q);