<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body{
margin:0;
padding:0;
}
#map{
position: absolute;
top:0;
bottom:0;
width:100%;
}
</style>
<script src='./mapbox-gl.js'></script>
<link href='./mapbox-gl.css' rel='stylesheet' />
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = '你的accessToken';
let map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
});
let size = 200;
let pulsingDot = {
width:size,
height:size,
data:new Uint8Array(size*size*4),
onAdd:function () {
//创建一个canvas元素
let canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
//获取context对象
this.context = canvas.getContext('2d');
},
render:function () {
//持续时间
let duration = 1000;
/*
* performance是前端性能监控的API
* 它可以检测白屏时间,首屏时间,用户可操作的时间节点,
* 页面总下载的时间,DNS查询的时间,TCP链接的时间
* 更详细的请查看 https://blog.csdn.net/mx18519142864/article/details/105967067?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159529741319724848315909%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159529741319724848315909&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-1-105967067.pc_ecpm_v3_pc_rank_v3&utm_term=performance
* performance.now()
* 返回一个当前页面执行的时间的时间戳,该方法使用了一个浮点数,返回的是以
* 毫秒为单位,小数点精确到微秒级别的时间,相比于Date.now()更精确
*
* */
let t = (performance.now()%duration)/duration;
/*
* 此处radius应该是中间不动的圆的半径,加上而外面圆的半径是从
* 和中间圆一样的大小开始随着t(t的变化是从0-1的)的增大而增大,
* 从而产生最终的效果
*
* */
let radius = size/2*0.3;
let outerradius = size/2*0.7*t +radius;
let context = this.context;
//画外面的圆
/*
* clearRect(x,y,width,height)
* :在给定的矩形内清除指定的像素
* 参数:
* x:要清除的矩形左上角的x坐标
* y:要清除的矩形左上角的y坐标
* width:要清除的矩形的宽度,以像素计
* height:要清除的矩形的高度,以像素计
*
* */
context.clearRect(0,0,this.width,this.height);
//beginPath():开始一条路径或充值当前的路径
context.beginPath();
/*
* arc():绘制圆或弧线
* 参数:
* x:圆的中心的x坐标
* y:圆的中心的y坐标
* r:圆的半径
* sAngle:起始角,以弧度计(弧的圆形的三点钟位置是0度)
* eAngle:结束角
* counterclockwise:可选,逆时针还是顺时针绘图,flase=顺时针,true=逆时针
*
* */
context.arc(this.width/2,this.height/2,outerradius,0,Math.PI*2);
/*
* fillStyle:设置或返回用于填充绘画的颜色,渐变或模式
* 属性值:
* color:指示绘图填充色的CSS颜色值,默认值是#000000
* gradient:用于填充绘图的渐变对象(线性或放射性)
* pattern:用于填充绘图的pattern对象
* 例子https://www.runoob.com/tags/canvas-fillstyle.html
* */
//设置颜色与变化的透明度
context.fillStyle = 'rgba(255,200,200,'+(1-t)+')';
//填充当前绘图路径
context.fill();
//画内圆
context.beginPath();
context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2);
context.fillStyle = 'rgba(255, 100, 100, 1)';
/*
* stroleStyle:设置或返回用于笔触的颜色,渐变或模式
* 属性值:
* color:指示绘图笔触颜色的CSS颜色值,默认值是#000000
* gradient:用于填充绘图的渐变对象(线性或放射性)
* pattern:用于创建pattern笔触的pattern对象
* */
context.strokeStyle = 'white';
//设置或返回当前线条的宽度
context.lineWidth = 2 + 4 * (1 - t);
context.fill();
//绘制已定义的路径
context.stroke();
/*
* getImageData()返回ImageData对象,该对象拷贝了画布指定矩形的像素数据
* 参数:
* x:开始复制的左上角位置的x坐标
* y:开始复制的左上角位置的y坐标
* width:要复制的矩形区域的宽度
* height:要复制的矩形区域的高度
*
* */
this.data = context.getImageData(0,0,this.width,this.height).data;
//使用自定义图层时,当图层发生改变,使用此方法去重渲染
map.triggerRepaint();
return true;
}
};
map.on('load',function () {
//此处id必须与下面layout内容保持一致,不然会报错
//pulsingDot为具有width,height,data的对象
//pixelRatio:图像像素与屏幕真实像素比例
map.addImage('pulsing-dot',pulsingDot,{pixleRatio:2});
//添加一个图层到地图样式上
//除了背景类型的图层,每个图层都需要引用源,图层从源从获取数据、
//可以选择过滤要素,然后定义如何对这些要素进行样式设置
let s = map.addLayer({
"id":"points",//唯一的图层名称
"type":"symbol",//显示类型为图标或文本标签
//用于此层的源的描述,出background以外的所有图层都需要
"source": {
"type": "geojson",//数据源类型为geojson
//data可以是geojson格式,也可以是geojson文件的url
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
}
}]
}
},
//
"layout": {
"icon-image": "pulsing-dot"
}
});
});
</script>
</body>
</html>
如有错误,敬请指正,不胜感激~