Customize camera animations
Customize camera animations using AnimationOptions
.
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Customize camera animations</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><script src="https://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-gl.js"></script><link href="https://unpkg.com/trackasia-gl@1.0.5/dist/trackasia-gl.css" rel="stylesheet" /><style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><style>.map-overlay {font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;position: absolute;width: 200px;top: 0;left: 0;padding: 10px;} .map-overlay .map-overlay-inner {background-color: #fff;box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);border-radius: 3px;padding: 10px;margin-bottom: 10px;} .map-overlay-inner fieldset {border: none;padding: 0;margin: 0 0 10px;} .map-overlay-inner fieldset:last-child {margin: 0;} .map-overlay-inner select {width: 100%;} .map-overlay-inner p {margin: 0;} .map-overlay-inner label {display: block;font-weight: bold;} .map-overlay-inner button {background-color: cornflowerblue;color: white;border-radius: 5px;display: inline-block;height: 20px;border: none;cursor: pointer;} .map-overlay-inner button:focus {outline: none;} .map-overlay-inner button:hover {background-color: blue;box-shadow: inset 0 0 0 3px rgba(0, 0, 0, 0.1);-webkit-transition: background-color 500ms linear;-ms-transition: background-color 500ms linear;transition: background-color 500ms linear;} .offset > label,.offset > input {display: inline;} #animateLabel {display: inline-block;min-width: 20px;}</style> <div id="map"></div><div class="map-overlay top"><div class="map-overlay-inner"><fieldset><label>Select easing function</label><select id="easing" name="easing"><option value="easeInCubic">Ease In Cubic</option><option value="easeOutQuint">Ease Out Quint</option><option value="easeInOutCirc">Ease In/Out Circ</option><option value="easeOutBounce">Ease Out Bounce</option></select></fieldset><fieldset><label for="duration">Set animation duration</label><p id="durationValue"></p><inputtype="range"id="duration"name="duration"min="0"max="10000"step="500"value="1000"/></fieldset><fieldset><label>Animate camera motion</label><label for="animate" id="animateLabel">Yes</label><input type="checkbox" id="animate" name="animate" checked /></fieldset><fieldset class="offset"><label for="offset-x">Offset-X</label><inputtype="number"id="offset-x"name="offset-x"min="-200"max="200"step="50"value="0"/></fieldset><fieldset class="offset"><label for="offset-y">Offset-Y</label><inputtype="number"id="offset-y"name="offset-y"min="-200"max="200"step="50"value="0"/><p>Offsets can be negative</p></fieldset><button type="button" id="animateButton" name="test-animation">Test Animation</button></div></div> <script>// declare various easing functions.// easing functions mathematically describe// how fast a value changes during an animation.// each function takes a parameter t that represents// the progress of the animation.// t is in a range of 0 to 1 where 0 is the initial// state and 1 is the completed state.var easingFunctions = {// start slow and gradually increase speedeaseInCubic: function (t) {return t * t * t;},// start fast with a long, slow wind-downeaseOutQuint: function (t) {return 1 - Math.pow(1 - t, 5);},// slow start and finish with fast middleeaseInOutCirc: function (t) {return t < 0.5? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2: (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;},// fast start with a "bounce" at the endeaseOutBounce: function (t) {var n1 = 7.5625;var d1 = 2.75; if (t < 1 / d1) {return n1 * t * t;} else if (t < 2 / d1) {return n1 * (t -= 1.5 / d1) * t + 0.75;} else if (t < 2.5 / d1) {return n1 * (t -= 2.25 / d1) * t + 0.9375;} else {return n1 * (t -= 2.625 / d1) * t + 0.984375;}}}; // set up some helpful UX on the formvar durationValueSpan = document.getElementById('durationValue');var durationInput = document.getElementById('duration');durationValueSpan.innerHTML = durationInput.value / 1000 + ' seconds';durationInput.addEventListener('change', function (e) {durationValueSpan.innerHTML = e.target.value / 1000 + ' seconds';}); var animateLabel = document.getElementById('animateLabel');var animateValue = document.getElementById('animate');animateValue.addEventListener('change', function (e) {animateLabel.innerHTML = e.target.checked ? 'Yes' : 'No';}); var map = new trackasiagl.Map({container: 'map',style: 'https://maps.track-asia.com/styles/v1/streets.json?key=public_key',center: {"lat":10.762622,"lng":106.660172},zoom: 10}); map.on('load', function () {// add a layer to display the map's center pointmap.addSource('center', {'type': 'geojson','data': {'type': 'Point','coordinates': [10.762622,106.660172]}});map.addLayer({'id': 'center','type': 'symbol','source': 'center','layout': {'icon-image': 'border-dot','text-field': 'Center: [106.660172, 0.762622]','text-font': ['DIN Pro Regular', 'Arial Unicode MS Regular'],'text-offset': [0, 0.6],'text-anchor': 'top'}}); var animateButton = document.getElementById('animateButton');animateButton.addEventListener('click', function () {var easingInput = document.getElementById('easing');var easingFn =easingFunctions[easingInput.options[easingInput.selectedIndex].value];var duration = parseInt(durationInput.value, 10);var animate = animateValue.checked;var offsetX = parseInt(document.getElementById('offset-x').value,10);var offsetY = parseInt(document.getElementById('offset-y').value,10); var animationOptions = {duration: duration,easing: easingFn,offset: [offsetX, offsetY],animate: animate,essential: true // animation will happen even if user has `prefers-reduced-motion` setting on}; // Create a random location to fly to by offsetting the map's// initial center point by up to 1 degrees.var center = [106 + (Math.random() - 0.5) * 2,10 + (Math.random() - 0.5) * 2]; // merge animationOptions with other flyTo optionsanimationOptions.center = center; map.flyTo(animationOptions);// update 'center' source and layer to show our new map center// compare this center point to where the camera ends up when an offset is appliedmap.getSource('center').setData({'type': 'Point','coordinates': center});map.setLayoutProperty('center','text-field','Center: [' +center[0].toFixed(1) +', ' +center[1].toFixed(1) +']');});});</script> </body></html>