鼠标光标与画布不匹配

时间:2015-05-06 16:35:07

标签: javascript html5 canvas

我有疑问:当我在画布上画一条线时,看起来鼠标位置与画布位置不匹配,因此每当我画画时,我的光标和图形之间都有一定的距离line ..请帮我解决这个问题,这是我的代码:

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

2 个答案:

答案 0 :(得分:1)

在鼠标事件处理程序中,this引用窗口对象,this.offsetLeft未定义。

您可以使用getBoundingClientRect获取canvas元素的边界:

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

如果画布没有相对于视口重新定位,您可以在应用程序开始时获取一次偏移量,这样就不需要每次在鼠标处理程序内重新计算它们。

答案 1 :(得分:0)

您可以在markE的答案中找到解决方案(也可以找到 here )。

如果布局允许,您可以执行以下操作

  • 将画布元素设置为位置相对
  • 使用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>