滚动上的画布签名会更改鼠标绘制位置

时间:2014-04-21 21:28:18

标签: javascript jquery html5 canvas

我正在尝试使用画布,以便用鼠标可以写出他们的签名。一切正常,直到我拉伸或滚动屏幕,然后它将线条绘制在远离鼠标的不同位置。

守则:

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>

5 个答案:

答案 0 :(得分:2)

看起来你需要一种更可靠的方法来获取页面回流时的相对坐标。

@RyanArtecona编写了以下函数以回应this question about mouse coordinates relative to a canvas

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

答案 1 :(得分:1)

event.clientX/Y相对于视口的左上角。因此不考虑滚动。 event.pageX/Y与文档有关。所以这是事件发生的屏幕上的位置,包括滚动。您可以将对clientX的所有引用更改为pageX,将clientY更改为pageY,这样就可以了。

Explanation of each screen/page/client XY.

答案 2 :(得分:1)

更改这两行

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工作,因为我们似乎缺少一些代码。

答案 3 :(得分:0)

将屏幕的滚动偏移添加到mouseX和mouseY。使用jQuery,它看起来像这样

mouseX = event.clientX - can.offsetLeft - mleft + $(window).scrollLeft;
mouseY = event.clientY - can.offsetTop - mtop + $(window).scrollTop;

答案 4 :(得分:0)

这不是一个简单的答案。解决这个问题的最好方法是从良好的基础开始,然后根据您的情况进行渐进式更改。我在这个主题上看到的最好的文章来自Internet Explorer团队:

Handling Multi-touch and Mouse Input in All Browsers

本文将为您正确捕获鼠标输入提供良好的基础。