Transition hacking by overwriting Date.now, tricking d3.timer into thinking it's whatever time we want. Beyond the obvious red flags of overwriting a browser global, this only really works for moving forward (each transition in a chain self-deletes once it hits t=1). I would not recommend this.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| body { | |
| text-align: center; | |
| font: 16px sans-serif; | |
| } | |
| button { | |
| margin: 0 0.5em; | |
| } | |
| circle { | |
| stroke: #000; | |
| stroke-width: 1.5px; | |
| } | |
| </style> | |
| <body> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js"></script> | |
| <script> | |
| var margin = {top: 100, right: 100, bottom: 100, left: 100}, | |
| width = 960 - margin.left - margin.right, | |
| height = 440 - margin.top - margin.bottom; | |
| var x = d3.scale.ordinal() | |
| .domain(d3.range(5)) | |
| .rangePoints([0, width]); | |
| var y = x.copy() | |
| .rangePoints([0, height]); | |
| var color = d3.scale.linear() | |
| .domain(d3.extent(x.domain())) | |
| .range(["hsl(297,50%,47%)", "hsl(81,78%,61%)"]) | |
| .interpolate(d3.interpolateHcl); | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width + margin.left + margin.right) | |
| .attr("height", height + margin.top + margin.bottom) | |
| .append("g") | |
| .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
| var dots = svg.selectAll("circle") | |
| .data(x.domain()) | |
| .enter() | |
| .append("circle") | |
| .attr("r",20) | |
| .attr("cx",0) | |
| .attr("cy",y) | |
| .style("fill",color); | |
| var curTime = 0, | |
| _now = Date.now; // save for later | |
| // FREEZE TIME | |
| Date.now = function fakeNow(){ | |
| return curTime; | |
| }; | |
| // Create a transition | |
| dots.transition() | |
| .duration(3500) | |
| .delay(function(d){ | |
| return d * 125; | |
| }) | |
| .attr("cx",x) | |
| .attr("r",40) | |
| .transition() | |
| .duration(2000) | |
| .attr("r",20) | |
| .attr("cx",width); | |
| d3.select("body").append("div") | |
| .text("Jump to: ") | |
| .selectAll("button") | |
| .data(d3.range(0,6500,500)) | |
| .enter() | |
| .append("button") | |
| .text(function(d){ | |
| return (Math.round(d/100)/10) + " s"; | |
| }) | |
| .on("click",function(d){ | |
| curTime = d; // TIME TRAVEL | |
| }); | |
| d3.select("div").append("button") | |
| .text("Finish") | |
| .style("font-weight","bold") | |
| .on("click",function(){ | |
| d3.selectAll("button").attr("disabled",true).on("click",null); | |
| var now = _now(); | |
| d3.timer(function(){ | |
| var t = _now(); | |
| curTime += (t - now); | |
| now = t; | |
| if (curTime >= 6000) { | |
| // Transitions are all done | |
| // Restore REAL TIME | |
| Date.now = _now; | |
| d3.select("div").remove(); | |
| return true; | |
| } | |
| },0,0); | |
| }); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
