Mouse Position in HTML 5 Responsive Canvas

I looked for other questions, but none of them matched my case.

I have a canvas element:

<canvas id="linear-synoptic-map" width="1053px" height="1000px" ng-click="linearSynopticCtrl.canvasClicked($event)" ng-mousemove="linearSynopticCtrl.mouseMovedOverCanvas($event)"> </canvas> 

And I get the position using this function:

 linearSynopticCtrl.getPositionFromEvent = function (event) { var rect = linearSynopticCtrl.canvas.getBoundingClientRect(); var x = event.x - rect.left; var y = event.y - rect.top; return new Point(x,y); }; 

The problem is that the canvas must be responsive, so I added the following css rule:

 canvas#linear-synoptic-map { width: 100%; } 

When resizing occurs (when the canvas size is squeezed above the definition or enlarged by definition: 1053x1000), a space starts to appear between the correct mouse position and the function returned.

I also tried to get a position with this approach:

 linearSynopticCtrl.getPositionFromEvent = function (event) { var x = event.x - linearSynopticCtrl.canvas.offsetLeft; var y = event.y - linearSynopticCtrl.canvas.offsetTop; return new Point(x,y); }; 

But I get much worse results.

Does anyone know how to solve this problem?

+6
source share
1 answer

Mouse coordinates never scale.

Therefore, you must scale the mouse coordinates to display them in order to display a scaled canvas.

Here is one way to make your canvas sensitive and get scaled mouse coordinates:

 // handle responsively resizing the canvas var scale=1.00; var originalWindowWidth=window.innerWidth; var originalCanvasWidth=document.getElementById('canvas').width; function debounce(func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; var resizeCanvas = debounce(function() { scale=window.innerWidth/originalWindowWidth; $('#canvas').css('width',originalCanvasWidth*scale); }, 250); window.addEventListener('resize', resizeCanvas); // now, do normal app stuff var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); $("#canvas").mousemove(function(e){handleMouseMove(e);}); ctx.fillRect(50,50,100,100); ctx.fillText('Rect drawn at [50,50]',50,35); function handleMouseMove(e){ var rect = canvas.getBoundingClientRect(); var x = parseInt((event.x - rect.left)/scale); var y = parseInt((event.y - rect.top)/scale); $('#mouse').text(x+'/'+y); } 
 body{ background-color: ivory; } #canvas{border:1px solid red;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <h4>Mouse will report rect corner at<br>[50,50] even after resizing window</h4> <h4 id=mouse>mouse</h4> <canvas id="canvas" width=300 height=300></canvas> 
+5
source

Source: https://habr.com/ru/post/982787/


All Articles