Skip to content

Commit 824a94c

Browse files
authored
Fix SVG line stroke width scaling (#81)
* Scale line stroke width in SVG snapshots * edge case handling
1 parent 1c6e376 commit 824a94c

File tree

4 files changed

+74
-16
lines changed

4 files changed

+74
-16
lines changed

lib/getSvgFromGraphicsObject.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,9 @@ export function getSvgFromGraphicsObject(
139139
svgWidth,
140140
svgHeight,
141141
)
142+
const strokeScale = Math.abs(matrix.a)
142143

143-
const shouldRenderLabel = (
144-
type: "points" | "lines" | "rects",
145-
): boolean => {
144+
const shouldRenderLabel = (type: "points" | "lines" | "rects"): boolean => {
146145
if (typeof includeTextLabels === "boolean") {
147146
return includeTextLabels
148147
}
@@ -236,7 +235,10 @@ export function getSvgFromGraphicsObject(
236235
points: projectedPoints.map((p) => `${p.x},${p.y}`).join(" "),
237236
fill: "none",
238237
stroke: line.strokeColor || "black",
239-
"stroke-width": (line.strokeWidth ?? 1).toString(),
238+
"stroke-width":
239+
typeof line.strokeWidth === "string"
240+
? line.strokeWidth
241+
: (strokeScale * (line.strokeWidth ?? 1)).toString(),
240242
...(line.strokeDash && {
241243
"stroke-dasharray": Array.isArray(line.strokeDash)
242244
? line.strokeDash.join(" ")

site/components/InteractiveGraphics/Arrow.tsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ export const Arrow = ({
3434
}
3535
}, [geometry, realToScreen])
3636

37-
const scaleFactor = useMemo(() => Math.hypot(realToScreen.a, realToScreen.b), [
38-
realToScreen.a,
39-
realToScreen.b,
40-
])
37+
const scaleFactor = Math.abs(realToScreen.a)
4138

4239
const baseColor =
4340
arrow.color || defaultColors[index % defaultColors.length] || "black"
@@ -62,7 +59,14 @@ export const Arrow = ({
6259
]
6360

6461
const isNear = segments.some(({ from, to }) => {
65-
const distance = distToLineSegment(mouseX, mouseY, from.x, from.y, to.x, to.y)
62+
const distance = distToLineSegment(
63+
mouseX,
64+
mouseY,
65+
from.x,
66+
from.y,
67+
to.x,
68+
to.y,
69+
)
6670
return distance < hoverThreshold
6771
})
6872

Lines changed: 44 additions & 0 deletions
Loading

tests/getSvgFromGraphicsObject.test.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,29 +42,37 @@ describe("getSvgFromGraphicsObject", () => {
4242
{
4343
points: [
4444
{ x: 0, y: 0 },
45-
{ x: 1, y: 1 },
45+
{ x: 10, y: 10 },
4646
],
4747
strokeWidth: 2,
4848
strokeColor: "blue",
4949
},
5050
{
5151
points: [
52-
{ x: 1, y: 0 },
53-
{ x: 0, y: 1 },
52+
{ x: 10, y: 0 },
53+
{ x: 0, y: 10 },
5454
],
5555
// Test default values when properties are not specified
5656
},
5757
],
5858
}
5959

60-
const svg = getSvgFromGraphicsObject(input)
60+
const svg = getSvgFromGraphicsObject(input, {
61+
svgWidth: 200,
62+
svgHeight: 200,
63+
})
6164
expect(svg).toBeString()
6265
expect(svg).toContain("<polyline")
6366
// Test custom stroke properties
64-
expect(svg).toContain('stroke-width="2"')
6567
expect(svg).toContain('stroke="blue"')
66-
// Test default values
67-
expect(svg).toContain('stroke-width="1"')
68+
// Test stroke width scaling
69+
const strokeWidths = Array.from(
70+
svg.matchAll(/<polyline[^>]*stroke-width="([0-9.]+)"/g),
71+
).map(([, value]) => parseFloat(value))
72+
expect(strokeWidths).toHaveLength(2)
73+
expect(strokeWidths[0]).toBeCloseTo(24)
74+
expect(strokeWidths[1]).toBeCloseTo(12)
75+
// Test default color
6876
expect(svg).toContain('stroke="black"')
6977
expect(svg).toMatchSvgSnapshot(import.meta.path, "lines")
7078
})

0 commit comments

Comments
 (0)