Vue+Openlayers自定義軌跡動畫
阿新 • • 發佈:2020-09-25
本文例項為大家分享了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"> 運動速度: <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>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。