66 строки
1.7 KiB
JavaScript
66 строки
1.7 KiB
JavaScript
var w = 960,
|
|
h = 500,
|
|
mouse = [null, null],
|
|
fill = d3.scale.linear().domain([0, 1e4]).range(["brown", "steelblue"]);
|
|
|
|
// Initialise boids.
|
|
var boids = d3.range(100).map(function() {
|
|
return boid()
|
|
.position([Math.random() * w, Math.random() * h])
|
|
.velocity([Math.random() * 2 - 1, Math.random() * 2 - 1])
|
|
.gravityCenter(mouse);
|
|
});
|
|
|
|
// Compute initial positions.
|
|
var vertices = boids.map(function(boid) {
|
|
return boid(boids);
|
|
});
|
|
|
|
d3.select(window).on("blur", nullGravity);
|
|
|
|
var svg = d3.select("#vis")
|
|
.append("svg:svg")
|
|
.attr("width", w)
|
|
.attr("height", h)
|
|
.attr("class", "PiYG")
|
|
.on("mousemove", function() {
|
|
var m = d3.svg.mouse(this);
|
|
mouse[0] = m[0];
|
|
mouse[1] = m[1];
|
|
})
|
|
.on("mouseout", nullGravity);
|
|
|
|
svg.selectAll("path")
|
|
.data(d3.geom.voronoi(vertices))
|
|
.enter().append("svg:path")
|
|
.attr("class", function(d, i) { return i ? "q" + (i % 9) + "-9" : null; })
|
|
.attr("d", function(d) { return "M" + d.join("L") + "Z"; });
|
|
|
|
svg.selectAll("circle")
|
|
.data(vertices)
|
|
.enter().append("svg:circle")
|
|
.attr("transform", function(d) { return "translate(" + d + ")"; })
|
|
.attr("r", 2);
|
|
|
|
d3.timer(function() {
|
|
// Update boid positions.
|
|
boids.forEach(function(boid, i) {
|
|
vertices[i] = boid(boids);
|
|
});
|
|
|
|
// Update circle positions.
|
|
svg.selectAll("circle")
|
|
.data(vertices)
|
|
.attr("transform", function(d) { return "translate(" + d + ")"; });
|
|
|
|
// Update voronoi diagram.
|
|
svg.selectAll("path")
|
|
.data(d3.geom.voronoi(vertices))
|
|
.attr("d", function(d) { return "M" + d.join("L") + "Z"; })
|
|
.style("fill", function(d) { return fill((d3.geom.polygon(d).area())); });
|
|
});
|
|
|
|
function nullGravity() {
|
|
mouse[0] = mouse[1] = null;
|
|
}
|