Reputation: 1569
I am creating a simple drawing app using the HTML5 canvas element. The program logic works fine, and everything runs great, except for one thing.
When I draw the first line, the mouse coordinates and the line match perfectly. However, after each subsequent line, the coordinates of the line being drawn are about 0.5~1px off. These discrepancies accumulate, and the effect is readily visible after drawing about ten separate lines. This occurs in all browsers.
For a live example, check this fiddle. I have stripped down everything as much as I could. Obviously the real app is a lot more complex, but even in this simplified version the problem persists, which leads me to think I'm missing something incredibly obvious.
It occurred to me that I might be somehow rounding up the coordinates, which is about the only thing I can think of that could account for such a gradual drift. I was using a proprietary function for getting the offset values, so I tried using jQuery (since that has never given me problems in the past) but nothing changed.
Please help me figure out why this is happening!
var offsetX = 0, offsetY = 0;
var currentMouseCoords = {
x : 0,
y : 0
};
var drawPing = null;
var ctx = null;
$('#cover').mousedown(function (event) {
event.preventDefault();
var f = $(this).offset();
offsetX = f.left;
offsetY = f.top;
currentMouseCoords.x = event.pageX - offsetX;
currentMouseCoords.y = event.pageY - offsetY;
drawStart();
if (!drawPing) {
drawPing = setInterval(draw, 10);
}
})
.mousemove(function (event) {
currentMouseCoords.x = event.pageX - offsetX;
currentMouseCoords.y = event.pageY - offsetY;
})
.mouseout(function (event) {
//When mouse leaves canvas, quit drawing
drawEnd();
})
.mouseup(function (event) {
//When mouse leaves canvas, quit drawing
drawEnd();
})
/* Functions that perform the actual drawing */
function drawStart () {
//Get canvas context
ctx = document.getElementById('canvas').getContext("2d");
ctx.translate(0.5,0.5);
//Set styles
ctx.strokeStyle = '#333333';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 1;
//Begin path
ctx.beginPath();
ctx.moveTo(
currentMouseCoords.x,
currentMouseCoords.y
);
}
function draw () {
ctx.lineTo(
currentMouseCoords.x,
currentMouseCoords.y
);
ctx.stroke();
}
function drawEnd () {
clearInterval(drawPing);
drawPing = null;
if (ctx) {
ctx.closePath();
ctx = null;
}
}
I imagine it'll make a lot more sense if you just look at the actual fiddle....
For the record, I googled for quite a while to see if anyone else had this issue, but either it's not that common or I can't find the right combination of words. There are myriad problems with mouse coordinates but none of them seem to be the same as the one I am experiencing.
Upvotes: 0
Views: 676
Reputation: 105015
You are repeatedly translating in your drawStart function and those translations are accumulating:
ctx.translate(0.5,0.5)
You can reverse the translate with translate(-.5,-.5) or wrap your drawing code in ctx.save()/ctx.restore().
You might also want to move your ctx=document... outside the drawStart "loop" for better performance.
//Get canvas context outside drawStart
ctx = document.getElementById('canvas').getContext("2d");
Upvotes: 1