Kineticjs dragBoundFunc在一个矩形一个矩形(Kineticjs dragBou

2019-08-20 01:21发布

我有下面的代码在一个更大的矩形拖动矩形小。

它几乎工作,但它可以移动的橙色矩形出白色之一。 是否有此行为的任何解决方案? 该大矩形是为小矩形的dragborder?

而另一个问题......才有可能做到这一点在任何多边形边境一个矩形?

<!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/

Answer 1:

这是设置您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>


文章来源: Kineticjs dragBoundFunc for a rect in a rect