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(); |