Skip to content

Commit 8c0252a

Browse files
2.20.7
1 parent eebfb59 commit 8c0252a

9 files changed

+201
-123
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "q5",
3-
"version": "2.20.6",
3+
"version": "2.20.7",
44
"description": "A sequel to p5.js that's optimized for interactive art",
55
"author": "quinton-ashley",
66
"contributors": [

q5.d.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -2726,14 +2726,14 @@ function draw() {
27262726
/** 🎞️
27272727
* Creates a recorder. Simply hit record to start recording!
27282728
*
2729-
* `format` is set to "H.264" by default. Encoding in "VP9" may not
2730-
* be possible on some devices.
2729+
* The following properties can be set via the recorder UI or
2730+
* programmatically.
27312731
*
2732-
* `bitrate` is a number in megabits per second (mbps). Its default
2732+
* - `format` is set to "H.264" by default. Encoding in "VP9" may not
2733+
* be possible on some devices.
2734+
* - `bitrate` is a number in megabits per second (mbps). Its default
27332735
* value is determined by the height of the canvas. Increasing the
27342736
* bitrate will increase the quality and file size of the recording.
2735-
*
2736-
* These properties can be set via the recorder UI or programmatically.
27372737
* @returns {HTMLElement} a recorder, q5 DOM element
27382738
* @example
27392739
createCanvas(200);

q5.js

+97-58
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,8 @@ Q5.modules.canvas = ($, q) => {
409409
}
410410
if ($._beginRender) $._beginRender();
411411

412+
c.mousePressed = (cb) => c.addEventListener('mousedown', cb);
413+
412414
return rend;
413415
};
414416

@@ -2607,6 +2609,8 @@ Q5.modules.dom = ($, q) => {
26072609
return el;
26082610
};
26092611

2612+
el.mousePressed = (cb) => el.addEventListener('mousedown', cb);
2613+
26102614
$._elements.push(el);
26112615
if ($.canvas) $.canvas.parentElement.append(el);
26122616
else document.body.append(el);
@@ -5147,9 +5151,7 @@ Q5.renderers.webgpu.drawing = ($, q) => {
51475151
const TAU = Math.PI * 2;
51485152
const HALF_PI = Math.PI / 2;
51495153

5150-
let drawingShader = Q5.device.createShaderModule({
5151-
label: 'drawingShader',
5152-
code: `
5154+
let drawingShaderCode = `
51535155
struct Uniforms {
51545156
halfWidth: f32,
51555157
halfHeight: f32
@@ -5168,12 +5170,17 @@ struct FragmentParams {
51685170
@group(0) @binding(1) var<storage> transforms: array<mat4x4<f32>>;
51695171
@group(0) @binding(2) var<storage> colors : array<vec4f>;
51705172
5171-
@vertex
5172-
fn vertexMain(v: VertexParams) -> FragmentParams {
5173-
var vert = vec4f(v.pos, 0.0, 1.0);
5174-
vert = transforms[i32(v.matrixIndex)] * vert;
5173+
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
5174+
var vert = vec4f(pos, 0.0, 1.0);
5175+
vert = transforms[i32(matrixIndex)] * vert;
51755176
vert.x /= uniforms.halfWidth;
51765177
vert.y /= uniforms.halfHeight;
5178+
return vert;
5179+
}
5180+
5181+
@vertex
5182+
fn vertexMain(v: VertexParams) -> FragmentParams {
5183+
var vert = transformVertex(v.pos, v.matrixIndex);
51775184
51785185
var f: FragmentParams;
51795186
f.position = vert;
@@ -5182,10 +5189,14 @@ fn vertexMain(v: VertexParams) -> FragmentParams {
51825189
}
51835190
51845191
@fragment
5185-
fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
5186-
return color;
5192+
fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
5193+
return f.color;
51875194
}
5188-
`
5195+
`;
5196+
5197+
let drawingShader = Q5.device.createShaderModule({
5198+
label: 'drawingShader',
5199+
code: drawingShaderCode
51895200
});
51905201

51915202
let vertexBufferLayout = {
@@ -5786,13 +5797,13 @@ struct VertexParams {
57865797
@location(1) texCoord: vec2f,
57875798
@location(2) tintIndex: f32,
57885799
@location(3) matrixIndex: f32,
5789-
@location(4) globalAlpha: f32
5800+
@location(4) imageAlpha: f32
57905801
}
57915802
struct FragmentParams {
57925803
@builtin(position) position: vec4f,
57935804
@location(0) texCoord: vec2f,
5794-
@location(1) tintIndex: f32,
5795-
@location(2) globalAlpha: f32
5805+
@location(1) tintColor: vec4f,
5806+
@location(2) imageAlpha: f32
57965807
}
57975808
57985809
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@@ -5802,29 +5813,33 @@ struct FragmentParams {
58025813
@group(1) @binding(0) var samp: sampler;
58035814
@group(1) @binding(1) var texture: texture_2d<f32>;
58045815
5805-
@vertex
5806-
fn vertexMain(v: VertexParams) -> FragmentParams {
5807-
var vert = vec4f(v.pos, 0.0, 1.0);
5808-
vert = transforms[i32(v.matrixIndex)] * vert;
5816+
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
5817+
var vert = vec4f(pos, 0.0, 1.0);
5818+
vert = transforms[i32(matrixIndex)] * vert;
58095819
vert.x /= uniforms.halfWidth;
58105820
vert.y /= uniforms.halfHeight;
5821+
return vert;
5822+
}
5823+
5824+
@vertex
5825+
fn vertexMain(v: VertexParams) -> FragmentParams {
5826+
var vert = transformVertex(v.pos, v.matrixIndex);
58115827
58125828
var f: FragmentParams;
58135829
f.position = vert;
58145830
f.texCoord = v.texCoord;
5815-
f.tintIndex = v.tintIndex;
5816-
f.globalAlpha = v.globalAlpha;
5831+
f.tintColor = colors[i32(v.tintIndex)];
5832+
f.imageAlpha = v.imageAlpha;
58175833
return f;
58185834
}
58195835
58205836
@fragment
58215837
fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
5822-
let texColor = textureSample(texture, samp, f.texCoord);
5823-
let tintColor = colors[i32(f.tintIndex)];
5824-
5825-
// Mix original and tinted colors using tint alpha as blend factor
5826-
let tinted = vec4f(texColor.rgb * tintColor.rgb, texColor.a * f.globalAlpha);
5827-
return mix(texColor, tinted, tintColor.a);
5838+
let texColor = textureSample(texture, samp, f.texCoord);
5839+
5840+
// Mix original and tinted colors using tint alpha as blend factor
5841+
let tinted = vec4f(texColor.rgb * f.tintColor.rgb, texColor.a * f.imageAlpha);
5842+
return mix(texColor, tinted, f.tintColor.a);
58285843
}
58295844
`;
58305845

@@ -5849,7 +5864,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
58495864
{ shaderLocation: 1, offset: 8, format: 'float32x2' },
58505865
{ shaderLocation: 2, offset: 16, format: 'float32' }, // tintIndex
58515866
{ shaderLocation: 3, offset: 20, format: 'float32' }, // matrixIndex
5852-
{ shaderLocation: 4, offset: 24, format: 'float32' } // globalAlpha
5867+
{ shaderLocation: 4, offset: 24, format: 'float32' } // imageAlpha
58535868
]
58545869
};
58555870

@@ -6020,7 +6035,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
60206035

60216036
$.imageMode = (x) => ($._imageMode = x);
60226037

6023-
const addVert = (x, y, u, v, ci, ti, ga) => {
6038+
const addVert = (x, y, u, v, ci, ti, ia) => {
60246039
let s = vertexStack,
60256040
i = vertIndex;
60266041
s[i++] = x;
@@ -6029,7 +6044,7 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
60296044
s[i++] = v;
60306045
s[i++] = ci;
60316046
s[i++] = ti;
6032-
s[i++] = ga;
6047+
s[i++] = ia;
60336048
vertIndex = i;
60346049
};
60356050

@@ -6085,12 +6100,12 @@ fn fragmentMain(f: FragmentParams) -> @location(0) vec4f {
60856100
v1 = (sy + sh) / h,
60866101
ti = $._matrixIndex,
60876102
ci = $._tint,
6088-
ga = $._globalAlpha;
6103+
ia = $._imageAlpha;
60896104

6090-
addVert(l, t, u0, v0, ci, ti, ga);
6091-
addVert(r, t, u1, v0, ci, ti, ga);
6092-
addVert(l, b, u0, v1, ci, ti, ga);
6093-
addVert(r, b, u1, v1, ci, ti, ga);
6105+
addVert(l, t, u0, v0, ci, ti, ia);
6106+
addVert(r, t, u1, v0, ci, ti, ia);
6107+
addVert(l, b, u0, v1, ci, ti, ia);
6108+
addVert(r, b, u1, v1, ci, ti, ia);
60946109

60956110
if (!isVideo) {
60966111
$.drawStack.push(1, img.textureIndex);
@@ -6214,9 +6229,7 @@ Q5.DILATE = 6;
62146229
Q5.ERODE = 7;
62156230
Q5.BLUR = 8;
62166231
Q5.renderers.webgpu.text = ($, q) => {
6217-
let textShader = Q5.device.createShaderModule({
6218-
label: 'MSDF text shader',
6219-
code: `
6232+
let textShaderCode = `
62206233
struct Uniforms {
62216234
halfWidth: f32,
62226235
halfHeight: f32
@@ -6228,7 +6241,9 @@ struct VertexParams {
62286241
struct FragmentParams {
62296242
@builtin(position) position : vec4f,
62306243
@location(0) texCoord : vec2f,
6231-
@location(1) fillColor : vec4f
6244+
@location(1) fillColor : vec4f,
6245+
@location(2) strokeColor : vec4f,
6246+
@location(3) strokeWeight : f32
62326247
}
62336248
struct Char {
62346249
texOffset: vec2f,
@@ -6241,7 +6256,8 @@ struct Text {
62416256
scale: f32,
62426257
matrixIndex: f32,
62436258
fillIndex: f32,
6244-
strokeIndex: f32
6259+
strokeIndex: f32,
6260+
strokeWeight: f32
62456261
}
62466262
62476263
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@@ -6257,52 +6273,73 @@ struct Text {
62576273
62586274
const quad = array(vec2f(0, -1), vec2f(1, -1), vec2f(0, 0), vec2f(1, 0));
62596275
6276+
fn sampleMsdf(texCoord: vec2f) -> f32 {
6277+
let c = textureSample(fontTexture, fontSampler, texCoord);
6278+
return max(min(c.r, c.g), min(max(c.r, c.g), c.b));
6279+
}
6280+
6281+
fn transformVertex(pos: vec2f, matrixIndex: f32) -> vec4f {
6282+
var vert = vec4f(pos, 0.0, 1.0);
6283+
vert = transforms[i32(matrixIndex)] * vert;
6284+
vert.x /= uniforms.halfWidth;
6285+
vert.y /= uniforms.halfHeight;
6286+
return vert;
6287+
}
6288+
62606289
@vertex
62616290
fn vertexMain(v : VertexParams) -> FragmentParams {
62626291
let char = textChars[v.instance];
6263-
62646292
let text = textMetadata[i32(char.w)];
6265-
62666293
let fontChar = fontChars[i32(char.z)];
62676294
62686295
let charPos = ((quad[v.vertex] * fontChar.size + char.xy + fontChar.offset) * text.scale) + text.pos;
62696296
6270-
var vert = vec4f(charPos, 0.0, 1.0);
6271-
vert = transforms[i32(text.matrixIndex)] * vert;
6272-
vert.x /= uniforms.halfWidth;
6273-
vert.y /= uniforms.halfHeight;
6297+
var vert = transformVertex(charPos, text.matrixIndex);
62746298
62756299
var f : FragmentParams;
62766300
f.position = vert;
62776301
f.texCoord = (quad[v.vertex] * vec2f(1, -1)) * fontChar.texExtent + fontChar.texOffset;
62786302
f.fillColor = colors[i32(text.fillIndex)];
6303+
f.strokeColor = colors[i32(text.strokeIndex)];
6304+
f.strokeWeight = text.strokeWeight;
62796305
return f;
62806306
}
62816307
6282-
fn sampleMsdf(texCoord: vec2f) -> f32 {
6283-
let c = textureSample(fontTexture, fontSampler, texCoord);
6284-
return max(min(c.r, c.g), min(max(c.r, c.g), c.b));
6285-
}
6286-
62876308
@fragment
62886309
fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
6289-
// pxRange (AKA distanceRange) comes from the msdfgen tool,
6290-
// uses the default which is 4.
62916310
let pxRange = 4.0;
62926311
let sz = vec2f(textureDimensions(fontTexture, 0));
6293-
let dx = sz.x*length(vec2f(dpdxFine(f.texCoord.x), dpdyFine(f.texCoord.x)));
6294-
let dy = sz.y*length(vec2f(dpdxFine(f.texCoord.y), dpdyFine(f.texCoord.y)));
6312+
let dx = sz.x * length(vec2f(dpdxFine(f.texCoord.x), dpdyFine(f.texCoord.x)));
6313+
let dy = sz.y * length(vec2f(dpdxFine(f.texCoord.y), dpdyFine(f.texCoord.y)));
62956314
let toPixels = pxRange * inverseSqrt(dx * dx + dy * dy);
62966315
let sigDist = sampleMsdf(f.texCoord) - 0.5;
62976316
let pxDist = sigDist * toPixels;
62986317
let edgeWidth = 0.5;
6299-
let alpha = smoothstep(-edgeWidth, edgeWidth, pxDist);
6300-
if (alpha < 0.001) {
6318+
6319+
if (f.strokeWeight == 0.0) {
6320+
let fillAlpha = smoothstep(-edgeWidth, edgeWidth, pxDist);
6321+
var color = vec4f(f.fillColor.rgb, f.fillColor.a * fillAlpha);
6322+
if (color.a < 0.01) {
6323+
discard;
6324+
}
6325+
return color;
6326+
}
6327+
6328+
let halfStroke = f.strokeWeight / 2.0;
6329+
let fillAlpha = smoothstep(-edgeWidth, edgeWidth, pxDist - halfStroke);
6330+
let strokeAlpha = smoothstep(-edgeWidth, edgeWidth, pxDist + halfStroke);
6331+
var color = mix(f.strokeColor, f.fillColor, fillAlpha);
6332+
color = vec4f(color.rgb, color.a * strokeAlpha);
6333+
if (color.a < 0.01) {
63016334
discard;
63026335
}
6303-
return vec4f(f.fillColor.rgb, f.fillColor.a * alpha);
6336+
return color;
63046337
}
6305-
`
6338+
`;
6339+
6340+
let textShader = Q5.device.createShaderModule({
6341+
label: 'textShader',
6342+
code: textShaderCode
63066343
});
63076344

63086345
let textBindGroupLayout = Q5.device.createBindGroupLayout({
@@ -6701,6 +6738,8 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
67016738
txt[3] = $._matrixIndex;
67026739
txt[4] = $._fillSet ? $._fill : 0;
67036740
txt[5] = $._stroke;
6741+
txt[6] = $._strokeSet ? $._strokeWeight : 0;
6742+
txt[7] = 0; // padding
67046743

67056744
textStack.push(txt);
67066745
$.drawStack.push(3, measurements.printedCharCount, $._font.index);
@@ -6777,7 +6816,7 @@ fn fragmentMain(f : FragmentParams) -> @location(0) vec4f {
67776816
charBuffer.unmap();
67786817

67796818
// calculate total buffer size for metadata
6780-
let totalMetadataSize = textStack.length * 6 * 4;
6819+
let totalMetadataSize = textStack.length * 8 * 4;
67816820

67826821
// create a single buffer for all metadata
67836822
let textBuffer = Q5.device.createBuffer({

q5.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/q5-canvas.js

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Q5.modules.canvas = ($, q) => {
8686
}
8787
if ($._beginRender) $._beginRender();
8888

89+
c.mousePressed = (cb) => c.addEventListener('mousedown', cb);
90+
8991
return rend;
9092
};
9193

src/q5-dom.js

+2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Q5.modules.dom = ($, q) => {
8686
return el;
8787
};
8888

89+
el.mousePressed = (cb) => el.addEventListener('mousedown', cb);
90+
8991
$._elements.push(el);
9092
if ($.canvas) $.canvas.parentElement.append(el);
9193
else document.body.append(el);

0 commit comments

Comments
 (0)