Search code examples
javascripthtmlmouseeventmousedown

How can I animate a line while drawing a line between two points using the mouse


If anyone is familiar with node-red, this is how it looks like there. The way it works. You click on the small rectancle and keep the mouse pressed. Then a line begins to be drawn and it is curved as below. How can I do this in html/javascript? I found bezier curves, but I don't get how to animate it. Are there libraries?

Node Red example

Basic code snippet what works but no animation:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function drawS(start, end) {
  const startX = start[0];
  const startY = start[1];
  const endX = end[0];
  const endY = end[1];
  const distX = endX - startX;
  const distY = endY - startY;
  const bezierP1X = endX;
  const bezierP1Y = startY;
  const bezierP2X = startX;
  const bezierP2Y = endY;
  ctx.beginPath();
  ctx.moveTo(...start);
  ctx.bezierCurveTo(bezierP1X, bezierP1Y, bezierP2X, bezierP2Y, ...end);
  ctx.stroke();
}

drawS([20, 20], [80, 100]);
<canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>


Solution

  • You need to draw (everything) and clear and draw again on mousemove or even on requestAnimationFrame

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    const width = canvas.width = canvas.clientWidth;
    const height = canvas.height = canvas.clientHeight
    
    
    function drawS(start, end) {
      const startX = start[0];
      const startY = start[1];
      const endX = end[0];
      const endY = end[1];
      const distX = endX - startX;
      const distY = endY - startY;
      const bezierP1X = endX;
      const bezierP1Y = startY;
      const bezierP2X = startX;
      const bezierP2Y = endY;
      ctx.beginPath();
      ctx.moveTo(...start);
      ctx.bezierCurveTo(bezierP1X, bezierP1Y, bezierP2X, bezierP2Y, ...end);
      ctx.stroke();
    }
    
    
    
    canvas.addEventListener('mousemove', function(ev) {
      var cx = ev.offsetX
      var cy = ev.offsetY
    
    ctx.clearRect(0,0,width, height)
      drawS([20, 20], [cx, cy]);
    
    })
    <canvas id="myCanvas" width="300" height="200" style="border:1px solid #d3d3d3;"></canvas>