Skip to content

Instantly share code, notes, and snippets.

@rveciana
Last active May 15, 2019 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rveciana/6a50336f5fffee99f29e1881ebee5e97 to your computer and use it in GitHub Desktop.
Save rveciana/6a50336f5fffee99f29e1881ebee5e97 to your computer and use it in GitHub Desktop.
Map scroller associated with video position

Play the video once loaded to see the example.

I took the idea from this tweet.

I created the path with the help of Geojson.io, and it's not exact. The idea was showing the possibility of syncing the video with the path.

The video is a timelapse (I don't dare driving this fast) taken at the paradise valley close to Agadir, Morocco. Go there if you have the opportunity!

The code should be improved. I think that some times don't work if play is pressed beffore the video ends loading.

<!DOCTYPE html>
<meta charset="utf-8">
<html>
<style>
video {
vertical-align: top;
}
</style>
<body>
<video width="320" height="240" controls>
<source src="valee.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/d3.geo.tile.v0.min.js"></script>
<script>
var width = 450,
height = 500;
var projection = d3.geo.mercator()
.center([-9.52, 30.5809])
.scale(1000000);
var path = d3.geo.path()
.projection(projection);
var tile = d3.geo.tile()
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]))
.zoomDelta((window.devicePixelRatio || 1) - .5);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var tiles = tile();
var defs = svg.append("defs");
svg.append("g")
.selectAll("image")
.data(tiles)
.enter().append("image")
.attr("xlink:href", function(d) {
return "http://b.tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png";
})
.attr("width", Math.round(tiles.scale) + 1)
.attr("height", Math.round(tiles.scale) + 1)
.attr("x", function(d) { return Math.round((d[0] + tiles.translate[0]) * tiles.scale); })
.attr("y", function(d) { return Math.round((d[1] + tiles.translate[1]) * tiles.scale); });
d3.json("path.json", function(error, route) {
var pathLength;
var routeLine = svg.append("path")
.attr("d",path(route))
.attr("stroke","#f44")
.attr("stroke-width","4px")
.attr("fill","none")
.style('stroke-dasharray', function(d) {
pathLength = d3.select(this).node().getTotalLength();
return pathLength + 'px, ' + pathLength + 'px';
})
.style('stroke-dashoffset', function(d) {
return d3.select(this).node().getTotalLength() + 'px';
});
var video = d3.select("video")
.on("play", function(){
var currentTime = this.currentTime;
var duration = this.duration;
routeLine
.style('stroke-dashoffset', function(d) {
return pathLength*(1-(currentTime/duration))+'px';
});
routeLine
.transition()
.duration(1000*(duration - currentTime))
.ease("linear")
.style('stroke-dashoffset', '0px');
})
.on("pause", function(){
routeLine
.transition();
})
.on("seeked", function(){
var currentTime = this.currentTime;
var duration = this.duration;
routeLine
.style('stroke-dashoffset', function(d) {
return pathLength*(1-(currentTime/duration))+'px';
});
});
});
</script>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file has been truncated, but you can view the full file.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment