0

I'm trying to create a drawing tablet with a mouse.

With KonvaJS, I can draw a line or an arrow. How do I change the style of the line and the end of the arrow?

I use Konva. Arrow and Konva.Line and that's what I need.

Example:

enter image description here

Ilya Frolov
  • 96
  • 2
  • 9
  • Maybe something you can adapt for the line style here: https://stackoverflow.com/questions/63128291/konva-js-waved-stroke-around-rect-element – Vanquished Wombat Aug 18 '21 at 08:15

1 Answers1

2

There are many ways to implement such shapes.

(1) You can use Konva.Path and generate data attribute with SVG path manually (from your mouse movements).

(2) You can use Konva.TextShape to draw arrow as a set of some symbols (like dots or dashes).

(3) You can use Custom Shape to draw with native 2d canvas API.

Here is a demo with all of them:

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight
});

const layer = new Konva.Layer();
stage.add(layer);

const getAngle = (points) => {
  const dx = points[1].x - points[0].x;
  const dy = points[1].y - points[0].y;
  const angle = Math.atan2(dy, dx);
  return Konva.Util.radToDeg(angle);
}

const createPathArrow = () => {
  return new Konva.Path({
    x: 50,
    y: 50,
    stroke: 'red',
    fill: 'red',
    data: 'M 0 0 L 100 0 L 80 -10 L 90 0 L 80 10 L 100 0'
  })
};



const createTextPathArrow = (points) => {
  const [p1, p2] = points;
  const group = new Konva.Group({
    x: 50,
    y: 150
  });
  group.add(new Konva.TextPath({
    stroke: 'red',
    text: '| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ',
    data: `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`
  }));
  group.add(new Konva.Text({
    x: p2.x,
    y: p2.y,
    text: '➤',
    fill: 'red',
    fontSize: 25,
    offsetY: 25 / 2,
    offsetX: 25 / 2,
    rotation: getAngle(points)
  }))
  return group;
};

const createSceneArrow = () => {
  return new Konva.Shape({
    x: 50,
    y: 250,
    stroke: 'red',
    length: 100,
    arcSize: 10,
    sceneFunc: (ctx, shape) => {
      const arcSize = shape.getAttr('arcSize');
      const number = shape.getAttr('length') / arcSize;
      ctx.beginPath();
      for(var i = 0; i < number; i++) {
          ctx.moveTo(i * arcSize, 0);
          const midX = (i * arcSize + arcSize / 2);
          const midY = 0;
          if (i % 2 === 0) {
            ctx.arc(midX, midY, arcSize / 2, Math.PI, 0, 1);            
          } else {
            ctx.arc(midX, midY, arcSize / 2, Math.PI, 0);            
          }
      }
      ctx.fillStrokeShape(shape);
    }
  })
}

const points = [{x: 0, y: 0}, {x: 100, y: 30}];

layer.add(createPathArrow());
layer.add(createTextPathArrow(points));
layer.add(createSceneArrow())
<script src="https://unpkg.com/konva@^8/konva.min.js"></script>
<div id="container"></div>
lavrton
  • 18,973
  • 4
  • 30
  • 63