我正在使用HTML5 canvas元素创建一个简单的绘图应用程序。程序逻辑工作正常,一切都很好,除了一件事。
当我绘制第一行时,鼠标坐标和线条完美匹配。但是,在每个后续行之后,所绘制的线的坐标约为0.5~1px。这些差异会累积,并且在绘制了大约十个单独的线后,效果很容易看出。这种情况发生在所有浏览器中。
有关实例,请检查this fiddle。我尽可能地剥夺了一切。显然真正的应用程序要复杂得多,但即使在这个简化版本中,问题仍然存在,这让我觉得我错过了一些非常明显的东西。
我突然意识到,我可能会以某种方式对坐标进行四舍五入,这是我能想到的唯一能够解释这种逐渐漂移的问题。我使用专有函数来获取偏移值,所以我尝试使用jQuery(因为过去从未给我带来任何问题),但没有任何改变。
请帮我弄清楚为什么会这样!
<小时/> 显然我现在需要发布代码才能链接到jsfiddle。我不知道代码的哪一部分可能出错了,所以我提前为发布所有内容并创建一个文本墙道歉。
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;
}
}
我想如果你只看实际的小提琴就会更有意义......
为了记录,我搜索了很长一段时间,看看是否有其他人有这个问题,但要么不是那么常见,要么我找不到正确的单词组合。鼠标坐标存在无数问题,但它们似乎都与我遇到的问题不同。
答案 0 :(得分:1)
您在drawStart函数中反复翻译,并且这些翻译正在累积:
ctx.translate(0.5,0.5)
您可以使用translate( - 。5, - 。5)反转翻译或将您的绘图代码包装在ctx.save()/ ctx.restore()中。
您可能还想将您的ctx = document ...移到drawStart“循环”之外以获得更好的性能。
//Get canvas context outside drawStart
ctx = document.getElementById('canvas').getContext("2d");