function f(){function j(s,w){var k=s[0],l=s[1],m=s[2],a=3.45565*k+27.1554*l+3.86714*m,p=0.0299566*k+0.184309*l+1.46709*m,t=2.02344*a+-2.52581*p,g=0.0809444479*t+-0.130504409*a+0.116721066*p,q=-0.0102485335*t+0.0540193266*a+-0.113614708*p;a=-3.65296938E-4*t+-0.00412161469*a+0.693511405*p;if(w)return[g>>0,q>>0,a>>0];g=k-g;q=l-q;a=m-a;return[k>>0,0.7*g+q+l>>0,0.7*g+a+m>>0]}var u=Math.random,h=document,i=h.getElementById("c"),c=i.getContext("2d"),r=(i.width=900)/199;i.height=520;h.body.style.background="#000";c.font="48px arial";c.fillText("RED",5,380);d=c.getImageData(8,344,97,37).data;for(n=o=d.length;(n-=4)>-1;){h=n/o*37;i=h%1*90;var b=d[n%o+3]>70;c.fillStyle="hsl("+((b?145:5)+30*u())+","+(90-50*u())+"%,"+((b?70:90)-50*u())+"%)";c.fillRect(0,0,1,1);b=c.getImageData(0,0,1,1).data;for(var e=0;e<4;e++){var v;v=e==1?j(b,true):e==2?j(b):e==3?j(j(b),true):[b[0],b[1],b[2]];c.fillStyle="rgb("+v.join(",")+")";c.fillRect(r*i+e%2*409,r*(h>>0)+(e>1?169:0),r,r)}}}window.onload=f;window.onmousedown=f;
function f() {
function f(rgb, blind) { // daltonize or simulate color
var r = rgb[0],
g = rgb[1],
b = rgb[2],
// RGB to LMS matrix conversion
L = (17.8824 * r) + (43.5161 * g) + (4.11935 * b),
M = (3.45565 * r) + (27.1554 * g) + (3.86714 * b),
S = (0.0299566 * r) + (0.184309 * g) + (1.46709 * b),
// Simulate color blindness in LMS space
l = (2.02344 * M) + (-2.52581 * S),
m = M,
s = S,
// LMS to RGB matrix conversion
R = (0.0809444479 * l) + (-0.130504409 * m) + (0.116721066 * s),
G = (-0.0102485335 * l) + (0.0540193266 * m) + (-0.113614708 * s),
B = (-0.000365296938 * l) + (-0.00412161469 * m) + (0.693511405 * s);
// Return protanope simulated color
if(blind) return [R>>0,G>>0,B>>0];
// Isolate invisible colors to color vision deficiency (calculate error matrix)
R = r - R;
G = g - G;
B = b - B;
// Shift colors towards visible spectrum (apply error modifications)
// Add compensation to original values
// Return daltonized color
return [r >> 0, (((0.7 * R) + G) + g) >> 0, (((0.7 * R) + B) + b) >> 0];
};
var rand = Math.random, // cache object
doc = document,
element = doc.getElementById("c"), // grab <canvas>
c = element.getContext("2d"), // get context
w = (element.width = 900) / 199; // dimensions
element.height = 520;
doc.body.style.background = "#000";
c.font = "48px arial"; // draw source pixels
c.fillText("RED", 5, 380);
d = c.getImageData(8, 344, 97, 37).data; // grab source pixels
n = (o = d.length); while((n-=4)>-1) { // loop through draw commands
var row = (n / o) * 37, // current pixel row
col = row % 1 * 90 , // current pixel column
b = d[n % o + 3]>70; // check whether pixel has alpha transparency (is this an ON or OFF pixel)
// draw randomized color along the confusion line for a protanopic observer with variable saturation and lightness
c.fillStyle = "hsl("+((b?145:5)+30*rand())+","+(90-50*rand())+"%,"+((b?70:90)-50*rand())+"%)";
c.fillRect(0, 0, 1, 1);
// convert color to RGB space, to LMS, and finally daltonize and/or simulate color blindness
var rgb = c.getImageData(0, 0, 1, 1).data;
for(var j = 0; j < 4; j++) { // loop through display types
var newcolor;
if(j==1) newcolor = f(rgb, true); // simulated protanope
else if(j==2) newcolor = f(rgb); // daltonized protanope
else if(j==3) newcolor = f(f(rgb), true); // daltonized simulated protanope
else newcolor = [rgb[0],rgb[1],rgb[2]];
c.fillStyle = "rgb("+newcolor.join(",")+")"; // record color style
c.fillRect(w * col + (j%2*409), w * (row>>0) + (j>1?169:0), w, w); // fill rect ;)
}
}
};
window.onload = f;
window.onmousedown = f;