检测鼠标是否在画布内的对象上 [英] Detect if Mouse is over an object inside canvas
问题描述
我在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屋!