fix line positioning in canvas

I have a canvas in a div like this

<div class="col-md-6">
    <img src="{{ image }}" class="img-class img-thumbnail img-responsive">
    <canvas id="can" class="hidden" style="position: absolute; width: 100%; height: 100%; top: 0px; left: 0px;"></canvas>
    <div class="hidden hover-div" style="position: absolute; width: 100%; height: 100%; background-color: rgba(128, 128, 128, 0.07); top: 0;">

    </div>
</div>

and the code to draw a line with it

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

var x = "black",
y = 2;

function initialize() {
    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);
}

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

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();
        }
    }
}

it works but the x,y co-ordinates are off, need help fixing this.

Here's a screen record demo of it's behaviour https://youtu.be/e8SUUZF81rk

the y pos is far down on the canvas compared to the mouse and x is slightly to the right.

I got this code from an example from here and edited it a little.

1 answer

  • answered 2017-08-16 19:34 Blindman67

    You need to set the canvas resolution to match the canvas display size, or scale the mouse coords to the canvas resolution.

    To set the resolution to match the canvas display size

     const bounds = canvasElement.getBoundingClientRect();
     canvasElement.width = bounds.width;
     canvasElement.height = bounds.height;
    

    Or if you prefer you can scale the mouse position to match the canvas resolution

     const bounds = canvasElement.getBoundingClientRect();
     const scaleX = canvasElement.width / bounds.width;
     const scaleY = canvasElement.height / bounds.height;
    
     // then scale the mouse with the above scales
     // in mouse event
    
     mouseX = mouseEvent.clientX * scaleX;
     mouseY = mouseEvent.clientY * scaleY;