Kineticjs组在调整到最小尺寸时开始拖动

时间:2013-09-04 01:55:35

标签: kineticjs

我有一个Kineticjs画布,上面有一层。该图层有一个组。该组有四个锚点和一个图像。我使用了调整大小教程(http://www.html5canvastutorials.com/labs/html5-canvas-drag-and-drop-resize-and-invert-images/)中的代码进行了一些修改。我想强制执行最小尺寸(50 x 50px)。当用户拖动其中一个调整大小的锚点(topLeft或bottomRight)时,一旦达到最小大小,整个组就开始拖动。这只发生在topLeft锚点上。 bottomRight按预期运行(当它达到最小大小时,它会停止并且组不会拖动)。任何帮助将不胜感激。感谢。

以下是我正在使用的代码:

调用resizingModeOn()

的选择器
$('.someSelector').on('click', function() {
              // created a layer, created an image...

              // add the new layer to the stage,
              // add the group to the layer,
              // add the large image to the group
              group.add(image);
              newLayer.add(group);
              stage.add(newLayer);
              addAnchor(group, 0, 0, 'topLeft');
              addAnchor(group, image.getWidth(), 0, 'topRight');
              addAnchor(group, 0, image.getHeight(), 'bottomLeft');
              addAnchor(group, image.getWidth(), image.getHeight(), 'bottomRight');

              // turn on resizing mode
              resizingModeOn(group);
        };


function addAnchor(group, x, y, name) {
  var stage = group.getStage();
  var layer = group.getLayer();

  var anchor = new Kinetic.Circle({
        x: x,
        y: y,
        stroke: '#666',
        strokeWidth: 2,
        radius: 8,
        name: name,
        dragOnTop: false
  });


  anchor.on('dragend', function() {
        group.setDraggable(true);
        layer.draw();
  });

  anchor.on('mousedown touchstart', function() {
        group.setDraggable(false);
        this.moveToTop();
  });

  // add hover styling
  anchor.on('mouseover', function() {
        var layer = this.getLayer();
        document.body.style.cursor = 'pointer';
        this.setStrokeWidth(4);
        layer.draw();
  });

  anchor.on('mouseout', function() {
        var layer = this.getLayer();
        document.body.style.cursor = 'default';
        this.setStrokeWidth(2);
        layer.draw();
  });

  group.add(anchor);
  //anchor.hide();
}

这会打开调整大小的锚点(topLeft,bottomRight)

function resizingModeOn(group) {

  // iterate through the anchors and set them
  var layer = group.getLayer();
  var anchors = group.getChildren();
  for (n = 0; n < anchors.length; n++) {
        switch(anchors[n].getName()) {

              // only the topLeft and bottom Right buttons are used for resizing
              case 'topLeft':
              case 'bottomRight':
                    anchors[n].setFill('#ddd');
                    anchors[n].setDraggable('true');

                    anchors[n].on('dragmove', function() {
                          update(this);
                          layer.draw();
                    });
                    break;

              // the topRight button is a delete/exit button
              case 'topRight':
                    anchors[n].setFill('ff0000');
                    anchors[n].setDraggable(false);
                    break;
              case 'bottomLeft':
                    anchors[n].setFill('0000ff');
                    anchors[n].setDraggable(false);
                    break;
              default:
                    break;
        }
  }
}

更新锚位置的更新功能

function update(activeAnchor) {
  var group = activeAnchor.getParent();

  var topLeft = group.get('.topLeft')[0];
  var topRight = group.get('.topRight')[0];
  var bottomRight = group.get('.bottomRight')[0];
  var bottomLeft = group.get('.bottomLeft')[0];
  var image = group.get('.image')[0];

  var anchorX = activeAnchor.getX();
  var anchorY = activeAnchor.getY();

  // update anchor positions
  switch (activeAnchor.getName()) {
        case 'topLeft':
              topRight.setY(anchorY);
              bottomLeft.setX(anchorX);
        break;
        case 'topRight':
              topLeft.setY(anchorY);
              bottomRight.setX(anchorX);
        break;
        case 'bottomRight':
              bottomLeft.setY(anchorY);
              topRight.setX(anchorX);
        break;
        case 'bottomLeft':
              bottomRight.setY(anchorY);
              topLeft.setX(anchorX);
        break;
  }

  // enforces a minimum size
  if (topRight.getX() < topLeft.getX() + 50) {
        topRight.setX(topLeft.getX() + 50);
  }
  if (bottomRight.getX() < topLeft.getX() + 50) {
        bottomRight.setX(topLeft.getX() + 50);
  }
  if (bottomRight.getY() < topLeft.getY() + 50) {
        bottomRight.setY(topLeft.getY() + 50);
  }
  if (bottomLeft.getY() < topLeft.getY() + 50) {
        bottomLeft.setY(topLeft.getY() + 50);
  }


  // enforces a minimum size
  var height = bottomLeft.getY() - topLeft.getY();
  var width = topRight.getX() - topLeft.getX();

  // Update handle positions to reflect new image dimensions
  topLeft.setPosition(topLeft.getX(), topLeft.getY());
  topRight.setPosition(topRight.getX(), topRight.getY());
  bottomRight.setPosition(bottomRight.getX(), bottomRight.getY());
  bottomLeft.setPosition(bottomLeft.getX(), bottomLeft.getY());
  image.setPosition(topLeft.getX(), topLeft.getY());

  if(width && height) {
        image.setSize(width, height);
  }
}

1 个答案:

答案 0 :(得分:0)

你走在正确的轨道上,但你在锚点上缺少一些“强制执行”,以完全限制调整大小/拖动图像。

在您的示例中:

// enforces a minimum size
if (topRight.getX() < topLeft.getX() + 50) {
      topRight.setX(topLeft.getX() + 50);
}
if (bottomRight.getX() < topLeft.getX() + 50) {
      bottomRight.setX(topLeft.getX() + 50);
}
if (bottomRight.getY() < topLeft.getY() + 50) {
      bottomRight.setY(topLeft.getY() + 50);
}
if (bottomLeft.getY() < topLeft.getY() + 50) {
      bottomLeft.setY(topLeft.getY() + 50);
}

只有bottomRight锚点通过(x,y)完全执行。然后,您只强制topRight x 值和bottomLeft y 值。剩下的呢?您需要对所有四个角实施(x,y)

注意:这就是为什么图像“调整大小到最小尺寸时拖动”。这是因为图像位置正在更新到topLeft位置,但是没有对每个锚执行 x y 值,因此代码会移动所有锚点和图像在一起,模拟“拖动”效果。

这就是我的做法,只需对tutorial进行一些修改:

    function update(activeAnchor) {
        var group = activeAnchor.getParent();

        var topLeft = group.get('.topLeft')[0];
        var topRight = group.get('.topRight')[0];
        var bottomRight = group.get('.bottomRight')[0];
        var bottomLeft = group.get('.bottomLeft')[0];
        var image = group.get('.image')[0];

        var anchorX = activeAnchor.getX();
        var anchorY = activeAnchor.getY();

        // update anchor positions
        switch (activeAnchor.getName()) {
            case 'topLeft':
                topRight.setY(anchorY);
                bottomLeft.setX(anchorX);
                if (anchorX > topRight.getX() - 50) {
                    activeAnchor.setX(topRight.getX() - 50);
                    bottomLeft.setX(topRight.getX() - 50);
                }
                if (anchorY > bottomLeft.getY() - 50) {
                    activeAnchor.setY(bottomLeft.getY() - 50);
                    topRight.setY(bottomLeft.getY() - 50);
                }
                break;
            case 'topRight':
                topLeft.setY(anchorY);
                bottomRight.setX(anchorX);
                if (anchorX < topLeft.getX() + 50) {
                    activeAnchor.setX(topLeft.getX() + 50);
                    bottomRight.setX(topLeft.getX() + 50);
                }
                if (anchorY > bottomLeft.getY() - 50) {
                    activeAnchor.setY(bottomLeft.getY() - 50);
                    topLeft.setY(bottomLeft.getY() - 50);
                }
                break;
            case 'bottomRight':
                bottomLeft.setY(anchorY);
                topRight.setX(anchorX);
                if (anchorX < bottomLeft.getX() + 50) {
                    activeAnchor.setX(bottomLeft.getX() + 50);
                    topRight.setX(bottomLeft.getX() + 50);
                }
                if (anchorY < topLeft.getY() + 50) {
                    activeAnchor.setY(topLeft.getY() + 50);
                    bottomLeft.setY(topLeft.getY() + 50);
                }
                break;
            case 'bottomLeft':
                bottomRight.setY(anchorY);
                topLeft.setX(anchorX);
                if (anchorX > topRight.getX() - 50) {
                    activeAnchor.setX(topRight.getX() - 50);
                    topLeft.setX(topRight.getX() - 50);
                }
                if (anchorY < topLeft.getY() + 50) {
                    activeAnchor.setY(topLeft.getY() + 50);
                    bottomRight.setY(topLeft.getY() + 50);
                }
                break;
        }

        image.setPosition(topLeft.getPosition());

        var width = topRight.getX() - topLeft.getX();
        var height = bottomLeft.getY() - topLeft.getY();
        if (width && height) {
            image.setSize(width, height);
        }
    }

它与您的方法略有不同,但它是相同的想法,它的工作原理。您应该能够看到我的意思并使其适应您的代码。祝你好运!

jsfiddle