2013-04-06 137 views
2

我有以下代碼拖動一個更大的矩形較小的矩形。Kineticjs dragBoundFunc rect在rect

它幾乎可以正常工作,但它可能將橙色矩形移出白色矩形。 有沒有解決這個問題的方法?更大的矩形是小矩形的邊框?

另一個問題是,它可以做任何多邊形作爲邊界rect嗎?

<!DOCTYPE HTML> 
<html> 
<head> 
<style> 
    body {margin: 0px; padding: 20px;} 
    canvas {border: 1px solid #777;} 
</style> 
</head> 
<body> 
<div id="container"></div> 
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.2.js"></script> 
<script> 
    var stage = new Kinetic.Stage({ 
     container: 'container', 
     width: 300, 
     height: 300 
    }); 
    var layer = new Kinetic.Layer(); 

    // White box 
    var white = new Kinetic.Rect({ 
     x: 100, 
     y: 50, 
     width: 150, 
     height: 100, 
     fill: 'white', 
     stroke: 'black', 
     strokeWidth: 2 
    }); 

    // orange box 
    var orange = new Kinetic.Rect({ 
     x: 150, 
     y: 100, 
     width: 50, 
     height: 30, 
     fill: 'orange', 
     stroke: 'black', 
     strokeWidth: 2, 
     draggable: true, 
     // this causes orange box to be stopped if try to leave white box 
     dragBoundFunc: function(pos){ 
      if(theyAreColliding(orange,white)){ 
       // orange box is touching white box 
       // let it move ahead 
       return ({ x:pos.x, y:pos.y }); 
      } else{ 
       // orange box is not touching white box 
       // don't let orange box move outside 
       if (white.getY() > orange.getY()){ 
        return({x: pos.x, y: white.getY()+1}); 
       } 
       else if (white.getY() + white.getHeight() - orange.getHeight() < orange.getY()){ 
        return({x: pos.x, y: white.getY() + white.getHeight() - orange.getHeight() -1}); 
       } 
       else if (white.getX() > orange.getX()){ 
        return({x: white.getX() +1, y: pos.y}) 
       } 
       else if (white.getX() + white.getWidth() - orange.getWidth() < orange.getX()){ 
        return({x: white.getX() +white.getWidth() - orange.getWidth() -1, y: pos.y}) 
       } 
      } 
     } 
    }); 

    function theyAreColliding(rect1, rect2) { 
     return !(rect2.getX() > rect1.getX() || 
       rect2.getX() + rect2.getWidth() - rect1.getWidth() < rect1.getX() || 
       rect2.getY() > rect1.getY() || 
       rect2.getY() + rect2.getHeight() - rect1.getHeight() < rect1.getY()); 
    } 

    layer.add(white); 
    layer.add(orange); 
    stage.add(layer); 

</script> 
</body> 
</html> 

,也是的jsfiddle鏈接:http://jsfiddle.net/dNfjM/

回答

8

這是設置您dragBoundFunc

與dragBoundFunc祕密的改進方法是允許它執行快速。請記住,它正在執行與每個鼠標移動

所以,在和dragBoundFunc外預計算所有的最小和最大邊界,就像這樣:

// pre-calc some bounds so dragBoundFunc has less calc's to do 
    var height=orangeRect.getHeight(); 
    var minX=white.getX(); 
    var maxX=white.getX()+white.getWidth()-orangeRect.getWidth(); 
    var minY=white.getY(); 
    var maxY=white.getY()+white.getHeight()-orangeRect.getHeight(); 

這樣,你的dragBoundFunc可以測試針對這些預calc'ed界這樣的當前位置:

 dragBoundFunc: function(pos) { 
      var X=pos.x; 
      var Y=pos.y; 
      if(X<minX){X=minX;} 
      if(X>maxX){X=maxX;} 
      if(Y<minY){Y=minY;} 
      if(Y>maxY){Y=maxY;} 
      return({x:X, y:Y}); 
     } 

這裏的代碼和一個小提琴:http://jsfiddle.net/m1erickson/n5xMs/

<!DOCTYPE HTML> 
<html> 
    <head> 
    <style> 
     body { 
     margin: 0px; 
     padding: 10px; 
     } 
     canvas{border:1px solid red;} 
    </style> 
    </head> 
    <body> 
     <div id="container"></div> 
     <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.4.1.min.js"></script> 
     <script> 
     var stage = new Kinetic.Stage({ 
      container: 'container', 
      width: 400, 
      height: 400 
     }); 
     var layer = new Kinetic.Layer(); 

     var white = new Kinetic.Rect({ 
      x: 20, 
      y: 20, 
      width: 300, 
      height: 300, 
      fill: 'white', 
      stroke: 'black', 
      strokeWidth: 2 
     }); 

     var orangeGroup = new Kinetic.Group({ 
      x: stage.getWidth()/2, 
      y: 70, 
      draggable: true, 
      dragBoundFunc: function(pos) { 
       var X=pos.x; 
       var Y=pos.y; 
       if(X<minX){X=minX;} 
       if(X>maxX){X=maxX;} 
       if(Y<minY){Y=minY;} 
       if(Y>maxY){Y=maxY;} 
       return({x:X, y:Y}); 
      } 
     }); 

     var orangeText = new Kinetic.Text({ 
      fontSize: 26, 
      fontFamily: 'Calibri', 
      text: 'boxed in', 
      fill: 'black', 
      padding: 10 
     }); 

     var orangeRect = new Kinetic.Rect({ 
      width: orangeText.getWidth(), 
      height: orangeText.getHeight(), 
      fill: 'orange', 
      stroke: 'blue', 
      strokeWidth: 4 
     }); 

     orangeGroup.add(orangeRect).add(orangeText); 
     layer.add(white); 
     layer.add(orangeGroup); 
     stage.add(layer); 

     // pre-calc some bounds so dragBoundFunc has less calc's to do 
     var height=orangeRect.getHeight(); 
     var minX=white.getX(); 
     var maxX=white.getX()+white.getWidth()-orangeRect.getWidth(); 
     var minY=white.getY(); 
     var maxY=white.getY()+white.getHeight()-orangeRect.getHeight(); 

     </script> 
    </body> 
</html> 
+0

謝謝你!那是我想要的行爲。完善! – 2013-04-07 20:35:19