示例
创建一个方形的规矩,并让点按轨迹移动。效果如下:
源代码
<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 animation
this.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 event
this.geoMarker.setGeometry(null);
},
stopAnimation() {
this.animating = false;
this.startButton.textContent = "Start Animation";
// Keep marker at current animation position
this.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>