识别圆弧上的事件

时间:2013-11-26 13:37:20

标签: javascript html5 canvas automatic-ref-counting mouseevent

我是html5的新用户,并使用画布为我的某个应用程序绘制圆圈。我画了几个弧形成一个圆圈。它工作正常。但是我的问题是我想为每个弧关联一个单独的鼠标事件。

我g目结舌,发现KinteticJS可能有用。我想知道是否有任何其他方法可用于为使用画布创建的每个弧附加鼠标事件。请注意我只使用了一个画布,没有鬼画布,我不想使用SVG。下面是我使用的代码行:

context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
canvas.addEventListener("mousedown", doMouseDown(evt), false);

问候 NAD

1 个答案:

答案 0 :(得分:7)

快速回答是:不,但......

否:

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&amp;&amp;!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("The mouse is INSIDE the arc");
}else{
    console.log("The mouse is OUTSIDE the arc");
}

测试多个弧,

  1. 定义一个弧(do context.arc,不带context.stroke)
  2. 使用isPointInStroke
  3. 测试该弧
  4. 下一个弧#1做#1

    除了IE :(

    isPointInStroke可在Chrome和Firefox中使用,但无法在Internet Explorer中使用。

    替代IE:

    您可以定义弧外部的路径,然后使用isPointInPath测试您的鼠标是否在该路径内。

    [更新:和示例]

    enter image description here

    这是一个小提琴(必须使用Chrome或FF查看 - IE无效):

    http://jsfiddle.net/m1erickson/DsPL7/

    以下是示例代码:

    <!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>