Last active
June 3, 2016 08:38
-
-
Save toja/135a6deb742e57d6cb5804af53b6ea54 to your computer and use it in GitHub Desktop.
Random Color Chart (RGB / DeltaE00)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
height: 480 | |
license: gpl-3.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// code adapted from https://github.com/zschuessler/DeltaE | |
function dE00(x1,x2){var sqrt=Math.sqrt;var pow=Math.pow;this.x1=x1;this.x2=x2;this.deltaLPrime=x2.l-x1.l;this.LBar=(x1.l+x2.l)/2;this.C1=sqrt(pow(x1.a,2)+pow(x1.a,2));this.C2=sqrt(pow(x2.b,2)+pow(x2.b,2));this.CBar=(this.C1+this.C2)/2;this.aPrime1=x1.a+x1.a/2*(1-sqrt(pow(this.CBar,7)/(pow(this.CBar,7)+pow(25,7))));this.aPrime2=x2.a+x2.a/2*(1-sqrt(pow(this.CBar,7)/(pow(this.CBar,7)+pow(25,7))));this.CPrime1=sqrt(pow(this.aPrime1,2)+pow(x1.b,2));this.CPrime2=sqrt(pow(this.aPrime2,2)+pow(x2.b,2));this.CBarPrime=(this.CPrime1+this.CPrime2)/2;this.deltaCPrime=this.CPrime2-this.CPrime1;this.SsubL=1+.015*pow(this.LBar-50,2)/sqrt(20+pow(this.LBar-50,2));this.SsubC=1+.045*this.CBarPrime;this.hPrime1=0;this.hPrime2=0;this.deltahPrime=0;this.deltaHPrime=0;this.HBarPrime=0;this.T=0;this.SsubH=0;this.RsubT=0}dE00.prototype.getDeltaE=function(){var sqrt=Math.sqrt;var sin=Math.sin;var pow=Math.pow;this.hPrime1=this.gethPrime1();this.hPrime2=this.gethPrime2();this.deltahPrime=this.getDeltahPrime();this.deltaHPrime=2*sqrt(this.CPrime1*this.CPrime2)*sin(this.degreesToRadians(this.deltahPrime)/2);this.HBarPrime=this.getHBarPrime();this.T=this.getT();this.SsubH=1+.015*this.CBarPrime*this.T;this.RsubT=this.getRsubT();var lightness=this.deltaLPrime/this.SsubL;var chroma=this.deltaCPrime/this.SsubC;var hue=this.deltaHPrime/this.SsubH;return sqrt(pow(lightness,2)+pow(chroma,2)+pow(hue,2)+this.RsubT*chroma*hue)};dE00.prototype.getRsubT=function(){var sin=Math.sin;var sqrt=Math.sqrt;var pow=Math.pow;var exp=Math.exp;return-2*sqrt(pow(this.CBarPrime,7)/(pow(this.CBarPrime,7)+pow(25,7)))*sin(this.degreesToRadians(60*exp(-pow((this.HBarPrime-275)/25,2))))};dE00.prototype.getT=function(){var cos=Math.cos;return 1-.17*cos(this.degreesToRadians(this.HBarPrime-30))+.24*cos(this.degreesToRadians(2*this.HBarPrime))+.32*cos(this.degreesToRadians(3*this.HBarPrime+6))-.2*cos(this.degreesToRadians(4*this.HBarPrime-63))};dE00.prototype.getHBarPrime=function(){var abs=Math.abs;if(abs(this.hPrime1-this.hPrime2)>180){return(this.hPrime1+this.hPrime2+360)/2}return(this.hPrime1+this.hPrime2)/2};dE00.prototype.getDeltahPrime=function(){var abs=Math.abs;if(0===this.C1||0===this.C2){return 0}if(abs(this.hPrime1-this.hPrime2)<=180){return this.hPrime2-this.hPrime1}if(this.hPrime2<=this.hPrime1){return this.hPrime2-this.hPrime1+360}else{return this.hPrime2-this.hPrime1-360}};dE00.prototype.gethPrime1=function(){return this._gethPrimeFn(this.x1.b,this.aPrime1)};dE00.prototype.gethPrime2=function(){return this._gethPrimeFn(this.x2.b,this.aPrime2)};dE00.prototype._gethPrimeFn=function(x,y){var hueAngle;if(x===0&&y===0){return 0}hueAngle=this.radiansToDegrees(Math.atan2(x,y));if(hueAngle>=0){return hueAngle}else{return hueAngle+360}};dE00.prototype.radiansToDegrees=function(radians){return radians*(180/Math.PI)};dE00.prototype.degreesToRadians=function(degrees){return degrees*(Math.PI/180)}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<meta charset="utf-8"> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script src="deltaE00.min.js"></script> | |
<body> | |
<script> | |
var width = 960, | |
height = 480, | |
grid = [32,32], | |
space = 1.0, | |
deltaMin = 5.0, | |
colors = []; | |
var rectangleWidth = width / grid[0] - space * 2, | |
rectangleHeight = height / grid[1] - space * 2; | |
var xz = d3.range(0, width, width / grid[0]), | |
yz = d3.range(0, height, height / grid[1]); | |
var offset = function (x, y) { return { x: x + space, y: y + space };} | |
var offsets = shuffle(d3.merge( | |
xz.map(function(x) { | |
return yz.map(function(y) { | |
return offset(x, y); | |
}); | |
}) | |
)); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
var rects = svg.append("g"); | |
d3.timer (function() { | |
var hsl = randomColor(); | |
if (!hsl) return true; | |
rects.append("rect") | |
.attr("x", offsets[colors.length - 1].x) | |
.attr("y", offsets[colors.length - 1].y) | |
.attr("width", rectangleWidth) | |
.attr("height", rectangleHeight) | |
.style("fill", hsl.toString()); | |
}); | |
function randomColor() { | |
if (colors.length >= grid[0] * grid[1]) return false; | |
do { | |
var hsl = d3.hsl(d3.rgb( | |
Math.floor(Math.random() * 256), | |
Math.floor(Math.random() * 256), | |
Math.floor(Math.random() * 256) | |
)); | |
var lab = d3.lab(hsl); | |
} | |
while (!hsl.h || !isValidColor(lab)); | |
colors.push(lab); | |
return hsl; | |
} | |
function isValidColor(lab) { | |
if (colors.length == 0) | |
return true; | |
for (i = 0; i < colors.length; i++) { | |
var delta = new dE00(lab, colors[i]).getDeltaE(); | |
if (delta < deltaMin) | |
return false; | |
} | |
return true; | |
} | |
// Fisher–Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle | |
// code borrowed from https://bost.ocks.org/mike/algorithms/ | |
function shuffle(array) { | |
var n = array.length, t, i; | |
while (n) { | |
i = Math.random() * n-- | 0; // 0 ≤ i < n | |
t = array[n]; | |
array[n] = array[i]; | |
array[i] = t; | |
} | |
return array; | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment