识别圆弧上的事件 [英] identifying event on arc of circle

查看:202
本文介绍了识别圆弧上的事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是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(鼠标在圆弧之外);
}

要测试多个圆弧,


  1. 定义一个圆弧(do context.arc without context.stroke)

  2. 使用isPointInStroke测试圆弧

  3. 除了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; i defineArc(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,

    1. Define one arc ( do context.arc without context.stroke )
    2. Test that arc with isPointInStroke
    3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆