当前位置: 首页 > article >正文

74.在 Vue 3 中使用 OpenLayers 实现游龙动画效果

1. 引言

在 WebGIS 开发中,OpenLayers 是一个强大的开源库,可以用于渲染地图、绘制矢量图层等功能。本篇文章将介绍如何在 Vue 3 中使用 OpenLayers 结合 Composition API,实现一个“游龙”动画效果,该动画通过数学公式计算轨迹,并动态渲染在地图上。


2. 项目环境与依赖

在开始之前,我们需要确保已经安装 Vue 3 以及 OpenLayers。

2.1 安装 Vue 3 项目

如果你还没有 Vue 3 项目,可以使用 Vite 快速创建:

npm create vite@latest vue-openlayers --template vue
cd vue-openlayers
npm install

2.2 安装 OpenLayers

npm install ol

3. 代码实现

<!--
 * @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 逻辑拆分。如果你觉得这篇文章对你有帮助,欢迎点赞收藏!🚀


http://www.kler.cn/a/538814.html

相关文章:

  • 前端 CSS 动态设置样式::class、:style 等技巧详解
  • 4G核心网的演变与创新:从传统到虚拟化的跨越
  • IDEA+DeepSeek让Java开发起飞
  • Mybatis
  • 我用AI做数据分析之数据清洗
  • redis项目
  • DeepSeek迁移学习与预训练模型应用
  • CST的TLM算法仿真5G毫米波阵列天线及手机
  • DeepSeek-R1 32B Windows+docker本地部署
  • C++学习笔记——类和对象(上)
  • 【C++八股】static关键字
  • 苹果iPhone 16 Pro Max上手体验:性能极致释放
  • 二级C语言题解:十进制转其他进制、非素数求和、重复数统计
  • Linux 系统搭建 Python 开发环境全流程
  • 基础入门-网站协议身份鉴权OAuth2安全Token令牌JWT值Authirization标头
  • PDF 2.0 的新特性
  • redis之GEO 模块
  • MVCC机制深度解析
  • html语义化
  • 详细教程 | 如何使用DolphinScheduler调度Flink实时任务
  • 瑞芯微 Rockchip 系列 RK3588 主流深度学习框架模型转成 rknn 模型教程
  • mysql8 从C++源码角度看sql生成抽象语法树
  • 定期删除一周前的数据,日志表的表空间会增长吗?
  • springboot基于微信小程序的短文写作竞赛管理系统
  • QT修仙之路1-1--遇见QT
  • docker部署superset并连接华为MRS hive数据库