Vue+Openlayers自定义轨迹动画

本文实例为大家分享了Vue+Openlayers实现轨迹动画的具体代码,供大家参考,具体内容如下

<template>
 <div class="map-warp">
 <h3>
  <a
  href="https://openlayers.org/en/latest/examples/feature-move-animation.html?q=polyline"
  target="_bank"
  >OpenlayersTrack</a>

  <!--js 轨迹回放 https://blog.csdn.net/Himire/article/details/80296738 -->
 </h3>
 <div class="progress-bar">
  <div class="bar-box">
  <div class="bar" :style="{width:progress+'%'}">
   <span>{{progress}}%</span>
  </div>
  </div>
 </div>
 <div id="map" class="map"></div>
 <el-row :gutter="20">
  <el-col :span="5">
  <label for="speed">
   运动速度:&nbsp;
   <input id="speed" type="range" step="10" value="5" />
  </label>
  </el-col>
  <el-col :span="5">
  <button @click="handlerPlay">{{textContent}}</button>
  </el-col>
 </el-row>
 </div>
</template>

<script>
import "ol/ol.css";
import Feature from "ol/Feature";
import Map from "ol/Map";
import View from "ol/View";
import Polyline from "ol/format/Polyline";
import { Projection } from "ol/proj";
import { Point, LineString } from "ol/geom";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import {
 Circle as CircleStyle,
 Fill,
 Icon,
 Stroke,
 Style,
 Text
} from "ol/style";
import { getVectorContext } from "ol/render";

export default {
 data() {
 return {
  map: null,
  progress: 0, // 进度
  animating: false, // 动画是否开始
  speed: null, // 速度
  now: null, // 当前时间
  textContent: "开始",
  routeCoords: null, // 数组点集合
  routeLength: null, // 数组长度
  route: null, // 线
  routeFeature: null, // 画线
  geoMarker: null, // 标记
  startMarker: null, // 开始标记
  endMarker: null, // 结束标记
  styles: {
  route: new Style({
   // 线的样式
   stroke: new Stroke({
   width: 6,
   color: [237, 212, 0, 0.8]
   })
  }),
  icon: new Style({
   // 默认icon样式
   image: new CircleStyle({
   radius: 7,
   fill: new Fill({ color: "red" }),
   stroke: new Stroke({
    color: "white",
    width: 2
   })
   })
  }),
  geoMarker: new Style({
   // 设置标记样式
   image: new Icon({
   anchor: [0.5, 1], // 偏移位置
   // rotation: 0, // 旋转
   // size: [52, 26], // 图标大小
   src: require("@/assets/tx-icon-1.png")
   })
  }),
  start: new Style({
   // 设置开始标记样式
   image: new Icon({
   anchor: [0.5, 1],
   src: require("@/assets/rise.png")
   })
  }),
  end: new Style({
   // 设置结束标记样式
   image: new Icon({
   anchor: [0.5, 1],
   src: require("@/assets/end.png")
   })
  })
  },
  vectorLayer: null, // 矢量图层
  center: [118.835014569433, 32.08414190192472] // 中心点
 };
 },
 methods: {
 // 初始化地图
 initMap() {
  let that = this;
  that.routeCoords = [
   [118.83476768752418, 32.08385299388422],
   [118.83491813875425, 32.08394894013734],
   [118.83504349233812, 32.08408332210981],
   [118.83504349233812, 32.08408332210981],
   [118.83512889261571, 32.083918456790876],
   [118.83517286002402, 32.083733744293006],
   [118.83496824937895, 32.084077663081935],
   [118.83490797978696, 32.08412326115879],
   [118.83489815812887, 32.08414025948315],
   [118.83488806541473, 32.084153465524956],
   [118.83488315718186, 32.08415572622981],
   [118.8348782482698, 32.0841596143537],
   [118.83485807031045, 32.08416812475921],
   [118.83484798473395, 32.08416424284437],
   [118.83483789451235, 32.08417148163059],
   [118.83483789122208, 32.08417934749756],
   [118.83489794089253, 32.084006273376524],
   [118.83490803262733, 32.08399523720106],
   [118.83491321591835, 32.08398700421235],
   [118.83491812613363, 32.083979861216235],
   [118.83491812890527, 32.08397308027895],
   [118.83492822118053, 32.0839606878946],
   [118.83493831179283, 32.08395236406387],
   [118.8349443113023, 32.08394818448314],
   [118.83494840317711, 32.0839421415609],
   [118.8349582198328, 32.08393707761024],
   [118.83495822192893, 32.08393192409512],
   [118.83495822314188, 32.083928940480945],
   [118.83495822600715, 32.08392188830153],
   [118.83496831727095, 32.08391193701643],
   [118.83496832133952, 32.083901901220244],
   [118.83497432325855, 32.083891754391544],
   [118.83497841676457, 32.083881642888024],
   [118.83498850812316, 32.083871420344074],
   [118.8349985986039, 32.08386336769408],
   [118.83499860472438, 32.08384817837085],
   [118.83500869639813, 32.08383714209293],
   [118.83500870130179, 32.083824936382825],
   [118.83501279510463, 32.08381401114558],
   [118.83501852555108, 32.08380088571361],
   [118.83502861687877, 32.08379066312818]
  ];
  that.routeLength = that.routeCoords.length;
  that.route = new LineString(that.routeCoords);

  that.routeFeature = new Feature({
  type: "route",
  geometry: that.route
  });
  that.geoMarker = new Feature({
  type: "geoMarker",
  geometry: new Point(that.routeCoords[0])
  });
  that.startMarker = new Feature({
  type: "start",
  geometry: new Point(that.routeCoords[0])
  });
  that.endMarker = new Feature({
  type: "end",
  geometry: new Point(that.routeCoords[that.routeLength - 1])
  });
  // that.endMarker.setStyle(

  // new Style({
  //  // image: new CircleStyle({
  //  // radius: 7,
  //  // fill: new Fill({ color: "red" }),
  //  // stroke: new Stroke({
  //  //  color: "white",
  //  //  width: 2
  //  // })
  //  // }),
  //  // image: new Icon({
  //  // src: require("@/assets/tx-icon-1.png")
  //  // }),
  //  // text: new Text({
  //  // text: '11133333333333333333333333333333333311',
  //  // scale: 1.3,
  //  // fill: new Fill({
  //  //  color: '#000000'
  //  //  }),
  //  // Stroke:new Stroke({
  //  //  color: '#FFFF99',
  //  //  width: 3.5
  //  // })
  //  // })
  // })
  // );

  that.vectorLayer = new VectorLayer({
  source: new VectorSource({
   features: [
   that.routeFeature,
   that.geoMarker,
   that.startMarker,
   that.endMarker
   ]
   // 线、标记、开始标记、结束标记
  }),
  style: function(feature) {
   // 如果动画处于活动状态,则隐藏标记
   if (that.animating && feature.get("type") === "geoMarker") {
   return null;
   }
   return that.styles[feature.get("type")];
  }
  });
  this.map = new Map({
  target: "map",
  layers: [
   new TileLayer({
   source: new XYZ({
    url:
    "http://www.google.cn/maps/vt?lyrs=m@189&gl=cn&x={x}&y={y}&z={z}"
   }),
   projection: "EPSG:3857"
   }),
   that.vectorLayer
  ],
  view: new View({
   projection: new Projection({ code: "EPSG:4326", units: "degrees" }),
   center: this.center,
   zoom: 19,
   minZoom: 2,
   maxZoom: 19
  })
  });
  this.mapClick();
 },

 // 地图绑定事件
 mapClick() {
  let that = this;
  this.map.on("click", function(event) {
  let feature = that.map.getFeaturesAtPixel(event.pixel);
  let pixel = that.map.getEventPixel(event.originalEvent);
  let coodinate = event.coordinate;
  // let temp = feature[0].geometryChangeKey_.target
  // Point
  if (feature.length > 0) {
   console.warn(feature[0].values_.type, 111);
   // console.warn(feature[0].get('geometryChangeKey'),9999999999)
  }
  });
 },

 // 运动轨迹开关
 handlerPlay() {
  if (this.textContent === "暂停") {
  this.stop(false);
  } else {
  this.start();
  }
 },

 // 轨迹移动
 moveFeature(event) {
  let vectorContext = getVectorContext(event);
  let frameState = event.frameState;
  if (this.animating) {
  let elapsedTime = frameState.time - this.now;
  let index = Math.round((this.speed * elapsedTime) / 1000);
  // 进度条
  this.progress = Math.floor(
   ((100 / this.routeLength) * (this.speed * elapsedTime)) / 1000
  );
  if (index >= this.routeLength) {
   this.progress = "100";
   this.stop(true);
   return;
  }

  let currentPoint = new Point(this.routeCoords[index]);
  let feature = new Feature(currentPoint);
  vectorContext.drawFeature(feature, this.styles.geoMarker);
  }
  // tell OpenLayers to continue the postrender animation
  this.map.render(); // 开始移动动画
 },

 // 开始动画
 start() {
  if (this.animating) {
  this.stop(false);
  } else {
  this.animating = true;
  this.textContent = "暂停";
  this.now = new Date().getTime();
  let speedInput = document.getElementById("speed");
  this.speed = speedInput.value;
  this.geoMarker.setStyle(null); // hide geoMarker 隐藏标记
  // just in case you pan somewhere else
  this.map.getView().setCenter(this.center); // 设置下中心点
  this.vectorLayer.on("postrender", this.moveFeature);
  this.map.render();
  }
 },

 // 停止
 stop(ended) {
  this.progress = 0;
  this.animating = false;
  this.textContent = "开始";
  let coord = ended
  ? this.routeCoords[this.routeLength - 1]
  : this.routeCoords[0];
  let geometry = this.geoMarker.getGeometry().setCoordinates(coord);
  //remove listener
  this.vectorLayer.un("postrender", this.moveFeature); // 删除侦听器
 }
 },
 mounted() {
 this.initMap();
 }
};
</script>

<style lang="scss">
#map {
 height: 500px;
 margin-top: 20px;
}
/*隐藏ol的一些自带元素*/
.ol-attribution,
.ol-zoom {
 display: none;
}
.progress-bar {
 width: 100%;
 height: 30px;
 margin: 30px 0;
 background: url("~@/assets/bg-5.png") center bottom no-repeat;
 background-size: 100% 30px;
 position: relative;
 box-sizing: border-box;
 .bar-box {
  position: absolute;
  top: 10px;
  left: 30px;
  right: 30px;
  height: 10px;
  border-radius: 5px;
  background: #034c77;
 }
 .bar {
  height: 10px;
  border-radius: 5px;
  background: url("~@/assets/bg-6.png") 0 bottom repeat #ecc520;
  position: relative;
  span {
  width: 50px;
  height: 50px;
  line-height: 18px;
  font-size: 12px;
  font-weight: bold;
  text-align: center;
  position: absolute;
  color: #fe0000;
  top: -30px;
  right: -25px;
  background: url("~@/assets/bg-7.png") center 0 no-repeat;
  background-size: 100% 30px;
  }
 }
 }
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • vue使用openlayers实现移动点动画

    本文实例为大家分享了vue使用openlayers实现移动点动画的具体代码,供大家参考,具体内容如下 做项目时,本来打算仿照官网的Example中动画制作,引入vue中后,发现它引用的库函数一直报错,最后我去vue中安装的依赖库中去查找这个函数,果然没有.也就是说官方例子使用的库和我安装的OL库存在一定差异. 后来我还是用笨方法去解决了,最终效果如下: 总体思路是将移动目标实例一个Overlay对象,然后将如图5个经纬度点没两点之间分割成多个(200个),之后通过定时器不断setPositon.

  • Vue+Openlayers自定义轨迹动画

    本文实例为大家分享了Vue+Openlayers实现轨迹动画的具体代码,供大家参考,具体内容如下 <template> <div class="map-warp"> <h3> <a href="https://openlayers.org/en/latest/examples/feature-move-animation.html?q=polyline" target="_bank" >Openla

  • vue openlayers实现台风轨迹示例详解

    目录 功能描述 创建一个地图容器 引入地图相关对象 创建地图对象 开始绘制 准备台风数据和图层 绘制台风名称 绘制台风轨迹点和轨迹线 添加台风风圈动画 让台风轨迹动起来 结尾 功能描述 台风轨迹点实时绘制,根据不同点的类型绘制不同的轨迹点颜色 轨迹线绘制,涉及实时轨迹线段与预报轨迹线,根据台风类型绘制成不同颜色 当前正在发生的台风还需增加当前台风所风圈位置 台风轨迹点点击弹框显示轨迹点信息 openlayers(简称ol)这里不做介绍,刚开始写此类文章,直接上代码 创建一个地图容器 引入地图相关

  • Vue transition实现点赞动画效果的示例

    目录 效果一览 爱心效果 数字滚动动画 点赞动画 效果一览 爱心效果 材料:爱心图标两个,没有我这种 icon 组件的用 png 图片代替 <transition :name=" isLike ? 'zoom' : '' " mode="out-in"> <!-- 爱心图标 --> <icon data="@icon/like.svg" color="#FF0000" v-if="isL

  • vue 封装自定义组件之tabal列表编辑单元格组件实例代码

    vue 封装自定义组件 tabal列表编辑单元格组件 <template> <div class="editable-cell"> <div class="editable-cell-input-wrapper" v-if='editable'> <el-input class="editInput" v-model="cellValue" placeholder="请输入内

  • vue 中自定义指令改变data中的值

    通过局部自定义指令实现了一个拖动的指令 html: <div style="position:absolute;width:100px;height:100px;border:1px solid red" v-drag="{set:set}"></div> script: methods:{ set(x,y){ this.data.x=x; this.data.y=y; } }, directives:{ // 拖动的自定义指令 drag(e

  • iOS利用MJRefresh实现自定义刷新动画效果

    本文主要介绍iOS 利用MJRefresh实现自定义动画的上拉刷新下拉加载效果,一般的类型(包括更新时间与loading图案)这里不做介绍. 要想实现此功能,首先得有一套load的图片数组. 接下来就是实现过程: 引入头文件: #import "MJRefresh.h" //自定义一个方法实现 - (void)prepareRefresh { NSMutableArray *headerImages = [NSMutableArray array]; for (int i = 1; i

  • Vue.js自定义指令的用法与实例解析

    市面上大多数关于Vue.js自定义指令的文章都在讲语法,很少讲实际的应用场景和用例,以致于即便明白了怎么写,也不知道怎么用.本文不讲语法,就讲自定义指令的用法. 自定义指令是用来操作DOM的.尽管Vue推崇数据驱动视图的理念,但并非所有情况都适合数据驱动.自定义指令就是一种有效的补充和扩展,不仅可用于定义任何的DOM操作,并且是可复用的. 比如谷歌图片的加载做得非常优雅,在图片未完成加载前,用随机的背景色占位,图片加载完成后才直接渲染出来.用自定义指令可以非常方便的实现这个功能. 效果: 自定义

  • JS实现自定义状态栏动画文字效果示例

    本文实例讲述了JS实现自定义状态栏动画文字效果.分享给大家供大家参考,具体如下: 在IE浏览器中打开,显示动态文字的效果,主要浏览器左下角的文字. <body onload="stack();"> <script type="text/javascript"> var statusText="自定义动画状态栏文字"; var out=""; var pause=100; var animateWidth

  • Android开发中MJRefresh自定义刷新动画效果

    [一]常见用法 最原始的用法,耦合度低,但是不能统一管理.我们需要在每一个控制器都写以下代码,很繁琐,以后项目修改起来更繁琐,得一个控制器一个控制器的去定位.修改. 1.1 使用默认刷新(耦合度底,但是想统一修改起来特别麻烦) self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{ //在这里执行刷新操作 }]; self.tableView.mj_header = [MJRefreshNorm

  • Vue.directive 自定义指令的问题小结

    1.今天复习一下Vue自定义指令的代码,结果出现一个很无语的结果,先贴代码. 2. <div id="example" v-change-by="myColor"></div> <script src="vue.min.js"></script> <script> new Vue({ el:"#example", data:{ msg:"", my

随机推荐