如何使用 Vue 和 Konva 调整画布形状的大小和旋转?
目前,没有纯声明性的"Vue 方式”使用 Transformer 工具。 不过,你仍然可以通过手动将其附加到 Konva 节点来有效使用它。
这个想法是创建一个 v-transformer 组件,并在选中时手动将其附加到所需的节点上。
说明:点击形状以选择它。然后,你可以使用变换手柄调整其大小和旋转。形状将在变换后改变颜色。
<template>
<v-stage
ref="stage"
:config="stageSize"
@mousedown="handleStageMouseDown"
@touchstart="handleStageMouseDown"
>
<v-layer ref="layer">
<v-rect
v-for="item in rectangles"
:key="item.id"
:config="item"
@transformend="handleTransformEnd"
/>
<v-transformer ref="transformer" />
</v-layer>
</v-stage>
</template>
<script setup>
import { ref } from 'vue';
import Konva from 'konva';
const stageSize = {
width: window.innerWidth,
height: window.innerHeight
};
const rectangles = ref([
{
rotation: 0,
x: 10,
y: 10,
width: 100,
height: 100,
scaleX: 1,
scaleY: 1,
fill: 'red',
name: 'rect1',
draggable: true
},
{
rotation: 0,
x: 150,
y: 150,
width: 100,
height: 100,
scaleX: 1,
scaleY: 1,
fill: 'green',
name: 'rect2',
draggable: true
}
]);
const selectedShapeName = ref('');
const transformer = ref(null);
const handleTransformEnd = (e) => {
// 在我们的状态中找到元素
const rect = rectangles.value.find(
(r) => r.name === selectedShapeName.value
);
if (!rect) return;
// 用新属性更新状态
rect.x = e.target.x();
rect.y = e.target.y();
rect.rotation = e.target.rotation();
rect.scaleX = e.target.scaleX();
rect.scaleY = e.target.scaleY();
// 随机改变填充颜色
rect.fill = Konva.Util.getRandomColor();
};
const updateTransformer = () => {
const transformerNode = transformer.value.getNode();
const stage = transformerNode.getStage();
const selected = selectedShapeName.value;
const selectedNode = stage.findOne('.' + selected);
// do nothing if selected node is already attached
if (selectedNode === transformerNode.nodes()[0]) {
return;
}
if (selectedNode) {
// 附加到选中的节点
transformerNode.nodes([selectedNode]);
} else {
// 移除变换器
transformerNode.nodes([]);
}
};
const handleStageMouseDown = (e) => {
// 点击舞台 - 清除选择
if (e.target === e.target.getStage()) {
selectedShapeName.value = '';
updateTransformer();
return;
}
// 点击变换器 - 不做任何事
const clickedOnTransformer =
e.target.getParent().className === 'Transformer';
if (clickedOnTransformer) {
return;
}
// 根据名字找到被点击的矩形
const name = e.target.name();
const rect = rectangles.value.find((r) => r.name === name);
if (rect) {
selectedShapeName.value = name;
} else {
selectedShapeName.value = '';
}
updateTransformer();
};
</script>