woodblock print 100-7289 from the Ukiyo-e.org database and image similarity analysis engine developed by @jeresig
a shameless iteration on @mbostock's Mona Lisa Histogram
.attr('class', (d, i) => `histogram-area histogram-${'rgb'[i]}`);| es5.html |
woodblock print 100-7289 from the Ukiyo-e.org database and image similarity analysis engine developed by @jeresig
a shameless iteration on @mbostock's Mona Lisa Histogram
.attr('class', (d, i) => `histogram-area histogram-${'rgb'[i]}`);| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| canvas, | |
| svg { | |
| position: absolute; | |
| } | |
| .brush .selection { | |
| stroke: #fff; | |
| stroke-opacity: 0.7; | |
| shape-rendering: crispEdges; | |
| } | |
| .histogram { | |
| pointer-events: none; | |
| } | |
| .histogram-panel { | |
| fill: #111; | |
| fill-opacity: 0.5; | |
| stroke: #000; | |
| } | |
| .histogram-area { | |
| mix-blend-mode: screen; | |
| } | |
| .histogram-area.histogram-r { | |
| fill: #f00; | |
| } | |
| .histogram-area.histogram-g { | |
| fill: #0f0; | |
| } | |
| .histogram-area.histogram-b { | |
| fill: #00f; | |
| } | |
| .histogram-line { | |
| fill: none; | |
| stroke: #000; | |
| stroke-width: 0.5px; | |
| } | |
| </style> | |
| <canvas width="960" height="1452"></canvas> | |
| <svg width="960" height="1452"></svg> | |
| <script src="https://d3js.org/d3.v4.0.0-alpha.44.min.js"></script> | |
| <script src="https://npmcdn.com/babel-core@5.8.34/browser.min.js"></script> | |
| <script> | |
| d3_color = | |
| d3_dispatch = | |
| d3_ease = | |
| d3_interpolate = | |
| d3_timer = | |
| d3_selection = | |
| d3_transition = | |
| d3_drag = d3; | |
| </script> | |
| <script src="https://d3js.org/d3-brush.v0.1.min.js"></script> | |
| <script type="text/babel"> | |
| const canvas = document.querySelector('canvas'); | |
| const context = canvas.getContext('2d'); | |
| const width = canvas.width; | |
| const height = canvas.height; | |
| const histomargin = { top: 10, right: 10, bottom: 0, left: width - 256 - 10 }; | |
| const histowidth = width - histomargin.left - histomargin.right; | |
| const histoheight = 256; | |
| let r = d3.range(257).map(() => 0); | |
| let g = d3.range(257).map(() => 0); | |
| let b = d3.range(257).map(() => 0); | |
| let x = (d, i) => i; | |
| let y = d => histoheight - Math.round(d / n * 32 * histoheight); | |
| let n = 1; | |
| const area = d3.area() | |
| .curve(d3.curveStepBefore) | |
| .x(x) | |
| .y0(y(0)) | |
| .y1(y); | |
| const line = d3.line() | |
| .curve(d3.curveStepBefore) | |
| .x(x) | |
| .y(y); | |
| const brush = d3_brush.brush() | |
| .on('start brush', brushed) | |
| .on('end', brushended); | |
| const svg = d3.select('svg'); | |
| const histogram = svg.append('g') | |
| .attr('class', 'histogram') | |
| .attr('transform', `translate(${histomargin.left}, ${histomargin.top})`); | |
| histogram.append('rect') | |
| .attr('class', 'histogram-panel') | |
| .attr('x', -0.5) | |
| .attr('y', -0.5) | |
| .attr('width', histowidth + 1) | |
| .attr('height', histoheight + 1); | |
| const histoarea = histogram.selectAll('.histogram-area') | |
| .data([r, g, b]) | |
| .enter().append('path') | |
| .attr('class', (d, i) => `histogram-area histogram-${'rgb'[i]}`); | |
| const histoline = histogram.selectAll('.histogram-line') | |
| .data([r, g, b]) | |
| .enter().append('path') | |
| .attr('class', (d, i) => `histogram-line histogram-${'rgb'[i]}`) | |
| .attr('transform', 'translate(0.5,-0.5)'); | |
| const image = new Image; | |
| image.src = '100-7289.jpg'; | |
| image.onload = loaded; | |
| function loaded() { | |
| context.drawImage(this, 0, 0, width, height); | |
| svg.append('g') | |
| .attr('class', 'brush') | |
| .call(brush) | |
| .call(brush.move, [[260, 228], [656, 600]]); | |
| } | |
| function brushed() { | |
| const s = d3.event.selection; | |
| x = s[0][0]; | |
| y = s[0][1]; | |
| const w = s[1][0] - x; | |
| const h = s[1][1] - y; | |
| for (let i = 0; i < 256; ++i) { | |
| r[i] = g[i] = b[i] = 0; | |
| } | |
| n = w * h; | |
| if (n) { | |
| const data = context.getImageData(x, y, w, h).data; | |
| for (let i = 0; i < w; ++i) { | |
| for (let j = 0; j < h; ++j) { | |
| const k = j * w + i << 2; | |
| ++r[data[k]]; | |
| ++g[data[k + 1]]; | |
| ++b[data[k + 2]]; | |
| } | |
| } | |
| histoarea.attr('d', area); | |
| histoline.attr('d', line); | |
| } else { | |
| histoarea.attr('d', null); | |
| histoline.attr('d', null); | |
| } | |
| } | |
| function brushended() { | |
| if (!d3.event.selection) { | |
| histoarea.attr('d', null); | |
| histoline.attr('d', null); | |
| } | |
| } | |
| </script> |