Skip to content

Instantly share code, notes, and snippets.

@danasilver
Last active March 4, 2016 03:10
Show Gist options
  • Save danasilver/edf6332dd875699aceb5 to your computer and use it in GitHub Desktop.
Save danasilver/edf6332dd875699aceb5 to your computer and use it in GitHub Desktop.
Gaussian Blur
height: 504
license: MIT
<!doctype html>
<meta charset="utf-8">
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 0, right: 0, bottom: 0, left: 0},
width = 960 - margin.left - margin.right,
height = 504 - margin.top - margin.bottom;
var pixels = d3.range(42)
.map(function() {
return d3.range(80).map(function() { return Math.random() * 255 | 0; });
});
var gaussian = [
[1/16, 2/16, 1/16],
[2/16, 4/16, 2/16],
[1/16, 2/16, 1/16]
];
var convolved = convolve(pixels, gaussian);
var svg = d3.select('body').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', ' translate(' + margin.left + ',' + margin.top + ')');
var row = svg.selectAll('g')
.data(pixels).enter()
.append('g')
.attr('class', 'row')
.attr('transform', function(d, i) { return 'translate(0,' + (i * height / 42) + ')'; });
row.selectAll('rect')
.data(function(d) { return d; }).enter()
.append('rect')
.attr('height', 11)
.attr('width', 11)
.attr('x', function(d, i) { return i * 12; })
.attr('fill', function(d) { return 'rgb(' + d + ',' + d + ',' + d + ')' });
transition();
setInterval(transition, 5600);
function transition() {
row
.data(convolve(pixels, gaussian))
.selectAll('rect')
.data(function(d) { return d; })
.transition()
.delay(function(d, i) { return i * 10; })
.duration(2000)
.attr('fill', function(d) { return 'rgb(' + d + ',' + d + ',' + d + ')' });
row
.data(pixels)
.selectAll('rect')
.data(function(d) { return d; })
.transition()
.delay(function(d, i) { return 3000 + (80 - i) * 10; })
.duration(2000)
.attr('fill', function(d) { return 'rgb(' + d + ',' + d + ',' + d + ')' });
}
function convolve(pixels, kernel) {
var height = pixels.length,
width = pixels[0].length,
kernelHeight = kernel.length,
kernelWidth = kernel[0].length;
var output = d3.range(height)
.map(function() { return d3.range(width).map(function() { return 0; }); });
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var accumulator = 0;
for (var kernelY = 0; kernelY < kernelHeight; kernelY++) {
for (var kernelX = 0; kernelX < kernelWidth; kernelX++) {
// kernel origin is in the center of the 2d array
var currentY = y + kernelY - Math.floor(kernelHeight / 2);
var currentX = x + kernelX - Math.floor(kernelWidth / 2);
if (currentY >= 0 && currentY < height &&
currentX >= 0 && currentX < width) {
var src = pixels[currentY][currentX];
var weight = kernel[kernelY][kernelX];
accumulator += src * weight;
}
}
}
output[y][x] = accumulator;
}
}
return output;
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment