控制点的透明度
在创建marker的构造当中会传递一个配置对象,这个里面就可以配置对应的透明度opacity,那么只需要去修改这个透明度的值就好了。通过定时器去一直改值即可。
const changeOpacity = (entity) => {
let i = 1;
let int = setInterval(() => {
if (!entity._map) clearInterval(int);
if (i < -1) {
i = 1;
}
i = i - 0.08;
if (i < 0) entity.setOpacity(i * -1);
else entity.setOpacity(i);
}, 60);
};
还可以对这段代码进行调整一下,改成用动画帧去渲染,那么也就是:
const changeOpacity = (entity) => {
let timer = null;
let i = 1;
function updateAnimation() {
if (!entity._map) return cancelAnimationFrame(timer);
if (i < -1) {
i = 1;
}
i = i - 0.01;
if (i < 0) entity.setOpacity(i * -1);
else entity.setOpacity(i);
timer = requestAnimationFrame(updateAnimation);
}
updateAnimation();
};
本质上是一样的,只要去改变透明度即可。最后创建一个点调用这个方法来进行测试一下
const marker2 = L.marker([22.5, 110], {}).addTo(map);
changeOpacity(marker2);
// 添加平面设置透明度,这个是下面那个,先一起把代码贴上来
// const polygon = L.polygon([
// [22, 111],
// [20, 115],
// [24, 118],
// [25, 113]
// ]).addTo(map);
// changePlaneOpacity(polygon);
拓展:控制平面的透明度
在控制平面的时候和点是不一样的,平面都继承至Path对象,这个里面需要通过setStyle去设置对应的属性,所以这里进行细微的调整一下。举一反三我们同样可以通过这种方式去改变其他属性值。
function changePlaneOpacity(entity) {
let timer = null;
let i = 1;
let j = 0.2; // 注意要和线的透明度同步修改,保持开始和结束时间一致
function updateAnimation() {
if (i < -1) {
i = 1;
}
i = i - 0.01;
if (j < -0.2) {
j = 0.2;
}
j = j - 0.002; //注意要和线的透明度同步修改,保持开始和结束时间一致
if (i < 0) entity.setStyle({opacity: i * -1, fillOpacity: j * -1});
else entity.setStyle({opacity: i, fillOpacity: j});
if (!entity._map) return cancelAnimationFrame(timer);
timer = requestAnimationFrame(updateAnimation);
}
updateAnimation();
}
leaflet-pulse-icon插件
简单使用插件,本质上就是构建出一个icon然后将这个icon作为marker标记的图标属性进行渲染
// 安装插件
// npm i @ansur/leaflet-pulse-icon
// 导入插件,同时需要把css一起导入进来
import '@ansur/leaflet-pulse-icon';
import '@ansur/leaflet-pulse-icon/dist/L.Icon.Pulse.css';
// 指定了点的大小以及外围圈的颜色
const pulsingIcon = L.icon.pulse({iconSize:[20,20],color:'red'});
const marker = L.marker([50,15],{icon: pulsingIcon}).addTo(map);
L.icon.pulse 配置说明
键 | 取值 | 说明 |
---|---|---|
iconSize | Array | 宽高 |
color | 颜色值 | 外围颜色,默认红色 |
fillColor | 颜色值 | 点的填充颜色,默认红色 |
heartbeat | 数字 | 一圈渲染完成需要时间,单位为秒,默认为1 |
渲染n个随机点
// 得到随机颜色
const getRandomColor = () => {
const r = Math.floor(Math.random() * 255);
const g = Math.floor(Math.random() * 255);
const b = Math.floor(Math.random() * 255);
return `rgb(${r},${g},${b})`;
};
// 得到min和max之间的随机整数
const getRandomInt = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const addPulseMarker = () => {
for (let i = 0; i < 100; i++) {
const size = getRandomInt(5, 10);
const color = getRandomColor();
const lat = 15 + Math.random() * 10;
const lng = 110 + Math.random() * 10;
const pulsingIcon = L.icon.pulse({
iconSize: [size, size],
color,
fillColor: color,
heartbeat: 1
});
const marker = L.marker([lat, lng], {icon: pulsingIcon}).addTo(map);
marker.bindPopup(`<b>我的位置:${lng.toFixed(2)}, ${lat.toFixed(2)}</b><br>我的尺寸${size}.`);
}
};
leaflet-pulse-icon插件源码透析
这个插件主要的就是前面引入的js和css文件。位置就在node_modules/@ansur/leaflet-pulse-icon/src
,
L.Icon.Pulse.js
- 使用的时候会使用
L.icon.pulse
在这里就是直接new了一个L.Icon.Pulse,然后传递的options配置就直接放到这里面,通过setOptions赋值 - 之后就是根据配置把对应的Dom元素给组装出来
- 最后将这个挂载到marker上也就完成了渲染
(function(window) {
L.Icon.Pulse = L.DivIcon.extend({
options: {
className: '',
iconSize: [12,12],
fillColor: 'red',
color: 'red',
animate: true,
heartbeat: 1,
},
initialize: function (options) {
L.setOptions(this,options);
// css
var uniqueClassName = 'lpi-'+ new Date().getTime()+'-'+Math.round(Math.random()*100000);
var before = ['background-color: '+this.options.fillColor];
var after = [
'box-shadow: 0 0 6px 2px '+this.options.color,
'animation: pulsate ' + this.options.heartbeat + 's ease-out',
'animation-iteration-count: infinite',
'animation-delay: '+ (this.options.heartbeat + .1) + 's',
];
if (!this.options.animate){
after.push('animation: none');
after.push('box-shadow:none');
}
var css = [
'.'+uniqueClassName+'{'+before.join(';')+';}',
'.'+uniqueClassName+':after{'+after.join(';')+';}',
].join('');
var el = document.createElement('style');
if (el.styleSheet){
el.styleSheet.cssText = css;
} else {
el.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(el);
// apply css class
this.options.className = this.options.className+' leaflet-pulsing-icon '+uniqueClassName;
// initialize icon
L.DivIcon.prototype.initialize.call(this, options);
}
});
L.icon.pulse = function (options) {
return new L.Icon.Pulse(options);
};
L.Marker.Pulse = L.Marker.extend({
initialize: function (latlng,options) {
options.icon = L.icon.pulse(options);
L.Marker.prototype.initialize.call(this, latlng, options);
}
});
L.marker.pulse = function (latlng,options) {
return new L.Marker.Pulse(latlng,options);
};
})(window);
L.Icon.Pulse.css
这个本质上也就是根据动画去改变外围圆的大小(scale)和透明度(opacity)
.leaflet-pulsing-icon {
border-radius: 100%;
box-shadow: 1px 1px 8px 0 rgba(0,0,0,0.75);
}
.leaflet-pulsing-icon:after {
content: "";
border-radius: 100%;
height: 300%;
width: 300%;
position: absolute;
margin: -100% 0 0 -100%;
}
@keyframes pulsate {
0% {
transform: scale(0.1, 0.1);
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
50% {
opacity: 1;
-ms-filter: none;
filter: none;
}
100% {
transform: scale(1.2, 1.2);
opacity: 0;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
filter: alpha(opacity=0);
}
}