【问题标题】:In kinetic.js, how to detect whether or not mouse is whithin a rotated rect when mouseup在动力学.js中,如何检测鼠标是否在鼠标向上的旋转矩形内
【发布时间】:2013-09-07 12:29:55
【问题描述】:

需要一个布尔值,而不是某个绑定到 rect.on('mouseup') 的函数 非常感谢

【问题讨论】:

    标签: drag-and-drop mouseevent kineticjs


    【解决方案1】:

    如何在 KineticJS 中对旋转的矩形进行命中测试

    演示小提琴:http://jsfiddle.net/m1erickson/wTYac/

    方法:

    • 将 mouseXY 坐标反向旋转矩形的旋转量。
    • 针对未旋转版本的 rect 对未旋转的 mouseXY 进行命中测试。

    详情:

    首先,获取有关矩形的当前信息

      // get current info about this rect
      var cx=this.getX();
      var cy=this.getY();
      var offX=this.getOffsetX();
      var offY=this.getOffsetY();
      var w=this.getWidth();
      var h=this.getHeight();
    

    然后计算 mouseXY 的当前角度与矩形的旋转点。

    注意:假设的旋转点是矩形的中心点。

      // calc the xy's angle versus the rect's centerpoint
      var dx=x-cx;
      var dy=y-cy;
      var rotatedRadians=Math.atan2(dy,dx);
    

    然后按照矩形的旋转量“取消旋转”mouseXY:

      // un-rotate the x,y by the amount of the rect's rotation
      var lengthToXY=Math.sqrt(dx*dx+dy*dy);
      var unrotatedRadians=rotatedRadians-this.getRotation();
      var unX=cx+lengthToXY*Math.cos(unrotatedRadians);
      var unY=cy+lengthToXY*Math.sin(unrotatedRadians);
    

    最后,点击测试未旋转的 mouseXY 与 rect 的旋转点:

      // unX/unY are now in unrotated space
      // so just hittest against the unrotated rect
      var xx=this.getX()-offX;
      var yy=this.getY()-offY;
      var hit=(unX>=xx && unX<=xx+w && unY>=yy && unY<=yy+h);
      return(hit);
    

    下面的代码将布尔值rect.hit 属性添加到 Kinetic.Rect

    这是代码和小提琴:http://jsfiddle.net/m1erickson/wTYac/

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Prototype</title>
        <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
        <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>
    
    <style>
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:300px;
      height:300px;
    }
    </style>        
    <script>
    $(function(){
    
        var stage = new Kinetic.Stage({
            container: 'container',
            width: 300,
            height: 300
        });
        var layer = new Kinetic.Layer();
        stage.add(layer);
    
        enableStageClick();
    
        function enableStageClick(){
            $(stage.getContent()).on('click', function (event) {
                var pos=stage.getMousePosition();
                var mouseX=parseInt(pos.x);
                var mouseY=parseInt(pos.y);
                var hit=rect1.hit(mouseX,mouseY)?"Clicked in rect":"Clicked outside rect";
                $("#hit").text(hit);
            });
        }
    
    
        var rect1=makeRect(150,150,100,50,"skyblue","lightgray",3);
    
    
        function makeRect(x,y,w,h,fill,stroke,linewidth){
    
            var rect = new Kinetic.Rect({
                x: x,
                y: y,
                width: w,
                height: h,
                offset:[w/2,h/2],   // rotate from rect centerpoint
                fill: fill,
                stroke: stroke,
                strokeWidth: linewidth,
                draggable:true
            });
            // return true if x,y is in this rotated rect
            rect.hit=function(x,y){
    
                // get current info about this rect
                var cx=this.getX();
                var cy=this.getY();
                var offX=this.getOffsetX();
                var offY=this.getOffsetY();
                var w=this.getWidth();
                var h=this.getHeight();
    
                // un-rotate this x,y
                var dx=x-cx;
                var dy=y-cy;
                var rotatedRadians=Math.atan2(dy,dx);
    
                // un-rotate the x,y by the amount of the rect's rotation
                var lengthToXY=Math.sqrt(dx*dx+dy*dy);
                var unrotatedRadians=rotatedRadians-this.getRotation();
                var unX=cx+lengthToXY*Math.cos(unrotatedRadians);
                var unY=cy+lengthToXY*Math.sin(unrotatedRadians);
    
                // unX/unY are now in unrotated space
                // so just hittest against the unrotated rect
                var xx=this.getX()-offX;
                var yy=this.getY()-offY;
                var hit=(unX>=xx && unX<=xx+w && unY>=yy && unY<=yy+h);
                return(hit);
            };
            layer.add(rect);
            layer.draw();
            return(rect);
        }
    
        $("#rotateBtn").click(function(){ 
            rect1.rotate(30*Math.PI/180); 
            layer.draw();
            });
    
    }); // end $(function(){});
    
    </script>       
    </head>
    
    <body>
        <p>Click to hit-test the rectangle</p>
        <button id="rotateBtn">rotate</button>
        <span id="hit"></span>
        <div id="container"></div>
    </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 2013-05-13
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多