Kineticjs将dragBoundFunc用于矩形中的矩形 [英] Kineticjs dragBoundFunc for a rect in a rect

查看:199
本文介绍了Kineticjs将dragBoundFunc用于矩形中的矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码在较大的矩形中拖动较小的矩形。

i have following code to drag a smaller rect in a bigger rect.

它几乎正常工作,但可以将橙色矩形移出白色矩形。
这个行为有什么解决方案吗?较大的rect是小矩形的拖拽者?

it is almost working, but its possible to move the orange rect out of the white one. Is there any solution for this behavior?? that the bigger rect is the dragborder for the small rect??

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

And another question... would it be possible to do it for a rect in any polygon as border?

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

and also the jsfiddle link: http://jsfiddle.net/dNfjM/

推荐答案

这是一种改进的设置dragBoundFunc的方法

dragBoundFunc的秘诀是允许它快速执行 。请记住,每次鼠标移动都会执行

The secret with dragBoundFunc is to allow it to execute fast. Remember that it is being executed with every mousemove.

因此,预先计算dragBoundFunc之前和之外的所有最小和最大边界,如下所示:

So, pre-calculate all the minimum and maximum boundaries before and outside dragBoundFunc, like this:

    // 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可以测试当前位置对这些预计算的边界,如下所示:

That way your dragBoundFunc can just test the current position against these pre-calc’ed bounds like this:

      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用于矩形中的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆