Created
June 8, 2018 21:52
-
-
Save ThomasG77/e254c900772fc0955763e3125bb820f2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Marker Animation</title> | |
<link rel="stylesheet" href="https://openlayers.org/en/v4.6.5/css/ol.css" type="text/css"> | |
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x --> | |
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script> | |
<script src="https://openlayers.org/en/v4.6.5/build/ol-debug.js"></script> | |
</head> | |
<body> | |
<div id="map" class="map"></div> | |
<label for="speed"> | |
speed: | |
<input id="speed" type="range" min="10" max="999" step="10" value="60"> | |
</label> | |
<button id="start-animation">Start Animation</button> | |
<script> | |
// This long string is placed here due to jsFiddle limitations. | |
// It is usually loaded with AJAX. | |
var strGeoJson = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[25.094146728515625,57.51877294160811],[25.135345458984375,57.55857562213471],[25.11749267578125,57.583614274541404],[25.022735595703125,57.58508660014084],[25.017242431640625,57.633639928856965],[25.11199951171875,57.655688188735766],[25.081787109374996,57.69240553526455],[24.97055053710937,57.68873547372526]]}}]}'; | |
var route = /** @type {ol.geom.LineString} */ (new ol.format.GeoJSON().readFeature(JSON.parse(strGeoJson).features[0], { | |
dataProjection: 'EPSG:4326', | |
featureProjection: 'EPSG:3857' | |
})).getGeometry(); | |
var routeCoords = route.getCoordinates(); | |
var routeLength = routeCoords.length; | |
var routeFeature = new ol.Feature({ | |
type: 'route', | |
geometry: route | |
}); | |
var geoMarker = new ol.Feature({ | |
type: 'geoMarker', | |
geometry: new ol.geom.Point(routeCoords[0]) | |
}); | |
var startMarker = new ol.Feature({ | |
type: 'icon', | |
geometry: new ol.geom.Point(routeCoords[0]) | |
}); | |
var endMarker = new ol.Feature({ | |
type: 'icon', | |
geometry: new ol.geom.Point(routeCoords[routeLength - 1]) | |
}); | |
var styles = { | |
'route': new ol.style.Style({ | |
stroke: new ol.style.Stroke({ | |
width: 6, color: [237, 212, 0, 0.8] | |
}) | |
}), | |
'icon': new ol.style.Style({ | |
image: new ol.style.Icon({ | |
anchor: [0.5, 1], | |
src: 'https://openlayers.org/en/v4.6.5/examples/data/icon.png' | |
}) | |
}), | |
'geoMarker': new ol.style.Style({ | |
image: new ol.style.Circle({ | |
radius: 7, | |
snapToPixel: false, | |
fill: new ol.style.Fill({color: 'black'}), | |
stroke: new ol.style.Stroke({ | |
color: 'white', width: 2 | |
}) | |
}) | |
}) | |
}; | |
var animating = false; | |
var speed, now; | |
var speedInput = document.getElementById('speed'); | |
var startButton = document.getElementById('start-animation'); | |
var vectorLayer = new ol.layer.Vector({ | |
source: new ol.source.Vector({ | |
features: [routeFeature, geoMarker, startMarker, endMarker] | |
}), | |
style: function(feature) { | |
// hide geoMarker if animation is active | |
if (animating && feature.get('type') === 'geoMarker') { | |
return null; | |
} | |
return styles[feature.get('type')]; | |
} | |
}); | |
var center = [2788881.4140129406, 7884938.089785639]; | |
var map = new ol.Map({ | |
target: document.getElementById('map'), | |
loadTilesWhileAnimating: true, | |
view: new ol.View({ | |
center: center, | |
zoom: 10, | |
minZoom: 2, | |
maxZoom: 19 | |
}), | |
layers: [ | |
new ol.layer.Tile({ | |
source: new ol.source.OSM() | |
}), | |
vectorLayer | |
] | |
}); | |
var moveFeature = function(event) { | |
var vectorContext = event.vectorContext; | |
var frameState = event.frameState; | |
if (animating) { | |
var elapsedTime = frameState.time - now; | |
// here the trick to increase speed is to jump some indexes | |
// on lineString coordinates | |
var index = Math.round(speed * elapsedTime / 1000); | |
if (index >= routeLength) { | |
stopAnimation(true); | |
return; | |
} | |
var currentPoint = new ol.geom.Point(routeCoords[index]); | |
var feature = new ol.Feature(currentPoint); | |
vectorContext.drawFeature(feature, styles.geoMarker); | |
} | |
// tell OpenLayers to continue the postcompose animation | |
map.render(); | |
}; | |
function startAnimation() { | |
if (animating) { | |
stopAnimation(false); | |
} else { | |
animating = true; | |
now = new Date().getTime(); | |
speed = speedInput.value; | |
startButton.textContent = 'Cancel Animation'; | |
// hide geoMarker | |
geoMarker.setStyle(null); | |
// just in case you pan somewhere else | |
map.getView().setCenter(center); | |
map.on('postcompose', moveFeature); | |
map.render(); | |
} | |
} | |
/** | |
* @param {boolean} ended end of animation. | |
*/ | |
function stopAnimation(ended) { | |
animating = false; | |
startButton.textContent = 'Start Animation'; | |
// if animation cancelled set the marker at the beginning | |
var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0]; | |
/** @type {ol.geom.Point} */ (geoMarker.getGeometry()) | |
.setCoordinates(coord); | |
//remove listener | |
map.un('postcompose', moveFeature); | |
} | |
startButton.addEventListener('click', startAnimation, false); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment