0

I have a image inside canvas. When I paint it draw the line far from the actual point. I can't figure out why this is happening and how to fix it.

This is the script and it is taken from here. When I click in one point it draw in another point. Draw on HTML5 Canvas using a mouse

var canvas, ctx, flag = false,
  prevX = 0,
  currX = 0,
  prevY = 0,
  currY = 0,
  dot_flag = false;

var x = "black",
  y = 2;

function init() {
  canvas = document.getElementById('can');
  ctx = canvas.getContext("2d");
  w = canvas.width;
  h = canvas.height;

  canvas.addEventListener("mousemove", function(e) {
    findxy('move', e)
  }, false);
  canvas.addEventListener("mousedown", function(e) {
    findxy('down', e)
  }, false);
  canvas.addEventListener("mouseup", function(e) {
    findxy('up', e)
  }, false);
  canvas.addEventListener("mouseout", function(e) {
    findxy('out', e)
  }, false);

  base_image = new Image();
  base_image.src = document.getElementById("editable_image_path").src
  base_image.onload = function() {
    ctx.drawImage(base_image, 0, 0, 800, 400);
  };

}

function color(obj) {
  switch (obj.id) {
    case "green":
      x = "green";
      break;
    case "blue":
      x = "blue";
      break;
    case "red":
      x = "red";
      break;
    case "yellow":
      x = "yellow";
      break;
    case "orange":
      x = "orange";
      break;
    case "black":
      x = "black";
      break;
    case "white":
      x = "white";
      break;
  }
  if (x == "white") y = 14;
  else y = 2;

}

function draw() {
  ctx.beginPath();
  ctx.moveTo(prevX, prevY);
  ctx.lineTo(currX, currY);
  ctx.strokeStyle = x;
  ctx.lineWidth = y;
  ctx.stroke();
  ctx.closePath();
}

function erase() {
  var m = confirm("Want to clear");
  if (m) {
    ctx.clearRect(0, 0, w, h);
    document.getElementById("canvasimg").style.display = "none";
  }
}

function save() {
  document.getElementById("canvasimg").style.border = "2px solid";
  var dataURL = canvas.toDataURL();
  document.getElementById("canvasimg").src = dataURL;
  document.getElementById("canvasimg").style.display = "inline";
}

function findxy(res, e) {
  if (res == 'down') {
    prevX = currX;
    prevY = currY;
    currX = e.clientX - canvas.offsetLeft;
    currY = e.clientY - canvas.offsetTop;

    flag = true;
    dot_flag = true;
    if (dot_flag) {
      ctx.beginPath();
      ctx.fillStyle = x;
      ctx.fillRect(currX, currY, 2, 2);
      ctx.closePath();
      dot_flag = false;
    }
  }
  if (res == 'up' || res == "out") {
    flag = false;
  }
  if (res == 'move') {
    if (flag) {
      prevX = currX;
      prevY = currY;
      currX = e.clientX - canvas.offsetLeft;
      currY = e.clientY - canvas.offsetTop;
      draw();
    }
  }
}
<div class="snap-field col-sm-12" style="height: 800px;">
  <body onload="init()">
    <canvas id="can" width="1000" height="500" 
            style="border:1px solid;position:absolute;">
    </canvas>
  </body>
</div>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
David
  • 246
  • 1
  • 4
  • 15

1 Answers1

1

Instead of using canvas.offsetX and canvas.offsetY in the findXY function, use canvas.getBoundingClientRect().left and canvas.getBoundingClientRect().top. It will give you more reliable absolute coordinates for the canvas as the reference point for drawing.

see sharper
  • 11,505
  • 8
  • 46
  • 65
  • can you help me with this: https://stackoverflow.com/questions/68861360/save-canvas-image-in-database – David Aug 20 '21 at 12:14