iHank
iHank

Reputation: 536

Canvas context.drawimage doesn't draw on the right coordinates

I have a canvas in the center of a website. When I perform a mouse click on the canvas, I want a small image to be drawn at the click-location. In manage to get the correct coordinates of a canvas click I structute a JavaScript-function like this:

function click( event ) {

    var ctxt;
    var myX =  event.clientX;
    var myY =  event.clientY;

    myX-=canvas.offsetTop;
    myY-=canvas.offsetLeft;

    ctxt = canvas.getContext("2d");

    ctxt.drawImage(myImage, myX, myY);

    alert(myX + " " + myY);
}

The alert function shows the correct coordinates, but the image is drawn at a location with much higher coordinate-values. If I click a little bit to far down or to the left, the image is not drawn at all (probably because its outside the canvas).

The drawn image has a x-coordinate that's about 3 times as high as the x-coordinate of the click, and the y-coordinate is about 5 times as high.

What can be the problem?

Hank

Upvotes: 4

Views: 3091

Answers (3)

user1693593
user1693593

Reputation:

You probably forgot to define a size for the canvas bitmap, and is only using CSS to set the size. Remember that canvas size must set implicit as CSS does not affect its bitmap size.

<canvas id="myCanvas" width=500 height=500></canvas>

If not your bitmap which defaults to 300x150 will be stretched to whatever you set with CSS which means your coordinates will be scaled as well.

CSS should be skipped for this but if you absolutely want to use it set width and height in CSS to the same size as defined for your canvas element.

The mouse position you get will be relative to the window so you need to subtract the canvas position to make it relative to canvas element. You probably have this working already and iHank's example should work, although I would not obtain the context each time:

var canvas = document.getElementById('myCanvas'),
    ctx = canvas.getContext('2d');

canvas.addEventListener('click', mouseClick, false);

ctx.strokeRect(0, 0, canvas.width, canvas.height);

function mouseClick(e) {

    var rect = canvas.getBoundingClientRect(),
        x = e.clientX - rect.left,
        y = e.clientY - rect.top;
 
    // draw image here, for demo - drawn from corner not center:
    ctx.fillRect(x, y, 5, 5);      
}
Canvas: <canvas id="myCanvas" width=500 height=180></canvas>

Upvotes: 7

Brendan
Brendan

Reputation: 1459

Try:

    function click( event ) {

        var ctxt;
        var myX =  event.clientX;
        var myY =  event.clientY;

    offsetXY = canvas.getBoundingClientRect();

        myX-=offsetXY.top;
        myY-=offsetXY.left;

        ctxt = canvas.getContext("2d");

        ctxt.drawImage(myImage, myX, myY);

        alert(myX + " " + myY);
    }

"The returned value is a TextRectangle object, which contains read-only left, top, right and bottom properties describing the border-box in pixels. top and left are relative to the top-left of the viewport." https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect

Hope that's what you needed.

EDIT: offsetXY.top and offsetXY.left. Those properties of the object are not capital.

Upvotes: 0

iHank
iHank

Reputation: 536

Seems like I missed that the default size of a canvas was (300, 150). If I change the width and height of the canvas-object to the sizes specified in the cs-file, it works!

Upvotes: 1

Related Questions