如何在React JS中通过鼠标事件绘制线条(非拖拽元素方式)
画布绘制的鼠标事件替代方案
你现在用onDrag事件实现绘制是走偏了——draggable属性本来就是用来开启元素原生拖拽功能的,这就是第二次拖拽会把div“拿起”的核心原因。正确的做法是用**mousedown、mousemove、mouseup**这三个原生鼠标事件组合,完全避开拖拽逻辑,精准实现“按下鼠标移动时绘制”的需求。
修改后的实现代码
import { useState, useRef } from 'react'; function CanvasApp() { const [items, setItems] = useState([]); // 标记是否处于绘制状态 const [isDrawing, setIsDrawing] = useState(false); // 用ref存储最新的items,避免闭包导致的旧值问题 const itemsRef = useRef(items); itemsRef.current = items; // 鼠标按下:开始绘制,记录第一个点 const handleMouseDown = (e) => { setIsDrawing(true); const { clientX, clientY } = e; setItems([...itemsRef.current, { x: clientX, y: clientY }]); }; // 鼠标移动:仅在绘制状态下记录点 const handleMouseMove = (e) => { if (!isDrawing) return; const { clientX, clientY } = e; setItems([...itemsRef.current, { x: clientX, y: clientY }]); }; // 鼠标抬起/离开画布:停止绘制 const handleMouseUp = () => setIsDrawing(false); const handleMouseLeave = () => setIsDrawing(false); return ( <div className="canvas" onMouseDown={handleMouseDown} onMouseMove={handleMouseMove} onMouseUp={handleMouseUp} onMouseLeave={handleMouseLeave} style={{ position: 'relative', width: '800px', height: '600px', border: '1px solid #000' }} > {items.map((item, index) => ( <div key={index} className="test" style={{ position: 'absolute', left: `${item.x - 5}px`, top: `${item.y - 5}px`, width: '10px', height: '10px', borderRadius: '50%', backgroundColor: '#000' }} ></div> ))} </div> ); } export default CanvasApp;
关键说明
- 彻底移除
draggable属性和onDrag事件,完全禁用浏览器原生拖拽行为; - 用
isDrawing状态精准控制绘制逻辑:只有鼠标按下时,移动才会记录坐标; - 通过
useRef存储最新的items数组,解决mousemove回调中因为闭包获取旧数据的问题; - 添加
onMouseLeave事件,防止鼠标移出画布后仍持续绘制。
这样修改后,就能实现你想要的“按下鼠标移动绘制线条”效果,同时不会出现div被拖拽的问题。
内容的提问来源于stack exchange,提问作者Tory
相关产品推荐
相关产品推荐

