在基于BMapGL的Web地图应用中,为了展示更加生动、直观的地理信息,需要对地图中的卡点进行动画展示。本文介绍了如何使用BMapGL提供的API和自定义渲染方式,实现个性化、交互式的动画卡点效果。
本代码主要实现了以下功能:
await Promise.all([
this.loadScripts([
'https://api.map.baidu.com/api?type=subway&v=1.0&ak=cxtWZ9zGiLlLdQwBSuGGwpanwqfaLvEc&services=&t=20240319170303',
'http://api.map.baidu.com/getscript?type=webgl&v=1.0&ak=cxtWZ9zGiLlLdQwBSuGGwpanwqfaLvEc&services=&t=20240319170303',
]),
])
const BMapGL = window.BMapGL
class CustomSymbol extends BMapGL.Symbol {
constructor(_size, _anchor) {
super(_size, _anchor)
this.isReDraw = true
}
render(map) {
const duration = 1500
const t = (performance.now() % duration) / duration
const radius = (this.width / 2) * 0.1
const outerRadius = (this.width / 2) * 0.5 * t + radius
const context = this.context
context.save()
context.beginPath()
context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2)
context.fillStyle = 'rgba(38,1,252,' + (1 - t) + ')'
context.fill()
context.beginPath()
context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2)
context.fillStyle = 'rgba(38,1,252, 1)'
context.strokeStyle = 'rgba(38,1,252, .1)'
context.lineWidth = 2 + 4 * (1 - t)
context.fill()
context.stroke()
context.restore()
this.data = context.getImageData(
0,
0,
this.context.canvas.width,
this.context.canvas.height,
)
return true
}
}
render
方法中,根据时间动态绘制扩散圆动画。map.addOverlay(marker1)
。// 自定义canvas
const canvas = document.createElement('canvas')
canvas.width = size * 2
canvas.height = size * 2
function getRadarTextureCanvas() {
const duration = 1000
const t = (performance.now() % duration) / duration
const radius = (size / 2) * 0.3
const outerRadius = (size / 2) * 0.7 * t + radius
const context = canvas.getContext('2d')
context.save()
context.beginPath()
context.arc(size / 2, size / 2, outerRadius, 0, Math.PI * 2)
context.fillStyle = 'rgba(255,200,200,' + (1 - t) + ')'
context.fill()
context.beginPath()
context.arc(size / 2, size / 2, radius, 0, Math.PI * 2)
context.fillStyle = 'rgba(255, 100, 100, 1)'
context.strokeStyle = 'white'
context.lineWidth = 2 + 4 * (1 - t)
context.fill()
context.stroke()
context.restore()
}
var canvasOverlay = new BMapGL.GroundOverlay(bounds, {
type: 'canvas',
url: canvas,
opacity: 0.9,
isReDraw: true,
drawHook: getRadarTextureCanvas,
})
map.addOverlay(canvasOverlay)
drawHook
。getRadarTextureCanvas
函数中,根据时间动态绘制雷达扫描动画。map.addOverlay(canvasOverlay)
。function RAIN(ctx, t, dotColor, clodColor) {
var w = ctx.canvas.width,
h = ctx.canvas.height,
s = Math.min(w, h)
rainObject(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, dotColor)
cloudObject(ctx, t, w * 0.5, h * 0.37, s * 0.9, s * STROKE, clodColor)
}
class RainSymbol extends BMapGL.Symbol {
constructor(_size, _anchor) {
super(_size, _anchor)
this.isReDraw = true
}
render(map) {
this.context.clearRect(0, 0, this.width * 2, this.height * 2)
var time = Date.now()
RAIN(this.context, time, '#BFBFBF', '#999')
this.data = this.context.getImageData(
0,
0,
this.context.canvas.width,
this.context.canvas.height,
)
return true
}
}
render
方法中,根据时间动态绘制雨滴动画。map.addOverlay(marker2)
。<ul class="drawing-panel">
<li class="btn" onclick="stop()">动画停止</li>
<li class="btn" onclick="start()">动画开始</li>
</ul>
function start() {
custom.isReDraw = true
canvasOverlay.isReDraw = true
}
function stop() {
custom.isReDraw = false
canvasOverlay.isReDraw = false
}
isReDraw
属性控制动画是否重绘。本代码展示了如何使用BMapGL的API和自定义渲染方式,实现个性化、交互式的动画卡点效果。该方法可以广泛应用于展示动态数据、可视化分析等场景。
未来拓展与优化方向: