简体   繁体   English

检测鼠标是否在画布内的对象上

[英]Detect if Mouse is over an object inside canvas

I have created a line inside a canvas element. 我在canvas元素中创建了一条线。 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
            };
        }

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. 我也看过这个主题Fabricjs检测鼠标在对象路径上 ,但它检测鼠标是否在画布内,而不是在对象内。

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

            }

where x[i] and y[i] are the arrays with the coordinates that I want. 其中x [i]和y [i]是具有我想要的坐标的数组。

I hope my question is clear, although I am not very familiar with javascript. 我希望我的问题很清楚,虽然我对javascript不是很熟悉。

Thanks Dimitra 谢谢迪米特拉

A Demo: http://jsfiddle.net/m1erickson/Cw4ZN/ 演示: 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 定义一条线的起点和终点

  • Listen for mouse events 听取鼠标事件

  • On mousemove, check if the mouse is within a specified distance of the line 在鼠标移动时,检查鼠标是否在该行的指定距离内

Here's annotated example code for you to learn from. 这是一个带注释的示例代码供您学习。

 $(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(){}); 
 body { background-color: ivory; } canvas { border: 1px solid red; } 
 <!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> </head> <body> <h2 id="hit">Move mouse near line</h2> <canvas id="canvas" width=300 height=300></canvas> </body> </html> 

About hit-testing Paths: 关于命中测试路径:

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(mouseX,mouseY)检查鼠标是否在路径中。 context.isPointInPath does not work well with lines however because lines theoretically have zero width to "hit". context.isPointInPath不适用于行但是因为行理论上具有零宽度来“击中”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM