基于MapBox实现缩放时固定中心标记的类Uber位置选择器
解决方案
方案1:原生配置实现(最优,无性能问题)
Mapbox 自带的交互控件支持直接指定缩放锚点,不需要手动监听高频事件修改中心,完全不会出现卡顿和多余动画:
初始化地图时修改scrollZoom和touchZoomRotate配置,强制所有缩放操作以地图中心为锚点:
const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12', center: [-74.5, 40], zoom: 9, // 核心配置:滚轮缩放以中心为锚点 scrollZoom: { around: 'center' }, // 核心配置:触摸捏合缩放以中心为锚点 touchZoomRotate: { around: 'center' } }); // 仅需要在非缩放的移动操作下更新标记位置即可 let markerLocation = map.getCenter(); const marker = new mapboxgl.Marker() .setLngLat(markerLocation) .addTo(map); map.on('move', () => { // 缩放已经固定中心,仅平移时更新标记位置 if (!map.isZooming() && !map.isRotating()) { markerLocation = map.getCenter(); marker.setLngLat(markerLocation); } });
该方案缩放过程中地图中心不会发生偏移,无跳变、无多余动画,性能最优。
方案2:修复现有代码的动画问题
如果你不需要调整地图初始化配置,仅需要把现有代码中的flyTo替换为无动画的setCenter即可去掉多余过渡:
let markerLocation = map.getCenter(); const marker = new mapboxgl.Marker() .setLngLat(markerLocation) .addTo(map); map.on('zoomend', (e) => { // 关闭动画直接设置中心 map.setCenter(markerLocation, { animate: false }); }); map.on('move', (e) => { if (map.isZooming()) { return; } markerLocation = map.getCenter(); marker.setLngLat(markerLocation); });
内容的提问来源于stack exchange,提问作者Pawel Kurzeja
相关产品推荐
相关产品推荐

