拖放多个形状
说明: 拖放形状或通过双击或双击来移除它们。
- Vanilla
- React
- Vue
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();
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
for (let i = 0; i < 6; i++) {
const box = new Konva.Rect({
x: i * 30 + 50,
y: i * 18 + 40,
fill: colors[i],
stroke: 'black',
strokeWidth: 4,
draggable: true,
width: 100,
height: 50,
});
box.on('dragstart', function () {
this.moveToTop();
});
box.on('dragmove', function () {
document.body.style.cursor = 'pointer';
});
// 双击移除盒子(桌面应用程序)
// 和双击移除盒子(移动应用程序)
box.on('dblclick dbltap', function () {
this.destroy();
});
box.on('mouseover', function () {
document.body.style.cursor = 'pointer';
});
box.on('mouseout', function () {
document.body.style.cursor = 'default';
});
layer.add(box);
}
// 将图层添加到舞台
stage.add(layer);
import { useState } from 'react';
import { Stage, Layer, Rect } from 'react-konva';
const App = () => {
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
// 初始化盒子,带有适当的 ID 和位置
const initialBoxes = colors.map((color, i) => ({
id: i.toString(),
x: i * 30 + 50,
y: i * 18 + 40,
width: 100,
height: 50,
fill: color,
stroke: 'black',
strokeWidth: 4
}));
const [boxes, setBoxes] = useState(initialBoxes);
const handleDragStart = (e) => {
// 将拖动的盒子移动到数组的末尾以模拟 moveToTop
const id = e.target.id();
setBoxes(currentBoxes => {
const box = currentBoxes.find(b => b.id === id);
if (!box) return currentBoxes;
return [...currentBoxes.filter(b => b.id !== id), box];
});
};
const handleDragMove = (e) => {
// 更新盒子的位置
const id = e.target.id();
setBoxes(currentBoxes => currentBoxes.map(box =>
box.id === id
? { ...box, x: e.target.x(), y: e.target.y() }
: box
));
};
const handleDoubleClick = (id) => {
// Remove the box on double click
setBoxes(currentBoxes => currentBoxes.filter(box => box.id !== id));
};
return (
<Stage width={window.innerWidth} height={window.innerHeight}>
<Layer>
{boxes.map((box) => (
<Rect
key={box.id}
id={box.id}
x={box.x}
y={box.y}
width={box.width}
height={box.height}
fill={box.fill}
stroke={box.stroke}
strokeWidth={box.strokeWidth}
draggable
onDragStart={handleDragStart}
onDragMove={handleDragMove}
onDblClick={() => handleDoubleClick(box.id)}
onDblTap={() => handleDoubleClick(box.id)}
onMouseOver={(e) => {
document.body.style.cursor = 'pointer';
}}
onMouseOut={(e) => {
document.body.style.cursor = 'default';
}}
/>
))}
</Layer>
</Stage>
);
};
export default App;
<template>
<v-stage :config="stageConfig">
<v-layer>
<v-rect
v-for="box in boxes"
:key="box.id"
:config="box"
@dragstart="handleDragStart"
@dragmove="handleDragMove"
@mouseover="handleMouseOver"
@mouseout="handleMouseOut"
@dblclick="handleDoubleClick"
@dbltap="handleDoubleClick"
/>
</v-layer>
</v-stage>
</template>
<script setup>
import { ref } from 'vue';
const stageConfig = {
width: window.innerWidth,
height: window.innerHeight
};
const colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
// 初始化盒子,带有适当的配置
const initialBoxes = colors.map((color, i) => ({
id: i.toString(),
x: i * 30 + 50,
y: i * 18 + 40,
width: 100,
height: 50,
fill: color,
stroke: 'black',
strokeWidth: 4,
draggable: true
}));
const boxes = ref(initialBoxes);
const handleDragStart = (e) => {
const id = e.target.id();
// 将拖动的盒子移动到数组的末尾以模拟 moveToTop
const box = boxes.value.find(b => b.id === id);
const filteredBoxes = boxes.value.filter(b => b.id !== id);
boxes.value = [...filteredBoxes, box];
};
const handleDragMove = (e) => {
const id = e.target.id();
const index = boxes.value.findIndex(b => b.id === id);
if (index !== -1) {
// 更新位置
const updatedBox = { ...boxes.value[index] };
updatedBox.x = e.target.x();
updatedBox.y = e.target.y();
// 替换数组中的盒子
const newBoxes = [...boxes.value];
newBoxes[index] = updatedBox;
boxes.value = newBoxes;
}
document.body.style.cursor = 'pointer';
};
const handleMouseOver = () => {
document.body.style.cursor = 'pointer';
};
const handleMouseOut = () => {
document.body.style.cursor = 'default';
};
const handleDoubleClick = (e) => {
const id = e.target.id();
// 移除盒子
boxes.value = boxes.value.filter(box => box.id !== id);
};
</script>