需求描述
在Openlayers地图的中,绘制一个点位闪烁动画的效果,类似于一种涟漪效果。
openlayers添加点后实现闪烁效果
参考
动画点
入门教程
地图实现点位闪烁
OpenLayers6实例分析:Custom Animation(水波扩散)
具体实现
插件版本
“ol”: “6.14.1”,
“ol-ext”: “^4.0.18”,
“d3-ease”: “^3.0.1”
相关代码
//重要引入
import "ol/ol.css";
import { Map, View, Feature } from "ol";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import {Vector as VectorSource, XYZ} from "ol/source";
import { Polygon, Point,LineString } from "ol/geom";
import {transform, get } from "ol/proj";
import { Style, Stroke, Fill, Circle,Text } from "ol/style";
import FillPattern from 'ol-ext/style/FillPattern';
import * as d3 from 'd3-ease'
import {getVectorContext} from 'ol/render';
methods: {
initMap() {
console.log("初始化地图")
var projection = get(this.$mapConfig.epsg);
this.source = new VectorSource();
this.source_td = new VectorSource();
this.locationLayer = new VectorSource();
this.map = new Map({
target: "map",
layers: [
new TileLayer({
name: "地图",
className:'blueLayer',//增加className属性
visible: true,
source: new XYZ({
minZoom: this.$mapConfig.minZoom,
maxZoom: this.$mapConfig.maxZoom,
projection: projection,
tileSize: this.$mapConfig.tileSize,
url: this.mapurl+"/{z}/{x}/{y}"+ this.$mapConfig.format,
}),
}),
],
controls: [],
view: new View({
center: transform([this.$mapConfig.centX, this.$mapConfig.centY], "EPSG:4326", this.$mapConfig.epsg),
projection: projection,
minZoom: this.$mapConfig.minZoom,
maxZoom: this.$mapConfig.maxZoom,
zoom: 16,
}),
});
this.getGisData()//添加点 线 面
var _this = this;
this.point_Source = new VectorSource();
this.point_Source.on('addfeature', function (e) {
_this.flash(e.feature);
});
this.point_Layer = new VectorLayer({
source: this.point_Source,
zIndex:3
});
_this.map.addLayer(this.point_Layer);
this.pointTempSource = new VectorSource();
this.locationTempLayer = new VectorLayer({
source: this.pointTempSource
});
_this.map.addLayer(this.locationTempLayer);
},
getLocation() {
var _this = this;
api.postWihtoutParam('后端地址').then(response => { // 这里应该改成你自己的接口地址
if (response.data.length > 0) {
if (_this.point_Layer) {
_this.point_Layer.getSource().clear();
}
_this.pointOptions = response.data;
for (var i in _this.pointOptions) {
var point = [];
point.push(parseFloat(_this.pointOptions[i].x));
point.push(parseFloat(_this.pointOptions[i].y));
var extent = transform(point, 'EPSG:4326', _this.$mapConfig.epsg);
var pointFeature = new Feature({
geometry: new Point(extent)
});
var pointTempFeature = new Feature({
geometry: new Point(extent)
});
var modetype = "#4a8fff";
//debugger;
if (_this.pointOptions[i].ModeType == 3) {
modetype = "#ff0000";
}
//console.log(modetype);
pointFeature.setStyle(
new Style({
text: new Text({
// 位置
textAlign: 'left',
offsetX: 12,
// 基准线
textBaseline: 'middle',
// 文字样式
font: 'bold 12px 微软雅黑',
// 文本内容
text: _this.pointOptions[i].mc,
// 文字颜色
fill: new Fill({ color: '#fff' })
// 文字背景
// stroke: new Stroke({ color: '#ffcc33', width: 10 })
}),
//边线颜色
stroke: new Style({
color: '#4a8fff',
width: 2
}),
//形状
image: new Circle({
radius: 4,
fill: new Fill({
color: modetype
})
})
}));
if (_this.point_Layer) {
_this.point_Layer.getSource().addFeature(pointFeature);
pointTempFeature.setStyle(new Style({
//边线颜色
stroke: new Stroke({
color: '#4a8fff',
width: 2
}),
//形状
image: new Circle({
radius: 3,
fill: new Fill({
color: modetype
})
})
}));
_this.locationTempLayer.getSource().addFeature(pointTempFeature);
}
}
}
})
},
//重点方法
//在ol6中,在图层上使用postrender事件,新的getVectorContext函数提供了对即时矢量渲染API的访问。
//OpenLayers 6 开始,ol.easing 已经被移除,取而代之的是使用单独的库或者自定义的缓动函数
//在 OpenLayers 6 及更高版本中,可以使用d3-ease,它提供了缓动函数。需要通过 npm 安装 d3-ease (npm install d3-ease)
flash(feature) {
var _this = this
var start = new Date().getTime();
var listenerKey;
function animate(event) {
var duration = 1000;
const vectorContext = getVectorContext(event);
var frameState = event.frameState;
var flashGeom = feature.getGeometry().clone();
var elapsed = frameState.time - start;
var elapsedRatio = elapsed / duration;
var radius = Math.max(d3.easeQuadOut(elapsedRatio) * 25 + 5, 0);//通过原来的写法有时会返回负值,改为使用 Math.max 函数来确保 radius 的值至少为 0
var opacity = d3.easeQuadOut(1 - elapsedRatio);
var style = new Style({
image: new Circle({
radius: radius,
snapToPixel: false,
stroke: new Stroke({
color: 'rgba(255, 0, 0, ' + opacity + ')',
width: 0.25 + opacity
})
})
});
vectorContext.setStyle(style);
vectorContext.drawGeometry(flashGeom);
if (elapsed > duration) {
_this.point_Layer.un('postrender',listenerKey);
return;
}
_this.map.render();
}
listenerKey = _this.point_Layer.on('postrender', animate);
},
}
mounted() {
this.$nextTick(() => {
this.initMap(); //初始化地图方法
this.interval = setInterval(() => {
this.getLocation()
}, 1000);
})
},
遇到问题
一开始使用地图postcompose事件时的问题 event.vectorContext获取不到
原因:在ol6中,在图层上使用postrender事件,新的getVectorContext函数提供了对即时矢量渲染API的访问。
import {getVectorContext} from 'ol/render';
layer.on('postrender', function(event) {
const vectorContext = getVectorContext(event);
});
1378

被折叠的 条评论
为什么被折叠?



