Skip to content

Instantly share code, notes, and snippets.

@eesur
Last active June 25, 2018 12:08
Show Gist options
  • Save eesur/98d670e00ba74b07c9d8d93ec36bf878 to your computer and use it in GitHub Desktop.
Save eesur/98d670e00ba74b07c9d8d93ec36bf878 to your computer and use it in GitHub Desktop.
d3 | pixelated image
license: mit
height: 500
border: no
*{box-sizing:border-box}body{font-family:'Space Mono',monospace;font-size:11px}
!function(n){function e(t){if(g[t])return g[t].exports;var c=g[t]={i:t,l:!1,exports:{}};return n[t].call(c.exports,c,c.exports,e),c.l=!0,c.exports}var g={};e.m=n,e.c=g,e.i=function(n){return n},e.d=function(n,g,t){e.o(n,g)||Object.defineProperty(n,g,{configurable:!1,enumerable:!0,get:t})},e.n=function(n){var g=n&&n.__esModule?function(){return n.default}:function(){return n};return e.d(g,"a",g),g},e.o=function(n,e){return Object.prototype.hasOwnProperty.call(n,e)},e.p="",e(e.s=2)}([function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = drawSvg;\nfunction drawSvg(props) {\n props = _extends({\n colors: null, // []\n size: 10,\n svg: null\n }, props);\n var _props = props,\n colors = _props.colors,\n size = _props.size,\n svg = _props.svg;\n\n console.log('colors', colors);\n var squares = svg.selectAll('.square').data(colors);\n squares.exit().remove();\n squares.enter().append('rect').attr('class', 'square').merge(squares).attr('x', function (d) {\n return d.x;\n }).attr('y', function (d) {\n return d.y;\n }).attr('width', size).attr('height', size).attr('fill', function (d) {\n return d.rgb;\n }).on('mouseover', function (d, i) {\n // console.log('d', d)\n d3.select('.js-info').text(d.rgb);\n });\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMC5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9kcmF3U3ZnLmpzPzJjMWIiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZHJhd1N2ZyAocHJvcHMpIHtcbiAgcHJvcHMgPSB7XG4gICAgY29sb3JzOiBudWxsLCAvLyBbXVxuICAgIHNpemU6IDEwLFxuICAgIHN2ZzogbnVsbCxcbiAgICAuLi5wcm9wc1xuICB9XG4gIGNvbnN0IHtjb2xvcnMsIHNpemUsIHN2Z30gPSBwcm9wc1xuICBjb25zb2xlLmxvZygnY29sb3JzJywgY29sb3JzKVxuICBjb25zdCBzcXVhcmVzID0gc3ZnLnNlbGVjdEFsbCgnLnNxdWFyZScpLmRhdGEoY29sb3JzKVxuICBzcXVhcmVzLmV4aXQoKS5yZW1vdmUoKVxuICBzcXVhcmVzLmVudGVyKCkuYXBwZW5kKCdyZWN0JylcbiAgICAuYXR0cignY2xhc3MnLCAnc3F1YXJlJylcbiAgICAubWVyZ2Uoc3F1YXJlcylcbiAgICAuYXR0cigneCcsIGQgPT4gZC54KVxuICAgIC5hdHRyKCd5JywgZCA9PiBkLnkpXG4gICAgLmF0dHIoJ3dpZHRoJywgc2l6ZSlcbiAgICAuYXR0cignaGVpZ2h0Jywgc2l6ZSlcbiAgICAuYXR0cignZmlsbCcsIGQgPT4gZC5yZ2IpXG4gICAgLm9uKCdtb3VzZW92ZXInLCBmdW5jdGlvbiAoZCwgaSkge1xuICAgICAgLy8gY29uc29sZS5sb2coJ2QnLCBkKVxuICAgICAgZDMuc2VsZWN0KCcuanMtaW5mbycpLnRleHQoZC5yZ2IpXG4gICAgfSlcbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBkcmF3U3ZnLmpzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBREE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFBQTtBQUNBO0FBQUE7QUFHQTtBQUFBO0FBRUE7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///0\n")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, \"__esModule\", {\n value: true\n});\n\nvar _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };\n\nexports.default = pixelate;\nfunction pixelate(props) {\n props = _extends({\n image: null, // new Image()\n size: 10,\n context: null }, props);\n var _props = props,\n image = _props.image,\n size = _props.size,\n context = _props.context;\n // Number of squares left-to-right and top-to-bottom.\n\n var xSquares = image.width / size;\n var ySquares = image.height / size;\n var data = [];\n for (var x = 0; x < xSquares; x++) {\n for (var y = 0; y < ySquares; y++) {\n var rgba = context.getImageData(x * size, y * size, size, size).data;\n var len = rgba.length;\n var num = len / 4;\n var r = 0;\n var g = 0;\n var b = 0;\n // Sum the color values.\n for (var i = 0; i < len; i += 4) {\n r += rgba[i];\n g += rgba[i + 1];\n b += rgba[i + 2];\n }\n // Save the position and average color value.\n data.push({\n x: x * size,\n y: y * size,\n rgb: 'rgb(' + [Math.round(r / num), Math.round(g / num), Math.round(b / num)].join(',') + ')'\n });\n }\n }\n return data;\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9waXhlbGF0ZS5qcz85MTZlIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHBpeGVsYXRlIChwcm9wcykge1xuICBwcm9wcyA9IHtcbiAgICBpbWFnZTogbnVsbCwgLy8gbmV3IEltYWdlKClcbiAgICBzaXplOiAxMCxcbiAgICBjb250ZXh0OiBudWxsLCAvLyBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaW1hZ2UnKVxuICAgIC4uLnByb3BzXG4gIH1cbiAgY29uc3Qge2ltYWdlLCBzaXplLCBjb250ZXh0fSA9IHByb3BzXG4gIC8vIE51bWJlciBvZiBzcXVhcmVzIGxlZnQtdG8tcmlnaHQgYW5kIHRvcC10by1ib3R0b20uXG4gIGNvbnN0IHhTcXVhcmVzID0gaW1hZ2Uud2lkdGggLyBzaXplXG4gIGNvbnN0IHlTcXVhcmVzID0gaW1hZ2UuaGVpZ2h0IC8gc2l6ZVxuICBsZXQgZGF0YSA9IFtdXG4gIGZvciAobGV0IHggPSAwOyB4IDwgeFNxdWFyZXM7IHgrKykge1xuICAgIGZvciAobGV0IHkgPSAwOyB5IDwgeVNxdWFyZXM7IHkrKykge1xuICAgICAgY29uc3QgcmdiYSA9IGNvbnRleHQuZ2V0SW1hZ2VEYXRhKHggKiBzaXplLCB5ICogc2l6ZSwgc2l6ZSwgc2l6ZSkuZGF0YVxuICAgICAgY29uc3QgbGVuID0gcmdiYS5sZW5ndGhcbiAgICAgIGNvbnN0IG51bSA9IGxlbiAvIDRcbiAgICAgIGxldCByID0gMFxuICAgICAgbGV0IGcgPSAwXG4gICAgICBsZXQgYiA9IDBcbiAgICAgIC8vIFN1bSB0aGUgY29sb3IgdmFsdWVzLlxuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkgKz0gNCkge1xuICAgICAgICByICs9IHJnYmFbaV1cbiAgICAgICAgZyArPSByZ2JhW2kgKyAxXVxuICAgICAgICBiICs9IHJnYmFbaSArIDJdXG4gICAgICB9XG4gICAgICAvLyBTYXZlIHRoZSBwb3NpdGlvbiBhbmQgYXZlcmFnZSBjb2xvciB2YWx1ZS5cbiAgICAgIGRhdGEucHVzaCh7XG4gICAgICAgIHg6IHggKiBzaXplLFxuICAgICAgICB5OiB5ICogc2l6ZSxcbiAgICAgICAgcmdiOiAncmdiKCcgKyBbXG4gICAgICAgICAgTWF0aC5yb3VuZChyIC8gbnVtKSxcbiAgICAgICAgICBNYXRoLnJvdW5kKGcgLyBudW0pLFxuICAgICAgICAgIE1hdGgucm91bmQoYiAvIG51bSlcbiAgICAgICAgXS5qb2luKCcsJykgKyAnKSdcbiAgICAgIH0pXG4gICAgfVxuICB9XG4gIHJldHVybiBkYXRhXG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gcGl4ZWxhdGUuanMiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSkE7QUFBQTtBQUFBO0FBQUE7QUFRQTtBQUNBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFIQTtBQVNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///1\n")},function(module,exports,__webpack_require__){"use strict";eval("\n\nvar _pixelate = __webpack_require__(1);\n\nvar _pixelate2 = _interopRequireDefault(_pixelate);\n\nvar _drawSvg = __webpack_require__(0);\n\nvar _drawSvg2 = _interopRequireDefault(_drawSvg);\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar canvas = document.querySelector('canvas');\nvar context = canvas.getContext('2d');\nvar srcImg = document.getElementById('image');\nvar image = new Image();\nvar size = 15;\nimage.src = srcImg.src;\n\nimage.onload = function () {\n var width = image.width;\n var height = image.height;\n // Render the image on the canvas.\n context.drawImage(image, 0, 0);\n // Create main SVG element.\n var svg = d3.select('#pixelated').append('svg').attr('width', width).attr('height', height).append('g');\n\n var squaresGroup = svg.append('g').attr('class', 'square-g');\n\n var data = (0, _pixelate2.default)({\n image: image,\n size: size,\n context: context\n });\n\n (0, _drawSvg2.default)({\n colors: data,\n size: size,\n svg: squaresGroup\n });\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMi5qcyIsInNvdXJjZXMiOlsid2VicGFjazovLy9zY3JpcHQuanM/OWE5NSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGl4ZWxhdGUgZnJvbSAnLi9waXhlbGF0ZSdcbmltcG9ydCBkcmF3U3ZnIGZyb20gJy4vZHJhd1N2ZydcblxuY29uc3QgY2FudmFzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignY2FudmFzJylcbmNvbnN0IGNvbnRleHQgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnKVxuY29uc3Qgc3JjSW1nID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ltYWdlJylcbmNvbnN0IGltYWdlID0gbmV3IEltYWdlKClcbmxldCBzaXplID0gMTVcbmltYWdlLnNyYyA9IHNyY0ltZy5zcmNcblxuaW1hZ2Uub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICBjb25zdCB3aWR0aCA9IGltYWdlLndpZHRoXG4gIGNvbnN0IGhlaWdodCA9IGltYWdlLmhlaWdodFxuICAvLyBSZW5kZXIgdGhlIGltYWdlIG9uIHRoZSBjYW52YXMuXG4gIGNvbnRleHQuZHJhd0ltYWdlKGltYWdlLCAwLCAwKVxuICAvLyBDcmVhdGUgbWFpbiBTVkcgZWxlbWVudC5cbiAgY29uc3Qgc3ZnID0gZDMuc2VsZWN0KCcjcGl4ZWxhdGVkJykuYXBwZW5kKCdzdmcnKVxuICAgIC5hdHRyKCd3aWR0aCcsIHdpZHRoKVxuICAgIC5hdHRyKCdoZWlnaHQnLCBoZWlnaHQpXG4gICAgLmFwcGVuZCgnZycpXG5cbiAgY29uc3Qgc3F1YXJlc0dyb3VwID0gc3ZnLmFwcGVuZCgnZycpXG4gICAgLmF0dHIoJ2NsYXNzJywgJ3NxdWFyZS1nJylcblxuICBjb25zdCBkYXRhID0gcGl4ZWxhdGUoe1xuICAgIGltYWdlOiBpbWFnZSxcbiAgICBzaXplOiBzaXplLFxuICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgfSlcblxuICBkcmF3U3ZnKHtcbiAgICBjb2xvcnM6IGRhdGEsXG4gICAgc2l6ZTogc2l6ZSxcbiAgICBzdmc6IHNxdWFyZXNHcm91cFxuICB9KVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHNjcmlwdC5qcyJdLCJtYXBwaW5ncyI6Ijs7QUFBQTtBQUNBOzs7QUFBQTtBQUNBOzs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBQ0E7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUhBO0FBS0EiLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///2\n")}]);
export default function drawSvg (props) {
props = {
colors: null, // []
size: 10,
svg: null,
...props
}
const {colors, size, svg} = props
console.log('colors', colors)
const squares = svg.selectAll('.square').data(colors)
squares.exit().remove()
squares.enter().append('rect')
.attr('class', 'square')
.merge(squares)
.attr('x', d => d.x)
.attr('y', d => d.y)
.attr('width', size)
.attr('height', size)
.attr('fill', d => d.rgb)
.on('mouseover', function (d, i) {
// console.log('d', d)
d3.select('.js-info').text(d.rgb)
})
}
<!DOCTYPE html>
<title>d3 | pixelated image</title>
<link href="https://unpkg.com/[email protected]/css/basscss.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Space+Mono" rel="stylesheet">
<link href='dist.css' rel='stylesheet' />
<body>
<main class="relative">
<h3 class="h5 caps absolute left-0 z2 bottom-0 pl3 pb1 js-info">roll over for RGB values</h3>
<div style="display:none;">
<img id="image" src="eagle.jpg" width="960" height="540" />
</div>
<canvas width="960" height="540" style="display:none;"></canvas>
<div id="pixelated"></div>
</main>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='dist.js'></script>
<script>
// change frame height for bl.ocks
d3.select(self.frameElement).style('height', '560px')
</script>
</body>
{
"standard": {
"globals": [
"d3"
]
}
}
export default function pixelate (props) {
props = {
image: null, // new Image()
size: 10,
context: null, // document.getElementById('image')
...props
}
const {image, size, context} = props
// Number of squares left-to-right and top-to-bottom.
const xSquares = image.width / size
const ySquares = image.height / size
let data = []
for (let x = 0; x < xSquares; x++) {
for (let y = 0; y < ySquares; y++) {
const rgba = context.getImageData(x * size, y * size, size, size).data
const len = rgba.length
const num = len / 4
let r = 0
let g = 0
let b = 0
// Sum the color values.
for (let i = 0; i < len; i += 4) {
r += rgba[i]
g += rgba[i + 1]
b += rgba[i + 2]
}
// Save the position and average color value.
data.push({
x: x * size,
y: y * size,
rgb: 'rgb(' + [
Math.round(r / num),
Math.round(g / num),
Math.round(b / num)
].join(',') + ')'
})
}
}
return data
}
import pixelate from './pixelate'
import drawSvg from './drawSvg'
const canvas = document.querySelector('canvas')
const context = canvas.getContext('2d')
const srcImg = document.getElementById('image')
const image = new Image()
let size = 15
image.src = srcImg.src
image.onload = function () {
const width = image.width
const height = image.height
// Render the image on the canvas.
context.drawImage(image, 0, 0)
// Create main SVG element.
const svg = d3.select('#pixelated').append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
const squaresGroup = svg.append('g')
.attr('class', 'square-g')
const data = pixelate({
image: image,
size: size,
context: context
})
drawSvg({
colors: data,
size: size,
svg: squaresGroup
})
}
*
box-sizing border-box
body
font-family: 'Space Mono', monospace
font-size: 11px
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment