SVG scaling/fitbox breaks on re-render
Description
I have an SVG rendered within a fitbox that shows as intended on first render, but the scaling breaks on subsequent re-renders.
I'm trying to add markers (with <Circle />) when a user taps on the canvas by keeping an array of these markers in state. When a marker is added, the marker itself displays fine but the SVG behind it breaks. If I then reload the app, both the markers and SVG display as intended.
Using with:
- Expo 50.0.3
- React Native 0.72.6
Version
0.1.234
Steps to reproduce
- load the initial canvas and markers
- tap on the canvas, which should add a marker
- the marker is added, but the SVG is broken
Snack, code example, screenshot, or link to a repository
Screen recording
https://github.com/Shopify/react-native-skia/assets/41151984/b4128d0d-13e9-43de-b7e6-9d7f2a158cd3
The component
export const RugbyPitchCanvas = () => {
const [circles, setCircles] = useState<any[]>([
{ x: 361 / 2, y: 60, radius: 7, fillColor: "red" },
]);
const [canvasLayout, setCanvasLayout] =
useState<LayoutRectangle>(EMPTY_LAYOUT);
const ref = useCanvasRef();
const pitchSvg = useSVG(require("./rugby-union-pitch.svg"));
const touchHandler = useTouchHandler({
onStart: (touchInfo) => {
const x = touchInfo.x;
const y = touchInfo.y;
setCircles((prevCircles) => [
...prevCircles,
{ x, y, radius: 10, fillColor: "red" },
]);
},
onActive: (touchInfo) => {
// ongoing touch interactions
},
onEnd: (touchInfo) => {
// when the touch ends
console.log("> Canvas touch end");
},
});
const src = rect(0, 0, pitchSvg?.width() ?? 0, pitchSvg?.height() ?? 0);
const dst = rect(0, 0, canvasLayout?.width, canvasLayout?.height);
return (
<Canvas
style={{ flex: 1, minHeight: dst.width * 1.032, backgroundColor: "blue" }}
ref={ref}
onLayout={(event) => setCanvasLayout(event.nativeEvent.layout)}
onTouch={touchHandler}
>
<Group transform={fitbox("fitWidth", src, dst)}>
<ImageSVG svg={pitchSvg} x={0} y={0} width={100} height={100} />
</Group>
<Group>
{circles.map((circle, index) => (
<Circle
key={index}
cx={circle.x}
cy={circle.y}
r={circle.radius}
color={circle.fillColor}
/>
))}
</Group>
</Canvas>
);
};
it's a bit hard to say by looking at the code, could you prepare a small example where I could test everything almost immediately? with the svg file ready etc. Also I'm not sure what LayoutRectangle is and so on.
Closing this but as soon as you have a small reproducible example that outlines the suspected issue, I will reopen it asap 💯
Sorry I missed your first comment! I'll put together a better example shortly.
For LayoutRectangle, that's provided by React Native:
export interface LayoutRectangle {
x: number;
y: number;
width: number;
height: number;
}