Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active January 18, 2023 08:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mbostock/a6649f007b76eabee549 to your computer and use it in GitHub Desktop.
Save mbostock/a6649f007b76eabee549 to your computer and use it in GitHub Desktop.
HCL Color Space
license: gpl-3.0
.DS_Store
node_modules
npm-debug.log

A two-dimensional cross section of the HCL color space: from top to bottom, hue ranges from 0° to 360°; from left to right, luminance ranges from 100 to 0. Chroma is a constant 50.

import {
color,
rgb,
hsl,
lab,
hcl
} from "d3-color";
export {
color,
rgb,
hsl,
lab,
hcl
};
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.d3={})}(this,function(e){"use strict";function t(e,t,s){this.h=(e%=360)<0?e+360:e,this.c=+t,this.l=Math.max(0,Math.min(100,+s))}function s(){}function n(e,t,s){this.l=Math.max(0,Math.min(100,+e)),this.a=+t,this.b=+s}function r(e){return 255*(.0031308>=e?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function i(e,t,s){this.r=Math.max(0,Math.min(255,Math.round(e))),this.g=Math.max(0,Math.min(255,Math.round(t))),this.b=Math.max(0,Math.min(255,Math.round(s)))}function a(e,t,s){return isNaN(e)&&(e=0),isNaN(t)&&(t=0),isNaN(s)&&(s=0),"#"+(16>e?"0"+e.toString(16):e.toString(16))+(16>t?"0"+t.toString(16):t.toString(16))+(16>s?"0"+s.toString(16):s.toString(16))}function o(e){return e>N?e*e*e:x*(e-v)}function l(e){return e>q?Math.pow(e,1/3):e/x+v}function h(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function u(e){return P(e>>16&255,e>>8&255,255&e)}function g(e,t,s){this.h=(e%=360)<0?e+360:e,this.s=Math.max(0,Math.min(1,+t)),this.l=Math.max(0,Math.min(1,+s))}function d(e,t,s){return 255*(60>e?t+(s-t)*e/60:180>e?s:240>e?t+(s-t)*(240-e)/60:t)}s.prototype={toString:function(){return this.rgb()+""}};var c=t.prototype=new s,b=18;c.brighter=function(e){return new t(this.h,this.c,this.l+b*(null==e?1:e))},c.darker=function(e){return new t(this.h,this.c,this.l-b*(null==e?1:e))};var f=n.prototype=new s;f.brighter=function(e){return new n(this.l+b*(null==e?1:e),this.a,this.b)},f.darker=function(e){return new n(this.l-b*(null==e?1:e),this.a,this.b)};var m=i.prototype=new s,p=.7;m.darker=function(e){return e=null==e?p:Math.pow(p,e),new i(this.r*e,this.g*e,this.b*e)};var w=1/p;m.brighter=function(e){return e=null==e?w:Math.pow(w,e),new i(this.r*e,this.g*e,this.b*e)},m.rgb=function(){return this},m.toString=function(){return a(this.r,this.g,this.b)};var y=.95047,k=1,M=1.08883,v=4/29,N=6/29,x=3*N*N,q=N*N*N;f.rgb=function(){var e=(this.l+16)/116,t=isNaN(this.a)?e:e+this.a/500,s=isNaN(this.b)?e:e-this.b/200;return e=k*o(e),t=y*o(t),s=M*o(s),new i(r(3.2404542*t-1.5371385*e-.4985314*s),r(-.969266*t+1.8760108*e+.041556*s),r(.0556434*t-.2040259*e+1.0572252*s))};var S=(new Map).set("aliceblue",15792383).set("antiquewhite",16444375).set("aqua",65535).set("aquamarine",8388564).set("azure",15794175).set("beige",16119260).set("bisque",16770244).set("black",0).set("blanchedalmond",16772045).set("blue",255).set("blueviolet",9055202).set("brown",10824234).set("burlywood",14596231).set("cadetblue",6266528).set("chartreuse",8388352).set("chocolate",13789470).set("coral",16744272).set("cornflowerblue",6591981).set("cornsilk",16775388).set("crimson",14423100).set("cyan",65535).set("darkblue",139).set("darkcyan",35723).set("darkgoldenrod",12092939).set("darkgray",11119017).set("darkgreen",25600).set("darkgrey",11119017).set("darkkhaki",12433259).set("darkmagenta",9109643).set("darkolivegreen",5597999).set("darkorange",16747520).set("darkorchid",10040012).set("darkred",9109504).set("darksalmon",15308410).set("darkseagreen",9419919).set("darkslateblue",4734347).set("darkslategray",3100495).set("darkslategrey",3100495).set("darkturquoise",52945).set("darkviolet",9699539).set("deeppink",16716947).set("deepskyblue",49151).set("dimgray",6908265).set("dimgrey",6908265).set("dodgerblue",2003199).set("firebrick",11674146).set("floralwhite",16775920).set("forestgreen",2263842).set("fuchsia",16711935).set("gainsboro",14474460).set("ghostwhite",16316671).set("gold",16766720).set("goldenrod",14329120).set("gray",8421504).set("green",32768).set("greenyellow",11403055).set("grey",8421504).set("honeydew",15794160).set("hotpink",16738740).set("indianred",13458524).set("indigo",4915330).set("ivory",16777200).set("khaki",15787660).set("lavender",15132410).set("lavenderblush",16773365).set("lawngreen",8190976).set("lemonchiffon",16775885).set("lightblue",11393254).set("lightcoral",15761536).set("lightcyan",14745599).set("lightgoldenrodyellow",16448210).set("lightgray",13882323).set("lightgreen",9498256).set("lightgrey",13882323).set("lightpink",16758465).set("lightsalmon",16752762).set("lightseagreen",2142890).set("lightskyblue",8900346).set("lightslategray",7833753).set("lightslategrey",7833753).set("lightsteelblue",11584734).set("lightyellow",16777184).set("lime",65280).set("limegreen",3329330).set("linen",16445670).set("magenta",16711935).set("maroon",8388608).set("mediumaquamarine",6737322).set("mediumblue",205).set("mediumorchid",12211667).set("mediumpurple",9662683).set("mediumseagreen",3978097).set("mediumslateblue",8087790).set("mediumspringgreen",64154).set("mediumturquoise",4772300).set("mediumvioletred",13047173).set("midnightblue",1644912).set("mintcream",16121850).set("mistyrose",16770273).set("moccasin",16770229).set("navajowhite",16768685).set("navy",128).set("oldlace",16643558).set("olive",8421376).set("olivedrab",7048739).set("orange",16753920).set("orangered",16729344).set("orchid",14315734).set("palegoldenrod",15657130).set("palegreen",10025880).set("paleturquoise",11529966).set("palevioletred",14381203).set("papayawhip",16773077).set("peachpuff",16767673).set("peru",13468991).set("pink",16761035).set("plum",14524637).set("powderblue",11591910).set("purple",8388736).set("rebeccapurple",6697881).set("red",16711680).set("rosybrown",12357519).set("royalblue",4286945).set("saddlebrown",9127187).set("salmon",16416882).set("sandybrown",16032864).set("seagreen",3050327).set("seashell",16774638).set("sienna",10506797).set("silver",12632256).set("skyblue",8900331).set("slateblue",6970061).set("slategray",7372944).set("slategrey",7372944).set("snow",16775930).set("springgreen",65407).set("steelblue",4620980).set("tan",13808780).set("teal",32896).set("thistle",14204888).set("tomato",16737095).set("turquoise",4251856).set("violet",15631086).set("wheat",16113331).set("white",16777215).set("whitesmoke",16119285).set("yellow",16776960).set("yellowgreen",10145074),$=g.prototype=new s;$.brighter=function(e){return e=null==e?w:Math.pow(w,e),new g(this.h,this.s,this.l*e)},$.darker=function(e){return e=null==e?p:Math.pow(p,e),new g(this.h,this.s,this.l*e)},$.rgb=function(){var e=this.h,t=isNaN(this.h)||isNaN(this.s)?0:this.s,s=this.l,n=.5>=s?s*(1+t):s+t-s*t,r=2*s-n;return new i(d(e>=240?e-240:e+120,r,n),d(e,r,n),d(120>e?e+240:e-120,r,n))};var I=function(e,t,n){if(1===arguments.length)if(e instanceof g)n=e.l,t=e.s,e=e.h;else{if(e instanceof s||(e=j(e)),e instanceof g)return e;e=e.rgb();var r=e.r/255,i=e.g/255,a=e.b/255,o=Math.min(r,i,a),l=Math.max(r,i,a),h=l-o;n=(l+o)/2,h?(t=.5>n?h/(l+o):h/(2-l-o),e=r===l?(i-a)/h+6*(a>i):i===l?(a-r)/h+2:(r-i)/h+4,e*=60):(e=NaN,t=n>0&&1>n?0:e)}return new g(e,t,n)},j=function(e){var t;return e=(e+"").trim().toLowerCase(),(t=/^#([0-9a-f]{3})$/.exec(e))?(t=parseInt(t[1],16),P(t>>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t)):(t=/^#([0-9a-f]{6})$/.exec(e))?u(parseInt(t[1],16)):(t=/^rgb\(\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*\)$/.exec(e))?P(t[1],t[2],t[3]):(t=/^rgb\(\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*\)$/.exec(e))?P(255*t[1]/100,255*t[2]/100,255*t[3]/100):(t=/^hsl\(\s*([-+]?\d+(?:\.\d+)?)\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*\)$/.exec(e))?I(t[1],t[2]/100,t[3]/100):S.has(e)?u(S.get(e)):P(NaN,NaN,NaN)},P=function(e,t,n){return 1===arguments.length&&(e instanceof s||(e=j(e)),e=e.rgb(),n=e.b,t=e.g,e=e.r),new i(e,t,n)},z=Math.PI/180,C=function(e,s,r){if(1===arguments.length)if(e instanceof n)r=e.b,s=e.a,e=e.l;else if(e instanceof t){var a=e.h*z;r=Math.sin(a)*e.c,s=Math.cos(a)*e.c,e=e.l}else{e instanceof i||(e=P(e));var o=h(e.r),u=h(e.g),r=h(e.b),g=l((.4124564*o+.3575761*u+.1804375*r)/y),d=l((.2126729*o+.7151522*u+.072175*r)/k),c=l((.0193339*o+.119192*u+.9503041*r)/M);r=200*(d-c),s=500*(g-d),e=116*d-16}return new n(e,s,r)};c.rgb=function(){return C(this).rgb()};var L=180/Math.PI,A=function(e,s,r){return 1===arguments.length&&(e instanceof t?(r=e.l,s=e.c,e=e.h):(e instanceof n||(e=C(e)),r=e.l,s=Math.sqrt(e.a*e.a+e.b*e.b),e=Math.atan2(e.b,e.a)*L)),new t(e,s,r)};e.color=j,e.rgb=P,e.hsl=I,e.lab=C,e.hcl=A});
<!DOCTYPE html>
<meta charset="utf-8">
<canvas width="960" height="500"></canvas>
<script src="d3.min.js"></script>
<script>
var canvas = document.querySelector("canvas"),
width = canvas.width,
height = canvas.height,
context = canvas.getContext("2d"),
image = context.createImageData(width, height),
hue,
y = -1,
i = -1;
while (++y < height) {
for (var x = 0, c; x < width; ++x) {
c = d3.hcl(360 * y / (height - 1), 50, 100 * (1 - x / (width - 1))).rgb();
image.data[++i] = c.r;
image.data[++i] = c.g;
image.data[++i] = c.b;
image.data[++i] = 255;
}
}
context.putImageData(image, 0, 0);
</script>
{
"scripts": {
"build": "d3-bundler -- d3.js | uglifyjs -c -m -o d3.min.js"
},
"dependencies": {
"uglify-js": "2"
},
"devDependencies": {
"d3-bundler": "~0.2.5",
"d3-color": "~0.1.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment