使用 JavaScript 和 Konva 实现 Canvas 拖放
Canvas API 不为绘制的图形提供拖放功能。原生 Canvas
应用程序必须实现以下四个部分:
- 存储每个图形及其位置。
- 检测指针下方的图形。
- 将浏览器坐标转换为 Canvas 坐标。
- 在拖动期间更新图形并重绘场景。
指针事件通过统一的事件模型支持鼠标、触控笔和触摸输入。
在原生 Canvas 实现中,请调用 setPointerCapture()。该调用应在 pointerdown 之后进行。
捕获指针后,移动事件在 Canvas 外仍保持活动状态。
拖动 Konva 节点
Konva 实现命中检测和指针跟踪。为节点设置 draggable。
然后,将其最终位置存储在应用程序 state 中。
import { useState } from 'react';
import { Stage, Layer, Rect, Text } from 'react-konva';
const App = () => {
const [position, setPosition] = useState({ x: 80, y: 100 });
const [dragging, setDragging] = useState(false);
return (
<Stage width={window.innerWidth} height={380}>
<Layer>
<Text
x={20}
y={20}
text={`Position: ${Math.round(position.x)}, ${Math.round(position.y)}`}
fontSize={18}
/>
<Rect
x={position.x}
y={position.y}
width={160}
height={100}
fill={dragging ? '#ff922b' : '#4dabf7'}
stroke="#1f2937"
strokeWidth={3}
shadowBlur={dragging ? 12 : 0}
cornerRadius={10}
draggable
onDragStart={() => setDragging(true)}
onDragMove={(event) => {
setPosition({ x: event.target.x(), y: event.target.y() });
}}
onDragEnd={(event) => {
setDragging(false);
setPosition({ x: event.target.x(), y: event.target.y() });
}}
/>
</Layer>
</Stage>
);
};
export default App;
Konva 在拖动期间更改节点位置。此示例还将该
位置写入 React state。该 state 使应用程序模型保持同步。
对于大型场景,不要在每个 dragmove 事件中更新无关的 React state。
在拖动期间更新 Konva 节点。如果其他组件不需要实时坐标,请在
dragend 时保存最终的应用程序 state。
Canvas 图形不是键盘控件。请为每项必要的拖动操作提供一个 HTML
控件。该控件可以按固定步长移动同一图形。
有关 Vanilla、React、Vue、Svelte 和 Angular 示例,请参阅
拖放指南。