【问题标题】:Canvas signature on scroll changes mouse draw location滚动上的画布签名更改鼠标绘制位置
【发布时间】:2014-04-21 21:28:18
【问题描述】:

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

代码:

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>

【问题讨论】:

    标签: javascript jquery html canvas


    【解决方案1】:

    event.clientX/Y 相对于视口的左上角。所以不考虑滚动。 event.pageX/Y 相对于文档。因此,事件发生在屏幕上的位置,包括滚动。您可以将所有对clientX 的引用更改为pageX 并将clientY 更改为pageY,它应该可以工作。

    Explanation of each screen/page/client XY.

    【讨论】:

      【解决方案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);
      }
      

      【讨论】:

        【解决方案3】:

        改变这两行

        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 stricts 工作,因为我们似乎遗漏了一些代码。

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            【解决方案5】:

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

            Handling Multi-touch and Mouse Input in All Browsers

            本文将为您正确捕捉鼠标输入打下良好的基础。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-01-20
              • 1970-01-01
              • 1970-01-01
              • 2017-10-06
              • 2020-08-09
              • 2014-08-18
              • 1970-01-01
              相关资源
              最近更新 更多