TheSinOfGreed
TheSinOfGreed

Reputation: 31

How force Fabric.js polygon to update his points correctly after modify

I’m using the latest version of Fabric.js, and I have a problem with a polygon. As we know, in Fabric.js, the points field of a polygon doesn’t update after modification (it always contains the initial points).

I want to recalculate the polygon's points after modification to get the current position of each point. To achieve this, I use the trick with calcTransformMatrix (the points are calculated correctly), and then I assign the new points to the existing polygon.

The problem occurs when I try to scale or rotate a polygon with updated points—this leads to crashes and bugs, and I don’t know why.

Here is my code:

const canvas = new fabric.Canvas("canvas", {
  width: 600,
  height: 600,
  backgroundColor: "lightgray",
});

const polygonPoints = [
  { x: 100, y: 50 },
  { x: 200, y: 80 },
  { x: 250, y: 200 },
  { x: 150, y: 300 },
  { x: 50, y: 200 },
];

const polygon = new fabric.Polygon(polygonPoints, {
  fill: "rgba(0, 128, 255, 0.5)",
  stroke: "blue",
  strokeWidth: 2,
  selectable: true,
});

canvas.add(polygon);

// On modified
polygon.on("modified", (o) => {
  // Calculate new points
  const newPoints = polygon
    .get("points")
    .map(
      (p) =>
        new fabric.Point(p.x - polygon.pathOffset.x, p.y - polygon.pathOffset.y)
    )
    .map((p) => p.transform(polygon.calcTransformMatrix()));

  polygon.set({ points: newPoints });
  polygon.setBoundingBox(true);
  canvas.requestRenderAll();

  // Now after recalculate points it work fine when drag but scale/rotate dont work correctly
  polygon.points.forEach((e) => {
    canvas.add(
      new fabric.Rect({
        left: e.x,
        top: e.y,
        width: 5,
        height: 5,
        fill: "red",
      })
    );
  });
});

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fabric js</title>

    <script src="https://cdn.jsdelivr.net/npm/fabric@latest/dist/index.min.js"></script>
  </head>
  <body>
    <canvas id="canvas" width="600" height="600"></canvas>
    <script src="main.js"></script>
  </body>
</html>

After dragging, when we try to scale or rotate, we can see weird behavior.

I expect that after updating the points, rotating or scaling should not break the polygon. Here is demo code:

https://codesandbox.io/p/devbox/vibrant-kowalevski-v8vkjk?workspaceId=ws_JP9WoSuC2iw5iMuNawSDEv

If you try scale/rotate after drag (so after update points) you will see crashes.

Before drag (before points update): enter image description here After drag & scale/rotate or just scale/rotate: enter image description here

Upvotes: 0

Views: 18

Answers (0)

Related Questions