Javascript 识别圆弧上的事件
我是html5的新用户,使用画布为我的一个应用程序画圆圈。我画了几条弧形成一个圆。它很好用。然而,我的问题是,我想为每个弧关联一个单独的鼠标事件 我目瞪口呆,发现KinteticJS可能有用。我想知道是否有其他方法可以用于为我使用画布创建的每个弧附加鼠标事件。请注意,我只使用了一个画布,没有鬼画布,我不希望使用SVG。下面是我使用的代码行:Javascript 识别圆弧上的事件,javascript,html,canvas,automatic-ref-counting,mouseevent,Javascript,Html,Canvas,Automatic Ref Counting,Mouseevent,我是html5的新用户,使用画布为我的一个应用程序画圆圈。我画了几条弧形成一个圆。它很好用。然而,我的问题是,我想为每个弧关联一个单独的鼠标事件 我目瞪口呆,发现KinteticJS可能有用。我想知道是否有其他方法可以用于为我使用画布创建的每个弧附加鼠标事件。请注意,我只使用了一个画布,没有鬼画布,我不希望使用SVG。下面是我使用的代码行: context.arc(x, y, radius, startAngle, endAngle, counterClockwise); canvas.addE
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
canvas.addEventListener("mousedown", doMouseDown(evt), false);
问候
答案是:不,但是
否:
画布本身不记得绘制的任何内容。图形只是添加到画布上的彩色像素。Canvas不知道弧的位置,无法点击测试查看鼠标是否在弧内
但是…你可以用数学
您可以使用数学测试圆内是否有任何点
如果任何x/y位于圆的外半径内而不在内半径内,则x/y位于圆弧内
给定中心X、中心Y、外半径、内半径:
测试x,y是否在外半径内:
var dx=testX-centerX;
var dy=testY-centerY;
var isInsideOuterRadius=(dx*dx+dy*dy<outerRadius*outerRadius);
var isInsideInnerRadius=(dx*dx+dy*dy<innerRadius*innerRadius);
您可以通过向isPointInStroke提供鼠标坐标来点击测试该圆弧:
if(context.isPointInStroke(mouseX,mouseY)){
console.log("The mouse is INSIDE the arc");
}else{
console.log("The mouse is OUTSIDE the arc");
}
要测试多个圆弧
定义一个不带context.stroke的弧do context.arc
用isPointInStroke测试电弧
对下一个弧执行1
除IE外:
isPointInStroke可以在Chrome和Firefox中使用,但还不能在Internet Explorer中使用
或者,对于IE:
可以围绕弧的外侧定义路径,然后使用isPointInPath测试鼠标是否在该路径内
[更新:和示例]
这里有一个必须使用Chrome或FF-IE查看的小提琴,但它不起作用:
下面是示例代码:
<!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(){
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.lineWidth=15;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var PI2=Math.PI*2;
// create some test data objects
var arcs=[];
//outer arcs
arcs.push({cx:100, cy:100, radius:75, start:0, end: PI2*.33, color:"red"});
arcs.push({cx:100, cy:100, radius:75, start:PI2*.33, end: PI2*.66, color:"green"});
arcs.push({cx:100, cy:100, radius:75, start:PI2*.66, end: PI2, color:"blue"});
// inner arcs
arcs.push({cx:100, cy:100, radius:45, start:0, end: PI2*.55, color:"purple"});
arcs.push({cx:100, cy:100, radius:45, start:PI2*.55, end: PI2*.75, color:"orange"});
arcs.push({cx:100, cy:100, radius:45, start:PI2*.75, end: PI2, color:"maroon"});
// visibly draw all arcs
for(var i=0;i<arcs.length;i++){
defineArc(arcs[i]);
context.strokeStyle=arcs[i].color;
context.stroke();
}
// define BUT NOT VISIBLY DRAW an arc
function defineArc(arc){
context.beginPath();
context.arc(arc.cx,arc.cy,arc.radius,arc.start,arc.end);
}
// handle mousemove events
function handleMouseMove(e){
// get mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// reset the results box to invisible
context.clearRect(225,30,20,20);
// hit-test each arc
for(var i=0;i<arcs.length;i++){
// define one arc
defineArc(arcs[i]);
// test that one arc
// if "hit" fill the results box with that arc's color
if(context.isPointInStroke(mouseX,mouseY)){
context.fillStyle=arcs[i].color;
context.fillRect(225,30,20,20);
return;
}
}
}
// listen for mousemoves
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Move mouse over any arc</h4>
<h4>When mouse is over arc, that color rect will appear</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
谢谢marke,但是如果我制作了几个圆弧,比如说一个圆中的四个圆弧,你提到的Context.isPointInStroke将只适用于最新创建的圆弧。若要点击测试4个圆弧中的任意一个,可以重新定义一个圆弧context.arc…但不需要context.stroke,然后执行isPointInStroke。如果你想测试一个完整的圆,我添加了一个可选的数学答案。谢谢,但我不明白。让我向你解释我在做什么。事实上,我画了一个同心圆,每个同心圆都有许多圆弧,我用它来可视化海量数据。一旦我画了所有的圆和弧,我将如何测试。下面是我正在使用的代码:对于var j=0;jI在我的答案中添加了一个例子,hit使用isPointInStroke测试多个同心圆弧。祝你的项目好运!:
<!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(){
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
context.lineWidth=15;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var PI2=Math.PI*2;
// create some test data objects
var arcs=[];
//outer arcs
arcs.push({cx:100, cy:100, radius:75, start:0, end: PI2*.33, color:"red"});
arcs.push({cx:100, cy:100, radius:75, start:PI2*.33, end: PI2*.66, color:"green"});
arcs.push({cx:100, cy:100, radius:75, start:PI2*.66, end: PI2, color:"blue"});
// inner arcs
arcs.push({cx:100, cy:100, radius:45, start:0, end: PI2*.55, color:"purple"});
arcs.push({cx:100, cy:100, radius:45, start:PI2*.55, end: PI2*.75, color:"orange"});
arcs.push({cx:100, cy:100, radius:45, start:PI2*.75, end: PI2, color:"maroon"});
// visibly draw all arcs
for(var i=0;i<arcs.length;i++){
defineArc(arcs[i]);
context.strokeStyle=arcs[i].color;
context.stroke();
}
// define BUT NOT VISIBLY DRAW an arc
function defineArc(arc){
context.beginPath();
context.arc(arc.cx,arc.cy,arc.radius,arc.start,arc.end);
}
// handle mousemove events
function handleMouseMove(e){
// get mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// reset the results box to invisible
context.clearRect(225,30,20,20);
// hit-test each arc
for(var i=0;i<arcs.length;i++){
// define one arc
defineArc(arcs[i]);
// test that one arc
// if "hit" fill the results box with that arc's color
if(context.isPointInStroke(mouseX,mouseY)){
context.fillStyle=arcs[i].color;
context.fillRect(225,30,20,20);
return;
}
}
}
// listen for mousemoves
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Move mouse over any arc</h4>
<h4>When mouse is over arc, that color rect will appear</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>