Skip to content

Instantly share code, notes, and snippets.

@bryc
Last active May 12, 2020 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bryc/b682efe307c8024c6b198b142461d730 to your computer and use it in GitHub Desktop.
Save bryc/b682efe307c8024c6b198b142461d730 to your computer and use it in GitHub Desktop.
// some color conversion code i didnt end up using but might as well put somewhere
function hcl2rgb(arr) {
function lab2xyz(t){return t>6/29?t*t*t:6/29*3*(6/29)*(t-4/29)}
function xyz2rgb(x){return 255*(x<=.0031308?12.92*x:1.055*Math.pow(x,1/2.4)-.055)}
var h = arr[0], c = arr[1], l = arr[2];
y = (l+16)/116,
a = Math.cos(h)*c, b = Math.sin(h)*c,
x = isNaN(a)?y:y+a/500, z = isNaN(b)?y:y-b/200;
y = 1*lab2xyz(y), x = 0.95047 * lab2xyz(x), z = 1.08883 * lab2xyz(z);
arr[0] = xyz2rgb(3.2404542 * x-1.5371385 * y-0.4985314 * z);
arr[1] = xyz2rgb(-0.969266 * x+1.8760108 * y+0.041556 * z);
arr[2] = xyz2rgb(0.0556434 * x-0.2040259 * y+1.0572252 * z);
return arr;
}
function lch2lab(lch) {
var l = lch[0],
c = lch[1],
h = lch[2],
a, b, hr;
hr = h / 360 * 2 * Math.PI;
a = c * Math.cos(hr);
b = c * Math.sin(hr);
return [l, a, b];
}
function lab2xyz(lab) {
var l = lab[0],
a = lab[1],
b = lab[2],
x, y, z, y2;
if (l <= 8) {
y = (l * 100) / 903.3;
y2 = (7.787 * (y / 100)) + (16 / 116);
} else {
y = 100 * Math.pow((l + 16) / 116, 3);
y2 = Math.pow(y / 100, 1/3);
}
x = x / 95.047 <= 0.008856 ? x = (95.047 * ((a / 500) + y2 - (16 / 116))) / 7.787 : 95.047 * Math.pow((a / 500) + y2, 3);
z = z / 108.883 <= 0.008859 ? z = (108.883 * (y2 - (b / 200) - (16 / 116))) / 7.787 : 108.883 * Math.pow(y2 - (b / 200), 3);
return [x, y, z];
}
function xyz2rgb(xyz) {
var x = xyz[0] / 100,
y = xyz[1] / 100,
z = xyz[2] / 100,
r, g, b;
r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
// assume sRGB
r = r > 0.0031308 ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
: r = (r * 12.92);
g = g > 0.0031308 ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
: g = (g * 12.92);
b = b > 0.0031308 ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
: b = (b * 12.92);
r = Math.min(Math.max(0, r), 1);
g = Math.min(Math.max(0, g), 1);
b = Math.min(Math.max(0, b), 1);
return [r * 255, g * 255, b * 255];
}
function lab2rgb(lab){
var y = (lab[0] + 16) / 116,
x = lab[1] / 500 + y,
z = y - lab[2] / 200,
r, g, b;
x = 0.95047 * ((x * x * x > 0.008856) ? x * x * x : (x - 16/116) / 7.787);
y = 1.00000 * ((y * y * y > 0.008856) ? y * y * y : (y - 16/116) / 7.787);
z = 1.08883 * ((z * z * z > 0.008856) ? z * z * z : (z - 16/116) / 7.787);
r = x * 3.2406 + y * -1.5372 + z * -0.4986;
g = x * -0.9689 + y * 1.8758 + z * 0.0415;
b = x * 0.0557 + y * -0.2040 + z * 1.0570;
r = (r > 0.0031308) ? (1.055 * Math.pow(r, 1/2.4) - 0.055) : 12.92 * r;
g = (g > 0.0031308) ? (1.055 * Math.pow(g, 1/2.4) - 0.055) : 12.92 * g;
b = (b > 0.0031308) ? (1.055 * Math.pow(b, 1/2.4) - 0.055) : 12.92 * b;
return [Math.max(0, Math.min(1, r)) * 255,
Math.max(0, Math.min(1, g)) * 255,
Math.max(0, Math.min(1, b)) * 255]
}
function rgb2xyz(rgbR, rgbG, rgbB) {
const [ lrgbR, lrgbB, lrgbG ] = [ rgbR, rgbG, rgbB ].map(
v => v > 4.045 ? pow((v + 5.5) / 105.5, 2.4) * 100 : v / 12.92
);
const [ xyzX, xyzY, xyzZ ] = matrix([ lrgbR, lrgbB, lrgbG ], [
[0.4124564, 0.3575761, 0.1804375],
[0.2126729, 0.7151522, 0.0721750],
[0.0193339, 0.1191920, 0.9503041]
]);
return [ xyzX, xyzY, xyzZ ];
}
function rgb2lch(rgbR, rgbG, rgbB) {
const [ xyzX, xyzY, xyzZ ] = rgb2xyz(rgbR, rgbG, rgbB);
const [ labL, labA, labB ] = xyz2lab(xyzX, xyzY, xyzZ);
const [ lchL, lchC, lchH ] = lab2lch(labL, labA, labB);
return [ lchL, lchC, lchH ];
}
/// more color shit
//colorChannelA and colorChannelB are ints ranging from 0 to 255
//rgbA and rgbB are arrays, amountToMix ranges from 0.0 to 1.0
//example (red): rgbA = [255,0,0]
function colorMixer(rgbA, rgbB, amountToMix){
function colorChannelMixer(colorChannelA, colorChannelB, amountToMix){
var channelA = colorChannelA*amountToMix;
var channelB = colorChannelB*(1-amountToMix);
return parseInt(channelA+channelB);
}
var r = colorChannelMixer(rgbA[0],rgbB[0],amountToMix);
var g = colorChannelMixer(rgbA[1],rgbB[1],amountToMix);
var b = colorChannelMixer(rgbA[2],rgbB[2],amountToMix);
return [r,g,b];
}
function hsl2rgb(r){var n,f,t,u,a,e=r[0]/360,i=r[1]/100,o=r[2]/100;if(0==i)return[a=255*o,a,a];n=2*o-(f=o<.5?o*(1+i):o+i-o*i),u=[0,0,0];for(var v=0;v<3;v++)(t=e+1/3*-(v-1))<0&&t++,t>1&&t--,a=6*t<1?n+6*(f-n)*t:2*t<1?f:3*t<2?n+(f-n)*(2/3-t)*6:n,u[v]=255*a;return u}
<style>
body{background:#000;}
div{display:inline-block;}
</style>
<script>
//transform:rotate(45deg);
rnd = w=>'#'+Math.random().toString(16).slice(-6)
clip = [
"circle(50% at 50% 50%)",
"polygon(50% 0%, 0% 100%, 100% 100%)",
"polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)",
"polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%)",
"polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%)"
]
for(i = 0; i < 99; i++) {
document.write(`
<div style='border-radius:16px;margin:4px;width:96px;height:96px;overflow:hidden;text-align:center;vertical-align:top;filter: contrast(150%) saturate(50%);background:linear-gradient(${Math.random()}turn,${rnd()+'80'},${rnd()+'80'},${rnd()+'80'},${rnd()+'80'}')>
<div style='width:100%;height:100%;transform: scale(${0.5+Math.random()}) rotate(${90*Math.random()|0}deg);'>
<div style='height:45%;width:45%;clip-path:${clip[Math.random()*clip.length|0]};background:linear-gradient(${Math.random()}turn,${rnd()},${rnd()},${rnd()},${rnd()}')></div>
<div style='margin-top:27%;height:45%;width:45%;clip-path:${clip[Math.random()*clip.length|0]};background:linear-gradient(${Math.random()}turn,${rnd()},${rnd()},${rnd()},${rnd()}')></div>
</div>
</div>
`)
}
</script>
<div class=a id=output></div>
<div class=a>
Iteratively generates 2 fully random RGB color values until each color's <i>Euclidean distance</i> is sufficiently distant.
With a target distance of 200, it can take up to 15 iterations, however it typically takes 0-4 iterations.
For more than 2 colors, this can quickly grow exponentially.
</div>
<script>
function cdis(c1, c2) {
var rd = c1[0]-c2[0], gd = c1[1]-c2[1], bd = c1[2]-c2[2];
return Math.sqrt(rd*rd + gd*gd + bd*bd);
}
function generate() {
for(var a,b,i = 0; i < 999; i++) {
a = [1,2,3].map(x=>Math.random()*256|0),
b = [1,2,3].map(x=>Math.random()*256|0);
if(cdis(a,b) >= 120 ) break;
}
console.log('iterations',i)
var gradient = `linear-gradient(${Math.random()*360|0}deg,rgb(${b}),rgb(${a}))`;
document.body.style.background = gradient;
document.getElementById("output").innerHTML =
`<h2>RGB Gradient Generator</h2><x style=background:rgb(${a})></x><x style=background:rgb(${b}></x>
<br>${document.body.style.background} `
}
window.onload = generate;
setInterval(generate, 1000);
</script>
<style>h2{margin:0}
body{font:bold 14px Segoe UI, Arial, sans-serif;}
x{margin:8px;outline:1px solid #0006;border:2px inset #FFFA; display:inline-block;width:24px;height:24px;}
.a{border-radius:8px;text-align:center;margin:auto;margin-top:56px;padding:16px;background:#FFF8;width:480px}
</style>
<body></body><script>
function generatePalette(sat, sati, lit, liti)
{
var hue=Math.random()*360;
for(var i=0, out=[]; i < 4; i++)
{
out.push([hue, sat, lit]);
hue += (11 + Math.random() * 60) % 360;
lit += liti; sat += sati;
}
return out;
}
for(var i = 0,u=''; i < 315; i++)
{
var x = generatePalette(
10 + Math.random() * 25,
15 + Math.random() * 5,
15 + Math.random() * 20,
10 + Math.random() * 10
);
u+=
`<y><x style=background:hsl(${x[0][0]},${x[0][1]}%,${x[0][2]}%)></x>`+
`<x style=background:hsl(${x[1][0]},${x[1][1]}%,${x[1][2]}%)></x>`+
`<x style=background:hsl(${x[2][0]},${x[2][1]}%,${x[2][2]}%)></x>`+
`<x style=background:hsl(${x[3][0]},${x[3][1]}%,${x[3][2]}%)></x></y>`
;
}
document.body.innerHTML=u;
</script>
<style>
y{display:inline-block;margin:2;border:3px double #5557}
x{display:inline-block;width:42;height:64}
body{width:960;margin:auto}
</style>
<!-- some sort of waveform testing thing, might be good to not lose it -->
<ul class="chart">
<!--<li><span style="height:5%" title="ActionScript"></span></li>-->
</ul>
<script>
TSH=s=>{for(var i=0,h=9;i<s.length;)h=Math.imul(h^s.charCodeAt(i++),9**9);return h^h>>>9}
var mb32=a=>(t)=>(a=a+1831565813|0,t=Math.imul(a^a>>>15,1|a),t=t+Math.imul(t^t>>>7,61|t)^t,(t^t>>>14)>>>0)
function elem(e){var n=document.createDocumentFragment(),t=e[0],r=e[1];if("string"==typeof t&&(n=document.createElement(t)),"object"==typeof r)for(var o in r)n[o]=r[o];else r&&(n.innerHTML=r);for(var a=1;a<arguments.length;a++)arguments[a].nodeType>0&&n.appendChild(arguments[a]);return n}
Array.prototype.rot=function(t){return this.slice(t,this.length).concat(this.slice(0,t))}
var tri=Array(32).fill(1).map((a,i)=>i<17?a-.125*i:a+.125*i-4),
squ=Array(32).fill(1).map((a,i)=>i>15?-1:a),
saw=Array(32).fill(1).map((a,i)=>a-.0625*i),
sin=Array(32).fill(1).map((a,i)=>a*Math.sin(i/5)),
rnd=function(seed) {
var rand = mb32(TSH(seed));
return Array(32).fill(1).map(a=>Math.round((rand()/2**32*2-1)*1000)/1000);
}
function mix(a, b) {
var wave = [];
b = b.rot(8)
for(var i = 0; i < 32; i++) {
wave[i] = a[i] + b[i]*0.8;
}
return wave;
}
var wave = mix(squ, rnd("abwed"));
var ul = document.querySelector("ul.chart");
for(var i = 0; i < 32; i++) {
var val = (wave[i]+1)*35;
var span = elem(["span",{title:wave[i]}])
span.style.height = val+"%";
ul.appendChild( elem(["li"], span ) )
}
</script>
<style>
body {
font: 12px Arial;
}
.chart {
display: table;
table-layout: fixed;
width: 100%;
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.1) 2%, rgba(0, 0, 0, 0) 2%);
background-size: 100% 50px;
background-position: left top;
}
ul {padding:0;margin:0;}
.chart li {
position: relative;
display: table-cell;
vertical-align: bottom;
height: 200px;
}
.chart span {
margin: 0 1px;
display: block;
background: #000;
animation: draw .04s ease-in-out;
}
.chart span:before {
position: absolute;
left: 0;
right: 0;
top: 100%;
padding: 5px 1em 0;
display: block;
text-align: center;
content: attr(title);
}
@keyframes draw {
0% {
height: 0;
}
}
}</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment