如何使用Konva为单个图形设置键盘移动事件
解决Konva多图形单独键盘移动的问题
你的问题核心是:每次点击图形都会给容器新增一个keydown事件监听,旧的监听没有被移除,导致按方向键时所有被点击过的图形对应的事件都会触发,最终多个图形一起移动。
下面是修正后的代码,关键是维护一个「当前选中图形」的变量,只绑定一次键盘事件:
<div id="container"></div> <script> var stage = new Konva.Stage({ container: 'container', width: window.innerWidth, height: window.innerHeight, }); var layer = new Konva.Layer(); stage.add(layer); var circle = new Konva.Circle({ x: stage.width() / 2, y: stage.height() / 2 + 10, radius: 70, fill: 'red', stroke: 'black', strokeWidth: 4, }); layer.add(circle); var rect = new Konva.Rect({ x: 300, y: 10, width: 70, height: 70, stroke: 'black', fill: 'blue', strokeWidth: 2, cornerRadius: 2, id: 'cRectSquare', visible: true, draggable: true, }); layer.add(rect); // 存储当前选中的图形 let selectedShape = null; const DELTA = 3; const container = stage.container(); container.tabIndex = 1; // 只绑定一次keydown事件 container.addEventListener('keydown', function (e) { // 没有选中图形则直接返回 if (!selectedShape) return; if (e.keyCode === 37) { selectedShape.x(selectedShape.x() - DELTA); } else if (e.keyCode === 38) { selectedShape.y(selectedShape.y() - DELTA); } else if (e.keyCode === 39) { selectedShape.x(selectedShape.x() + DELTA); } else if (e.keyCode === 40) { selectedShape.y(selectedShape.y() + DELTA); } else { return; } e.preventDefault(); // 移动后刷新图层确保显示更新 layer.draw(); }); // 点击事件:更新选中的图形 stage.on('click', function (e) { if (e.target === stage) { selectedShape = null; return; } selectedShape = e.target; container.focus(); }); </script>
关键改动说明
- 新增
selectedShape变量,专门存储当前被点击选中的图形 - 只给容器绑定一次
keydown事件,事件内只操作selectedShape对应的图形 - 点击事件仅负责更新
selectedShape的值,并让容器获得焦点(保证键盘事件能触发) - 移除了原代码中无效的
mousemove事件处理:原代码用匿名函数绑定事件,无法通过removeEventListener移除,这部分逻辑完全不起作用 - 新增
layer.draw()确保图形移动后图层能及时刷新显示
内容的提问来源于stack exchange,提问作者José Maia
相关产品推荐
相关产品推荐

