mapbox带你一键飞行

464 阅读2分钟

最近,Mapbox GL JS 从 v2.9 开始支持将地图显示为 3D 地球。

话不多说,马上看看效果怎么样:

c7355f47-b7f8-48fa-9897-4a4ed1957767.gif

我们通过设置投影属性projection:globe,即可将地图更改为地球

const map = new mapboxgl.Map({
    container: 'map',
    projection: 'globe'
});

地图基础数据配置

    var map = new mapboxgl.Map({
      style: "mapbox://styles/mapbox/satellite-streets-v11",
      // center: [121.42, 31.22], //上海市长宁区
      // zoom: 11.5, //缩放级别
      // minZoom: 9,
      // maxZoom: 19,
      container: "map",
      // pitch: 60, // 俯视
      projection: "globe",
      localIdeographFontFamily: "'Noto Sans', 'Noto Sans CJK SC', sans-serif",
      ...start,
      
    });

氛围造型:朦胧星星

在这里插入图片描述

map.on('style.load', () => {
    map.setFog({
        color: "rgb(186, 210, 235)",
        'high-color': 'rgb(36, 92, 223)', 
        'horizon-blend': 0.02, 
        'space-color': 'rgb(11, 11, 25)', 
        'star-intensity': 0.6 
      });
});

你可以自定义配置,支持缩放表达式

配置飞行动画

  //球体飞行
  const start = {
      center: [80, 36], //放置在屏幕中心的位置
      zoom: 1,  //所需的缩放级别
      pitch: 0,  //所需的音高(以度为单位
      bearing: 0, //所需的方位角(以度为单位)
  };
  const end = {
      center: [121.42, 31.22],
      zoom: 12.5,
      bearing: 130,
      pitch: 75,
  };
    
 let isAtStart = true;
      document.getElementById("fly").addEventListener("click", () => {
        const target = isAtStart ? end : start;
        isAtStart = !isAtStart;
        map.flyTo({
          ...target,
          duration: 12000,
          essential: true,
        });
 });
  • animate :false 不会出现动画。 (boolean)false
  • duration :动画的持续时间,以毫秒为单位。 (number)
  • easing :一个函数,时间在 0..1 范围内,并返回一个数字,其中 0 是初始状态,1 是最终状态。 (Function)
  • essential :true则动画被认为是必不可少的,不会受到影响 。 (boolean)trueprefers-reduced-motion
  • offset :动画结束时目标中心相对于真实地图容器中心的偏移量。 (PointLike)
  • preloadOnly :ture它会触发瓦片在动画路径上的加载,但不会发生动画。 (boolean)true
 <Button id="fly" type="dashed">
      <span>一键飞行✈️</span>
 </Button>

旋转动画

function rotateCamera(timestamp: any) {
  map.rotateTo((timestamp / 100) % 360, { duration: 0 });
  requestAnimationFrame(rotateCamera);
}
//动画
rotateCamera(0);
const layers = map.getStyle().layers;
for (const layer of layers) {
	if (layer.type === "symbol" && layer.layout["text-field"]) {
		map.removeLayer(layer.id);
	}
}

最后,很高兴附上github地址,以及demo体验地址希望能够帮助到你~