1. 引言
在 WebGIS 开发中,OpenLayers 是一个强大的开源库,可以用于渲染地图、绘制矢量图层等功能。本篇文章将介绍如何在 Vue 3 中使用 OpenLayers 结合 Composition API,实现一个“游龙”动画效果,该动画通过数学公式计算轨迹,并动态渲染在地图上。
2. 项目环境与依赖
在开始之前,我们需要确保已经安装 Vue 3 以及 OpenLayers。
2.1 安装 Vue 3 项目
如果你还没有 Vue 3 项目,可以使用 Vite 快速创建:
javascript">npm create vite@latest vue-openlayers --template vue
cd vue-openlayers
npm install
2.2 安装 OpenLayers
npm install ol
3. 代码实现
javascript"><!--
* @Author: 彭麒
* @Date: 2025/2/6
* @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>
<div id="vue-openlayers"></div>
</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import "ol/ol.css";
import Map from "ol/Map";
import OSM from "ol/source/OSM";
import TileLayer from "ol/layer/Tile";
import View from "ol/View";
import {Circle as CircleStyle, Fill, Stroke, Style} from "ol/style";
import {MultiPoint, Point} from "ol/geom";
import {getVectorContext} from "ol/render";
const map = ref(null);
const initMap = () => {
const tileLayer = new TileLayer({
source: new OSM(),
});
map.value = new Map({
target: "vue-openlayers",
layers: [tileLayer],
view: new View({
center: [0, 0],
zoom: 2,
}),
});
const imageStyle = new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({
color: "LimeGreen",
}),
stroke: new Stroke({
color: "yellow",
width: 1,
}),
}),
});
const headInnerImageStyle = new Style({
image: new CircleStyle({
radius: 8,
fill: new Fill({
color: "red",
}),
}),
});
const headOuterImageStyle = new Style({
image: new CircleStyle({
radius: 10,
fill: new Fill({
color: "black",
}),
}),
});
const n = 200;
const omegaTheta = 30000; // Rotation period in ms
const R = 7e6;
const r = 2e6;
const p = 2e6;
tileLayer.on("postrender", (event) => {
const vectorContext = getVectorContext(event);
const frameState = event.frameState;
const theta = (2 * Math.PI * frameState.time) / omegaTheta;
const coordinates = [];
for (let i = 0; i < n; ++i) {
const t = theta + (2 * Math.PI * i) / n;
const x = (R + r) * Math.cos(t) + p * Math.cos(((R + r) * t) / r);
const y = (R + r) * Math.sin(t) + p * Math.sin(((R + r) * t) / r);
coordinates.push([x, y]);
}
vectorContext.setStyle(imageStyle);
vectorContext.drawGeometry(new MultiPoint(coordinates));
const headPoint = new Point(coordinates[coordinates.length - 1]);
vectorContext.setStyle(headOuterImageStyle);
vectorContext.drawGeometry(headPoint);
vectorContext.setStyle(headInnerImageStyle);
vectorContext.drawGeometry(headPoint);
map.value.render();
});
map.value.render();
};
onMounted(() => {
initMap();
});
</script>
<style scoped>
.container {
width: 840px;
height: 590px;
margin: 50px auto;
border: 1px solid #42b983;
}
#vue-openlayers {
width: 800px;
height: 470px;
margin: 0 auto;
border: 1px solid #42b983;
position: relative;
}
</style>
4. 代码解析
4.1 轨迹动画原理
游龙动画的轨迹基于外摆线公式计算得出:
x = (R + r) \cos(t) + p \cos\left(\frac{(R + r) t}{r}\right)$$
y = (R + r) \sin(t) + p \sin\left(\frac{(R + r) t}{r}\right)$$
其中:
R
是大圆半径,r
是小圆半径,p
是轨迹偏移量,t
代表时间。
4.2 OpenLayers 动态渲染
我们利用 postrender
事件,在每一帧中重新计算轨迹点,并使用 getVectorContext
绘制动画。
5. 运行效果
将 OpenLayers.vue
组件引入 App.vue
,运行项目:
npm run dev
最终,我们可以看到 OpenLayers 中动态渲染出一个游龙轨迹动画。
6. 结语
本篇文章介绍了如何在 Vue 3 中使用 OpenLayers 实现游龙动画效果,涉及 OpenLayers 基础知识、数学公式计算轨迹以及 Vue 3 的 Composition API 逻辑拆分。如果你觉得这篇文章对你有帮助,欢迎点赞收藏!🚀