React-Konva拖拽组后如何获取/更新子元素位置
React-Konva 多边形拖拽跳动问题解决
我在基于react-konva开发的Web应用中实现了一个可绘制以圆形为顶点的多边形工具,目前已支持拖拽单个顶点并更新状态,但希望实现整个多边形的拖拽功能,通过获取组内圆形的新位置来更新状态。
我尝试在handleDragEnd函数中编写了以下代码:
const handlePolygonDragEnd = ( event: KonvaEventObject<DragEvent>, polygonName: string ) => { if (isDrawing) return; const group = event.target; const newGroupPosition = {x:group.x(), y:group.y()}; if (group === null) return; if (group instanceof Konva.Group) { // const children = group.getChildren().slice(1); const newPolygons = polygons.map((polygon) => { if (polygon.name === polygonName) { const newPoints = polygon.points.map((point) => { return [point[0] + newGroupPosition.x, point[1] + newGroupPosition.y]; }); return { ...polygon, points: [...newPoints], }; } return polygon; }); setPolygons(newPolygons); // group.setAbsolutePosition({ x: 0, y: 0 }); } };
但运行后发现多边形会出现跳动现象,无法停留在拖拽后的预期位置。
问题原因
- 直接使用
group.x()和group.y()作为偏移量,但Konva Group的位置是累积的,每次拖拽后Group位置会叠加,导致计算的偏移量错误。 - 未在更新状态后重置Group位置,React重渲染时,Group位置与顶点绝对位置重复叠加,引发跳动。
修复后的代码
const handlePolygonDragEnd = ( event: KonvaEventObject<DragEvent>, polygonName: string ) => { if (isDrawing) return; const group = event.target; if (!(group instanceof Konva.Group)) return; // 获取本次拖拽的实际偏移量 const deltaX = group.x(); const deltaY = group.y(); const newPolygons = polygons.map((polygon) => { if (polygon.name === polygonName) { const newPoints = polygon.points.map((point) => { return [point[0] + deltaX, point[1] + deltaY]; }); return { ...polygon, points: [...newPoints], }; } return polygon; }); setPolygons(newPolygons); // 重置Group位置为原点,避免偏移量累积 group.setPosition({ x: 0, y: 0 }); };
关键修复点
- 用
deltaX和deltaY记录本次拖拽的实际偏移量,而非直接使用Group当前位置。 - 更新顶点状态后,必须调用
group.setPosition({x:0, y:0})重置Group位置,确保下次拖拽时偏移量计算准确,避免重复叠加导致的跳动。
内容的提问来源于stack exchange,提问作者Umar Hassan
相关产品推荐
相关产品推荐

