React-Konva中Shape与Stage的onClick事件冲突问题咨询
解决React-Konva中Stage与Shape的onClick事件冲突问题
方案1:阻止Shape事件冒泡
在Shape的点击回调中阻止事件向上冒泡,这样点击Shape时就不会触发Stage的点击事件:
const Basic = ({points}) => { const onBasicClick = (e) => { console.log("onBasicClick"); // 阻止事件冒泡到Stage e.cancelBubble = true; }; return ( <Shape points={points} onClick={onBasicClick} sceneFunc={(context, shape) => { // 自定义形状绘制逻辑,示例绘制一个以点击点为中心的矩形 context.beginPath(); context.rect(points.x - 20, points.y - 20, 40, 40); context.fillStrokeShape(shape); }} stroke="#C879E6" strokeWidth={1} fill='#F6DEFF' /> ); };
方案2:在Stage的点击事件中判断目标元素
通过判断点击事件的目标是否为Stage本身,仅在点击空白区域时添加新形状:
function App() { const [basicFigure, setBasic] = useState([]); const onSolveClick = (e) => { // 仅当点击对象是Stage本身时,执行添加逻辑 if (e.target === e.target.getStage()) { const pos = e.target.getStage().getPointerPosition(); const newBasicFigure = [...basicFigure, pos]; setBasic(newBasicFigure); } }; return ( <> <Stage width={w} height={h} onClick={onSolveClick}> <Layer> {basicFigure.map(item => ( <Basic points={item} key={`${item.x}-${item.y}`} /> ))} </Layer> </Stage> </> ); }
方案3:通过点击位置检测已有形状(你的思路落地)
利用Konva的getIntersection方法,检查点击位置是否被已有形状覆盖,若有则不添加新形状:
function App() { const [basicFigure, setBasic] = useState([]); const layerRef = useRef(null); const onSolveClick = (e) => { const stage = e.target.getStage(); const pos = stage.getPointerPosition(); // 检测点击位置是否命中Layer内的任意形状 const hitShape = layerRef.current?.getIntersection(pos); if (!hitShape) { // 未命中任何形状,添加新形状 const newBasicFigure = [...basicFigure, pos]; setBasic(newBasicFigure); } }; return ( <> <Stage width={w} height={h} onClick={onSolveClick}> <Layer ref={layerRef}> {basicFigure.map(item => ( <Basic points={item} key={`${item.x}-${item.y}`} /> ))} </Layer> </Stage> </> ); }
注意:此方案要求sceneFunc中正确定义了形状的路径,Konva的命中检测依赖于该路径的准确性。
内容的提问来源于stack exchange,提问作者sieun
相关产品推荐
相关产品推荐

