基于Leaflet与Leaflet Routing Machine的撤销/重做功能实现求助
完善Leaflet Routing Machine的撤销/重做功能
咱们先梳理下核心思路:要实现完整的撤销/重做,光靠一个activityBuffer是不够的,得再加一个缓冲区存被撤销的操作(方便重做);另外你用到的undoFlag用来区分「正常操作」和「撤销/重做触发的状态恢复」,这个思路很对,避免把恢复的状态重复存入历史。接下来我帮你补全代码并优化细节:
1. 完善变量定义
首先补充重做缓冲区,同时初始化时要把初始路点存入历史,避免第一次撤销出错:
// 历史操作缓冲区:存每次变更后的路点状态 var activityBuffer = []; // 重做缓冲区:存被撤销的操作,方便恢复 var redoBuffer = []; // 标记是否是撤销/重做触发的状态变更,避免重复存入历史 var undoFlag = false; // 初始化:把初始路点存入历史缓冲区 activityBuffer.push(Routing.getWaypoints());
2. 优化routeselected事件监听
当用户正常修改路点时,清空重做缓冲区(因为新操作后之前的撤销状态不能再重做了);如果是撤销/重做触发的状态变更,就跳过存入历史:
Routing.on('routeselected', function(){ if (undoFlag) { undoFlag = false; } else { var newWaypoints = Routing.getWaypoints(); activityBuffer.push(newWaypoints); // 新操作后清空重做缓冲区 redoBuffer = []; console.log("历史状态:", activityBuffer); } });
3. 补全undoActivity函数
撤销时,把当前状态移到重做缓冲区,然后恢复上一个历史状态:
function undoActivity(){ // 至少要有2个状态(初始+至少一次操作)才能撤销 if (activityBuffer.length > 1) { // 把当前状态移到重做缓冲区 var currentState = activityBuffer.pop(); redoBuffer.push(currentState); // 恢复上一个历史状态 var oldState = activityBuffer[activityBuffer.length - 1]; Routing.setWaypoints(oldState); // 标记这次状态变更是撤销触发的,避免存入历史 undoFlag = true; console.log("已撤销,当前历史状态数:", activityBuffer.length); } else { console.log("没有可撤销的操作"); } }
4. 添加redoActivity函数
重做时,把重做缓冲区的最后一个状态移回历史缓冲区,然后恢复该状态:
function redoActivity(){ if (redoBuffer.length > 0) { // 把重做缓冲区的最后一个状态移回历史 var redoState = redoBuffer.pop(); activityBuffer.push(redoState); // 恢复该状态 Routing.setWaypoints(redoState); // 标记这次状态变更是重做触发的,避免存入历史 undoFlag = true; console.log("已重做,当前重做缓冲区剩余:", redoBuffer.length); } else { console.log("没有可重做的操作"); } }
关键细节说明
- 双缓冲区设计:
activityBuffer记录所有正向操作的状态,redoBuffer记录被撤销的操作,这样在用户执行新操作前,都可以重做之前的撤销动作;一旦有新操作,redoBuffer就清空,符合常规的撤销/重做逻辑。 - undoFlag的作用:因为调用
Routing.setWaypoints()会触发routeselected事件,用这个标记可以区分是用户主动修改还是代码恢复状态,避免把恢复的状态重复存入历史缓冲区。 - 初始状态存入:页面加载时把初始路点存入
activityBuffer,保证第一次撤销有状态可恢复。
你可以把这些代码整合到你的项目里,然后给撤销/重做按钮绑定对应的函数(比如onclick="undoActivity()"和onclick="redoActivity()")就可以正常使用啦。
内容的提问来源于stack exchange,提问作者Farhan Habib
相关产品推荐
相关产品推荐

