检测鼠标是否在画布内的对象上 [英] Detect if Mouse is over an object inside canvas

查看:111
本文介绍了检测鼠标是否在画布内的对象上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在canvas元素中创建了一条线。我正在寻找最简单的方法来检测鼠标的位置是否在画布内部的行内。

I have created a line inside a canvas element. I am looking for the easiest way to detect if the position of the mouse is inside the line, which is inside the canvas.

我用这个函数来查看画布内鼠标的位置,但我对如何继续操作感到很困惑。

I have used this function to see the position of the mouse inside the canvas, but I am very confused on how I should proceed.

function getMousePos(c, evt) {
            var rect = c.getBoundingClientRect();
            return {
                x: evt.clientX - rect.left,
                y: evt.clientY - rect.top
            };
        }

我也看了这个主题Fabricjs检测鼠标在对象路径上,但它检测鼠标是否在画布内,而不是在对象内。

I have also looked at this topic Fabricjs detect mouse over object path , but it detects if the mouse is inside the canvas, not inside the object.

我创建的行是较小行的一部分,相互连接。

The line that I create is a part of smaller lines, connected to each other.

 for (var i = 0; i < 140 ; i++) {

                ctx.beginPath();

                ctx.moveTo(x[i],y[i]);
                ctx.quadraticCurveTo(x[i],50,x[i+1],y[i+1]);
                ctx.lineWidth = 40;

                ctx.strokeStyle = 'white';
                ctx.lineCap = 'round';
                ctx.stroke();

            }

其中x [i]和y [i]是具有我想要的坐标的数组。

where x[i] and y[i] are the arrays with the coordinates that I want.

我希望我的问题很清楚,虽然我对javascript不是很熟悉。

I hope my question is clear, although I am not very familiar with javascript.

谢谢
Dimitra

Thanks Dimitra

推荐答案

演示:< a href =http://jsfiddle.net/m1erickson/Cw4ZN/ =noreferrer> http://jsfiddle.net/m1erickson/Cw4ZN/

您需要这些概念来检查鼠标是否在一行内:

You need these concepts to check if the mouse is inside a line:


  • 定义起始&行的结束点

  • Define the starting & ending points of a line

监听鼠标事件

在mousemove上,检查是否鼠标位于行的指定距离内

On mousemove, check if the mouse is within a specified distance of the line

这是带有注释的示例代码供您学习。

Here's annotated example code for you to learn from.

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    // canvas related variables
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    // dom element to indicate if mouse is inside/outside line
    var $hit=$("#hit");

    // determine how close the mouse must be to the line
    // for the mouse to be inside the line
    var tolerance=5;

    // define the starting & ending points of the line
    var line={x0:50,y0:50,x1:100,y1:100};

    // set the fillstyle of the canvas
    ctx.fillStyle="red";

    // draw the line for the first time
    draw(line);

    // function to draw the line
    // and optionally draw a dot when the mouse is inside
    function draw(line,mouseX,mouseY,lineX,lineY){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        ctx.beginPath();
        ctx.moveTo(line.x0,line.y0);
        ctx.lineTo(line.x1,line.y1);
        ctx.stroke();
        if(mouseX && lineX){
            ctx.beginPath();
            ctx.arc(lineX,lineY,tolerance,0,Math.PI*2);
            ctx.closePath();
            ctx.fill();
        }
    }

    // calculate the point on the line that's 
    // nearest to the mouse position
    function linepointNearestMouse(line,x,y) {
        //
        lerp=function(a,b,x){ return(a+x*(b-a)); };
        var dx=line.x1-line.x0;
        var dy=line.y1-line.y0;
        var t=((x-line.x0)*dx+(y-line.y0)*dy)/(dx*dx+dy*dy);
        var lineX=lerp(line.x0, line.x1, t);
        var lineY=lerp(line.y0, line.y1, t);
        return({x:lineX,y:lineY});
    };

    // handle mousemove events
    // calculate how close the mouse is to the line
    // if that distance is less than tolerance then
    // display a dot on the line
    function handleMousemove(e){
      e.preventDefault();
      e.stopPropagation();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      if(mouseX<line.x0 || mouseX>line.x1){
          $hit.text("Outside");
          draw(line);
          return;          
      }
      var linepoint=linepointNearestMouse(line,mouseX,mouseY);
      var dx=mouseX-linepoint.x;
      var dy=mouseY-linepoint.y;
      var distance=Math.abs(Math.sqrt(dx*dx+dy*dy));
      if(distance<tolerance){
          $hit.text("Inside the line");
          draw(line,mouseX,mouseY,linepoint.x,linepoint.y);
      }else{
          $hit.text("Outside");
          draw(line);
      }
    }

    // tell the browser to call handleMousedown
    // whenever the mouse moves
    $("#canvas").mousemove(function(e){handleMousemove(e);});

}); // end $(function(){});
</script>
</head>
<body>
    <h2 id="hit">Move mouse near line</h2>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

关于命中测试路径:

如果使用路径命令创建路径,则可以使用context.isPointInPath(mouseX,mouseY)检查鼠标是否在路径中。 context.isPointInPath不适用于行,但因为理论上线条的宽度为零,所以点击。

If you create Paths using path commands you can use context.isPointInPath(mouseX,mouseY) to check if the mouse is inside a path. context.isPointInPath does not work well with lines however because lines theoretically have zero width to "hit".

这篇关于检测鼠标是否在画布内的对象上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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