Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Picture not rerendering on iOS #2732

Open
mbpictures opened this issue Nov 12, 2024 · 2 comments
Open

Picture not rerendering on iOS #2732

mbpictures opened this issue Nov 12, 2024 · 2 comments

Comments

@mbpictures
Copy link

Hi!

I'm creating a drawing-like component using skia and gesture handler. My code looks like this (simplified):

const DrawBoard = forwardRef<DrawBoardType, Props>(({style}, ref) => {
    const path = useSharedValue<Element>({path: Skia.Path.Make(), paint: Skia.Paint(), type: "draw"});
    const lastTouch = useSharedValue<{x: number; y: number}>({x: 0, y: 0});
    const {toolbar} = useToolbar();
    const currentPicture = useSharedValue(emptyPicture);

    const panGesture = Gesture.Pan()
        .maxPointers(1)
        .minDistance(0)
        .averageTouches(true)
        .enabled(toolbar.activeTool !== Tools.None)
        .onStart(e => {
            const newPath = Skia.Path.Make();
            newPath.moveTo(e.x, e.y);
            if (toolbar.activeTool === Tools.Pencil || toolbar.activeTool === Tools.Eraser) {
                newPath.lineTo(e.x, e.y);
            }
            const newPaint = Skia.Paint();
            newPaint.setStyle(PaintStyle.Stroke);
            newPaint.setColor(Skia.Color(toolbar.color));
            newPaint.setStrokeWidth(toolbar.strokeWidth);
            if (toolbar.activeTool === Tools.Eraser) {
                newPaint.setBlendMode(BlendMode.Clear);
            } else {
                newPaint.setBlendMode(BlendMode.Src);
            }
            path.value = {
                path: newPath,
                paint: newPaint,
                type: toolbar.activeTool === Tools.Eraser ? "erase" : "draw"
            };
            lastTouch.value = {x: e.x, y: e.y};
        })
        .onUpdate(e => {
            if (toolbar.activeTool === Tools.Rectangle) {
                path.value.path.reset();
                path.value.path.addRect({
                    x: lastTouch.value.x,
                    y: lastTouch.value.y,
                    width: e.x - lastTouch.value.x,
                    height: e.y -lastTouch.value.y
                });
            } else if (toolbar.activeTool === Tools.Circle) {
                path.value.path.reset();
                path.value.path.addCircle(lastTouch.value.x, lastTouch.value.y, Math.sqrt(Math.pow(e.x - lastTouch.value.x, 2) + Math.pow(e.y - lastTouch.value.y, 2)));
            } else {
                path.value.path.lineTo(e.x, e.y);
            }
            // update the picture
            currentPicture.value = createPicture(
                canvas => {
                    canvas.drawPath(path.value.path, path.value.paint);
                }
            )
        })
        .onEnd(() => {
            path.value = {path: Skia.Path.Make(), paint: Skia.Paint(), type: "draw"};
        });

    return (
        <View style={[style, {pointerEvents: toolbar.activeTool === Tools.None ? "none" : "auto"}]}>
            <View style={styles.container}>
                <GestureDetector gesture={panGesture}>
                    <Canvas style={styles.canvas}>
                        <Picture picture={currentPicture} />
                    </Canvas>
                </GestureDetector>
            </View>
        </View>
    )
});

This works fine on Android, but on iOS the Picture doesn't rerender. I already added logs inside of the createPicture function and saw, that it is called while painting and also the value of the path looks good, so I have no idea why the picture doesn't rerender.

@wcandillon
Copy link
Contributor

Can you provide a standalone reproducible example? I would be happy to take a look

@mbpictures
Copy link
Author

Repro is available here: https://github.com/mbpictures/react-native-skia-sketch-repro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants