重庆市政府网站管理办法数据分析平台
前言
在 WebGIS 开发中,OpenLayers 是一个功能强大的开源地图库,能够帮助开发者快速构建地图应用。在 Vue 3 组合式 API (Composition API) 的加持下,我们可以更优雅地封装 OpenLayers,并实现炫酷的地图交互功能。
本文将介绍如何在 Vue 3 项目中使用 OpenLayers 实现 地图定位动画,包括 平移、弹性平移、飞行 三种效果,并通过 Vue 3 的 setup
语法优化代码结构,使代码更加清晰、易维护。
效果演示
最终效果如下:
- 平移:地图视图平滑地移动到指定位置。
- 弹性平移:使用缓动函数 (
easing
) 使地图带有缓冲的移动效果。 - 飞行:通过缩放动画模拟飞行效果,让视角从远处逐渐拉近目标点。
项目初始化
我们使用 Vue 3 + Vite 创建一个新的 Vue 项目,并安装 Element Plus 组件库来支持按钮交互。
1. 创建 Vue 3 项目
npm create vite@latest vue3-openlayers-demo --template
vue cd vue3-openlayers-demo
npm install
2. 安装 Element Plus
npm install element-plus
3. 安装 OpenLayers
npm install ol
核心代码实现
接下来,我们将在 src/components
目录下创建一个 OpenLayersMap.vue
组件,实现地图初始化和定位动画。
完整代码
<!--* @Author: 彭麒* @Date: 2025/3/19* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div class="container"><div class="w-full flex justify-center flex-wrap"><div class="font-bold text-[24px]">在Vue3中使用OpenLayers实现定位动画(平移-弹性平移-飞行)</div></div><h4><el-button type="primary" size="small" @click="pan">平移</el-button><el-button type="primary" size="small" @click="elastic">弹性平移</el-button><el-button type="primary" size="small" @click="fly">飞行</el-button></h4><div id="vue-openlayers"></div></div>
</template><script setup>
import { ref, onMounted } from "vue";
import "ol/ol.css";
import { Map, View } from "ol";
import Tile from "ol/layer/Tile";
import BingMaps from "ol/source/BingMaps";
import * as olEasing from "ol/easing";const map = ref(null);const pan = () => {map.value?.getView().animate({center: [119, 39],duration: 2000,});
};const elastic = () => {map.value?.getView().animate({center: [-36, -22],easing: olEasing.easeOut,});
};const fly = () => {flyTo([-55, 36]);
};const flyTo = (location, done = () => {}) => {let view = map.value?.getView();if (!view) return;let duration = 2000;let zoom = view.getZoom();let parts = 2;let called = false;function callback(complete) {--parts;if (called) return;if (parts === 0 || !complete) {called = true;done(complete);}}view.animate({ center: location, duration }, callback);view.animate({ zoom: zoom - 1, duration: duration / 2 },{ zoom: zoom, duration: duration / 2 },callback);
};const bing = () => {map.value?.getLayers().getArray().forEach((layer) => {if (layer) map.value.removeLayer(layer);});let nsource = new BingMaps({key: "AqQf9nX6PZKkFZOkdOqBOh3vg8xwGV1AYWGqC6EsOoJ0OHSUwm8CN8AhaFpT7mfR",imagerySet: "RoadOnDemand",});let bingMapLayer = new Tile({ source: nsource });map.value?.addLayer(bingMapLayer);
};const initMap = () => {map.value = new Map({target: "vue-openlayers",layers: [],view: new View({center: [122, 47],zoom: 4,projection: "EPSG:4326",}),loadTilesWhileAnimating: true,});bing();
};onMounted(() => {initMap();
});
</script><style scoped>
.container {width: 840px;height: 590px;margin: 50px auto;border: 1px solid #42b983;
}#vue-openlayers {width: 800px;height: 400px;margin: 0 auto;border: 1px solid #42b983;position: relative;
}
</style>
代码解析
1. 初始化地图
我们使用 onMounted
生命周期,在组件加载后执行 initMap()
初始化 OpenLayers 地图:
const initMap = () => {map.value = new Map({target: "vue-openlayers",layers: [],view: new View({center: [122, 47],zoom: 4,projection: "EPSG:4326",}),loadTilesWhileAnimating: true,});bing();
};
2. Bing 地图加载
const bing = () => {map.value?.getLayers().getArray().forEach((layer) => {if (layer) map.value.removeLayer(layer);});let nsource = new BingMaps({key: "AqQf9nX6PZKkFZOkdOqBOh3vg8xwGV1AYWGqC6EsOoJ0OHSUwm8CN8AhaFpT7mfR",imagerySet: "RoadOnDemand",});let bingMapLayer = new Tile({ source: nsource });map.value?.addLayer(bingMapLayer);
};
这里使用 Bing 地图服务 作为底图,你可以替换成其他地图源,如 OpenStreetMap (OSM)。
3. 定位动画
const pan = () => {map.value?.getView().animate({center: [119, 39],duration: 2000,});
};
animate()
方法可以平滑移动地图视图。
4. 飞行动画
const flyTo = (location, done = () => {}) => {let view = map.value?.getView();if (!view) return;let duration = 2000;let zoom = view.getZoom();let parts = 2;let called = false;function callback(complete) {--parts;if (called) return;if (parts === 0 || !complete) {called = true;done(complete);}}view.animate({ center: location, duration }, callback);view.animate({ zoom: zoom - 1, duration: duration / 2 },{ zoom: zoom, duration: duration / 2 },callback);
};
这里通过 缩放动画 模拟飞行效果。
总结
本文介绍了如何在 Vue 3 + OpenLayers 中实现 定位动画,并使用 Composition API 优化代码。希望对大家有所帮助!如果喜欢的话,记得点赞、收藏、关注哦!🚀🚀🚀