拖放多个形状
说明: 拖放形状或通过双击或双击来移除它们。
- 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(); const box = boxes.find(b => b.id === id); const filteredBoxes = boxes.filter(b => b.id !== id); setBoxes([...filteredBoxes, box]); }; const handleDragMove = (e) => { // 更新盒子的位置 const id = e.target.id(); const newBoxes = boxes.map(box => { if (box.id === id) { return { ...box, x: e.target.x(), y: e.target.y() }; } return box; }); setBoxes(newBoxes); }; const handleDoubleClick = (id) => { // 双击时移除盒子 setBoxes(boxes.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>