高德地图setFitView效果优化,模拟mapbox动画效果,高德镜头动画

高德地图setFitView效果前后对比视频

高德setfitVIew效果

是不是好多了,做这个东西完全是想吐槽一下高德地图的动画效果太拉了,完全跟不上现代的审美,做得好的想苹果地图、mapbox、cesium,他们的切换动画做的很好,就想着在高德上实现这种动画,让它的过度变得流畅起来,开干!

原本的代码:

// 合适的位置
 map.setFitView([marker的数组], false, [UI上下左右的偏移])

首先是知道到中心点,我们只需要传进点位数组,会自动计算出中心点,这里用到turf插件,这是个特别特别好用的数学地理插件,强烈推荐:Turf.js中文网 (fenxianglu.cn) ,高德自带也有,不过turf更专业

npm install @turf/turf


//获取中心点代码,points:[ [lng,lat],[lng,lat],... ]
export function getFitCenter(points) {
	let features = turf.featureCollection(points.map((point) => turf.point(point)));
	let center = turf.center(features);
	return [center.geometry.coordinates[0], center.geometry.coordinates[1]];
}

其次是知道合适的zoom级别,这是难点,高德似乎没有返回合适的zoom级别api,那就的自己写了,,后续会加上考虑UI的偏移,比如说右边有一个悬浮的操作界面,那么展示的时候就往左偏移一点,就像手机版高德那样


//map是好的地图实例化后的map,points是位置数据,同上
export function getFitZoom(map, points) {
	const mapWidth = map.getSize().width;
	const mapHeight = map.getSize().height;

	const WORLD_DIM = { height: 256, width: 256 };
	const ZOOM_MAX = 18;
	let features = turf.featureCollection(points.map((point) => turf.point(point)));
	const bounds = turf.bbox(features); // [minX, minY, maxX, maxY]

	function zoom(mapPx, worldPx, fraction) {
		return Math.floor(Math.log(mapPx / worldPx / fraction) / Math.LN2);
	}

	const latFraction = (bounds[3] - bounds[1]) / WORLD_DIM.height;
	const lngFraction = (bounds[2] - bounds[0]) / WORLD_DIM.width;

	const latZoom = zoom(mapHeight, WORLD_DIM.height, latFraction);
	const lngZoom = zoom(mapWidth, WORLD_DIM.width, lngFraction);

	return Math.min(latZoom, lngZoom, ZOOM_MAX);
}

我们现在知道的中心点和缩放级别,接下来的事就交给镜头动画了,舒服的贝塞尔曲线会让画面更高级,更自然,这里推荐一个在线编辑贝塞尔曲线:CSS3贝塞尔曲线工具 - bejson在线工具 也可以用到css的动画中,废话不多说,首先我们加载loca

AMapLoader.load({
		key: AMAP_KEY,
		version: AMAP_VERSION,
		Loca: {
			version: "2.0.0",
		},
		plugins: AMAP_PLUGINS.concat(["Loca"]),   //这里我是继续添加进去,你可以这样写[你用到的插件、你用到的插件、"Loca"]

	}).then((AMap) => {
		instance = AMap;

		map = new instance.Map(mapRef.value, {
			...AMAP_DEFAULT_THEME,
			zoom: 10,
			showLabel: false,
			pitch: 0,
			center: [117.260355, 31.875092],
			viewMode: "2D",
			skyColor: "#0D121F",
		});


		// 创建 Loca 容器
		loca = new Loca.Container({  //这里加载loca,放到全局,方便使用
			map: map,
		});

高德镜头动画函数:

export function setFitView(center, zoom,map, loca) {
	const curZoom = map.getZoom();
	const curPitch = map.getPitch();
	const curRotation = map.getRotation();
	const curCenter = [map.getCenter().lng, map.getCenter().lat];

	const targZoom = zoom;
	const targPitch = 0;
	const targRotation = 0;
	const targCenter = center;

	const route = [
		{
			pitch: {
				value: targPitch,
				duration: 1000,
				control: [
					[0, curPitch],
					[1, targPitch],
				],
				timing: [0.23, 1.0, 0.32, 1.0],
			},
			zoom: {
				value: targZoom,
				duration: 3000,
				control: [
					[0, curZoom],
					[1, targZoom],
				],
				timing: [0.13, 0.31, 0.105, 1],
			},
			rotation: {
				value: targRotation,
				duration: 1000,
				control: [
					[0, curRotation],
					[1, targRotation],
				],
				timing: [0.13, 0.31, 0.105, 1],
			},
			center: {
				value: targCenter,
				duration: 1500,
				control: [curCenter, targCenter],
				timing: [0.13, 0.31, 0.105, 1],
			},
		},
	];

	loca.viewControl.addAnimates(route, () => {});
loca.animate.start();
}

使用


	// 之前的代码
	// map.setFitView(currentRoute.points, false)

	const points = currentRoute.points.map((item) => [item.getPosition().lng,                 
    item.getPosition().lat]);


	const fitzoom = getFitZoom(map, points);
	const fitcenter = getFitCenter(points);
	setFitView(fitcenter, fitzoom , map, loca);

欧克!对你有帮助记得关注一下哦

  • 10
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值