Official website example: Add an animated icon to the map | Mapbox GL JS
accomplish
sample data
const sampleData = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"coordinates": [
112.58261709330202,
22.76596784315703
],
"type": "Point"
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"coordinates": [
113.59425670069453,
23.67775776441485
],
"type": "Point"
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"coordinates": [
114.37244101407515,
23.249455907195042
],
"type": "Point"
}
}
]
}
main content
// !引入地图对象 const map = new mapboxgl.Map({
{...}) 的那个
import map from "../creatMap.js";
export class AnimatedPoint {
constructor() {
const size = 200;
const pulsingDot = {
width: size,
height: size,
data: new Uint8Array(size * size * 4),
// When the layer is added to the map,
// get the rendering context for the map canvas.
onAdd: function () {
const canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
this.context = canvas.getContext('2d');
},
// Call once before every frame where the icon will be used.
render: function () {
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 = this.context;
// Draw the outer circle.
context.clearRect(0, 0, this.width, this.height);
context.beginPath();
context.arc(
this.width / 2,
this.height / 2,
outerRadius,
0,
Math.PI * 2
);
context.fillStyle = `rgba(255, 200, 200, ${
1 - t})`;
context.fill();
// Draw the inner circle.
context.beginPath();
context.arc(
this.width / 2,
this.height / 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();
// Update this image's data with data from the canvas.
this.data = context.getImageData(
0,
0,
this.width,
this.height
).data;
// Continuously repaint the map, resulting
// in the smooth animation of the dot.
map.triggerRepaint();
// Return `true` to let the map know that the image was updated.
return true;
}
};
map.addImage('pulsing-dot', pulsingDot, {
pixelRatio: 1 });
}
// 绘制点
drawPoint(features) {
// 如果已经存在名为animatedPoint的数据源了,就更新数据
// 否则就新建一个数据源和图层
if (map.getSource('animatedPoint')) {
map.getSource('animatedPoint').setData({
type: "FeatureCollection",
features: features,
});
} else {
map.addSource('animatedPoint', {
type: "geojson",
data: features
})
map.addLayer({
'id': 'animatedPoint', //图层ID
'type': 'symbol', //图层类型
'source': 'animatedPoint', //数据源
layout: {
'icon-image': 'pulsing-dot',
'icon-anchor': 'center',
},
})
}
}
// 移除点图层
clearPoint() {
if (map.getSource('animatedPoint')) {
map.removeLayer('animatedPoint')
map.removeSource('animatedPoint')
}
}
}
transfer
// 引入
import {
AnimatedPoint } from './AnimatedPoint'
// 声明
window.animatedPoint = new AnimatedPoint()
// 绘制示例数据
window.animatedPoint.drawPoint(sampleData)
// 移除示例数据的图层
window.animatedPoint.clearPoint()
illustrate
Introduction to Core Objects
The core of this function is const pulsingDot = {...}
this end. pulsingDot
This object represents a dynamic pulse point, which includes the following properties and methods:
width
andheight
: represent the width and height of the pulse point respectively.data
: Represents the pixel data stored in the form of a one-dimensional array for rendering animation effects.onAdd
: The method used to add pulse points to the map, will create a canvas element, and set its size to be the same as the object'swidth
andheight
attributes.render
: The method used to render dynamic pulse points on the canvas. Inside the method, the progress percentage of the current time relative to the total time of a cycle is first calculatedt
. Next,t
calculate the size, color and border of the pulse point according to the style, and use the canvas API to draw the effect of the pulse point on the canvas. Finally copy the result intodata
a property of this object and notify the map to redraw.
The effect of this dynamic pulse point is render
realized by calling the method regularly. Each time this method is called, the effect of the pulse point is recalculated and drawn, and the pixel data ( this.data
) in it is updated. After adding this object to the map, it will automatically call its onAdd
methods to initialize the canvas and complete some other settings.
The final final use map.triggerRepaint()
of causes the map view to do a redraw.
onAdd
onAdd
is a function in the Mapbox GL JS API that is a callback function that is executed when a custom map element is added to the map. When you use methods such as map.addControl
, map.addSource
, or map.addLayer
to add a custom layer, control or source to the map, Mapbox GL JS will automatically call the onAdd()
function of the element to perform some initialization settings.