识别圆弧上的事件 [英] identifying event on arc of circle
问题描述
我是html5的新用户,并使用canvas来绘制我的应用程序之一的圆圈。我画了几个弧形成一个圆。它工作正常。但是我的问题是,我想为每个弧关联一个单独的鼠标事件。
我偷偷摸摸,发现KinteticJS可能很有用。我想知道是否有任何其他方法,可以用于连接鼠标事件为我使用画布创建的每个弧。请注意,我只使用一个画布没有ghost画布,我不想使用SVG。下面是我使用的代码的行:
context.arc(x,y,radius,startAngle,endAngle,counterClockwise) ;
canvas.addEventListener(mousedown,doMouseDown(evt),false);
关于
nad
快速回答是:不,但...
strong>
Canvas不会记住自己绘制的任何东西 - 图纸只是添加到画布的颜色像素。 Canvas不知道你的弧的位置,不能命中测试看看mousdown是否在弧内。
但你...可以使用数学
您可以使用数学来测试圆圈内是否有点。
如果任何x / y在圆的外半径内并且不在内半径内,则x / y在圆弧中。
给定centerX,centerY,outerRadius,innerRadius:
测试x,y是否在外半径内:
var dx = testX-centerX;
var dy = testY-centerY;
var isInsideOuterRadius =(dx * dx + dy * dy< outerRadius * outerRadius);
测试x,y是否在内部内半径:
var isInsideInnerRadius =(dx * dx + dy * dy< innerRadius * innerRadius);
所以
if(isInsideOuterRadius&&!isInsideInnerRadius){alert(x / y在你的弧); }
如果你想要花哨:
Context.isPointInStroke将测试X / Y是否位于最近绘制的路径内。
例如,如果画出这条弧:
context.beginPath();
context.arc(100,100,50,0,Math.PI);
您可以通过使用鼠标坐标提供isPointInStroke命中测试圆弧:
if(context.isPointInStroke(mouseX,mouseY)){
console.log(鼠标位于弧内
} else {
console.log(鼠标在圆弧之外);
}
要测试多个圆弧,
- 定义一个圆弧(do context.arc without context.stroke)
- 使用isPointInStroke测试圆弧
- 除了IE:(
)
isPointInStroke可在Chrome和Firefox中使用,但在Internet Explorer中无法使用。
您可以在圆弧外部定义一个路径,然后使用isPointInPath测试鼠标是否在该路径内。
[更新:和示例]
这是一个小提琴(必须用Chrome或FF查看 - IE将不工作):
http://jsfiddle.net/m1erickson/DsPL7/
以下是示例代码:
<!doctype html>
< html>
< head>
< link rel =stylesheettype =text / cssmedia =allhref =css / reset.css/> <! - reset css - >
< script type =text / javascriptsrc =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;
//创建一些测试数据对象
var arcs = [];
$ b b //外圆弧
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: ,color:maroon});
//可视地绘制所有圆弧
for(var i = 0; idefineArc(arcs [i]);
context.strokeStyle = arcs [i] .color;
context.stroke();
}
// define BUT NOT VISIBLY DRAW a arc
function defineArc(arc){
context.beginPath();
context.arc(arc.cx,arc.cy,arc.radius,arc.start,arc.end);
}
//处理mousemove事件
函数handleMouseMove(e){
//获取鼠标位置
mouseX = parseInt(e.clientX-offsetX);
mouseY = parseInt(e.clientY-offsetY);
//将结果框重置为不可见
context.clearRect(225,30,20,20);
// hit-test each arc
for(var i = 0; i
//定义一个弧
defineArc(arcs [i]);
//测试一个弧
//如果hit填充结果框的颜色
if(context.isPointInStroke(mouseX,mouseY)){
context.fillStyle = arcs [i] .color;
context.fillRect(225,30,20,20);
return;
}
}
}
//监听mousemoves
$(#canvas ).mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
< / script>
< / head>
< body>
< h4>将鼠标悬停在任意圆弧上< / h4>
< h4>当鼠标悬停在弧上时,该颜色rect将出现< / h4>
< canvas id =canvaswidth = 300 height = 300>< / canvas>
< / body>
< / html>
I am a new user of html5 and using canvas to draw circle for one of my application. I have drawn several arcs to form a circle. it works fine. However my problem is that i want to associate a separate mouse event for each of the arc.
I goggled and found KinteticJS may be useful. I wish to know is there any other way that could be used to attached mouse event for every arc i created using the canvas. Please note i have used just one canvas there is no ghost canvas and I do not wish to use SVG. Below is the line of the code i used:
context.arc(x, y, radius, startAngle, endAngle, counterClockwise); canvas.addEventListener("mousedown", doMouseDown(evt), false);
regards nad
解决方案The quick answer is: No, but...
No:
Canvas does not "remember" anything drawn on itself--drawings are just color pixels added to the canvas. Canvas doesn't know the position of your arc and can't hit-test to see if the mousdown is inside that arc.
but...you can use math
You can use math to test if any point is inside the circle.
If any x/y is inside the outer radius of a circle and not inside the inner radius, then x/y is in the arc.
Given centerX,centerY,outerRadius,innerRadius:
Test if x,y is inside the outer radius:
var dx=testX-centerX; var dy=testY-centerY; var isInsideOuterRadius=(dx*dx+dy*dy<outerRadius*outerRadius);
Test if x,y is not inside the inner radius:
var isInsideInnerRadius=(dx*dx+dy*dy<innerRadius*innerRadius);
So if( isInsideOuterRadius && !isInsideInnerRadius){ alert("x/y is in your arc"); }
If you want to get fancy:
If you "remember" the arc for canvas, then canvas has a hit-test for that arc.
Context.isPointInStroke will test if an X/Y is located inside the most recently drawn path. If that most recent path is your arc, you can hit-test your arc.
For example, if you draw this arc:
context.beginPath(); context.arc(100,100,50,0,Math.PI);
You can hit-test that arc by supplying isPointInStroke with your mouse coordinates:
if(context.isPointInStroke(mouseX,mouseY)){ console.log("The mouse is INSIDE the arc"); }else{ console.log("The mouse is OUTSIDE the arc"); }
To test multiple arcs,
- Define one arc ( do context.arc without context.stroke )
- Test that arc with isPointInStroke
- Do #1 with the next arc
Except IE :(
isPointInStroke will work in Chrome and Firefox but won't yet work in Internet Explorer.
Alternatively for IE:
You can define a path around the outside of your arc and then use isPointInPath to test if your mouse is inside that path.
[ Update: and example ]
Here's a Fiddle (must view with Chrome or FF -- IE won't work):
http://jsfiddle.net/m1erickson/DsPL7/
Here's example code:
<!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>
这篇关于识别圆弧上的事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!