Skip to content

Commit aae199f

Browse files
authored
fix(radius): avoid seam on fractional position (#675)
Resolve visual line artifacts in rounded corners when elements are positioned at fractional coordinates.
1 parent 340ce38 commit aae199f

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

examples/tests/viewport-largebound.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,36 @@ import type { INode } from '../../dist/exports/index.js';
55
export async function automation(settings: ExampleSettings) {
66
const page = await test(settings);
77
page(1);
8+
await waitForRendererIdle(settings.renderer);
89
await settings.snapshot();
910

1011
page(2);
12+
await waitForRendererIdle(settings.renderer);
1113
await settings.snapshot();
1214

1315
page(3);
16+
await waitForRendererIdle(settings.renderer);
1417
await settings.snapshot();
1518
}
1619

20+
function waitForRendererIdle(renderer: ExampleSettings['renderer']) {
21+
return new Promise<void>((resolve) => {
22+
let timeout: ReturnType<typeof setTimeout> | undefined;
23+
24+
const finishSoon = () => {
25+
timeout = setTimeout(() => resolve(), 200);
26+
};
27+
28+
renderer.once('idle', () => {
29+
if (timeout) clearTimeout(timeout);
30+
finishSoon();
31+
});
32+
33+
// Fallback in case `idle` already fired before we attached the listener
34+
finishSoon();
35+
});
36+
}
37+
1738
export default async function test({ renderer, testRoot }: ExampleSettings) {
1839
// Create a container node
1940
const containerNode = renderer.createNode({
@@ -62,7 +83,7 @@ export default async function test({ renderer, testRoot }: ExampleSettings) {
6283
'Container bound: ' + JSON.stringify(containerNode.renderState) + '\n';
6384

6485
for (const node of containerNode.children) {
65-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
86+
6687
status += `${
6788
(node.children[0] as CoreTextNode)?.text
6889
} bound: ${JSON.stringify(node.renderState)} \n`;

src/core/renderers/webgl/shaders/effects/RadiusEffect.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ export class RadiusEffect extends ShaderEffect {
9797

9898
static override onShaderMask = `
9999
vec2 halfDimensions = u_dimensions * 0.5;
100-
float r = radius[0] * step(v_nodeCoordinate.x, 0.5) * step(v_nodeCoordinate.y, 0.5);
101-
r = r + radius[1] * step(0.5, v_nodeCoordinate.x) * step(v_nodeCoordinate.y, 0.5);
102-
r = r + radius[2] * step(0.5, v_nodeCoordinate.x) * step(0.5, v_nodeCoordinate.y);
103-
r = r + radius[3] * step(v_nodeCoordinate.x, 0.5) * step(0.5, v_nodeCoordinate.y);
104-
return $boxDist(v_nodeCoordinate.xy * u_dimensions - halfDimensions, halfDimensions, r);
100+
vec2 p = v_nodeCoordinate.xy * u_dimensions - halfDimensions;
101+
vec4 r = radius;
102+
r.xy = (p.x > 0.0) ? r.yz : r.xw;
103+
float cornerRadius = (p.y > 0.0) ? r.y : r.x;
104+
return $boxDist(p, halfDimensions, cornerRadius);
105105
`;
106106

107107
static override onEffectMask = `

0 commit comments

Comments
 (0)