谷歌地图实现扩散波效果

最近在做有关地图的工作,使用的技术栈是谷歌地图,先说一下需求吧。
需求背景:
现在地图上有marker,我要在marker上面添加一层扩散波的波纹效果;
整体思路:
首先要考虑,实现扩散波的起点,或者说入口,就是谷歌地图的maps对象里的Circle方法。实现扩散其实就是需要在marker上使用circle画一些圆,然后让圆圈以一定的速度改变半径、透明度等要素;
下面开始上代码啦:

function DiffusionWave(radius, level, point, color, zoom, map) {
	this.radius = radius // 半径
	this.google = window.google
	this.level = level // 扩散波数量
	this.point = point // 添加扩散波的位置
	this.zoom = zoom // 地图层级
	this.map = map // 谷歌地图实例
	this.color = color // circle配置对象,主要是fillColor,fillOpacity等,根据业务需求可以自己添加其他属性
	// 我自己的代码在这里由于需求,有一部分限制扩散波范围的逻辑,就是一些简单的判断,需要的朋友自己加一下,我就不写了。
	this.endOpacity = 0.5
	this.speedOpacity = (this.color.fillOpacity - this.endOpacity) / this.radius
	// 这里是计算了每一次变化透明度的变化速度
	this.circles = []
	for (let i =  1; i < this.level; i++) {
		const circle = new this.google.maps.Circle({
			strokeColor: color.strokeColor,
			strokeOpacity: 0.8,
			strokeWeight: 1,
			fillColor: color.fillColor,
			fillOpacity: 0.35,
			map: this.map,
			center: this.point
			radius: 100
		})
		this.circles.push(circle)
	}
	this.clock = new Array(this.level)
}
DiffusionWave.prototype.start = function (delay, speed) {
	const that = this
	function animateStart (startTime, circle, index) {
		const time = new Date.getTime() - startTime
		if (time < 0) {
			circle.setOptions({
				strokeColor: that.color.strokeColor,
				strokeOpacity: 0.8,
				strokeWeight: 1,
				fillColor: that.color.fillColor,
				fillOpacity: 0.35,
				map: that.map,
				center: that.point,
				radius: 0
			})
			//这里的window方法的使用,详见https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame
			that.clock[index] = window.requestAnimationFrame(animateStart.bind(null, startTime, circle, index))
			return
		}

		const r = Math.floor(that.radius * (2 * time / speed - time * time / speed / speed))
		if (time >= speed) {
			circle.setOptions({
				strokeColor: that.color.strokeColor,
				strokeOpacity: 0.8,
				strokeWeight: 1,
				fillColor: that.color.fillColor,
				fillOpacity: 0.35,
				map: that.map,
				center: that.point,
				radius: 0
			})
			startTime = new Date().getTime() + delay
			that.clock[index] = window.requestAnimationFrame(animateStart.bind(null, startTime, circle, index))
		} else {
			const opacity = that.color.fillOpacity - Number.parseFloat((that.speedOpacity * r).toFixed(5))
			circle.setOptions({
				strokeColor: that.color.strokeColor,
				strokeOpacity: opacity,
				strokeWeight: 1,
				fillColor: that.color.fillColor,
				fillOpacity: opacity,
				map: that.map,
				center: that.point,
				radius: r
			})
		    that.clock[index] = window.requestAnimationFrame(animateStart.bind(null, startTime, circle, index))
		}
	}
	for (const [index, circle] of this.circles.entries()) {
		animateStart(new Date().getTime() + index * delay, circle, index)
	}
}

DiffusionWave.prototype.remove = function () {
	for(const caf of clock) {
		window.cancelAnimationFrame(caf)
	}
	for (const circle of this.circles) {
		circle.setMap(null)
	}
}

代码到这里就结束了,因为内网开发,这些代码都是手打的,可能会有错误的地方,欢迎指正。
这里呢,其实这种方法也不是我自己想到的,借鉴了网友的案例,然后根据我自己的需求进行了改造,基本上实现了我这边的需求,在此非常感谢各位网友,帮助我成长了不少。
学习这些代码让我感触最深的就是两点,第一是实现一个需求或者功能,的一种思路,尽管很多官方已经给我们提供了非常方便的API,但是有时候项目需要更’酷炫’的效果,就需要我们自己封装了。第二是以前没关注过requestAnimationFrame这个API,哈哈,这次也了解了一些。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值