使用画布绘图不跟随光标

问题描述:

我使用HTML5画布创建绘图应用程序。它的作品接受一件事。绘图发生在光标处向下/向右约50px。以下是我的代码,是否可以说明为什么会发生这种情况?使用画布绘图不跟随光标

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; 
}); 

我看到的一些项目。首先,针对您的核心问题,您只查看pageX和pageY,但您并未考虑画布的偏移量。因此,如果画布在页面上向下放置50 px,则会在错误的位置绘制。

此外,您不会希望在mousemove中使用moveTo和lineTo,因为这不是有效的语法。 。你基本上是说“画从点线(X,Y)至(X,Y),这里是你的代码更新一下,你可以在这里找到的jsfiddle它: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; 
    }); 
}); 
+0

感谢您的答案,就像一个魅力! – holyredbeard 2011-12-21 19:21:41

要获得确切的鼠标位置,您将需要一些计算。我不知道是否有任何其他方式,但这通常是使用

function getMousePoint(ex, ey){ 

    var px = 0, py = 0; 
    var el = document.getElementById('paint'); 
    while (el) { 
     px += el.offsetLeft; 
     py += el.offsetTop; 
     el = el.offsetParent; 
    } 

    return {x: ex-px ,y: ey-py}; 
} 

使用此功能用于获取点绘制

var mp = getMousePoint(e.pageX, e.pageY); 
    ctx.moveTo(mp.x, mp.y); 
    ctx.lineTo(mp.x, mp.y); 

这应该可以解决的问题之一。

+0

您是否在所有浏览器中测试过该功能?我问,因为调用** moveTo **和** lineTo **相继的x,y点在某些浏览器中不起作用。如果您在mousedown事件触发时调用** moveTo **,并且鼠标移动时只有** lineTo **,那将会更好。 – Diode 2011-12-21 19:03:20

+0

感谢您的回答!你对浏览器兼容性的缺乏是正确的,它适用于Firefox,但不适用于Chrome。我已经实现了你的功能以及你所建议的改变,但是现在当我尝试绘制时没有任何反应。如果你想,并有时间,新的代码在这里(也许我做错了什么):http://jsfiddle.net/bXC39/ – holyredbeard 2011-12-21 19:16:37

你可以通过分别从X和Y坐标中减去画布的offsetLeftoffsetTop获得精确的鼠标坐标。另一个注意事项是,想象一下,如果在ms paint或photoshop中,只通过移动鼠标来绘制,无论是否与你有鼠标按钮,它会画,反正,你可以从鼠标事件中拉出相关数据,并在一个时间间隔内检查它们

幸运的是,这种东西很简单,只要像jQueryprototype这样的库不是必要的,并且它可以在“原始”JavaScript中完成。

这是我在这重击,例如:

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); 

你可以看到它在行动here。点击并拖动以绘制。


我希望这是有帮助的。

+0

增加'fps'变量以获得更准确,锯齿较少的线条。 – 2013-01-19 18:44:55