0

我有一个 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);
  }
}
4

1 回答 1

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). 然后你只对 强制执行x值,对topRight强制执行ybottomLeft。其余的呢?您需要强制执行(x,y)所有四个角。

注意:这就是图像“在调整到最小尺寸时拖动”的原因。这是因为图像位置正在更新到该topLeft位置,但并未对每个锚点强制执行xy值,因此代码将所有锚点和图像一起移动,模拟“拖动”效果。

这就是我对教程进行一些编辑的方式:

    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

于 2013-09-04T15:16:50.707 回答