HTML 5响应式画布中的鼠标位置

时间:2015-02-20 12:25:00

标签: javascript html5 canvas responsive-design

我已经搜索了其他问题但没有一个适合我的情况。

我有一个canvas元素:

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

我正在使用此功能获得该职位:

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);
};

问题是画布需要响应,所以我添加了以下css规则:

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

当调整大小发生时(当画布尺寸在定义上缩小或在定义上放大时:1053x1000),函数会在正确的鼠标位置和返回的位置之间显示间隙。

我也试过用这种方法获得这个位置:

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

但是我得到了更糟糕的结果。

有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:5)

鼠标坐标永远不会缩放。

因此,您必须缩放它们的鼠标坐标以反映缩放的画布。

这是使画布响应并获得缩放鼠标坐标的一种方法:

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