react-native-skia
react-native-skia copied to clipboard
How can I update Path without rerendering
Description
const [path, setPath] = useState<SkPath>(Skia.Path.Make());
const panGesture = useMemo(
() =>
Gesture.Pan()
.onBegin(e => {
'worklet';
const coords = getRelativeCoords(viewRef as any, e.absoluteX, e.absoluteY);
path.moveTo(coords?.x||0, coords?.y||0)
})
.onUpdate(e => {
'worklet';
const coords = getRelativeCoords(viewRef as any, e.absoluteX, e.absoluteY);
path.lineTo(coords?.x||0, coords?.y||0);
})
[],
);
return (
<GestureDetector gesture={panGesture}>
<View ref={viewRef} style={styles.canvas}>
<Canvas style={{flex: 1}}>
{/* Drawing path */}
<Path
path={path}
// style="stroke"
color={strokeColor}
stroke={{width: typeof strokeWidth === 'number' ? strokeWidth : strokeWidth.value}}
/>
</Canvas>
</View>
</GestureDetector>
);
it doesn't work. how can I change Path without rerendering?
Version
1.3.11
Steps to reproduce
Above code
Snack, code example, screenshot, or link to a repository
no
@doublelam Use sharedValue if you don't want to rerender entire screen:
const currentPath = useSharedValue(Skia.Path.Make());
const panGesture = useMemo(
() =>
Gesture.Pan()
.onBegin(e => {
'worklet';
currentPath.modify((v) => {
const coords = getRelativeCoords(viewRef as any, e.absoluteX, e.absoluteY);
v.lineTo(coords.x || 0, coords.y || 0);
return v;
});
})
.onUpdate(e => {
'worklet';
const coords = getRelativeCoords(viewRef as any, e.absoluteX, e.absoluteY);
currentPath.modify((v) => {
const coords = getRelativeCoords(viewRef as any, e.absoluteX, e.absoluteY);
v.lineTo(coords.x || 0, coords.y || 0);
return v;
});
})
[],
);
..... // next code stays same
@wcandillon issue can be closed
Ok now it works, but I need to use derived value or it does not work
const derived = useDerivedValue(() => {
return pathSharedVal.value.toSVGString()
});
Thank you!
@mrEuler thanks for the insights, Why am I still unable to draw rects based on shared values? Why it requires a rerendering?
import React from "react";
import { Canvas, Rect } from "@shopify/react-native-skia";
import { useSharedValue } from "react-native-reanimated";
import {
Gesture,
GestureDetector,
GestureHandlerRootView,
} from "react-native-gesture-handler";
const AnimatedPathCanvas = () => {
const points = useSharedValue([{ x: 50, y: 50 }]); // Initial point
const panGesture = Gesture.Pan()
.onBegin((e) => {
"worklet";
points.modify((v) => {
v.push({ x: e.x, y: e.y });
return v;
});
})
.onUpdate((e) => {
"worklet";
points.modify((v) => {
v.push({ x: e.x, y: e.y });
return v;
});
});
return (
<GestureHandlerRootView>
<GestureDetector gesture={panGesture}>
<Canvas style={{ flex: 1, backgroundColor: "yellow" }}>
{/* Drawing Rect */}
{points?.value?.map((point, index) => (
<Rect
key={index}
x={point.x}
y={point.y}
width={2.5}
height={2.5}
color="blue"
/>
))}
</Canvas>
</GestureDetector>
</GestureHandlerRootView>
);
};
export default AnimatedPathCanvas;