鼠标光标与画布不匹配



我有问题:当我在画布中绘制一条线时,鼠标位置似乎与帆布位置不匹配,因此,每当我绘制时,我光标和绘图线。请帮助我解决这个问题,这是我的代码:

$(document).ready(function(){
        context = document.getElementById('canvasInAPerfectWorld').getContext("2d");

        $('#canvasInAPerfectWorld').mousedown(function(e){
          var mouseX = e.pageX - this.offsetLeft;
          var mouseY = e.pageY - this.offsetTop;
          paint = true;
          addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
          redraw();
        });
        $('#canvasInAPerfectWorld').mousemove(function(e){ 
          if(paint){
            addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
            redraw();
          }
        });

        $('#canvasInAPerfectWorld').mouseup(function(e){
          paint = false;
        });
        $('#canvasInAPerfectWorld').mouseleave(function(e){
          paint = false;
        });         
});

    var clickX = new Array();
    var clickY = new Array();
    var clickDrag = new Array();
    var paint;
    function addClick(x, y, dragging)
    {
      clickX.push(x);
      clickY.push(y);
      clickDrag.push(dragging);
    }   
    function clear_canvas(){
        //alert('masuk claear');
        context.clearRect(0,0,context.canvas.width,context.canvas.height);  
    }
    function redraw(){        
      context.strokeStyle = "#df4b26";
      context.lineJoin = "round";
      context.lineWidth = 5;
      for(var i=0; i < clickX.length; i++) {        
        context.beginPath();
        if(clickDrag[i] && i){
          context.moveTo(clickX[i-1], clickY[i-1]);
         }else{
           context.moveTo(clickX[i]-1, clickY[i]);
         }
         context.lineTo(clickX[i], clickY[i]);
         context.closePath();
         context.stroke();
      }
    } 

在您的鼠标事件处理程序中,this指的是窗口对象,而您的this.offsetLeft是未定义的。

您可以使用getBoundingClientRect获取画布元素的界限:

// get a reference to your canvas element at the start of your app
var canvas=document.getElementById('canvasInAPerfectWorld');
// example mousedown handler
// get the current canvas offsets using getBoundingClientRect
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;        
// calculate the current mouse position relative to the canvas
// using e.client and the offsets calculated above
var mouseX=parseInt(e.clientX-offsetX);
var mouseY=parseInt(e.clientY-offsetY);

如果您的画布不是相对于视口的重新定位,则可以在应用程序开始时获得一次偏移,因此无需每次在鼠标处理程序内重新计算它们。

您可以在Marke的答案中遵循解决方案(也可以找到在此处)。

,如果您的布局允许

,则可以执行以下操作
  • 将画布元素设置为位置相对
  • 使用layerXlayerY读取鼠标位置

这种方法给出了更简单的代码。

两种方法都会受填充和边界厚度的影响(如果使用的话,则需要减去它们)。如果您想要边框/填充,最好将画布包裹在Div中,然后将Div造型。

使用相对定位的画布

示例

var c = document.querySelector("canvas"),
    ctx = c.getContext("2d");
ctx.font = "bold 16px sans-serif";
c.onmousemove = function(e) {
  
  var x = e.layerX,
      y = e.layerY;
  ctx.clearRect(0, 0, 300, 20);
  ctx.fillText("x: " + x + ", y: " + y, 10, 16);
};
div {padding:20px}
canvas {background:#eee; position:relative}
<div><div><canvas></canvas></div></div>

使用getBoundingClientRect()

示例

var c = document.querySelector("canvas"),
    ctx = c.getContext("2d");
ctx.font = "bold 16px sans-serif";
c.onmousemove = function(e) {
  
  var rect = this.getBoundingClientRect(),
      x = e.clientX - rect.left,
      y = e.clientY - rect.top;
  ctx.clearRect(0, 0, 300, 20);
  ctx.fillText("x: " + x + ", y: " + y, 10, 16);
};
div {padding:20px}
canvas {background:#eee; position:relative}
<div><div><canvas></canvas></div></div>

最新更新