Skip to content

Instantly share code, notes, and snippets.

@EmilienDupont
Last active June 6, 2016 15:43
Show Gist options
  • Select an option

  • Save EmilienDupont/53f3a36a7ffd68662dbff421e83d89e5 to your computer and use it in GitHub Desktop.

Select an option

Save EmilienDupont/53f3a36a7ffd68662dbff421e83d89e5 to your computer and use it in GitHub Desktop.
Fountain
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
g = 5, // Low gravity for visualization
then = Date.now();
var scale_x = d3.scale.linear()
.domain([0, width])
.range([0, 5]);
var scale_y = d3.scale.linear()
.domain([0, height])
.range([5 * height/width, 0]);
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
/* Create droplets with random initial velocities */
function create_droplets(num_droplets) {
var droplets = [];
for (i = 0; i < num_droplets; i++) {
var v_x_init = 2.5 * (Math.random() - 0.5),
v_y_init = 1.5 * Math.random() + 3.5,
x_init = scale_x(width/2),
y_init = scale_y(height),
time_delay = 2 * Math.random(),
period = v_y_init / 2.5;
droplets.push({ "vel_init": {"x" : v_x_init, "y" : v_y_init},
"pos_init": {"x" : x_init, "y" : y_init},
"time_delay": time_delay,
"period": period});
}
return droplets;
}
/* Returns (x,y) position at time t given inital velocity and position */
function position(pos_init, vel_init, t) {
var x_pos = vel_init.x * t + pos_init.x,
y_pos = -.5 * g * t * t + vel_init.y * t + pos_init.y;
return {"x" : x_pos, "y" : y_pos};
}
droplets_data = create_droplets(200);
var circles = svg.selectAll("circle")
.data(droplets_data)
.enter()
.append("circle")
.attr("cx", function(d) { return scale_x.invert(position(d.pos_init, d.vel_init, 0).x); })
.attr("cy", function(d) { return scale_y.invert(position(d.pos_init, d.vel_init, 0).y); })
.attr("r", function(d) { return 5 + 5 * Math.random(); })
.attr("fill", function(d) { return d3.hsl(150 + Math.floor(50 * Math.random()), 1, .5); } );
function redraw(t) {
circles.attr("cx", function(d) { return scale_x.invert(position(d.pos_init, d.vel_init, Math.max(0, t - d.time_delay) % d.period ).x); })
.attr("cy", function(d) { return scale_y.invert(position(d.pos_init, d.vel_init, Math.max(0, t - d.time_delay) % d.period ).y); })
.attr("fill-opacity", function (d) { return 1 - Math.max(0, t - d.time_delay) % d.period /d.period; });
}
d3.timer(function() {
var time = (Date.now() - then)/1000;
redraw(time);
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment