1

How to update position of a custom shape after drag? With other shapes e.target.position() works, but with custom shapes it returns position relative to original position when drawing the shape.

I tried to update position by adding new coordinates to the original position but shape goes to wrong position.

Ted
  • 13
  • 2
  • Can you make an online demo of your issue? Dragging for all shapes works the same way. By changing `x` and `y` of a shape. – lavrton Jun 19 '23 at 17:27
  • https://codesandbox.io/embed/compassionate-lake-whsknr?fontsize=14&hidenavigation=1&theme=dark Code works correctly if Shape is changed to Line and using Line in my project isn't a solution as I need more complex shapes. – Ted Jun 20 '23 at 19:20

1 Answers1

1

Here is your old code of the shape:

<Shape
  sceneFunc={(context, shape) => {
    context.beginPath();
    context.moveTo(pos.x, pos.y);

    for (let i = 0; i < pos.points.length; i++) {
      context.lineTo(pos.x + pos.points[i].x, pos.y + pos.points[i].y);
    }
    context.stroke();
    // (!) Konva specific method, it is very important
    context.fillStrokeShape(shape);
  }}
  stroke="black"
  strokeWidth={4}
  draggable={true}
  onDragEnd={handleDrag}
/>

Here you are using the position of the node pos.x and pos.y inside sceneFunc. You don't need to do that! Konva automatically applies transform into 2D context before calling sceneFunc.

Here is fixed version of full code:

export default function App() {
  const [pos, setPos] = useState({
    x: 20,
    y: 50,
    points: [
      { x: 200, y: 60 },
      { x: 300, y: 200 }
    ]
  });

  const handleDrag = (e) => {
    setPos((prev) => ({ ...prev, x: e.target.x(), y: e.target.y() }));
  };

  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <Shape
          sceneFunc={(context, shape) => {
            context.beginPath();
            context.moveTo(0, 0);

            for (let i = 0; i < pos.points.length; i++) {
              context.lineTo(pos.points[i].x, pos.points[i].y);
            }
            // (!) Konva specific method, it is very important
            context.fillStrokeShape(shape);
          }}
          stroke="black"
          strokeWidth={4}
          draggable={true}
          onDragEnd={handleDrag}
        />
      </Layer>
    </Stage>
  );
}

Demo: https://codesandbox.io/s/react-konva-custom-shape-with-drag-9f78lr?file=/src/App.js

lavrton
  • 18,973
  • 4
  • 30
  • 63
  • In my app user can draw shapes so initial position can’t be (0,0). It should be the coordinates pos.x and pos.y which are first generated from mouse position and then updated by the drag. How do I set the initial position based on that? – Ted Jun 21 '23 at 22:24
  • ihave a related question here https://stackoverflow.com/questions/76525337/ how can we get width and height values and display them along the rectangle? i.e. dimension of the the frame – Deep Kakkar Jun 22 '23 at 06:03
  • I fixed the issue. Thank you! – Ted Jun 22 '23 at 09:47