Reputation: 21188
I'm creating a drawing application with HTML5 canvas. It works accept for one thing. The drawing happens like ~50px down/right from the cursor. Below is my code, is it possible to tell why this is happening?
var letsdraw = false;
var theCanvas = document.getElementById('paint');
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
$('#paint').mousemove(function(e) {
if (letsdraw === true){
ctx.strokeStyle = 'blue';
ctx.lineWidth = 100;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(e.pageX, e.pageY);
ctx.lineTo(e.pageX, e.pageY);
ctx.stroke();
}
});
$('#paint').mousedown(function(){
letsdraw = true;
});
$('#paint').mouseup(function(){
letsdraw = false;
});
Upvotes: 0
Views: 4190
Reputation: 8998
You can get accurate mouse coordinates by subtracting the canvas's offsetLeft
and offsetTop
from the X and Y coordinates, respectively. On another note, imagine if in ms paint or photoshop, you drew only by moving the mouse, and it didn't matter whether or not you had the mouse button down, it would draw anyway. Wouldn't that be annoying and unintuitive? Instead, you can pull the relevant data from the mouse events, and check them in an interval.
Luckily, this kind of stuff is simple enough to do that libraries like jQuery
and prototype
aren't really necessary, and it can be done in "raw" JavaScript.
Here's my whack at it, for example:
var mouse = [0,0], mouseDown = false, last = [0,0], fps = 24
ctx = canvas.getContext('2d');
getMouse = function(e){
var X,Y;
X = e.pageX || e.clientX || e.offsetX;
Y = e.pageY || e.clientY || e.offsetY;
X = X - canvas.offsetLeft;
Y = Y - canvas.offsetTop;
mouse = [X,Y];
}
canvas.onmousedown = function(e){
getMouse(e);
mouseDown = true;
last = mouse;
}
canvas.onmouseup = function(){
mouseDown = false;
}
canvas.onmousemove = getMouse;
setInterval(function(){
if(mouseDown){
ctx.beginPath();
ctx.moveTo(last[0],last[1]);
ctx.lineTo(mouse[0],mouse[1]);
ctx.stroke();
ctx.closePath();
last = mouse;
}
},1000/fps);
You can see it in action here. Click and drag to draw.
Upvotes: 0
Reputation: 3247
A couple of items I see. First, for your core problem, you're only looking at pageX and pageY, but you're not taking in to account the offset of the canvas. So, if the canvas is 50 px down on the page, you're going to be drawing in the wrong location.
Also, you won't want to use moveTo and lineTo both in the mousemove, as this isn't valid syntax. You're basically saying "draw a line from point (x,y) to (x,y). Here's an updated bit of code for you, you can find the jsfiddle for it here: http://jsfiddle.net/fordlover49/wPx4d/
$(function() {
var letsdraw = false;
var theCanvas = document.getElementById('paint');
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
var canvasOffset = $('#paint').offset();
$('#paint').mousemove(function(e) {
if (letsdraw === true) {
ctx.lineTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
ctx.stroke();
}
});
$('#paint').mousedown(function() {
// setup all of the properties for your line on mousedown, not mousemove
letsdraw = true;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 10;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
});
$(window).mouseup(function() {
// bind to the window mouse up, that way if you mouse up and you're not over
// the canvas you'll still get the release of the drawing.
letsdraw = false;
});
});
Upvotes: 4