【问题标题】:Kineticjs dragBoundFunc for a rect in a rectKineticjs dragBoundFunc 用于矩形中的矩形
【发布时间】:2016-02-24 10:51:09
【问题描述】:

我有以下代码可以将较小的矩形拖到较大的矩形中。

它几乎可以工作了,但它可以将橙色矩形移出白色矩形。 这种行为有什么解决办法吗??较大的矩形是小矩形的拖动边框??

还有一个问题......是否可以将任何多边形中的矩形作为边框?

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

【问题讨论】:

    标签: javascript kineticjs


    【解决方案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 可以像这样针对这些预先计算的边界测试当前位置:

          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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 2017-12-07
      • 1970-01-01
      • 2012-12-25
      • 1970-01-01
      • 2012-12-29
      • 1970-01-01
      相关资源
      最近更新 更多