
官网demo地址:
首先先创建1000个随机点,创建点对象。
- const n = 1000;
- const geometries = new Array(n);
-
- for (let i = 0; i < n; ++i) {
- const lon = 360 * Math.random() - 180;
- const lat = 180 * Math.random() - 90;
- geometries[i] = new Point([lon, lat]);
- }
因为创建的点坐标是地理坐标,而地图默认是3857投影展示,所以使用 useGeographic()让所有坐标都直接使用地理坐标系(EPSG:4326)
- import { useGeographic } from "ol/proj.js";
- useGeographic();
等同于在view中设置projection为"EPSG:4326"
- view: new View({
- center: [0, 0],
- zoom: 2,
- projection: "EPSG:4326",
- }),
然后利用postrender在地图上绘制动画效果,每次随机生成一个点,push进geometries数组中,同时将数组的第一个删除,使地图上的点动态的出现消失。
- layer.on("postrender", function (event) {
- const vectorContext = getVectorContext(event);
-
- for (let i = 0; i < n; ++i) {
- const importance = upAndDown(Math.pow((n - i) / n, 0.15));
- if (importance < 0.1) {
- continue;
- }
- style.getImage().setOpacity(importance);
- style.getImage().setScale(importance);
- vectorContext.setStyle(style);
- vectorContext.drawGeometry(geometries[i]);
- }
-
- const lon = 360 * Math.random() - 180;
- const lat = 180 * Math.random() - 90;
- geometries.push(new Point([lon, lat]));
- geometries.shift();
- map.render();
- });
其中upAndDown 是openlayers提供的缓动函数,创建动画效果。定义了动画的进度和速度曲线,使得动画效果更加平滑和自然。调整点的透明度和缩放比例,从而实现点的渐显渐隐效果。
const importance = upAndDown(Math.pow((n - i) / n, 0.15));
计算了每个点的重要性,Math.pow((n - i) / n, 0.15) 计算了一个缩放值,upAndDown 函数应用了缓动效果,使得这个缩放值先增加后减少。
如果不喜欢点,也可以换成星星图形。
- const star = new RegularShape({
- radius: 10,
- radius2: 3,
- points: 5,
- angle: Math.PI,
- fill: new Fill({
- color: "rgba(255, 153, 0, 0.8)",
- }),
- });
- const style = new Style({
- // image: image,
- image: star,
- });

完整代码:
- <template>
- <div class="box">
- <h1>Immediate Rendering (Geographic)</h1>
- <div id="map" class="map"></div>
- </div>
- </template>
-
- <script>
- import StadiaMaps from "ol/source/StadiaMaps.js";
- import TileLayer from "ol/layer/Tile.js";
- import { Circle, Fill, Style, Icon, RegularShape } from "ol/style.js";
- import { Map, View } from "ol/index.js";
- import { Point } from "ol/geom.js";
- import { getVectorContext } from "ol/render.js";
- import { upAndDown } from "ol/easing.js";
- import { useGeographic } from "ol/proj.js";
- export default {
- name: "",
- components: {},
- data() {
- return {
- map: null,
- };
- },
- computed: {},
- created() {},
- mounted() {
- useGeographic();
-
- const layer = new TileLayer({
- source: new StadiaMaps({
- layer: "stamen_toner",
- }),
- });
-
- const map = new Map({
- layers: [layer],
- target: "map",
- view: new View({
- center: [0, 0],
- zoom: 2,
- projection: "EPSG:4326",
- }),
- });
-
- const image = new Circle({
- radius: 8,
- fill: new Fill({ color: "rgba(255, 153, 0, 0.8)" }),
- });
- const star = new RegularShape({
- radius: 10,
- radius2: 3,
- points: 5,
- angle: Math.PI,
- fill: new Fill({
- color: "rgba(255, 153, 0, 0.8)",
- }),
- });
- const style = new Style({
- // image: image,
- image: star,
- });
-
- const n = 1000;
- const geometries = new Array(n);
-
- for (let i = 0; i < n; ++i) {
- const lon = 360 * Math.random() - 180;
- const lat = 180 * Math.random() - 90;
- geometries[i] = new Point([lon, lat]);
- }
- layer.on("postrender", function (event) {
- const vectorContext = getVectorContext(event);
-
- for (let i = 0; i < n; ++i) {
- const importance = upAndDown(Math.pow((n - i) / n, 0.15));
- if (importance < 0.1) {
- continue;
- }
- style.getImage().setOpacity(importance);
- style.getImage().setScale(importance);
- vectorContext.setStyle(style);
- vectorContext.drawGeometry(geometries[i]);
- }
-
- const lon = 360 * Math.random() - 180;
- const lat = 180 * Math.random() - 90;
- geometries.push(new Point([lon, lat]));
- geometries.shift();
- map.render();
- });
- },
- methods: {},
- };
- </script>
-
- <style lang="scss" scoped>
- #map {
- width: 100%;
- height: 500px;
- }
- .box {
- height: 100%;
- }
- #popup {
- width: 160px;
- height: 80px;
- border-radius: 10px;
- background: #fff;
- position: absolute;
- padding: 10px;
- box-sizing: border-box;
- }
- .triangle {
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- bottom: -20px;
- border-top: 10px solid #fff;
- border-bottom: 10px solid transparent;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- }
- </style>
-