如何知道mousedown事件是否发生在我们想要的画布上? [英] How to know whether the mousedown event is occured on where we want in canvas?

查看:172
本文介绍了如何知道mousedown事件是否发生在我们想要的画布上?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里我有一个代码示例,涉及在canvas上移动元素。
要在画布上将圆圈移动到其他位置,以下代码检查mousedown事件是否已在圆圈元素本身上触发,以便使用mousemove启动进一步拖动。但我不明白的逻辑,已经习惯了知道是否鼠标双击在正确的圆圈上来拖动它。

  //开始拖动
function DragStart(e){

//鼠标从mousedown事件e {x,y}
e = MousePos(e);
var dx,dy;

// initialCirclePosition是圆的中心(x,y)
dx = initialCiclePosition.x - e.x;
dy = initialCiclePosition.y - e.y;

if((dx * dx)+(dy * dy)< circleRadius * circleRadius){

//是,用户试图仅移动圆$ b ........
}
}

用户对任何元素(通过点击它)保持鼠标控制,mousedown事件发生,然后,当他试图拖动元素时,发生mousemove事件。但是,在让mousemove被触发之前,我们应该找到用户是否试图拖动正确的元素(在这里圆圈)。如果你看到上面的代码,if()语句中的逻辑用于检查。我无法理解这个逻辑,这就是问题所在。感谢。

解决方案

您的代码正在测试的解释。 b

这部分代码...

  * dx)+(dy * dy)  

...



(dx * dx)+(dx * dx)使用毕达哥拉斯定理在数学上测试鼠标是否在圆的圆周内。 dy * dy)测量圆心和鼠标之间的距离。它实际上测量中心点到鼠标的距离平方,但由于 Math.sqrt 是一个昂贵的操作,我们只需将鼠标距离平方 圆半径平方。我们得到相同的结果,但避免了昂贵的 Math.sqrt



以下是使用毕达哥拉斯定理确定距离的教程:



https://www.youtube.com/watch?v=We3LG8pK-LU






我们无法判断为什么测试正在进行,而且没有看到更多的代码。



但是,但是假定如果鼠标内,则表示您决定用户要拖动圆形。



相反,如果鼠标在外面,则表示您决定用户要执行点击。






替代点击与拖动测试



测试是不错的,因为你可以让使用或者点击圆圈或拖动圆。这个替代方法试图读取用户的意图。


  1. 在mousedown中,保存起始mouseX&

      var isDown,startX,startY,itIsADrag; 

    function handleMouseDown(e){

    //保存鼠标位置在mousedown
    startX = parseInt(e.clientX-offsetX);
    startY = parseInt(e.clientY-offsetY);

    //最初将itIsADrag标志设置为false
    itIsADrag = false;

    //将isDown标志设置为true
    isDown = true;

    ...任何其他代码...
    }


  2. 在mousemove中,测试鼠标移动量是否小于约5个像素(或10像素或其他任何值)。




    • 如果移动<5像素,则不会产生任何点击。

    • p>如果移动了> = 5像素,则开始拖动操作。

        function handleMouseMove(e){
      $ b b //返回如果鼠标没有按下
      if(!isDown){return;}

      //获取当前鼠标位置
      mouseX = parseInt(e.clientX- offsetX);
      mouseY = parseInt(e.clientY-offsetY);

      如果鼠标从mousedown开始移动的总像素少于5个,则不执行任何操作
      if(!itIsADrag&& Math.abs(mouseX-startX)+ Math.abs -startY)< 5){return;}

      //将拖动标记设置为true
      //如果我们知道我们拖动
      itIsADrag = true;

      //开始拖动操作
      ...执行拖动操作...
      }



  3. 在mouseup发生时,我们可以读取 itIsADrag 标记以确定用户是否点击或拖动。

     函数handleMouseUp(e){

    if (itIsADrag){
    console.log(You've been dragging);
    } else {
    console.log(你做了点击);
    }

    //清除isDown标志清除
    isDown = false;
    }


示例代码和演示:



< preValue(canvas); var ctx = canvas.getContext(2d); function reOffset(canvas ){var BB = canvas.getBoundingClientRect(); offsetX = BB.left; offsetY = BB.top; } var offsetX,offsetY; reOffset(); window.onscroll = function(e){reOffset(); } var isDown = false; var isDown,startX,startY,itIsADrag; $(#canvas)。mousedown(function(e){handleMouseDown(e);}); e){handleMouseMove(e);}); $(#canvas)mouseup(function(e){handleMouseUp(e);} (e);}); function handleMouseDown(e){//告诉浏览器我们正在处理这个事件e.preventDefault(); e.stopPropagation(); //保存鼠标位置在mousedown startX = parseInt(e.clientX-offsetX); startY = parseInt(e.clientY-offsetY); //最初将itIsADrag标志设置为false itIsADrag = false; //设置isDown标志为true isDown = true;} function handleMouseUp(e){//告诉浏览器我们正在处理这个事件e.preventDefault(); e.stopPropagation(); // report if this is a click or a drag if(itIsADrag){alert(You've been dragging); } else {alert(您做了点击); } //通过清除isDown标志清除isDown = false;} function handleMouseOut(e){//清除isDown标志isDown = false;} function handleMouseMove(e){//如果鼠标没有关闭,返回if(!isDown){return;} //告诉浏览器我们正在处理这个事件e.preventDefault(); e.stopPropagation(); //获取当前鼠标位置mouseX = parseInt(e.clientX-offsetX); mouseY = parseInt(e.clientY-offsetY); //如果鼠标从mousedown以来移动的总像素少于5,则不做任何操作if(!itIsADrag&& Math.abs(mouseX-startX)+ Math.abs(mouseY-startY)< 5){return;} / /将拖动标志设置为true //如果我们知道我们拖动itIsADrag = true;} 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>在画布中点击或拖动。 ; / h4>< canvas id =canvaswidth = 300 height = 300>< / canvas>  


Here I have a code sample related to moving an element on canvas. To move a circle to an other position on canvas, the below code is checking whether the mousedown event got triggered on the circle element itself or not so that further dragging can be initiated using mousemove. But I dont understand the logic that's been used to know whether or not the mouse is doubleclicked on the correct circle to drag it.

// start dragging
function DragStart(e) {

    //coordinates of mouse from mousedown event e{x,y}
    e = MousePos(e);
    var dx, dy;

    //initialCirclePosition is the centre (x,y) of the circle
    dx = initialCiclePosition.x - e.x;
    dy = initialCiclePosition.y - e.y;

    if ((dx * dx) + (dy * dy) < circleRadius * circleRadius)   { 

        //Yes, user is trying to move the circle only
        ........
    }
}

When user holds the mouse control on any element(by clicking on it), mousedown event occurs, Then, when he tries to drag the element, mousemove event occurs. But, before letting mousemove gets triggered, we should find whether or not the user is trying to drag the right element (circle here). If you see the code above, the logic in if() statement was used to check that. I am unable to understand that logic and that's the question is about. Thanks.

解决方案

An explanation of what your code is testing.

This part of your code...

((dx * dx) + (dy * dy) < circleRadius * circleRadius)

...uses the Pythagorean Theorem to mathematically test if the mouse is inside the circumference of a circle.

(dx * dx) + (dy * dy) measures the distance between the circle centerpoint and the mouse. It actually measures the centerpoint-to-mouse distance squared, but since Math.sqrt is an expensive operation, we just compare the mouse distance squared to the circle radius squared. We get the same result but avoid the expensive Math.sqrt.

Here's a tutorial on determining distances using the Pythagorean Theorem:

https://www.youtube.com/watch?v=We3LG8pK-LU


We can't tell why the test is being done without seeing more of your code.

But, but presumably if the mouse is inside the circle you are deciding that the user intends to drag the circle.

And conversely if the mouse is outside the circle you are deciding that the user intends to execute a click.


An alternative click vs drag test:

This alternative test is nice because you can let the use either click in the circle or drag the circle. This alternative tries to "read the intent" of the user.

  1. In mousedown, save the starting mouseX & mouseY position.

    var isDown,startX,startY,itIsADrag;
    
    function handleMouseDown(e){                
    
      // save the mouse position at mousedown
      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);
    
      // initially set the "itIsADrag" flag to false
      itIsADrag=false;
    
      // set the "isDown" flag to true
      isDown=true;
    
      ... any other code ...
    }
    

  2. In mousemove, test if the mouse has moved less than about 5 total pixels (or 10px or whatever).

    • If moved <5 pixels do nothing in anticipation of this being a click.
    • If moved >=5 pixels start a drag operation.

      function handleMouseMove(e){
      
          // return if the mouse is not down
          if(!isDown){return;}
      
          // get the current mouse position
          mouseX=parseInt(e.clientX-offsetX);
          mouseY=parseInt(e.clientY-offsetY);
      
          // do nothing if the mouse has moved less than 5 total pixels since mousedown
          if(!itIsADrag && Math.abs(mouseX-startX)+Math.abs(mouseY-startY)<5){return;}
      
          // Set the dragging flag to true
          // This flag prevents the Math.abs test above if we know we're dragging
          itIsADrag=true;
      
          // start a drag operation
          ... do drag stuff ...
      }
      

  3. By the time mouseup occurs, we can just read our itIsADrag flag to determine if the user clicked or dragged.

    function handleMouseUp(e){
    
      if(itIsADrag){
          console.log("You have been dragging");
      }else{
          console.log("You've did a click");
      }
    
      // clean up by clearing the isDown flag
      isDown=false;
    }
    

Example code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }

var isDown=false;
var isDown,startX,startY,itIsADrag;

$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});

function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // save the mouse position at mousedown
  startX=parseInt(e.clientX-offsetX);
  startY=parseInt(e.clientY-offsetY);

  // initially set the "itIsADrag" flag to false
  itIsADrag=false;

  // set the "isDown" flag to true
  isDown=true;
}

function handleMouseUp(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // report if this was a click or a drag
  if(itIsADrag){
    alert("You have been dragging");
  }else{
    alert("You've did a click");
  }

  // clean up by clearing the isDown flag
  isDown=false;
}

function handleMouseOut(e){
  // clean up by clearing the isDown flag
  isDown=false;
}

function handleMouseMove(e){
  // return if the mouse is not down
  if(!isDown){return;}

  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // get the current mouse position
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // do nothing if the mouse has moved less than 5 total pixels since mousedown
  if(!itIsADrag && Math.abs(mouseX-startX)+Math.abs(mouseY-startY)<5){return;}

  // Set the dragging flag to true
  // This flag prevents the Math.abs test above if we know we're dragging
  itIsADrag=true;
}

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>Click or drag in the canvas.</h4>
<canvas id="canvas" width=300 height=300></canvas>

这篇关于如何知道mousedown事件是否发生在我们想要的画布上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆