forked from theopenwindow's block: Animation point on route
xxxxxxxxxx
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style>
body {
font-family: Helvetica, sans-serif;
padding: 40px;
}
.map {
stroke: #e0e9ef;
stroke-width:0.8px;
fill: white;
fill-opacity: .5;
}
path {
fill:none;
stroke: blue;
stroke-width: 2px;
}
</style>
<body>
<h2>Road Trip</h2>
<button>Pause</button>
<div id="vis"></div>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/queue.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 1000,
height = 600;
var svg = d3.select('#vis').append('svg')
.attr('width', width)
.attr('height', height);
var projection = d3.geo.mercator()
.center([-95, 40])
.scale(900)
.translate([width / 2, height / 2 - 20])
.clipExtent([[0, 0], [width, height + 1]])
.precision(0);
var projectPath = d3.geo.path()
.projection(projection);
var routePath = d3.svg.line()
.x(function(d) {
console.log(d);
return projection([+d.lon, +d.lat])[0];
})
.y(function(d) {
return projection([+d.lon, +d.lat])[1];
});
var arcGroup = svg.append('g').attr("class", "arcgroup");
var pointGroup = svg.append('g').attr("class","pointgroup");
d3.json("usatopo.json", function(error, usatopo) {
var map = topojson.feature(usatopo, usatopo.objects.units);
svg.append('path')
.datum(map)
.attr('class', 'map')
.attr('d', projectPath);
d3.csv("route.csv", function(error, route){
var pathArcs = arcGroup.append("path").datum(route)
.attr("d", routePath);
//draw stable points
var nodes = [];
for(var i=0, len=route.length-1; i<len; i++){
nodes.push(
[ +route[i].lon, +route[i].lat ],
[ +route[i+1].lon, +route[i+1].lat ]
);
}
console.log("nodes", nodes);
pointGroup.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r", 2)
.attr("cx", function (d) {
console.log(d);
return projection(d)[0]; })
.attr("cy", function (d) {
return projection(d)[1]; });
//draw running points
var circle = svg.append("circle")
.attr("r", 3)
.attr("fill", "red")
.attr("transform", "translate(" + nodes[0] + ")");
var pauseValues = {
lastT: 0,
currentT: 0
};
function transition() {
circle.transition()
//.duration(duration - (duration * pauseValues.lastT))--->to change speed
.duration(5000)
.attrTween("transform", translateAlong(pathArcs.node()))
// console.log(translateAlong(path.node()))
.each("end", function(){
pauseValues = {
lastT: 0,
currentT: 0
};
transition()
});
}
function translateAlong(path) {
var l = path.getTotalLength();
console.log("in transl", path);
return function(d, i) {
return function(t) {
t += pauseValues.lastT;
var p = path.getPointAtLength(t * l);
pauseValues.currentT = t;
return "translate(" + p.x + "," + p.y + ")";
};
};
}
d3.select('button').on('click',function(d,i){
var self = d3.select(this);
if (self.text() == "Pause"){
self.text('Play');
circle.transition()
.duration(0);
setTimeout(function(){
pauseValues.lastT = pauseValues.currentT;
}, 100);
}else{
self.text('Pause');
transition();
}
});
transition();
});
});
</script>
</body>
</html>
https://d3js.org/d3.v3.min.js
https://d3js.org/queue.v1.min.js
https://d3js.org/topojson.v1.min.js