简体   繁体   English

HTML5画布和鼠标事件问题

[英]HTML5 Canvas and mouse events issue

I'm trying to have a HTML5 page that includes a customer signature box. 我正在尝试使用包含客户签名框的HTML5页面。 This would be used on tablets for the most part. 这在大多数情况下将用于平板电脑。 This is done with a Canvas element, and JavaScript events on the mouse. 这是通过Canvas元素和鼠标上的JavaScript事件完成的。

Issue 1: The Y portion works perfectly, but the X portion will ONLY work if I set my canvas with to 300. If the width is 500, then the X portion is correct at x-coord 0. When the user draws to x-coord 300, the line on the screen is now at the 500px mark on the canvas. 问题1:Y部分工作正常,但是如果我将画布设置为300,X部分将仅起作用。如果宽度为500,则X部分在x-coord 0处正确。当用户绘制到x-时coord 300,屏幕上的线条现在在画布上的500px标记处。 NOWHERE in my code do I set anything to 300px, so I just don't get what's up. 在我的代码中,我设置任何东西到300px,所以我只是没有得到什么。

Issue 2: I have code to stop scrolling on tablets and allow the user to sign in the canvas (see "prevent" var in JavaScript). 问题2:我有代码停止在平板电脑上滚动并允许用户登录画布(请参阅“阻止”JavaScript中的var)。 That does not work at all. 这根本不起作用。

HTML: HTML:

<div id="canvasDiv">
   <canvas id="canvasSignature"></canvas>
</div>

CSS: (Makes the width 100% up to 500px, and always 150px high) CSS :(使宽度100%达到500px,总是高150px)

#canvasDiv
{
   float: left;
   width: 100%;
   height: 150px;
   max-width: 500px;
}

#canvasSignature
{
   width: 100%;
   height: 100%;
   background-color: #F0F0F0;
   border: 1px solid Black;
   cursor: crosshair;
}

JavaScript: JavaScript的:

<script type="text/javascript">
   $(document).ready(function () {
      initialize();
   });

   var prevent = false;

   // works out the X, Y position of the click INSIDE the canvas from the X, Y position on the page
   function getPosition(mouseEvent, element) {
      var x, y;
      if (mouseEvent.pageX != undefined && mouseEvent.pageY != undefined) {
         x = mouseEvent.pageX;
         y = mouseEvent.pageY;
      } else {
         x = mouseEvent.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
         y = mouseEvent.clientY + document.body.scrollTop + document.documentElement.scrollTop;
      }

      x = x - element.offsetLeft;
      return { X: x, Y: y - element.offsetTop };
   }

   function initialize() {
      // get references to the canvas element as well as the 2D drawing context
      var element = document.getElementById("canvasSignature");
      var context = element.getContext("2d");

      // start drawing when the mousedown event fires, and attach handlers to 
      // draw a line to wherever the mouse moves to
      $("#canvasSignature").mousedown(function (mouseEvent) {
         var position = getPosition(mouseEvent, element);

         context.moveTo(position.X, position.Y);
         context.beginPath();
         prevent = true;

         // attach event handlers
         $(this).mousemove(function (mouseEvent) {
            drawLine(mouseEvent, element, context);
         }).mouseup(function (mouseEvent) {
            finishDrawing(mouseEvent, element, context);
         }).mouseout(function (mouseEvent) {
            finishDrawing(mouseEvent, element, context);
         });
      });

      document.addEventListener('touchmove', function (event) {
         if (prevent) {
            event.preventDefault();
         }

         return event;
      }, false);
   }

   // draws a line to the x and y coordinates of the mouse event inside
   // the specified element using the specified context
   function drawLine(mouseEvent, element, context) {

      var position = getPosition(mouseEvent, element);

      context.lineTo(position.X, position.Y);
      context.stroke();
   }

   // draws a line from the last coordiantes in the path to the finishing
   // coordinates and unbind any event handlers which need to be preceded
   // by the mouse down event
   function finishDrawing(mouseEvent, element, context) {
      // draw the line to the finishing coordinates
      drawLine(mouseEvent, element, context);

      context.closePath();

      // unbind any events which could draw
      $(element).unbind("mousemove")
                .unbind("mouseup")
                .unbind("mouseout");
      prevent = false;
   }
</script>
#canvasSignature
{
   width: 100%;
   height: 100%;
   background-color: #F0F0F0;
   border: 1px solid Black;
   cursor: crosshair;
}

This is no good! 这不好! As a rule of thumb you never want to change the CSS width/height of a canvas. 根据经验,您永远不想更改画布的CSS宽度/高度。

You are literally stretching a canvas sized 300x150 to skew across the entire screen. 你实际上正在拉伸一个尺寸为300x150的画布,以在整个屏幕上倾斜。 This is probably the source of 99% of your mouse problems. 这可能是99%的鼠标问题的根源。

The reason is seems fine in the y-direction is purely coincidence: The canvas is by default 300x150 and you have a div that is 150 high, so there is no skewing by the CSS. 原因似乎在y方向上很好是纯粹的巧合:画布默认为300x150,你有一个150高的div,所以CSS没有偏差。 But if you wanted the div to be 200 high you'd see the problem there too! 但如果你想让div高达200,你也会看到问题!

You need to set the Canvas height and width as attributes and not as CSS properties: 您需要将Canvas高度和宽度设置为属性,而不是 CSS属性:

<canvas id="canvasSignature" width="500" height="150"></canvas>

Or else in JavaScript: 或者在JavaScript中:

var can = document.getElementById('canvasSignature');
can.width = 500;
can.height = 150;

It looks like you want to have the canvas width change dynamically. 看起来您希望动态更改画布宽度。 This is OK, but you have to do one of a few things. 这没关系,但你必须做一些事情。 One would be to use the window's onresize event, and set the canvas width equal to the div's clientWidth every time this happens (if the clientWidth has changed of course). 一种方法是使用窗口的onresize事件,并在每次发生这种情况时将画布宽度设置为等于div的clientWidth(如果clientWidth当然已经改变)。 The other would be to do a simple general timer to check for the same thing every half-second or so. 另一个是做一个简单的通用计时器来检查每半秒左右的同一件事。


Note that I did not check the validity of your getPosition function. 请注意,我没有检查getPosition函数的有效性。 There might be other errors there that may be a separate issue, but its probably OK. 可能存在其他错误可能是一个单独的问题,但它可能没问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM