You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:24:05