在React JS中如何使用react-konva通过onClick事件绘制图形?
React-Konva 鼠标交互绘制图形实现方案
核心实现逻辑
基于Konva画布的鼠标生命周期事件,配合React状态管理记录绘制过程中的坐标数据,实时更新临时图形的渲染参数,拖拽结束后将最终图形存入已完成列表即可。
具体实现步骤
- 初始化状态:声明四个核心状态:
isDrawing(布尔值,标记是否处于拖拽绘制状态)、startPoint(记录鼠标按下时的画布坐标)、currentShape(存储正在绘制的临时图形参数)、shapes(存储所有已完成绘制的图形数据列表) - 监听Stage画布的三个核心鼠标事件:
onMouseDown:鼠标按下时触发,将isDrawing设为true,记录当前画布坐标为起始点,初始化临时图形的基础参数onMouseMove:鼠标移动时触发,仅当isDrawing为true时执行逻辑,计算当前坐标和起始坐标的差值,动态更新临时图形的尺寸、位置参数onMouseUp/onMouseLeave:鼠标抬起或移出画布时触发,将临时图形参数存入已完成图形列表,重置所有绘制状态
- 渲染图形:遍历
shapes数组渲染所有已完成的图形,额外单独渲染currentShape临时图形,实现拖拽过程中的实时预览效果
注意要调用Stage实例的getPointerPosition()方法获取坐标,不要直接使用浏览器原生事件的clientX/clientY,避免画布存在偏移、缩放时坐标计算错误
矩形绘制参考代码
import { useState } from 'react'; import { Stage, Layer, Rect } from 'react-konva'; function DrawApp() { const [isDrawing, setIsDrawing] = useState(false); const [startPoint, setStartPoint] = useState({ x: 0, y: 0 }); const [currentRect, setCurrentRect] = useState(null); const [rects, setRects] = useState([]); const handleMouseDown = (e) => { setIsDrawing(true); const { x, y } = e.target.getStage().getPointerPosition(); setStartPoint({ x, y }); setCurrentRect({ x, y, width: 0, height: 0 }); }; const handleMouseMove = (e) => { if (!isDrawing) return; const { x, y } = e.target.getStage().getPointerPosition(); // 处理拖拽方向为左上时的坐标翻转问题 setCurrentRect({ x: Math.min(startPoint.x, x), y: Math.min(startPoint.y, y), width: Math.abs(x - startPoint.x), height: Math.abs(y - startPoint.y), }); }; const handleMouseUp = () => { if (!isDrawing) return; setRects([...rects, currentRect]); setIsDrawing(false); setCurrentRect(null); }; return ( <Stage width={window.innerWidth} height={window.innerHeight} onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} onMouseLeave={handleMouseUp} > <Layer> {/* 渲染所有已完成的矩形 */} {rects.map((rect, i) => ( <Rect key={i} {...rect} fill="transparent" stroke="black" strokeWidth={2} /> ))} {/* 渲染正在绘制的临时矩形 */} {currentRect && <Rect {...currentRect} fill="transparent" stroke="black" strokeWidth={2} />} </Layer> </Stage> ); } export default DrawApp;
扩展说明
- 如果需要绘制圆形、直线、多边形等其他图形,仅需修改状态存储的图形参数,以及对应渲染的Konva组件即可,整体交互逻辑和矩形绘制完全一致
- 如果需要支持选中、编辑已绘制的图形,可以给每个图形绑定
onTransform等事件配合Transformer组件实现
内容的提问来源于stack exchange,提问作者Namya LG
相关产品推荐
相关产品推荐

