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

基于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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:27:04