Skip to main content

HTML5 Canvas 拖动、放置和调整图像大小演示

本演示展示了如何手动实现带有角部锚点的图像调整大小功能。图像既可以拖动也可以调整大小。

注意:我们还提供了一个内置的方法用于这种情况,即特殊的 Konva.Transformer 节点。请查看 选择和变换演示 以获取更简单的方法。

说明: 拖动图像以移动它们。点击并拖动角部锚点以调整大小。

import Konva from 'konva';

const width = window.innerWidth;
const height = window.innerHeight;

const stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

const layer = new Konva.Layer();
stage.add(layer);

// 根据锚点移动更新图像大小的函数
function update(activeAnchor) {
  const group = activeAnchor.getParent();

  const topLeft = group.findOne('.topLeft');
  const topRight = group.findOne('.topRight');
  const bottomRight = group.findOne('.bottomRight');
  const bottomLeft = group.findOne('.bottomLeft');
  const image = group.findOne('Image');

  const anchorX = activeAnchor.x();
  const anchorY = activeAnchor.y();

  // 根据哪个锚点被移动来更新锚点位置
  switch (activeAnchor.getName()) {
    case 'topLeft':
      topRight.y(anchorY);
      bottomLeft.x(anchorX);
      break;
    case 'topRight':
      topLeft.y(anchorY);
      bottomRight.x(anchorX);
      break;
    case 'bottomRight':
      bottomLeft.y(anchorY);
      topRight.x(anchorX);
      break;
    case 'bottomLeft':
      bottomRight.y(anchorY);
      topLeft.x(anchorX);
      break;
  }

  // 将图像位置放置在左上角
  image.position(topLeft.position());

  // 更新图像尺寸
  const width = topRight.x() - topLeft.x();
  const height = bottomLeft.y() - topLeft.y();
  if (width && height) {
    image.width(width);
    image.height(height);
  }
}

// 为一个组添加调整大小锚点的函数
function addAnchor(group, x, y, name) {
  const anchor = new Konva.Circle({
    x: x,
    y: y,
    stroke: '#666',
    fill: '#ddd',
    strokeWidth: 2,
    radius: 8,
    name: name,
    draggable: true,
    dragOnTop: false,
  });

  // 添加事件监听器以实现调整大小的行为
  anchor.on('dragmove', function () {
    update(this);
  });
  
  anchor.on('mousedown touchstart', function () {
    group.draggable(false);
    this.moveToTop();
  });
  
  anchor.on('dragend', function () {
    group.draggable(true);
  });
  
  // 添加悬停样式
  anchor.on('mouseover', function () {
    document.body.style.cursor = 'pointer';
    this.strokeWidth(4);
  });
  
  anchor.on('mouseout', function () {
    document.body.style.cursor = 'default';
    this.strokeWidth(2);
  });

  group.add(anchor);
}

// 创建达斯·维德组及其图像和锚点
const darthVaderImg = new Konva.Image({
  width: 200,
  height: 137,
});

const darthVaderGroup = new Konva.Group({
  x: 180,
  y: 50,
  draggable: true,
});

layer.add(darthVaderGroup);
darthVaderGroup.add(darthVaderImg);

// 在角落添加锚点
addAnchor(darthVaderGroup, 0, 0, 'topLeft');
addAnchor(darthVaderGroup, 200, 0, 'topRight');
addAnchor(darthVaderGroup, 200, 137, 'bottomRight');
addAnchor(darthVaderGroup, 0, 137, 'bottomLeft');

// 创建尤达组及其图像和锚点
const yodaImg = new Konva.Image({
  width: 93,
  height: 104,
});

const yodaGroup = new Konva.Group({
  x: 20,
  y: 110,
  draggable: true,
});

layer.add(yodaGroup);
yodaGroup.add(yodaImg);

// 在角落添加锚点
addAnchor(yodaGroup, 0, 0, 'topLeft');
addAnchor(yodaGroup, 93, 0, 'topRight');
addAnchor(yodaGroup, 93, 104, 'bottomRight');
addAnchor(yodaGroup, 0, 104, 'bottomLeft');

// 加载图像
const imageObj1 = new Image();
imageObj1.onload = function () {
  darthVaderImg.image(imageObj1);
};
imageObj1.src = 'https://konvajs.org/assets/darth-vader.jpg';

const imageObj2 = new Image();
imageObj2.onload = function () {
  yodaImg.image(imageObj2);
};
imageObj2.src = 'https://konvajs.org/assets/yoda.jpg';