0

rect.on('mouseup') にバインドされた関数ではなく、ブール値が必要です

4

1 に答える 1

0

KineticJS で回転した四角形をヒット テストする方法

デモ フィドル: http://jsfiddle.net/m1erickson/wTYac/

メソッド:

  • rect が回転した分、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();

次に、rect の回転点に対する 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);

次に、rect の回転量だけ 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);

以下のコードは、booleanrect.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 に答える