owl
owl

Reputation: 4461

Canvas element with offset

Draws nothing if the item is biased.

jsfiddle: http://jsfiddle.net/9UyxF/

JavaScript:

var ctx = document.getElementById("drawing").getContext("2d");

$("#drawing").mousemove(function(e) {
    ctx.lineTo(e.clientX, e.clientY);
    ctx.stroke();
});

var ctx_without_offset = document.getElementById("without_offset").getContext("2d");

$("#without_offset").mousemove(function(e) {
    ctx_without_offset.lineTo(e.clientX, e.clientY);
    ctx_without_offset.stroke();
});

CSS:

#drawing {
    border: 1px solid #000;
    position: absolute;
    top: 50px;
    right: 0;
}
#without_offset {
    border: 1px solid #000;
}

How to fix it? Thanks in advance.

Upvotes: 4

Views: 8476

Answers (5)

Kiril
Kiril

Reputation: 2963

You have to "normalize" pointer coords like:

var ctx = document.getElementById("drawing").getContext("2d"),
    ctx_rect= ctx.canvas.getBoundingClientRect();

$("#drawing").mousemove(function(e) {
    ctx.lineTo(e.clientX - ctx_rect.left, e.clientY - ctx_rect.top);
    ctx.stroke();
});

In that case you'll have pointer coords relative to the canvas. Demo: http://jsfiddle.net/BuDpz/. Also note that calculating offsets on every mousemove may affect the performance. That's why it's better to calculate it once, save values and update them on demand later.

Upvotes: 1

Marco Di Scala
Marco Di Scala

Reputation: 484

Use pageX and pageY that will handle scroll offset for you, then subtract the offset position of the canvas and that's it. Try it: http://jsfiddle.net/9UyxF/14/

var ctx = document.getElementById("drawing").getContext("2d");

$("#drawing").mousemove(function(e) {
    var pos = $(this).offset();
    ctx.lineTo(e.pageX - pos.left, e.pageY - pos.top);
    ctx.stroke();
});

var ctx_without_offset = document.getElementById("without_offset").getContext("2d");

$("#without_offset").mousemove(function(e) {
    var pos = $(this).offset();
    ctx_without_offset.lineTo(e.pageX - pos.left, e.pageY - pos.top);
    ctx_with

Upvotes: 1

sabof
sabof

Reputation: 8192

The coordinates on the canvas, and cooridnates of clientX and clientY have different origins. This version realigns them:

function makeDrawFunction(elem) {
    var context = elem.getContext('2d');
    return function(e) {
        var offset = $(elem).offset();
        context.lineTo(e.clientX - offset.left, e.clientY - offset.top);
        context.stroke();
    }
}


$("#drawing").mousemove(makeDrawFunction(
  document.getElementById("drawing")
));

$("#without_offset").mousemove(makeDrawFunction(
  document.getElementById("without_offset")
));

live demo

Upvotes: 5

Michael Kunst
Michael Kunst

Reputation: 2988

You have to look for the offset of the element, too. You can find an updated fiddle here. As I'm in a rush it's quick and dirty, but it works.

$("#without_offset").mousemove(function(e) {
    var left = e.clientX - $("#without_offset").offset().left;
    var top = e.clientY - $("#without_offset").offset().top;
    ctx_without_offset.lineTo(left, top);
    ctx_without_offset.stroke();
});

Upvotes: 0

Sebastien C.
Sebastien C.

Reputation: 4833

Your problem comes from how you get the mouse position.

clientX and clientY returns the mouse position relative to the page.

I don't know if there is something with jQuery to get the right coordinates, but you can try this :

.lineTo(e.clientX - this.offsetLeft, e.clientY - this.offsetTop);

Upvotes: 3

Related Questions