Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save afternoon2/5d00ca1fdca95b4478c855d52fc954b7 to your computer and use it in GitHub Desktop.
Save afternoon2/5d00ca1fdca95b4478c855d52fc954b7 to your computer and use it in GitHub Desktop.
color palette distribution for different color spaces
a.github-corner(href='//github.com/meodai/color-names', target='_blank', aria-label='View source on Github')
svg(width='80', height='80', viewbox='0 0 250 250', aria-hidden='true')
path.triange(d='M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z')
path.octo-arm(d='M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2', style='transform-origin: 130px 106px;')
path.octo-body(d='M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z')
label
select
option(value="rgb") rgb
option(value="yuv") yuv
option(value="lab") lab
option(value="lch") lch
option(value="hsv") hsv
option(value="hsl") hsl
option(value="hsi") hsi
button
span toggle darkmode
strong.
<svg xmlns="http://www.w3.org/2000/svg" width="184" height="184" viewBox="0 0 184 184">
<g>
<path class="line" d="M43.27,54.49A7.93,7.93,0,0,0,54.49,43.27l-8.33-8.33A7.93,7.93,0,0,0,34.95,46.16Z" transform="translate(-8 -8)"/>
<path class="line" d="M159.45,167.38a7.93,7.93,0,0,0,5.61-13.54l-8.33-8.33a7.93,7.93,0,0,0-11.21,11.21l8.33,8.33A7.9,7.9,0,0,0,159.45,167.38Z" transform="translate(-8 -8)"/>
<path class="line" d="M46.16,165.05l8.33-8.33a7.93,7.93,0,1,0-11.21-11.21l-8.33,8.33a7.93,7.93,0,1,0,11.21,11.21Z" transform="translate(-8 -8)"/>
<path class="line" d="M151.12,56.81a7.91,7.91,0,0,0,5.61-2.32l8.33-8.33a7.93,7.93,0,0,0-11.21-11.21l-8.33,8.33a7.93,7.93,0,0,0,5.61,13.54Z" transform="translate(-8 -8)"/>
<path class="line" d="M15.93,107.93H27.71a7.93,7.93,0,0,0,0-15.86H15.93a7.93,7.93,0,0,0,0,15.86Z" transform="translate(-8 -8)"/>
<path class="line" d="M164.36,100a7.93,7.93,0,0,0,7.93,7.93h11.78a7.93,7.93,0,0,0,0-15.86H172.29A7.93,7.93,0,0,0,164.36,100Z" transform="translate(-8 -8)"/>
<path class="line" d="M100,164.36a7.93,7.93,0,0,0-7.93,7.93v11.78a7.93,7.93,0,0,0,15.86,0V172.29A7.93,7.93,0,0,0,100,164.36Z" transform="translate(-8 -8)"/>
<path class="line" d="M100,35.64a7.93,7.93,0,0,0,7.93-7.93V15.93a7.93,7.93,0,0,0-15.86,0V27.71A7.93,7.93,0,0,0,100,35.64Z" transform="translate(-8 -8)"/>
<path class="circle" d="M100,153.09A53.09,53.09,0,1,0,46.91,100,53.15,53.15,0,0,0,100,153.09Zm0-90.33A37.23,37.23,0,1,1,62.77,100,37.27,37.27,0,0,1,100,62.77Z" transform="translate(-8 -8)"/>
</g>
</svg>
#container
let cam, scene, root, renderer, controls,
objects = [], cubeSize = 100, dotSize = 1.5,
width = window.innerWidth + 1,
height = window.innerHeight + 1,
$select = document.querySelector('select'),
cDark = '#212121', cLight = '#dddddd',
bg = cDark, colorMode = 'rgb', spaceCube, isDark = true;
document.querySelector('body').classList.add('isDark');
const colorModes = {
hsv: {
func: 'hsv',
x: [0, 360],
y: [1, 1],
z: [2, 1]
},
hsi: {
func: 'hsi',
x: [0, 360],
y: [1, 1],
z: [2, 1]
},
hsl: {
func: 'hsl',
x: [0, 360],
y: [1, 1],
z: [2, 1]
},
rgb: {
func: 'rgb',
x: [0, 255],
y: [1, 255],
z: [2, 255]
},
lab: {
func: 'lab',
z: [0, 100],
y: [1, 127, -128],
x: [2, 127, -128]
},
lch: {
func: 'lch',
z: [0, 100],
y: [1, 140],
x: [2, 0, 360]
},
yuv: {
func: 'yuv',
z: [0, 255],
y: [1, 255],
x: [2, 255]
}
}
init();
function onWindowResize() {
width = window.innerWidth + 1;
height = window.innerHeight + 1;
cam.aspect = width / height;
cam.updateProjectionMatrix();
renderer.setSize( width, height );
}
let colorList = [];
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://unpkg.com/color-name-list/dist/colornames.json');
xhr.onload = e => {
if (xhr.status === 200) {
colorList = JSON.parse(xhr.responseText);
addParticles(colorList, colorMode);
} else {
console.log(xhr.status);
}
};
xhr.send();
let part;
function addParticles (colorNames, cMode) {
// create the particle variables
const particleCount = colorNames.length,
particles = new THREE.Geometry(),
pMaterial = new THREE.PointsMaterial({
vertexColors: THREE.VertexColors,
//map: texture,
size: dotSize,
//blending: THREE.SubstractiveBlending,
//transparent: true,
});
let colors = [];;
const mode = colorModes[cMode];
colorNames.forEach(col => {
let colorComp;
if (mode.func === 'yuv') {
colorComp = yuv(chroma(col.hex).rgb());
} else {
colorComp = chroma(col.hex)[mode.func]();
}
const pX = translate(colorComp[mode.x[0]], mode.x[2] || 0, mode.x[1], -cubeSize*.5,cubeSize*.5),
pZ = translate(colorComp[mode.z[0]], mode.z[2] || 0, mode.z[1], -cubeSize*.5,cubeSize*.5),
pY = translate(colorComp[mode.y[0]], mode.y[2] || 0, mode.y[1], -cubeSize*.5,cubeSize*.5),
particle = new THREE.Vector3(pX, pY, pZ),
Tcolor = new THREE.Color(col.hex);
colors.push(Tcolor)
// add it to the geometry
particles.vertices.push(particle);
});
// create the particle system
const particleSystem = new THREE.Points(
particles,
pMaterial);
particleSystem.name = 'colors';
particles.colors = colors;
// add it to the scene
objects.push(particleSystem)
scene.add(particleSystem);
part = particleSystem;
}
renderer.render(scene, cam);
animate();
function setSceneColor(color) {
scene.background = new THREE.Color(color);
scene.fog = new THREE.Fog(color, 150, 200);
}
function init() {
cam = new THREE.PerspectiveCamera( 60, width/height, 1, 200 );
cam.position.z = cubeSize * 1.5;
scene = new THREE.Scene();
setSceneColor(bg)
root = new THREE.Object3D();
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(width, height);
addCube();
controls = new THREE.OrbitControls( cam, renderer.domElement );
// controls.addEventListener( 'change', render ); // remove when using animation loop
// enable animation loop when using damping or autorotation
controls.enableDamping = true;
controls.dampingFactor = .75;
controls.enableZoom = true;
controls.zoomSpeed = .25;
controls.autoRotate = true;
controls.autoRotateSpeed = 2.0;
controls.maxDistance = cubeSize * 1.75;
controls.maxPolarAngle = Math.PI * 4;
var container = document.querySelector('#container');
container.appendChild( renderer.domElement );
window.addEventListener('resize', onWindowResize, false);
document.querySelector('button').addEventListener('click', toggleDarkMode, false);
}
function addCube(color){
let geometryCube = cube( cubeSize );
geometryCube.computeLineDistances();
const colorspace = new THREE.LineSegments( geometryCube,
new THREE.LineDashedMaterial(
{
color: color || 0xffffff,
dashSize: 1,
gapSize: 1,
linewidth: 1,
//transparent: true,
blending: THREE.AdditiveBlending
}
)
);
colorspace.name ='colorspace';
objects.push( colorspace );
scene.add( colorspace );
spaceCube = colorspace;
}
function cube(size) {
const h = size * 0.5;
const geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, -h, h ),
new THREE.Vector3( h, -h, h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, -h, -h ),
new THREE.Vector3( -h, -h, h ),
new THREE.Vector3( -h, h, -h ),
new THREE.Vector3( -h, h, h ),
new THREE.Vector3( h, h, -h ),
new THREE.Vector3( h, h, h ),
new THREE.Vector3( h, -h, -h ),
new THREE.Vector3( h, -h, h )
);
return geometry;
}
function toggleDarkMode () {
isDark = !isDark;
document.querySelector('body').classList.toggle('isDark');
const newColor = isDark ? cDark : cLight;
setSceneColor(newColor);
const colorspace = scene.getObjectByName('colorspace');
scene.remove(colorspace);
addCube(isDark ? '#ffffff' : cDark);
document.documentElement.style.setProperty(`--background`, newColor);
document.documentElement.style.setProperty(`--foreground`, isDark ? '#ffffff' : cDark);
}
function render() {
const time = Date.now() * 0.0001;
renderer.render( scene, cam );
//controls.update();
objects.forEach(object => {
//object.rotation.x = 0.25 * time * ( i%2 == 1 ? 1 : -1);
object.rotation.x = 0.25 * time;
object.rotation.y = 0.25 * time;
})
}
function animate() {
requestAnimationFrame( animate );
render();
}
$select.addEventListener('change', e => {
colorMode = $select.value;
objects = [];
const colorspace = scene.getObjectByName('colorspace');
scene.remove(colorspace);
const colors = scene.getObjectByName('colors');
scene.remove(colors);
addParticles(colorList, colorMode);
addCube(isDark ? cLight : cDark);
}, false);
function translate(value, low1, high1, low2, high2) {
return low2 + (high2 - low2) * ((value - low1) / (high1 - low1));
}
function yuv(rgb) {
return [
/*Y*/ rgb[0] * .299000 + rgb[1] * .587000 + rgb[2] * .114000,
/*U*/ rgb[0] * -.168736 + rgb[1] * -.331264 + rgb[2] * .500000 + 128,
/*V*/ rgb[0] * .500000 + rgb[1] * -.418688 + rgb[2] * -.081312 + 128
]
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/1.3.4/chroma.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/dev/examples/js/controls/OrbitControls.js"></script>
$c-black: #212121;
$c-white: #dddddd;
$bg: $c-white;
:root {
--dark: $c-black;
--light: $c-white;
--background: var(--dark);
--foreground: var(--light);
}
// <link href="https://fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet">
@import 'https://fonts.googleapis.com/css?family=Inconsolata';
$t-code: 'Inconsolata', ipm, Menlo, 'Courier New', monospace;
//@import 'https://fonts.googleapis.com/css?family=Space+Mono';
//$t-code: 'Space Mono', ipm, Menlo, 'Courier New', monospace;
body {
overflow: hidden;
background: $c-black;
background: var(--background);
font-family: $t-code;
color: #fff;
color: var(--foreground);
}
.github-corner {
position: absolute;
top: 0; right: 0;
transform: translate3d(0,0,0);
transition: 333ms transform cubic-bezier(.7,.3,.25,1.15) 1200ms;
will-change: transform;
svg {
width: 4rem; height: 4rem;
}
path {
will-chrange: fill;
}
.octo-arm,
.octo-body {
fill: $c-black;
fill: var(--background);
}
.triange {
fill: $c-white;
fill: var(--foreground);
}
}
.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}
button,
select {
position: absolute;
font-family: $t-code;
box-sizing: border-box;
appearance: none;
-webkit-appearance: none;
border: none;
color: $c-white;
color: var(--foreground);
background-color: transparent;
cursor: pointer;
}
button {
bottom: 1rem; left: 1rem;
padding: 0;
outline: none;
padding: 0 0 0.5em 0.3em;
span {
display: none;
}
stonrg {
display: block;
}
svg {
display: block;
width: 2rem; height: 2rem;
}
path {
fill: currentColor;
}
.line {
display: none;
}
}
.isDark {
button {
.line {
display: block;
}
}
}
select {
bottom: 1rem; right: 1rem;
font-size: 2rem;
appearance: none;
-webkit-appearance: none;
border-radius: 0;
padding: 0.25em 1.25em 0.25em 0.3em;
background-color: rgba(#212121,.5);
background-size: auto 40%;
background-repeat: no-repeat;
background-position: 85% 50%;
background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%20%3C%21--%20Generator%3A%20IcoMoon.io%20--%3E%20%3C%21DOCTYPE%20svg%20PUBLIC%20%22-//W3C//DTD%20SVG%201.1//EN%22%20%22http%3A//www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd%22%3E%20%3Csvg%20width%3D%22512%22%20height%3D%22512%22%20viewBox%3D%220%200%20512%20512%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20fill%3D%22%23ffffff%22%3E%3Cpath%20d%3D%22M%2096.00%2C96.00l-96.00%2C96.00l%20256.00%2C256.00l%20256.00-256.00l-96.00-96.00L%20256.00%2C256.00L%2096.00%2C96.00z%22%20%3E%3C/path%3E%3C/svg%3E');
transition: 150ms background-color;
&:focus {
outline: none;
}
&:hover {
background-color: rgba(#212121,.8);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment