1. 程式人生 > 程式設計 >Vue+Openlayers自定義軌跡動畫

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.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,src: require("@/assets/rise.png")
   })
  }),end: new Style({
   // 設定結束標記樣式
   image: new Icon({
   anchor: [0.5,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.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>

Vue+Openlayers自定義軌跡動畫

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。