我在canvas元素中创建了一条线。我正在寻找最简单的方法来检测鼠标的位置是否在画布内部的行内。
我已经使用这个函数来查看画布中鼠标的位置,但我对如何继续操作感到很困惑。
function getMousePos(c, evt) {
var rect = c.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
我也查看了这个主题Fabricjs detect mouse over object path,但它检测到鼠标是否在画布内,而不是在对象内部。
我创建的行是较小行的一部分,彼此连接。
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]是具有我想要的坐标的数组。
我希望我的问题很清楚,虽然我对javascript不是很熟悉。
由于 迪米特拉
答案 0 :(得分:11)
演示:http://jsfiddle.net/m1erickson/Cw4ZN/
您需要这些概念来检查鼠标是否在一行内:
定义起点&amp;一行的终点
收听鼠标事件
在鼠标移动时,检查鼠标是否在行的指定距离内
这是一个带注释的示例代码供您学习。
<!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不适用于行,但因为理论上线条的宽度为零而无法“击中”。