Skip to main content

Canvas 调整图像大小 — 使用 JavaScript 拖动、放置和调整图像大小

此演示展示了如何通过实现可拖动的角落锚点来调整画布上的图像大小。图像既可以被拖动,也可以被调整大小——这是画布图像编辑中的一种常见模式。

注意:我们还提供了一个内置的方法用于这种情况,即特殊的 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';