HTML5 Canvas and Mouse Events Issue

I am trying to create an HTML5 page that contains a customer subscription field. This will be used on tablets for the most part. This is done using the Canvas element and JavaScript mouse events.

Problem 1: the Y part works fine, but the X part will ONLY work if I set my canvas to 300. If the width is 500, then the X part is correct at x-coordinate 0. When the user draws x-coordinate 300, the line on the screen is now is at 500 pixels on the canvas. NOWHERE in my code i am setting anything to 300px so i just don't understand what.

Problem 2: I have some code to stop scrolling on tablets and allow the user to subscribe to the canvas (see "prevent" var in JavaScript). It doesn't work at all.

HTML:

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

      

CSS: (makes 100% wide to 500px and always 150px high)

#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:

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

      

+3


source to share


1 answer


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

      

It won't do! Generally, you never want to change the CSS width / height of the canvas.

You literally stretch a 300x150 canvas to warp the entire screen. This is probably the source of 99% of mouse problems.

It looks like you can see perfectly well in the y-direction that this is a pure coincidence: the canvas is by default 300x150 and you have a div that is 150 so the CSS is not distorted. But if you wanted the div to be 200, you would see a problem too!

You need to set the canvas height and width as attributes and not as CSS properties:

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

      



Or in JavaScript:

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

      

It sounds like you want to dynamically change the width of the canvas. This is fine, but you need to do one of several things. One could use the window event onresize

and set the canvas width to div's clientWidth each time this happens (assuming the client font has changed, of course). Another is to make a simple shared timer to check the same every half second or so.


Please note that I have not tested the correctness of your getPosition function. There may be other errors that could be a separate issue, but this is probably normal.

+2


source







All Articles