滚动上的画布签名更改鼠标绘制位置
我正在尝试使用画布,以便用鼠标可以写出他们的签名。 一切工作,直到我伸展或滚动屏幕,然后它在与鼠标不同的地方绘制线条。
代码:
function onMouseUp(event) {
'use strict';
mousePressed = false;
}
function onMouseMove(event) {
'use strict';
if (mousePressed) {
event.preventDefault();
mouseX = event.clientX - can.offsetLeft - mleft;
mouseY = event.clientY - can.offsetTop - mtop;
ctx.lineTo(mouseX, mouseY);
ctx.stroke();
}
}
function onMouseDown(event) {
'use strict';
mousePressed = true;
mouseX = event.clientX - can.offsetLeft - mleft;
mouseY = event.clientY - can.offsetTop - mtop;
ctx.beginPath();
ctx.moveTo(mouseX, mouseY);
}
can.addEventListener('mousemove', onMouseMove, false);
can.addEventListener('mousedown', onMouseDown, false);
can.addEventListener('mouseup', onMouseUp, false);
HTML看起来像: <canvas id="signature" width="567" height="150"></canvas>
event.clientX/Y
相对于视口的左上角。 所以没有考虑到滚动。 event.pageX/Y
是相对于文档。 所以事件发生在屏幕上的位置包括滚动。 您可以将所有对clientX
引用clientX
为pageX
和clientY
,并将其clientY
为pageY
并且它应该可以工作。
每个屏幕/页面/客户端XY的说明。
看起来你只需要一个更可靠的方法来获得页面重排时的相对坐标。
@RyanArtecona在回答关于相对于画布的鼠标坐标的这个问题时写了下面的函数:
function relMouseCoords(event){
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do{
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
}
while(currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
return {x:canvasX, y:canvasY}
}
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;
这很方便,因为它增加了一个函数来获取相对坐标到HTMLCanvasElement
函数的原型上,这意味着您可以传递对要使用的画布的引用,并获取相对于其的坐标。
使用这个你可以重写你的mousedown函数(并且你也会想要做其他的,但只是举个例子),如下所示:
function onMouseDown(event) {
'use strict';
mousePressed = true;
// get a reference to the 'signature' canvas
var canvas = document.getElementById('signature');
// this returns an object with 'x' and 'y' properties
var mouse = canvas.relMouseCoords(event)
ctx.beginPath();
// use the coordinates you got
ctx.moveTo(mouse.x, mouse.y);
}
改变这两条线
mouseX = event.clientX - can.offsetLeft - mleft;
mouseY = event.clientY - can.offsetTop - mtop;
至
mouseX = event.offsetX || event.layerX;
mouseY = event.offsetY || event.layerY;
在你的处理程序中。 浏览器可以处理相对坐标,而无需执行任何特殊的数学运算。 offsetX/Y
似乎是Chrome / IE特有的, layerX/Y
可以让你支持Firefox。
这是一个jsfiddle。 我做了一些轻微的声明更改,以便让您的use strict
起作用,因为我们似乎缺少一些代码。