Mayur Kukadiya
Mayur Kukadiya

Reputation: 2747

How to calculate mouse pointer position in canvas?

I am implementing image manipulation tool and I want to erase background from image where mouse clicked on canvas.

My canvas is automatically set fit to windows. If image is too large, then it will automatically zoomed Out to fit in view-port.

Now, when my canvas is zoomed Out, my image is blurry. I am calculating position of mouse using below code :

mouse:move': (evt) => {
   var canvasOffset = $('#eraserCanvas').offset();
   var x = evt.e.pageX - canvasOffset.left;
   var y = evt.e.pageY - canvasOffset.top;
   var pixel = ctx.getImageData(x, y, 1, 1);
}

But here problem is that my context is also small same as canvas size (zoomed Out) so my image's pixel data is of small image which may result of blur final output.

After lot's of searching and thinking, I found one solution is that, If we keep our context scaling to original image size. Only canvas is resize then our final output is clear.

Now problem is that my mouse position is according to my scaled canvas. So It's necessary to calculate mouse position in original size of canvas to get correct pixel in scaled canvas. but i don't know how to calculate position of pointer in scaled canvas is what position in original size canvas or context.

See below image for more understanding : enter image description here

Here original size canvas will not display to user. but process of remove pixel is on original size canvas.


Whole scenario (above image)

  1. display small (zoomedOut) canvas to user.
  2. User pick pixel from that canvas(image).
  3. we first get mouse pointer position on scaled canvas(image).
  4. now what will position of mouse pointer in original canvas if we scale scaled-out canvas to original size canvas ?

this fourth step is calculation that I don't know How?

Please help me.

Upvotes: 0

Views: 648

Answers (1)

enxaneta
enxaneta

Reputation: 33062

If you intend to scale the canvas using css I would use this function to get the mouse position over the canvas. First you calculate the scale as a rapport between the initial size of the canvas and the size of the scaled canvas. Next you recalculate the position of the mouse over the canvas.

function oMousePosScaleCSS(canvas, evt) {
      let ClientRect = canvas.getBoundingClientRect(), 
          scaleX = canvas.width / ClientRect.width,
          scaleY = canvas.height / ClientRect.height; 
          return {
          x: (evt.clientX - ClientRect.left) * scaleX, 
          y: (evt.clientY - ClientRect.top) * scaleY 
      }
    }

Please see a working example:

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let cw = canvas.width = 150;
let ch = canvas.height = 150;


function oMousePosScaleCSS(canvas, evt) {
  let ClientRect = canvas.getBoundingClientRect(), 
      scaleX = canvas.width / ClientRect.width,
      scaleY = canvas.height / ClientRect.height; 
      return {
      x: (evt.clientX - ClientRect.left) * scaleX, 
      y: (evt.clientY - ClientRect.top) * scaleY 
  }
}


let last = {}

canvas.addEventListener("mousedown", (e)=>{
  m = oMousePosScaleCSS(canvas, e)
  
  ctx.clearRect(0,0,cw,ch);

  last.x = m.x;
  last.y = m.y;
  
  
 
});

canvas.addEventListener("mouseup", (e)=>{
last={}

});


canvas.addEventListener("mousemove", (e)=>{
  if(last.x){
   m = oMousePosScaleCSS(canvas, e)
   
    
    ctx.beginPath();
    ctx.moveTo(last.x,last.y);
    ctx.lineTo(m.x,m.y);
    ctx.stroke();
    
    
    last.x = m.x;
    last.y = m.y;
    
  }
  

})
canvas {
  border:1px solid #d9d9d9;
  display: block;
  position:absolute;
  margin:auto;
  left:0;
  right:0;
  top:0;
  bottom:0;
  /***********************/
  transform: scale(.75, .75);
  /***********************/
}
<canvas id="canvas"></canvas>

Upvotes: 1

Related Questions