Search code examples
konvajskonvajs-reactjs

How to make rounded-perpendicular lines with react-konva?


I need to make rounded-perpendicular lines with react-konva, is it achievable using existing APIs? If yes, how?

I used bezier API for Line class, it works great. Somehow now I need to revamp the bezier curve to be rounded-perpendicular lines.

Sth like this: rounded-perpendicular-line


Solution

  • There are many ways you can implement it. You can use tension to create curved lines or use lineCap property.

    But to have more control it is better to create a custom shape.

    const RADIUS = 20;
    
    const Line = ({ points }) => {
      return (
        <Shape
          points={points}
          sceneFunc={(context, shape) => {
            const width = points[1].x - points[0].x;
            const height = points[1].y - points[0].y;
            const dir = Math.sign(height);
            const radius = Math.min(RADIUS, Math.abs(height / 2), Math.abs(width / 2));
    
            context.beginPath();
            context.moveTo(points[0].x, points[0].y);
            context.lineTo(points[0].x + width / 2 - RADIUS, points[0].y);
            context.quadraticCurveTo(
              points[0].x + width / 2,
              points[0].y,
              points[0].x + width / 2,
              points[0].y + dir * radius
            );
            context.lineTo(points[0].x + width / 2, points[1].y - dir * radius);
            context.quadraticCurveTo(
              points[0].x + width / 2,
              points[1].y,
              points[0].x + width / 2 + radius,
              points[1].y
            );
            context.lineTo(points[1].x, points[1].y);
            context.fillStrokeShape(shape);
          }}
          stroke="black"
          strokeWidth={2}
        />
      );
    };
    

    Demo: https://codesandbox.io/s/757nw05p6