如何判断olext动画已结束?Openlayers是否有动画结束监听事件?
Openlayers+olext feature动画结束监听与防重复触发方案
olext的animateFeature方法本身支持动画结束回调,不需要额外监听全局事件,配合状态锁即可实现动画执行完成前禁止重复触发的需求,具体实现如下:
推荐实现方式:使用官方提供的结束回调
map.animateFeature支持传入第三个参数作为动画结束后的回调函数,配合全局状态锁即可实现防重复触发,修改后的代码示例:
// 定义在动画触发逻辑外层的状态锁,false表示当前无正在执行的动画 let isAnimating = false; // 动画触发入口处先校验状态 if (!isAnimating) { // 触发动画前先上锁 isAnimating = true; var f = new ol.Feature(new ol.geom.Point(coord)); f.setStyle(new ol.style.Style({ image: new ol.style.Circle({ radius: 18, points: 10, stroke: new ol.style.Stroke({ color: "rgba(0,0,0,1)", width:3 }) }) })); map.animateFeature(f, new ol.featureAnimation.Zoom({ fade: ol.easing.easeOut, duration: 1300, easing: ol.easing["easeOut"] }), () => { // 动画执行完成后自动触发该回调,释放状态锁 isAnimating = false; // 可在此处添加其他动画结束后需要执行的逻辑 }); }
旧版本兼容实现:定时器兜底方案
如果你使用的olext版本较老,不支持结束回调参数,可以直接和你配置的duration动画时长对齐,用定时器释放状态锁:
let isAnimating = false; if (!isAnimating) { isAnimating = true; var f = new ol.Feature(new ol.geom.Point(coord)); f.setStyle(new ol.style.Style({ image: new ol.style.Circle({ radius: 18, points: 10, stroke: new ol.style.Stroke({ color: "rgba(0,0,0,1)", width:3 }) }) })); map.animateFeature(f, new ol.featureAnimation.Zoom({ fade: ol.easing.easeOut, duration: 1300, easing: ol.easing["easeOut"] })); // 定时器时长和动画配置的duration保持一致,到期释放锁 setTimeout(() => { isAnimating = false; }, 1300) }
注意事项
- 状态锁变量需要定义在动画触发逻辑的外层,确保多次触发动画时读取的是同一个变量状态
- 如果你的业务逻辑中存在动画中途取消的场景(比如移除动画关联的feature、销毁地图实例),需要在取消逻辑中同步将
isAnimating重置为false,避免出现锁死无法触发动画的问题
内容的提问来源于stack exchange,提问作者howord
相关产品推荐
相关产品推荐

