q5 2.4.4 → 2.4.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.
- package/package.json +1 -1
- package/q5.d.ts +1425 -0
- package/q5.js +201 -103
- package/q5.min.js +1 -1
- package/src/q5-2d-canvas.js +20 -11
- package/src/q5-2d-image.js +1 -0
- package/src/q5-2d-text.js +52 -42
- package/src/q5-canvas.js +2 -2
- package/src/q5-vector.js +3 -3
- package/src/q5-webgpu-canvas.js +101 -43
- package/src/q5-webgpu-drawing.js +11 -0
- package/src/q5-webgpu-image.js +9 -0
- package/src/readme.md +5 -5
package/src/q5-webgpu-canvas.js
CHANGED
|
@@ -86,6 +86,37 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
86
86
|
$._setCanvasSize(w, h);
|
|
87
87
|
};
|
|
88
88
|
|
|
89
|
+
// current color index, used to associate a vertex with a color
|
|
90
|
+
let colorIndex = 0;
|
|
91
|
+
const addColor = (r, g, b, a = 1) => {
|
|
92
|
+
if (typeof r == 'string') r = $.color(r);
|
|
93
|
+
else if (b == undefined) {
|
|
94
|
+
// grayscale mode `fill(1, 0.5)`
|
|
95
|
+
a = g ?? 1;
|
|
96
|
+
g = b = r;
|
|
97
|
+
}
|
|
98
|
+
if (r._q5Color) colorsStack.push(r.r, r.g, r.b, r.a);
|
|
99
|
+
else colorsStack.push(r, g, b, a);
|
|
100
|
+
colorIndex++;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
$.fill = (r, g, b, a) => {
|
|
104
|
+
addColor(r, g, b, a);
|
|
105
|
+
$._doFill = true;
|
|
106
|
+
$._fillIndex = colorIndex;
|
|
107
|
+
};
|
|
108
|
+
$.stroke = (r, g, b, a) => {
|
|
109
|
+
addColor(r, g, b, a);
|
|
110
|
+
$._doStroke = true;
|
|
111
|
+
$._strokeIndex = colorIndex;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
$.noFill = () => ($._doFill = false);
|
|
115
|
+
$.noStroke = () => ($._doStroke = false);
|
|
116
|
+
|
|
117
|
+
$._strokeWeight = 1;
|
|
118
|
+
$.strokeWeight = (v) => ($._strokeWeight = Math.abs(v));
|
|
119
|
+
|
|
89
120
|
$.resetMatrix = () => {
|
|
90
121
|
// Initialize the transformation matrix as 4x4 identity matrix
|
|
91
122
|
|
|
@@ -109,24 +140,6 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
109
140
|
// Stack to keep track of transformation matrix indexes
|
|
110
141
|
$._transformIndexStack = [];
|
|
111
142
|
|
|
112
|
-
$.push = $.pushMatrix = () => {
|
|
113
|
-
// Push the current matrix index onto the stack
|
|
114
|
-
$._transformIndexStack.push($._transformIndex);
|
|
115
|
-
$._pushStyles();
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
$.pop = $.popMatrix = () => {
|
|
119
|
-
if (!$._transformIndexStack.length) {
|
|
120
|
-
return console.warn('Matrix index stack is empty!');
|
|
121
|
-
}
|
|
122
|
-
// Pop the last matrix index from the stack and set it as the current matrix index
|
|
123
|
-
let idx = $._transformIndexStack.pop();
|
|
124
|
-
$._matrix = $.transformStates[idx].slice();
|
|
125
|
-
$._transformIndex = idx;
|
|
126
|
-
$._matrixDirty = false;
|
|
127
|
-
$._popStyles();
|
|
128
|
-
};
|
|
129
|
-
|
|
130
143
|
$.translate = (x, y, z) => {
|
|
131
144
|
if (!x && !y && !z) return;
|
|
132
145
|
// Update the translation values
|
|
@@ -172,6 +185,57 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
172
185
|
$._matrixDirty = true;
|
|
173
186
|
};
|
|
174
187
|
|
|
188
|
+
$.shearX = (ang) => {
|
|
189
|
+
if (!ang) return;
|
|
190
|
+
if ($._angleMode) ang *= $._DEGTORAD;
|
|
191
|
+
|
|
192
|
+
let tanAng = Math.tan(ang);
|
|
193
|
+
|
|
194
|
+
let m0 = $._matrix[0],
|
|
195
|
+
m1 = $._matrix[1],
|
|
196
|
+
m4 = $._matrix[4],
|
|
197
|
+
m5 = $._matrix[5];
|
|
198
|
+
|
|
199
|
+
$._matrix[0] = m0 + m4 * tanAng;
|
|
200
|
+
$._matrix[1] = m1 + m5 * tanAng;
|
|
201
|
+
|
|
202
|
+
$._matrixDirty = true;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
$.shearY = (ang) => {
|
|
206
|
+
if (!ang) return;
|
|
207
|
+
if ($._angleMode) ang *= $._DEGTORAD;
|
|
208
|
+
|
|
209
|
+
let tanAng = Math.tan(ang);
|
|
210
|
+
|
|
211
|
+
let m0 = $._matrix[0],
|
|
212
|
+
m1 = $._matrix[1],
|
|
213
|
+
m4 = $._matrix[4],
|
|
214
|
+
m5 = $._matrix[5];
|
|
215
|
+
|
|
216
|
+
$._matrix[4] = m4 + m0 * tanAng;
|
|
217
|
+
$._matrix[5] = m5 + m1 * tanAng;
|
|
218
|
+
|
|
219
|
+
$._matrixDirty = true;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
$.applyMatrix = (...args) => {
|
|
223
|
+
let m;
|
|
224
|
+
if (args.length == 1) m = args[0];
|
|
225
|
+
else m = args;
|
|
226
|
+
|
|
227
|
+
if (m.length == 9) {
|
|
228
|
+
// Convert 3x3 matrix to 4x4 matrix
|
|
229
|
+
m = [m[0], m[1], 0, m[2], m[3], m[4], 0, m[5], 0, 0, 1, 0, m[6], m[7], 0, m[8]];
|
|
230
|
+
} else if (m.length != 16) {
|
|
231
|
+
throw new Error('Matrix must be a 3x3 or 4x4 array.');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Overwrite the current transformation matrix
|
|
235
|
+
$._matrix = m.slice();
|
|
236
|
+
$._matrixDirty = true;
|
|
237
|
+
};
|
|
238
|
+
|
|
175
239
|
// Function to save the current matrix state if dirty
|
|
176
240
|
$._saveMatrix = () => {
|
|
177
241
|
$.transformStates.push($._matrix.slice());
|
|
@@ -179,37 +243,31 @@ Q5.renderers.webgpu.canvas = ($, q) => {
|
|
|
179
243
|
$._matrixDirty = false;
|
|
180
244
|
};
|
|
181
245
|
|
|
182
|
-
// current
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
246
|
+
// Push the current matrix index onto the stack
|
|
247
|
+
$.pushMatrix = () => {
|
|
248
|
+
if ($._matrixDirty) $._saveMatrix();
|
|
249
|
+
$._transformIndexStack.push($._transformIndex);
|
|
250
|
+
};
|
|
251
|
+
$.popMatrix = () => {
|
|
252
|
+
if (!$._transformIndexStack.length) {
|
|
253
|
+
return console.warn('Matrix index stack is empty!');
|
|
190
254
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
255
|
+
// Pop the last matrix index from the stack and set it as the current matrix index
|
|
256
|
+
let idx = $._transformIndexStack.pop();
|
|
257
|
+
$._matrix = $.transformStates[idx].slice();
|
|
258
|
+
$._transformIndex = idx;
|
|
259
|
+
$._matrixDirty = false;
|
|
194
260
|
};
|
|
195
261
|
|
|
196
|
-
$.
|
|
197
|
-
|
|
198
|
-
$.
|
|
199
|
-
$._fillIndex = colorIndex;
|
|
262
|
+
$.push = () => {
|
|
263
|
+
$.pushMatrix();
|
|
264
|
+
$.pushStyles();
|
|
200
265
|
};
|
|
201
|
-
$.
|
|
202
|
-
|
|
203
|
-
$.
|
|
204
|
-
$._strokeIndex = colorIndex;
|
|
266
|
+
$.pop = () => {
|
|
267
|
+
$.popMatrix();
|
|
268
|
+
$.popStyles();
|
|
205
269
|
};
|
|
206
270
|
|
|
207
|
-
$.noFill = () => ($._doFill = false);
|
|
208
|
-
$.noStroke = () => ($._doStroke = false);
|
|
209
|
-
|
|
210
|
-
$._strokeWeight = 1;
|
|
211
|
-
$.strokeWeight = (v) => ($._strokeWeight = Math.abs(v));
|
|
212
|
-
|
|
213
271
|
$._calcBox = (x, y, w, h, mode) => {
|
|
214
272
|
let hw = w / 2;
|
|
215
273
|
let hh = h / 2;
|
package/src/q5-webgpu-drawing.js
CHANGED
|
@@ -224,6 +224,15 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4<f32> {
|
|
|
224
224
|
$.endShape(1);
|
|
225
225
|
};
|
|
226
226
|
|
|
227
|
+
$.quad = (x1, y1, x2, y2, x3, y3, x4, y4) => {
|
|
228
|
+
$.beginShape();
|
|
229
|
+
$.vertex(x1, y1);
|
|
230
|
+
$.vertex(x2, y2);
|
|
231
|
+
$.vertex(x3, y3);
|
|
232
|
+
$.vertex(x4, y4);
|
|
233
|
+
$.endShape(1);
|
|
234
|
+
};
|
|
235
|
+
|
|
227
236
|
$.rectMode = (x) => ($._rectMode = x);
|
|
228
237
|
|
|
229
238
|
$.rect = (x, y, w, h) => {
|
|
@@ -245,6 +254,8 @@ fn fragmentMain(@location(1) colorIndex: f32) -> @location(0) vec4<f32> {
|
|
|
245
254
|
drawStack.push(0, 6);
|
|
246
255
|
};
|
|
247
256
|
|
|
257
|
+
$.square = (x, y, s) => $.rect(x, y, s, s);
|
|
258
|
+
|
|
248
259
|
$.point = (x, y) => {
|
|
249
260
|
colorIndex = $._strokeIndex;
|
|
250
261
|
let sw = $._strokeWeight;
|
package/src/q5-webgpu-image.js
CHANGED
|
@@ -204,3 +204,12 @@ fn fragmentMain(@location(0) texCoord: vec2<f32>) -> @location(0) vec4<f32> {
|
|
|
204
204
|
verticesStack.length = 0;
|
|
205
205
|
});
|
|
206
206
|
};
|
|
207
|
+
|
|
208
|
+
Q5.THRESHOLD = 1;
|
|
209
|
+
Q5.GRAY = 2;
|
|
210
|
+
Q5.OPAQUE = 3;
|
|
211
|
+
Q5.INVERT = 4;
|
|
212
|
+
Q5.POSTERIZE = 5;
|
|
213
|
+
Q5.DILATE = 6;
|
|
214
|
+
Q5.ERODE = 7;
|
|
215
|
+
Q5.BLUR = 8;
|
package/src/readme.md
CHANGED
|
@@ -181,15 +181,15 @@ Implemented functions:
|
|
|
181
181
|
|
|
182
182
|
> Use `textFill` and `textStroke` to set text colors.
|
|
183
183
|
|
|
184
|
-
WebGPU (and WebGL) don't have HTML5 based text rasterization functionality like Canvas2D does.
|
|
184
|
+
WebGPU (and WebGL) don't have fast HTML5 based text rasterization functionality, like Canvas2D does.
|
|
185
185
|
|
|
186
|
-
In p5.js WebGL mode, text is drawn directly to the canvas. This is a complex task, since letters have intricate geometry: thus many triangles must be used to render text at high resolution.
|
|
186
|
+
In p5.js WebGL mode, text is drawn directly to the canvas. This is a complex task, since letters have intricate geometry: thus many triangles must be used to render text at high resolution. Unless a user wants to render a lot of text, the performance cost is actually negligible. Yet since p5.js depends on opentype.js for this, which is 528kb (171kb minified), a different approach was needed to keep q5 lightweight.
|
|
187
187
|
|
|
188
|
-
Internally, q5's WebGPU renderer uses a q5 graphics object to draw text to a Canvas2D canvas via `createTextImage`, then converts that canvas to a WebGPU texture. Each texture is cached so it doesn't have to be recreated every frame that users want to display the same text.
|
|
188
|
+
Internally, q5's WebGPU renderer uses a q5 graphics object to draw text to a Canvas2D canvas via `createTextImage`, then converts that canvas to a WebGPU texture. Each texture is cached, so it doesn't have to be recreated every frame that users want to display the same text.
|
|
189
189
|
|
|
190
|
-
|
|
190
|
+
Creating a text image is slower than rendering text if it's only displayed for one frame, but displaying static text multiple frames from a cached image is way faster than re-rendering the text. So just try not to have long strings of text that change every frame.
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
For typical use cases, this is a great trade-off!
|
|
193
193
|
|
|
194
194
|
Complete implementation of text rendering in WebGPU.
|
|
195
195
|
|