Published
Edited
Feb 1, 2020
1 fork
32 stars
Insert cell
Insert cell
Insert cell
{
const n = width / radius;
const m = height / radius;
const context = DOM.context2d(width, height);
const tiles = [hexagons, squares, triangles]
.map(tile => tile(n, m)
.map(translate(width / 2, height / 2))
.map(jitter(1e-2))); // avoid collinear input
context.lineWidth = 1.5;
for (let i = 0; true; ++i) {
const ti = d3.interpolate(tiles[i % 3], tiles[(i + 1) % 3]);
for (let f = 0, F = 120; f < F; ++f) {
const delaunay = d3.Delaunay.from(ti(d3.easeCubic(f / F)));
const voronoi = delaunay.voronoi([0, 0, width, height]);
context.clearRect(0, 0, width, height);
context.beginPath();
voronoi.render(context);
context.stroke();
if (viewof centroids.value) {
context.beginPath();
delaunay.renderPoints(context, 1.5);
context.fill();
}
yield context.canvas;
}
}
}
Insert cell
function hexagons(n, m) {
const points = [];
const r = radius * Math.sqrt(8 / Math.sqrt(3));
const dx = r;
const dy = r * 3 / (4 * Math.sin(Math.PI / 3));
const x0 = -dx * n / 2;
const y0 = -dy * m / 2;
for (let j = 0, y = y0; j < m; y += dy, ++j) {
for (let i = 0, x = x0 + (j & 1) * dx / 2; i < n; x += dx, ++i) {
points.push([x, y]);
}
}
return points;
}
Insert cell
function squares(n, m) {
const points = [];
const r = radius * 2;
const dx = r;
const dy = r;
const x0 = -dx * n / 2;
const y0 = -dy * m / 2;
for (let j = 0, y = y0; j < m; y += dy, ++j) {
for (let i = 0, x = x0; i < n; x += dx, ++i) {
points.push([x, y]);
}
}
return points;
}
Insert cell
function triangles(n, m) {
const points = [];
const r = radius * Math.sqrt(4 / Math.sqrt(3));
const dx = r;
const dy = r * Math.sqrt(3);
const dr = r / Math.sqrt(12);
const x0 = -dx * n / 2;
const y0 = -dy * m / 2;
for (let j = 0, y = y0; j < m; y += dy, ++j) {
for (let i = 0, x = x0; i < n; x += dx, ++i) {
points.push([x, y + (j & 1 ^ i & 1 ? -1 : +1) * dr]);
}
}
return points;
}
Insert cell
jitter = e => ([x, y]) => [x + (Math.random() - 0.5) * e, y + (Math.random() - 0.5) * e]
Insert cell
translate = (tx, ty) => ([x, y]) => [x + tx, y + ty]
Insert cell
radius = 16
Insert cell
height = 640
Insert cell
d3 = require("d3-delaunay@5", "d3-ease@1", "d3-interpolate@1")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more