Skip to content

Instantly share code, notes, and snippets.

@mbostock
Last active February 9, 2016 01:50
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 mbostock/13970ac06608fbe26030 to your computer and use it in GitHub Desktop.
Save mbostock/13970ac06608fbe26030 to your computer and use it in GitHub Desktop.
HCL Interpolation II
license: gpl-3.0
.DS_Store
node_modules
npm-debug.log

Another example of HCL interpolation, except using interpolateHclLong to choose the longer path when interpolating between hues greater than 180° apart.

import {
color,
rgb,
hcl,
interpolateRgb,
interpolateHcl,
interpolateHclLong
} from "d3-color";
import {
timer
} from "d3-timer";
export {
color,
rgb,
hcl,
interpolateRgb,
interpolateHcl,
interpolateHclLong,
timer
};
!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){e=null==e?Date.now():+e;var t=k;for(k=w;k;)e>=k.time&&(k.flush=k.callback(e-k.time,e)),k=k.next;k=t,e=1/0;for(var s,n=w;n;)n.flush?n=s?s.next=n.next:w=n.next:(n.time<e&&(e=n.time),n=(s=n).next);return y=s,e}function s(){N=v=0,M=1/0,n(t())}function n(e){if(!N){var t=e-Date.now();t>24?M>e&&(v&&clearTimeout(v),v=setTimeout(s,t),M=e):(v&&(v=clearTimeout(v),M=1/0),N=requestAnimationFrame(s))}}function r(e,t){this.callback=e,this.time=t,this.flush=!1,this.next=null}function i(e,t,s){s=null==s?Date.now():+s,null!=t&&(s+=+t);var i=new r(e,s);y?y.next=i:w=i,y=i,n(s)}function a(e,t,s){this.h=+e,this.c=+t,this.l=+s}function o(){}function l(e,t,s){this.l=+e,this.a=+t,this.b=+s}function h(e){return 255*(.0031308>=e?12.92*e:1.055*Math.pow(e,1/2.4)-.055)}function u(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 c(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 g(e){return e>P?e*e*e:z*(e-L)}function d(e){return e>A?Math.pow(e,1/3):e/z+L}function f(e){return(e/=255)<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function b(e){return E(e>>16&255,e>>8&255,255&e)}function m(e,t,s){this.h=+e,this.s=Math.max(0,Math.min(1,+t)),this.l=Math.max(0,Math.min(1,+s))}function p(e,t,s){return 255*(60>e?t+(s-t)*e/60:180>e?s:240>e?t+(s-t)*(240-e)/60:t)}var w,y,k,N,v,M=1/0;o.prototype={toString:function(){return this.rgb()+""}};var x=a.prototype=new o,q=18;x.brighter=function(e){return new a(this.h,this.c,this.l+q*(null==e?1:e))},x.darker=function(e){return new a(this.h,this.c,this.l-q*(null==e?1:e))};var S=l.prototype=new o;S.brighter=function(e){return new l(this.l+q*(null==e?1:e),this.a,this.b)},S.darker=function(e){return new l(this.l-q*(null==e?1:e),this.a,this.b)};var $=u.prototype=new o,I=.7;$.darker=function(e){return e=null==e?I:Math.pow(I,e),new u(this.r*e,this.g*e,this.b*e)};var D=1/I;$.brighter=function(e){return e=null==e?D:Math.pow(D,e),new u(this.r*e,this.g*e,this.b*e)},$.rgb=function(){return this},$.toString=function(){return c(this.r,this.g,this.b)};var T=.95047,j=1,H=1.08883,L=4/29,P=6/29,z=3*P*P,A=P*P*P;S.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=j*g(e),t=T*g(t),s=H*g(s),new u(h(3.2404542*t-1.5371385*e-.4985314*s),h(-.969266*t+1.8760108*e+.041556*s),h(.0556434*t-.2040259*e+1.0572252*s))};var C=(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),F=m.prototype=new o;F.brighter=function(e){return e=null==e?D:Math.pow(D,e),new m(this.h,this.s,this.l*e)},F.darker=function(e){return e=null==e?I:Math.pow(I,e),new m(this.h,this.s,this.l*e)},F.rgb=function(){var e=this.h%360+360*(this.h<0),t=isNaN(e)||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 u(p(e>=240?e-240:e+120,r,n),p(e,r,n),p(120>e?e+240:e-120,r,n))};var R=function(e,t,s){if(1===arguments.length)if(e instanceof m)s=e.l,t=e.s,e=e.h;else{if(e instanceof o||(e=B(e)),e instanceof m)return e;e=e.rgb();var n=e.r/255,r=e.g/255,i=e.b/255,a=Math.min(n,r,i),l=Math.max(n,r,i),h=l-a;s=(l+a)/2,h?(t=.5>s?h/(l+a):h/(2-l-a),e=n===l?(r-i)/h+6*(i>r):r===l?(i-n)/h+2:(n-r)/h+4,e*=60):(e=NaN,t=s>0&&1>s?0:e)}return new m(e,t,s)},B=function(e){var t;return e=(e+"").trim().toLowerCase(),(t=/^#([0-9a-f]{3})$/.exec(e))?(t=parseInt(t[1],16),E(t>>8&15|t>>4&240,t>>4&15|240&t,(15&t)<<4|15&t)):(t=/^#([0-9a-f]{6})$/.exec(e))?b(parseInt(t[1],16)):(t=/^rgb\(\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*,\s*([-+]?\d+)\s*\)$/.exec(e))?E(t[1],t[2],t[3]):(t=/^rgb\(\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*,\s*([-+]?\d+(?:\.\d+)?)%\s*\)$/.exec(e))?E(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))?R(t[1],t[2]/100,t[3]/100):C.has(e)?b(C.get(e)):E(NaN,NaN,NaN)},E=function(e,t,s){return 1===arguments.length&&(e instanceof o||(e=B(e)),e=e.rgb(),s=e.b,t=e.g,e=e.r),new u(e,t,s)},G=Math.PI/180,J=function(e,t,s){if(1===arguments.length)if(e instanceof l)s=e.b,t=e.a,e=e.l;else if(e instanceof a){var n=e.h*G;s=Math.sin(n)*e.c,t=Math.cos(n)*e.c,e=e.l}else{e instanceof u||(e=E(e));var r=f(e.r),i=f(e.g),s=f(e.b),o=d((.4124564*r+.3575761*i+.1804375*s)/T),h=d((.2126729*r+.7151522*i+.072175*s)/j),c=d((.0193339*r+.119192*i+.9503041*s)/H);s=200*(h-c),t=500*(o-h),e=116*h-16}return new l(e,t,s)};x.rgb=function(){return J(this).rgb()};var K=180/Math.PI,O=function(e,t,s){return 1===arguments.length&&(e instanceof a?(s=e.l,t=e.c,e=e.h):(e instanceof l||(e=J(e)),s=e.l,t=Math.sqrt(e.a*e.a+e.b*e.b),e=Math.atan2(e.b,e.a)*K,0>e&&(e+=360))),new a(e,t,s)},Q=function(e,t){e=O(e),t=O(t);var s=isNaN(e.h)?t.h:e.h,n=isNaN(e.c)?t.c:e.c,r=e.l,i=isNaN(t.h)?0:t.h-s,a=isNaN(t.c)?0:t.c-n,o=t.l-r;return function(t){return e.h=s+i*t,e.c=n+a*t,e.l=r+o*t,e+""}},U=function(e,t){var s=(e-t)%360;return s+(s>180?-360:-180>s?360:0)},V=function(e,t){e=O(e),t=O(t);var s=isNaN(e.h)?t.h:e.h,n=isNaN(e.c)?t.c:e.c,r=e.l,i=isNaN(t.h)?0:U(t.h,s),a=isNaN(t.c)?0:t.c-n,o=t.l-r;return function(t){return e.h=s+i*t,e.c=n+a*t,e.l=r+o*t,e+""}},W=function(e,t){e=E(e),t=E(t);var s=e.r,n=e.g,r=e.b,i=t.r-s,a=t.g-n,o=t.b-r;return function(e){return c(Math.round(s+i*e),Math.round(n+a*e),Math.round(r+o*e))}};e.color=B,e.rgb=E,e.hcl=O,e.interpolateRgb=W,e.interpolateHcl=V,e.interpolateHclLong=Q,e.timer=i});
<!DOCTYPE html>
<meta charset="utf-8">
<canvas width="960" height="1" style="width:960px;height:500px;"></canvas>
<script src="d3.min.js"></script>
<script>
var canvas = document.querySelector("canvas"),
width = canvas.width,
context = canvas.getContext("2d"),
image = context.createImageData(width, 1);
d3.timer(function(elapsed) {
var hue = elapsed * .1,
interpolate = d3.interpolateHclLong(d3.hcl(hue, 50, 95), d3.hcl(hue + 360, 50, 25));
for (var i = 0, j = -1, c; i < width; ++i) {
c = d3.rgb(interpolate(i / (width - 1)));
image.data[++j] = c.r;
image.data[++j] = c.g;
image.data[++j] = c.b;
image.data[++j] = 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",
"d3-timer": "~0.0.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment