D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
veltman
Full window
Github gist
Quadtree pixelation
Inspired by
Koalas to the max
.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> </head> <body> <canvas width="960" height="500"></canvas> <script src="https://d3js.org/d3.v4.min.js"></script> <script> let width = 960, height = 500, canvas = document.querySelector("canvas"), context = canvas.getContext("2d"), active = width * height, img = new Image(), tree = d3.quadtree() .extent([[0, 0], [width, height]]); img.onload = draw; img.src = "neon.jpg"; function draw() { context.drawImage(img, 0, 0); let data = context.getImageData(0, 0, width, height).data; for (let x = 0; x < width; x++) { for (let y = 0; y < height; y++) { tree.add(colorAt(data, x, y)); } } setAverageColor(tree.root()); depixelate(tree.root()); } function depixelate(node, x=0, y=0, w=(tree._x1 - tree._x0), h=(tree._y1 - tree._y0), depth=1) { context.fillStyle = "rgb(" + node.color.map(d => Math.round(d)) + ")"; context.fillRect(x, y, w, h); if (node.length) { node.forEach((child, i) => { let cw = w / 2, ch = h / 2, cx = i % 2 ? x + cw : x, cy = i > 1 ? y + ch : y; setTimeout(() => depixelate(child, cx, cy, cw, ch, depth + 1), depth > 7 ? 0 : d3.randomExponential(1 / 1000)()); }); } else { active--; if (!active) { active = width * height; setTimeout(() => depixelate(tree.root()), 500); } } } function setAverageColor(node) { if (!node.length) { return node.color = node.data.slice(2); } return node.color = arrayMean(node.filter(d => d).map(setAverageColor)); } function arrayMean(arrays) { let mean = new Array(3).fill(0); for (let i = 0, l = arrays.length; i < l; i++) { for (let j = 0; j < 3; j++) { mean[j] += arrays[i][j] / l; } } return mean; } function colorAt(data, x, y) { let index = y * width + x; return [x, y, data[index * 4], data[index * 4 + 1], data[index * 4 + 2]]; } </script>
https://d3js.org/d3.v4.min.js