如何为React-Leaflet的CSS SVG路线动画绑定onAnimationEnd事件
解决方案
你需要监听Leaflet Routing的路线加载完成事件,再手动给动态生成的路径元素绑定animationend原生事件,具体实现如下:
核心思路
- Leaflet Routing计算完路线后会触发
routesfound事件,此时路径DOM元素才会被插入页面 - 在事件回调中获取所有带有
animate类的路径元素,绑定animationend事件监听 - 组件卸载时清理所有事件监听器避免内存泄漏
修改后的代码示例
1. Map组件调整
export default function Map() { // ...其余代码保持不变 const RoutingMachineRef = useRef(null); useEffect(() => { if (!RoutingMachineRef.current) return; const routingInstance = RoutingMachineRef.current; // 动画结束后的业务逻辑 const handleRouteAnimationEnd = (e) => { console.log('路线绘制动画已完成', e.target); // 此处添加你需要执行的逻辑 }; // 路线计算完成后绑定动画事件 const handleRouteLoaded = () => { // 短延时确保DOM已渲染完成,复杂场景可替换为MutationObserver setTimeout(() => { const animatePathList = document.querySelectorAll('path.leaflet-interactive.animate'); animatePathList.forEach(pathEl => { // 先移除旧监听避免重复绑定 pathEl.removeEventListener('animationend', handleRouteAnimationEnd); pathEl.addEventListener('animationend', handleRouteAnimationEnd); }); }, 50); }; // 绑定路线加载事件 routingInstance.on('routesfound', handleRouteLoaded); // 设置路点触发路线计算 routingInstance.setWaypoints([start, end]); // 清理函数 return () => { // 移除路线加载事件监听 routingInstance.off('routesfound', handleRouteLoaded); // 移除所有路径元素的动画事件监听 const animatePathList = document.querySelectorAll('path.leaflet-interactive.animate'); animatePathList.forEach(pathEl => { pathEl.removeEventListener('animationend', handleRouteAnimationEnd); }); }; }, [start, end]); // 仅需依赖start和end即可,RoutingMachineRef为稳定引用无需加入依赖 return( <MapContainer> <RoutingMachine ref={RoutingMachineRef} waypoints={[start, end]} /> </MapContainer> ) };
2. 其余代码无需改动
你原来的RoutingMachine组件和CSS代码可以保持不变。
可选优化
如果对延时方案不满意,可使用MutationObserver监听地图容器的DOM变化,匹配到带animate类的路径元素插入时自动绑定事件,适合路点频繁更新的场景。
内容的提问来源于stack exchange,提问作者lys
相关产品推荐
相关产品推荐

