Click it to make it go again.
A d3.js version of the "egyptian" effect used in Tron. A few really fun pages over here by GMUNK were the inspiration.
Click it to make it go again.
A d3.js version of the "egyptian" effect used in Tron. A few really fun pages over here by GMUNK were the inspiration.
| <!DOCTYPE html> | |
| <html> | |
| <meta charset="utf-8"> | |
| <style> | |
| body { | |
| margin: 0; | |
| background: #111; | |
| min-width: 960px; | |
| } | |
| line { | |
| fill: none; | |
| } | |
| </style> | |
| <body> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script src="main.js"></script> | |
| </body> | |
| </html> |
| var width = Math.max(960, innerWidth), | |
| height = Math.max(500, innerHeight); | |
| var rectWave = [ | |
| function(x, y) { return [x, y+this.size]; }, | |
| function(x, y) { return [x+this.size, y]; }, | |
| function(x, y) { return [x+this.size * 2, y]; }, | |
| function(x, y) { return [x, y-this.size]; }, | |
| ]; | |
| var triWave = [ | |
| function(x, y) { return [x + this.size, y + this.size]; }, | |
| function(x, y) { return [x + this.size, y]; }, | |
| function(x, y) { return [x + this.size, y - this.size]; }, | |
| ]; | |
| var n = 15, // Total number of fliers | |
| fadeTime = 500, // Time to fade between colors | |
| colors = ["#311", "blue"], // Two colors to fade between | |
| colorSwapChance = 0.0, // Try 0, 0.05, or 0.5! | |
| minSize = 2, // minimum line segment length | |
| maxSize = 10, // maximum line segment length | |
| waveFunction = rectWave; | |
| var stop = 200; | |
| var svg = d3.select("body").append("svg") | |
| .attr("width", width) | |
| .attr("height", height); | |
| function choose(ary) { | |
| return ary[Math.floor(Math.random()*ary.length)]; | |
| } | |
| var fliers = d3.range(n).map(function(d) { | |
| var flier = { | |
| index: d, | |
| size: Math.random() * (maxSize - minSize) + minSize, | |
| }; | |
| flier.next = function(x, y) { | |
| return choose(waveFunction).call(this, x, y); | |
| }.bind(flier); | |
| return flier; | |
| }); | |
| var flier = svg.selectAll('line.head') | |
| .data(fliers); | |
| function start() { | |
| svg.on("ontouchstart" in document ? "touchstart" : "mousedown", function() {}); | |
| flier.enter() | |
| .append('line') | |
| .attr('class', 'head') | |
| .attr('x1', 0) | |
| .attr('y1', function(d) { return d.index * height / (n+1); }) | |
| .attr('x2', 2) | |
| .attr('y2', function(d) { return d.index * height / (n+1); }); | |
| stop = 200; | |
| d3.timer(function() { | |
| if (Math.random() < colorSwapChance) { | |
| colors = colors.reverse(); | |
| } | |
| d3.selectAll('line.head') | |
| .data(fliers) | |
| .attr('class', 'tail') | |
| .transition() | |
| .duration(fadeTime) | |
| .styleTween('stroke', function() { return d3.interpolate.apply(this, colors); }) | |
| .each(function(d) { | |
| var x1 = +this.getAttribute('x2'), | |
| y1 = +this.getAttribute('y2'), | |
| next = d.next(x1, y1); | |
| svg.append('line') | |
| .attr('class', 'head') | |
| .attr('x1', x1) | |
| .attr('y1', y1) | |
| .attr('x2', next[0]) | |
| .attr('y2', next[1]); | |
| }) | |
| .remove(); | |
| if (stop-- < 0) { | |
| d3.selectAll('line.head') | |
| .remove(); | |
| svg.on("ontouchstart" in document ? "touchstart" : "mousedown", start); | |
| return true; | |
| } | |
| }); | |
| } | |
| start(); |