Pranjal Koshti
Pranjal Koshti

Reputation: 185

While drawing on a HTML5 canvas using mouse, mouse position is not correctly positioned

canvas actual height,width is bigger than style height, width.

<canvas id="canvas" class="page" width="1190" height="1683" style="height: 841.68px; width: 595.44px;"></canvas>

What calculations that needs to be considered when finding proper mouse position in this case. Current code for mouse position is

function getMousePos(canvas, evt) {
        let ancestor = document.getElementById('viewer')
        var offsetAncestor = ancestor.getBoundingClientRect();

        var rect = canvas.getBoundingClientRect(), // abs. size of element
            scaleX = canvas.width / rect.width,    // relationship bitmap vs. element for X
            scaleY = canvas.height / rect.height;  // relationship bitmap vs. element for Y

        // return {
        //   x: (evt.clientX - rect.left) * scaleX,   // scale mouse coordinates after they have
        //   y: (evt.clientY - rect.top) * scaleY     // been adjusted to be relative to element
        // }
        return {
            x: (evt.clientX - (rect.left - offsetAncestor.left)),   // scale mouse coordinates after they have
            y: (evt.clientY - (rect.top + offsetAncestor.top))     // been adjusted to be relative to element
        }
    }

Upvotes: 1

Views: 64

Answers (1)

Blindman67
Blindman67

Reputation: 54026

Element.getBoundingClientRect is an absolute coordinate relative to the viewport. You don not need to use the coordinates of the container eg ancestor.getBoundingClientRect(); is not required.

Example converting mouse event client coords to canvas pixel coords. (assuming Window.devicePixelRatio === 1)

const ctx = canvas.getContext("2d");
ctx.lineWidth = 10;
var x, y;
addEventListener("mousemove", mouseMove);
function mouseMove(e) {
    const canRect = canvas.getBoundingClientRect(); 
    const scaleX = canvas.width / canRect.width;  
    const scaleY = canvas.height / canRect.height; 
    const xx = (e.clientX - canRect.left) * scaleX;
    const yy = (e.clientY - canRect.top) * scaleY;
    
    if (x !== undefined) {
        ctx.beginPath();
        ctx.lineTo(x, y);
        ctx.lineTo(xx, yy);
        ctx.stroke();
    }
    x = xx;
    y = yy;
}    
canvas {
    height: 150px; 
    width: 300px;
    border: 1px solid black;
}
#viewer {
   position: absolute;
   top: 40px;
   left: 100px;
}
Move mouse over canvas.
<div id="viewer">
  <canvas id="canvas" width="1190" height="1683" style=""></canvas>
</div>

Upvotes: 1

Related Questions