示例
创建一个方形的规矩,并让点按轨迹移动。效果如下:
源代码
<template><div><div id="map" class="map"></div><button id="start-animation" ref="startButton">Start Animation</button></div>
</template><script>
import "ol/ol.css";
import "@/assets/css/map.css";
import { Map, View, Feature } from "ol";
import { Circle as CircleStyle, Fill, Icon, Stroke, Style } from "ol/style";
import { OSM, Vector as VectorSource } from "ol/source";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { getVectorContext } from "ol/render";
import { LineString, Point } from "ol/geom";
import { ref } from "vue";export default {setup(props) {const map = ref(null);const startButton = ref(null);const styles = {route: new Style({stroke: new Stroke({width: 6,color: [237, 212, 0, 0.8],}),}),icon: new Style({image: new Icon({anchor: [0.5, 1],src: "https://openlayers.org/en/latest/examples/data/icon.png",}),}),geoMarker: new Style({image: new CircleStyle({radius: 7,fill: new Fill({ color: "red" }),stroke: new Stroke({color: "white",width: 2,}),}),}),};return { map, styles, startButton };},data() {return {speedInput: 5,animating: false,distance: 0,lastTime: null,position: null,geoMarker: null,vectorLayer: null,route: null,};},mounted() {this.map = new Map({layers: [new TileLayer({source: new OSM(),}),],target: "map",view: new View({center: [-5645116.561407479, -3504865.8960142885],zoom: 10,}),});this.createRoute();var that = this;that.startButton.addEventListener("click", function () {if (that.animating) {that.stopAnimation();} else {that.startAnimation();}});},methods: {moveFeature(event) {const speed = 20;const time = event.frameState.time;const elapsedTime = time - this.lastTime;this.distance = (this.distance + (speed * elapsedTime) / 1e5) % 2;this.lastTime = time;//按比例获取坐标位置const currentCoordinate = this.route.getCoordinateAt(this.distance > 1 ? 2 - this.distance : this.distance);this.position.setCoordinates(currentCoordinate);const vectorContext = getVectorContext(event);vectorContext.setStyle(this.styles.geoMarker);vectorContext.drawGeometry(this.position);// tell OpenLayers to continue the postrender animationthis.map.render();},startAnimation() {this.animating = true;this.lastTime = Date.now();this.startButton.textContent = "Stop Animation";this.vectorLayer.on("postrender", this.moveFeature);// hide geoMarker and trigger map render through change eventthis.geoMarker.setGeometry(null);},stopAnimation() {this.animating = false;this.startButton.textContent = "Start Animation";// Keep marker at current animation positionthis.geoMarker.setGeometry(this.position);this.vectorLayer.un("postrender", this.moveFeature);},createRoute() {var that = this;var coordinates = [[-5701523.274225562, -3508003.9130105707],[-5570600.171389932, -3508003.9130105707],[-5570600.171389932, -3522590.9336281433],[-5701523.274225562, -3522590.9336281433],[-5701523.274225562, -3508003.9130105707],];that.route = new LineString(coordinates);const routeFeature = new Feature({type: "route",geometry: that.route,});const startMarker = new Feature({type: "icon",geometry: new Point(that.route.getFirstCoordinate()),});const endMarker = new Feature({type: "icon",geometry: new Point(that.route.getLastCoordinate()),});that.position = startMarker.getGeometry().clone();that.geoMarker = new Feature({type: "geoMarker",geometry: that.position,});that.vectorLayer = new VectorLayer({source: new VectorSource({features: [routeFeature, that.geoMarker, startMarker, endMarker],}),style: function (feature) {return that.styles[feature.get("type")];},});that.map.addLayer(that.vectorLayer);},},
};
</script>