0

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

4

1 回答 1

0

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

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

方法:

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

细节:

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

  // 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 的当前角度与 rect 的旋转点。

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

  // 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 与矩形的旋转点进行命中测试:

  // 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-09-07T04:29:55.513 回答