Skip to content

Instantly share code, notes, and snippets.

@rveciana
Last active May 15, 2019
Embed
What would you like to do?
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>
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