<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);
if (selectedNode === transformerNode.node()) {
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>