Last active
July 22, 2019 06:42
-
-
Save elenatorro/ab00b847d42376a793df770395691d32 to your computer and use it in GitHub Desktop.
Multiple animation controls
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>Animation | CARTO VL</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<meta charset="UTF-8"> | |
<script src="https://libs.cartocdn.com/carto-vl/v1.4/carto-vl.min.js"></script> | |
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.js"></script> | |
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.0.0/mapbox-gl.css" rel="stylesheet" /> | |
<link href="https://fonts.googleapis.com/css?family=Roboto:100,200,400,500" rel="stylesheet"> | |
<style type="text/css"> | |
body { | |
margin: 0; | |
} | |
aside.toolbox { | |
right: 96px; | |
position: absolute; | |
top: 24px; | |
right: 24px; | |
min-width: 250px; | |
max-width: 250px; | |
max-width: 350px; | |
z-index: 2; | |
overflow-wrap: break-word; | |
} | |
.box { | |
width: 320px; | |
background: #f2f2f2; | |
z-index: 2; | |
border-radius: 4px; | |
padding: 16px; | |
margin: 0 0 24px; | |
box-shadow: 0 0px 16px rgba(0, 0, 0, 0.24); | |
} | |
section { | |
display: flex; | |
flex-direction: row; | |
justify-content: space-between; | |
} | |
section.controls { | |
margin-top: 15px; | |
flex-direction: column; | |
align-items: left; | |
} | |
hr { | |
margin: 15px auto; | |
} | |
input[type=range] { | |
-webkit-appearance: none; | |
border: 1px solid white; | |
background: transparent; | |
border: none; | |
cursor: pointer; | |
flex: 1; | |
padding: auto 10px; | |
margin: auto 5px; | |
width: 100%; | |
} | |
input[type=range]::-webkit-slider-runnable-track { | |
height: 3px; | |
background: #1785FB; | |
border: none; | |
border-radius: 3px; | |
} | |
input[type=range]::-webkit-slider-thumb { | |
-webkit-appearance: none; | |
border: none; | |
height: 10px; | |
width: 10px; | |
border-radius: 50%; | |
background: #1785FB; | |
margin-top: -4px; | |
} | |
input[type=range]:focus { | |
outline: none; | |
} | |
input[type=range]::-moz-range-track { | |
height: 3px; | |
background: #1785FB; | |
border: none; | |
border-radius: 3px; | |
} | |
input[type=range]::-moz-range-thumb { | |
border: none; | |
height: 10px; | |
width: 10px; | |
border-radius: 50%; | |
background: #1785FB; | |
} | |
input[type=range].white-thumb::-moz-range-thumb { | |
border-radius: 50%; | |
border: 2px solid #1785FB; | |
background: white; | |
height: 12px; | |
width: 12px; | |
} | |
input[type=range].white-thumb::-webkit-slider-thumb { | |
border-radius: 50%; | |
border: 3px solid #1785FB; | |
background: white; | |
height: 15px; | |
width: 15px; | |
margin-top: -6px; | |
} | |
input[type=range].white-thumb::-ms-thumb { | |
border-radius: 50%; | |
border: 2px solid #1785FB; | |
background: white; | |
height: 12px; | |
width: 12px; | |
} | |
input[type=range]:-moz-focusring { | |
outline: 1px solid white; | |
outline-offset: -1px; | |
} | |
input[type=range]::-ms-track { | |
height: 3px; | |
background: transparent; | |
border-color: transparent; | |
border-width: 6px 0; | |
color: transparent; | |
} | |
input[type=range]::-ms-fill-lower { | |
background: #1785FB; | |
} | |
input[type="range"]::-moz-range-progress { | |
background: #1785FB; | |
} | |
input[type=range]::-ms-fill-upper { | |
background: #ccc; | |
} | |
input[type="range"]::-moz-range-track { | |
background: #ccc; | |
} | |
input[type=range]::-ms-thumb { | |
border: none; | |
height: 10px; | |
width: 10px; | |
border-radius: 50%; | |
background: #1785FB; | |
} | |
input[type="button"] { | |
width: 36px; | |
height: 36px; | |
border-radius: 4px; | |
border: 0; | |
box-shadow: none; | |
color: #fff; | |
cursor: pointer; | |
display: inline-flex; | |
font: 500 12px/20px 'Roboto'; | |
margin: 0; | |
margin-right: 10px; | |
} | |
#map { | |
flex: 1; | |
position: absolute; | |
height: 100%; | |
width: 100%; | |
z-index: 0; | |
} | |
#js-duration-span { | |
background: white; | |
border: 1px solid #ddd; | |
width: 32px; | |
height: 32px; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
#js-play-button { | |
background-color: #1785FB; | |
background-position: center; | |
} | |
#js-pause-button { | |
background-color: #1785FB; | |
background-position: center; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<!-- Animation control elements --> | |
<aside class="toolbox"> | |
<div class="box"> | |
<header> | |
<h1>Seattle Collisions</h1> | |
</header> | |
<section> | |
<p class="description open-sans">Add animation controls for "play", "pause" and "set" commands</p> | |
</section> | |
<section class="controls"> | |
<div> | |
<button id="js-play-button">Play</button> | |
<button id="js-pause-button">Pause</button> | |
</div> | |
<div> | |
<p>Animation 1 progress</p> | |
<input type="range" id="js-time-range-1" min="0" max="1" step="0.01"> | |
</div> | |
<div> | |
<p>Animation 2 progress</p> | |
<input type="range" id="js-time-range-2" min="0" max="1" step="0.01"> | |
</div> | |
</section> | |
<br /> | |
<section> | |
<span id="js-current-time" class="open-sans"></span> | |
</section> | |
<hr> | |
<section> | |
<span style="margin-right: 5px" class="open-sans">Duration (seconds)</span> | |
<input class="white-thumb" type="range" id="js-duration-range" min="1" max="60" step="1"> | |
<span style="margin-left: 5px" class="open-sans" id="js-duration-span">10</span> | |
</section> | |
</div> | |
</aside> | |
<div id="loader"> | |
<div class="CDB-LoaderIcon CDB-LoaderIcon--big"> | |
<svg class="CDB-LoaderIcon-spinner" viewBox="0 0 50 50"> | |
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"></circle> | |
</svg> | |
</div> | |
</div> | |
<script> | |
const map = new mapboxgl.Map({ | |
container: 'map', | |
style: carto.basemaps.darkmatter, | |
center: [-122.33, 47.61], | |
zoom: 10, | |
scrollZoom: false | |
}); | |
const nav = new mapboxgl.NavigationControl(); | |
map.addControl(nav, 'top-left'); | |
map.addControl(new mapboxgl.FullscreenControl(), 'top-left'); | |
carto.setDefaultAuth({ | |
username: 'cartovl', | |
apiKey: 'default_public' | |
}); | |
const source1 = new carto.source.Dataset('seattle_collisions'); | |
const source2 = new carto.source.Dataset('seattle_collisions'); | |
// Define animation viz with variables | |
const viz1 = new carto.Viz(` | |
@duration: 30 | |
@animation: animation($incdate, @duration, fade(1, 1)) | |
filter: @animation | |
color: turquoise | |
strokeWidth: 0 | |
`); | |
const viz2 = new carto.Viz(` | |
@duration: 30 | |
@animation: animation($incdate, @duration, fade(1, 1)) | |
filter: @animation | |
color: purple | |
strokeWidth: 0 | |
`); | |
const layer1 = new carto.Layer('layer1', source1, viz1); | |
const layer2 = new carto.Layer('layer2', source2, viz2); | |
layer2.addTo(map); | |
layer1.addTo(map); | |
// Get HTML elements | |
const $playbutton = document.getElementById('js-play-button'); | |
const $pausebutton = document.getElementById('js-pause-button'); | |
const $durationRange = document.getElementById('js-duration-range'); | |
const $timeRange1 = document.getElementById('js-time-range-1'); | |
const $timeRange2 = document.getElementById('js-time-range-2'); | |
const $spanDuration = document.getElementById('js-duration-span'); | |
const $currentTime = document.getElementById('js-current-time'); | |
// Save initial time range value | |
let last1 = $timeRange1.value; | |
let last2 = $timeRange2.value; | |
// Listen to interaction events | |
$durationRange.addEventListener('change', () => { | |
const duration = parseInt($durationRange.value, 10); | |
// Update animation duration | |
viz1.variables.duration = $spanDuration.innerHTML = duration; | |
viz2.variables.duration = $spanDuration.innerHTML = duration; | |
}); | |
$playbutton.addEventListener('click', () => { | |
// Play the animation | |
viz1.variables.animation.play() | |
viz2.variables.animation.play(); | |
}); | |
$pausebutton.addEventListener('click', () => { | |
// Pause the animation | |
viz1.variables.animation.pause(); | |
viz2.variables.animation.pause(); | |
}); | |
$timeRange1.addEventListener('change', () => { | |
// Update animation progress | |
viz1.variables.animation.setProgressPct($timeRange1.value); | |
last1 = $timeRange1.value; | |
}); | |
$timeRange2.addEventListener('change', () => { | |
// Update animation progress | |
viz2.variables.animation.setProgressPct($timeRange2.value); | |
last2 = $timeRange2.value; | |
}); | |
// Listen to layer events | |
layer1.on('updated', () => { | |
if ($timeRange1.value == last1) { | |
$timeRange1.value = viz1.variables.animation.getProgressPct(); | |
last1 = $timeRange1.value; | |
} | |
if ($timeRange2.value == last2) { | |
$timeRange2.value = viz2.variables.animation.getProgressPct(); | |
last2 = $timeRange2.value; | |
} | |
}); | |
carto.on('loaded', [layer1, layer2], hideLoader); | |
function hideLoader() { | |
document.getElementById('loader').style.opacity = '0'; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment