Signature on canvas with mouse scroll changes

I am trying to use a canvas so that with a mouse a person can write his signature. Everything works until I stretch or scroll the screen and then draw a line elsewhere from the mouse.

The code:

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 looks like this: <canvas id="signature" width="567" height="150"></canvas>

+7
javascript jquery html5 canvas
source share
5 answers

event.clientX/Y refers to the upper left corner of the viewport. Thus, the scroll is not counted. event.pageX/Y refers to the document. Thus, the screen displays that an event has occurred, including scrolling. You can change all references to clientX to pageX and clientY to pageY , and this should work.

Explanation of each XY screen / page / client.

0
source share

It seems you only need a more reliable method of obtaining relative coordinates when the page is full.

@RyanArtecona wrote the following function in response to this question about mouse coordinates relative to the 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; 

This is convenient because it adds a function for obtaining relative coordinates directly on the prototype of the HTMLCanvasElement function, which means that you can just pass the link to the canvas you want to use and get the coordinates relative to it.

Using this, you can rewrite the mousedown function (and you also want to do the rest, but just for example) as follows:

 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); } 
+2
source share

Change these two lines

 mouseX = event.clientX - can.offsetLeft - mleft; mouseY = event.clientY - can.offsetTop - mtop; 

to

 mouseX = event.offsetX || event.layerX; mouseY = event.offsetY || event.layerY; 

in both of your handlers. The browser can handle relative coordinates for you without doing any special math. offsetX/Y seems specific to Chrome / IE, and layerX/Y gets Firefox support.

Here is the jsfiddle . I made a couple of small changes to the declaration to make your use strict work, as we seem to be missing code.

+1
source share

Add a screen scroll offset to mouseX and mouseY. with jQuery it will look like

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

This is not an easy answer. The best way to understand this is to start with a good foundation and then make additional changes to your situation. The best article I've seen on this subject is the Internet Explorer team:

Handling Multi-Touch and Mouse Inputs in All Browsers

This article will provide you with an excellent foundation for the correct mouse input.

0
source share

All Articles