Revisitng the famous mbostock's block: Rotating Voronoi with the d3-distanceLimitedVoronoi plugin I made.
At each iteration, maximum distance from each datum/seed is updated. Compare to the SVG version.
license: gpl-3.0 |
Revisitng the famous mbostock's block: Rotating Voronoi with the d3-distanceLimitedVoronoi plugin I made.
At each iteration, maximum distance from each datum/seed is updated. Compare to the SVG version.
<meta charset="utf-8"> | |
<style> | |
body { | |
background: #000; | |
} | |
path { | |
fill: #fff; | |
stroke: #000; | |
stroke-width: 1.5px; | |
} | |
</style> | |
<body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://raw.githack.com/Kcnarf/d3-distanceLimitedVoronoi/master/distance-limited-voronoi.js"></script> | |
<script> | |
var width = 960, | |
height = 500; | |
var start = Date.now(), | |
points = []; | |
var maxDistance = 400; | |
circle(0, 0, 120, 96, -.001); | |
circle(0, 0, 30, 10, .03); | |
circle(0, 0, 60, 3, -.05); | |
circle(0, 0, 15, 4, -.02); | |
circle(0, 0, 0, 1, -.02); | |
circle(240, -120, 80, 4, -.02); | |
circle(240, -120, 0, 1, -.02); | |
circle(280, +120, 40, 8, .02); | |
circle(280, +120, 20, 8, -.02); | |
circle(280, +120, 0, 1, .02); | |
var canvas = d3.select("body").append("canvas") | |
.attr("width", width) | |
.attr("height", height); | |
var context = canvas.node().getContext("2d"); | |
context.translate(width/2, height/2); | |
var limitedVoronoi = d3.distanceLimitedVoronoi() | |
limitedVoronoi.extent([[-width / 2, -height / 2],[+width / 2, +height / 2]]).limit(maxDistance).context(context); | |
d3.timer(function(elapsed) { | |
//update limit | |
limitedVoronoi.limit(2+maxDistance*Math.pow(Math.cos((elapsed++)/5000), 4)); | |
//delete previous rendering | |
context.fillStyle = 'black'; | |
context.fillRect(-width/2, -height/2, width, height); | |
//renders new distance-limited voronoi | |
context.strokeStyle = 'black'; | |
context.fillStyle = 'white'; | |
context.beginPath(); | |
limitedVoronoi(points); | |
context.fill(); | |
context.stroke(); | |
}); | |
function circle(cx, cy, r, n, δθ) { | |
d3.range(1e-6, 2 * Math.PI, 2 * Math.PI / n).map(function(θ, i) { | |
var point = [cx + Math.cos(θ) * r, cy + Math.sin(θ) * r]; | |
d3.timer(function(elapsed) { | |
var angle = θ + δθ * elapsed / 60; | |
point[0] = cx + Math.cos(angle) * r; | |
point[1] = cy + Math.sin(angle) * r; | |
}); | |
points.push(point); | |
return point; | |
}); | |
} | |
</script> | |
</body> |