konvajsreact-konvakonvakonvajs-reactjs

How do I get/update position of children after dragging group react-konva


So in my web application using react-konva, I have a tool that lets me draw polygons with vertices as circles, I can drag the vertices and update the state of the vertices, but I would like to be able to drag the entire polygon and get the new position of circles in the group to update my state.

I tried this in my handleDragEnd function:

const handlePolygonDragEnd = (
        event: KonvaEventObject<DragEvent>,
        polygonName: string
    ) => {
        if (isDrawing) return;

        const group = event.target;

        const newGroupPosition = {x:group.x(), y:group.y()};
       
        if (group === null) return;
        if (group instanceof Konva.Group) {
            // const children = group.getChildren().slice(1);

            const newPolygons = polygons.map((polygon) => {
                if (polygon.name === polygonName) {
                    const newPoints = polygon.points.map((point) => {
                        return [point[0] + newGroupPosition.x, point[1] + newGroupPosition.y];
                    });
                    return {
                        ...polygon,
                        points: [...newPoints],
                    };
                }
                return polygon;
            });
            setPolygons(newPolygons);

            // group.setAbsolutePosition({ x: 0, y: 0 });
        }
    };

But for some reason it just makes my polygons jump rather than staying in the position that I want it to be.

Edit: Here is a demo of the issue that I am facing: Demo

Thank you


Solution

  • You have a jump because you are changing the position of the polygon twice:

    1. When a group is moved, its x and y attributes are changed. All children elements are moved by that x and y
    2. On dragend, you are adding x and y into points attribute. It gives you the second (and not expected) move.

    There are two solutions:

    1. Do not change points. Just keep using x and y of the group to control its position
    2. Or, read x and y (the shift after dragging), update points, then reset group position back to {x: 0, y: 0}.