How to get Mouse Position on Transformed HTML5 Canvas

前端 未结 1 814
悲哀的现实
悲哀的现实 2021-01-24 19:47

I am trying to get the mouse position on a transformed canvas. Here is my resize method:

window.addEventListener(\'resize\', resize);
function resize() {
    scr         


        
相关标签:
1条回答
  • 2021-01-24 20:36

    I don't know exactly what you have tried so far, but for a basic mouse coordinate to transformed canvas (non skewed), you'll have to do

    mouseX = (evt.clientX - canvas.offsetLeft - translateX) / scaleX;
    mouseY = (evt.clientY - canvas.offsetTop - translateY) / scaleY;
    

    But canvas.offsetXXX doesn't take scroll amount into account, so this demo uses getBoundingRect instead.

    var ctx = canvas.getContext('2d');
    
    window.addEventListener('resize', resize);
    // you probably have these somewhere
    var maxScreenWidth = 1800,
      maxScreenHeight = 1200,
      scaleFillNative, screenWidth, screenHeight;
    
    // you need to set available to your mouse move listener
    var translateX, translateY;
    
    function resize() {
      screenWidth = window.innerWidth;
      screenHeight = window.innerHeight;
      // here you set scaleX and scaleY to the same variable
      scaleFillNative = Math.max(screenWidth / maxScreenWidth, screenHeight / maxScreenHeight);
      canvas.width = screenWidth;
      canvas.height = screenHeight;
      // store these values
      translateX = Math.floor((screenWidth - (maxScreenWidth * scaleFillNative)) / 2);
      translateY = Math.floor((screenHeight - (maxScreenHeight * scaleFillNative)) / 2);
    
      ctx.setTransform(scaleFillNative, 0, 0, scaleFillNative, translateX, translateY);
    }
    
    window.addEventListener('mousemove', mousemoveHandler, false);
    
    function mousemoveHandler(e) {
      // Note : I don't think there is any event default on mousemove, no need to prevent it
    
      // normalize our event's coordinates to the canvas current transform
      // here we use .getBoundingRect() instead of .offsetXXX 
      //   because we also need to take scroll into account,
      //   in production, store it on debounced(resize + scroll) events.
      var rect = canvas.getBoundingClientRect();
      var mouseX = (e.clientX - rect.left - translateX) / scaleFillNative,
        mouseY = (e.clientY - rect.top - translateY) / scaleFillNative;
    
      ctx.fillRect(mouseX - 5, mouseY - 5, 10, 10);
    }
    
    // an initial call
    resize();
    <canvas id="canvas"></canvas>

    0 讨论(0)
提交回复
热议问题