<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
<style>
html, body { background: white; }
.bookmarklet {
border:1px solid black;
border-radius: 5px;
padding:12px 5px;
display: block;
margin: 1em;
width: 7em;
text-align: center;
}
</style>
</head>
<body>
<h1>Sort-on-Hue proof of concept Bookmarklet</h1>
<p>by <a href="http://twitter.com/TheRealPomax">Pomax</a></p>
<a href="javascript:(function(t){function s(e,r){r=r||t.RGBAnalyseOptions||{};Object.keys(i).forEach(function(e){r[e]=r[e]||i[e]});var s=Math.PI,o=2*s;var u=function(e){var t=n.createElement('canvas');t.width=e.width*r.width;t.height=e.height*r.height;var i=t.getContext('2d');i.drawImage(e,-e.width*r.xoffset,-e.height*r.yoffset);var u,f,l,c,h,p=0,d=0,v=0;var m=255;var g=(new Array(255)).join('.').split('.').map(function(){return 0});var y=g.slice();var b=g.slice();var w=i.getImageData(0,0,t.width,t.height).data;var E=w.length;for(c=0;c<E;c+=4){u=w[c];f=w[c+1];l=w[c+2];a=w[c+3];g[u]++;y[f]++;b[l]++;p+=u;d+=f;v+=l}p=r.cr*p;d=r.cg*d;v=r.cb*v;var S={canvas:t,red:g,ra:p,green:y,ga:d,blue:b,ba:v},x,T,N,C=Math.max(p,Math.max(d,v));x=p/C;T=d/C;N=v/C;S.R=x;S.G=T;S.B=N;var k=x-T/2-N/2,L=Math.sqrt(.75)*(T-N),A=Math.atan2(L,k),O=Math.sqrt(k*k+L*L);S.α=k;S.β=L;S.H=(A+o)%o;S.C=O*10/s;return S};var f=function(e){var t=n.createElement('canvas');var i=255;var s=e.huedata.red.length;t.height=i;t.width=s;ctx=t.getContext('2d');var o=e.huedata.H,u=(o<1?255:o<2?(1-(o-1))*255:o<4?0:o<5?(o-5)*255:255)|0,a=(o<1?o*255:o<3?255:o<4?(1-(o-4))*255:0)|0,f=(o<2?0:o<3?(o-2)*255:o<5?255:(1-(o-5))*255)|0;ctx.fillStyle='rgb('+(u|0)+','+(a|0)+','+(f|0)+')';ctx.fillRect(0,0,s,r.barsize);for(var l=0,c=i*r.gradient|0,h=1/c,p;l<c;l++){p=1-l*h;ctx.fillStyle='rgba('+(u|0)+','+(a|0)+','+(f|0)+','+Math.pow(p,r.falloff)+')';ctx.fillRect(0,r.barsize+(l|0),s,1)}var d=[{color:'red',data:e.huedata.red},{color:'green',data:e.huedata.green},{color:'blue',data:e.huedata.blue}];d.forEach(function(e){ctx.strokeStyle=e.color;ctx.beginPath();e.data.forEach(function(e,t){ctx.moveTo(t,i);ctx.lineTo(t,i-e)});ctx.stroke();ctx.closePath()});var v=t.toDataURL('image/png');var m=n.createElement('img');m.src=v;m.width=e.width/2;m.height=e.height;m.style.background=r.background;var g=1e3,y=(g*e.huedata.H|0)/g,b=(g*e.huedata.C|0)/g;m.setAttribute('data-hue',y);m.setAttribute('data-chroma',b);if(b<r.chromacutoff){e.huedata.canvas.setAttribute('data-neutral','neutral');m.setAttribute('data-neutral','neutral')}m.setAttribute('data-rgb',u+','+a+','+f);e.huedata.viz=m};var l=Array.prototype.slice.call(n.querySelectorAll(e));l.forEach(function(e){e.huedata=u(e);f(e)});l.sort(function(e,t){e=(e.huedata.H+r.hueshift)%6;t=(t.huedata.H+r.hueshift)%6;return e-t});return l}var n=t.document;var r=n.body;var i={xoffset:0,yoffset:0,width:1,height:1,cr:1,cg:1,cb:1,barsize:20,gradient:.2,falloff:3,hueshift:1,chromacutoff:.07,background:'transparent'};var o=prompt('Image query selector?');if(!o){console.log('No query selector specified')}else{var u=s(o,{xoffset:.5,width:.5});var f=function(e,t){Object.keys(t).forEach(function(n){e.style[n]=t[n]})};var l=function(e,t){var r=n.createElement('h1');r.textContent=t;r.style.margin='1em 0';r.style.fontSize='300%';r.style.fontVariant='small-caps';e.appendChild(r)};var c=n.createElement('div');f(c,{position:'fixed',top:'0',left:'0',right:'0',bottom:'0',background:'rgba(0,0,0,0.4)',zIndex:9998,overflow:'hidden'});r.appendChild(c);content=n.createElement('div');f(content,{position:'fixed',top:'2em',left:'2em',right:'2em',bottom:'2em',background:'white',zIndex:9999,overflowX:'hidden',overflowY:'scroll',padding:'0 2em',textAlign:'left'});c.appendChild(content);l(content,'colours');var h=getComputedStyle(n.body);var p={x:h.getPropertyValue('overflow-x'),y:h.getPropertyValue('overflow-y')};r.style.overflowX='hidden';r.style.overflowY='hidden';u.forEach(function(e){var t=e.huedata;content.appendChild(t.canvas);content.appendChild(t.viz)});u=Array.prototype.slice.call(n.querySelectorAll('*[data-neutral]'));if(u.length>0){l(content,'darks, greys, whites (neutrals)');u.forEach(function(e){content.appendChild(e)})}c.onclick=content.onclick=function(e){e.preventDefault();e.stopPropagation();r.removeChild(c);r.style.overflowX=p.x;r.style.overflowY=p.y;return false}}}(this))"
title="rgb+h analysis"
class="bookmarklet">RGB+H Analysis</a>
<p>drag the "RGB+H Analysis" link into your bookmark bar, then go to some site where you want to perform some RGB/H image analysis, and click the bookmark bar button. You'll have to know the query selector for your image(s). For instance, on the <a target="_blank" href="http://www.gouletpens.com/Shop_All_Bottled_Ink_s/1106.htm?searching=Y&sort=7&cat=1106&brand=Noodler%27s&show=300&page=1">gouletpens ink page (showing all Noodler inks)</a> you can use the query selector [<strong>.v65-productPhoto img</strong>] (without the brackets).</p>
<p>The code that makes this work can be found as a github gist, <a href="https://gist.github.com/Pomax/0dec927f805f7c0af5b2">here</a>.</p>
</body>
</html>
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |