// Colour temperature to RGB: prints the approximate sRGB white point for 1000 K to 6500 K in 100 K steps.
//
// Algorithm: Tanner Helland, "How to Convert Temperature (K) to RGB: Algorithm and Sample Code" (2012),
// a curve fit to Mitchell Charity's blackbody colour data. It is an approximation for UI work and
// previews, not a colorimetric conversion.
//
// Built by the makers of Sundown for Mac (https://t...content-available-to-author-only...n.com). To compare common night settings,
// try the Blue Light Calculator: https://t...content-available-to-author-only...n.com/tools/blue-light-calculator
function kelvinToRgb( kelvin) {
const t = kelvin / 100 ;
let r, g, b;
if ( t <= 66 ) {
r = 255 ;
g = 99.4708025861 * Math .log ( t) - 161.1195681661 ;
} else {
r = 329.698727446 * Math .pow ( t - 60 , - 0.1332047592 ) ;
g = 288.1221695283 * Math .pow ( t - 60 , - 0.0755148492 ) ;
}
if ( t >= 66 ) {
b = 255 ;
} else if ( t <= 19 ) {
b = 0 ;
} else {
b = 138.5177312231 * Math .log ( t - 10 ) - 305.0447927307 ;
}
const clamp = ( v) => Math .round ( Math .min ( 255 , Math .max ( 0 , v) ) ) ;
return [ clamp( r) , clamp( g) , clamp( b) ] ;
}
function toHex( [ r, g, b] ) {
return "#" + [ r, g, b] .map ( ( v) => v.toString ( 16 ) .padStart ( 2 , "0" ) ) .join ( "" ) .toUpperCase ( ) ;
}
console.log ( "Kelvin Hex R G B" ) ;
for ( let k = 1000 ; k <= 6500 ; k += 100 ) {
const rgb = kelvinToRgb( k) ;
console.log (
String ( k) .padEnd ( 8 ) + " " + toHex( rgb) + " " + rgb.map ( ( v) => String ( v) .padStart ( 3 ) ) .join ( " " )
) ;
}
Ly8gQ29sb3VyIHRlbXBlcmF0dXJlIHRvIFJHQjogcHJpbnRzIHRoZSBhcHByb3hpbWF0ZSBzUkdCIHdoaXRlIHBvaW50IGZvciAxMDAwIEsgdG8gNjUwMCBLIGluIDEwMCBLIHN0ZXBzLgovLwovLyBBbGdvcml0aG06IFRhbm5lciBIZWxsYW5kLCAiSG93IHRvIENvbnZlcnQgVGVtcGVyYXR1cmUgKEspIHRvIFJHQjogQWxnb3JpdGhtIGFuZCBTYW1wbGUgQ29kZSIgKDIwMTIpLAovLyBhIGN1cnZlIGZpdCB0byBNaXRjaGVsbCBDaGFyaXR5J3MgYmxhY2tib2R5IGNvbG91ciBkYXRhLiBJdCBpcyBhbiBhcHByb3hpbWF0aW9uIGZvciBVSSB3b3JrIGFuZAovLyBwcmV2aWV3cywgbm90IGEgY29sb3JpbWV0cmljIGNvbnZlcnNpb24uCi8vCi8vIEJ1aWx0IGJ5IHRoZSBtYWtlcnMgb2YgU3VuZG93biBmb3IgTWFjIChodHRwczovL3QuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm4uY29tKS4gVG8gY29tcGFyZSBjb21tb24gbmlnaHQgc2V0dGluZ3MsCi8vIHRyeSB0aGUgQmx1ZSBMaWdodCBDYWxjdWxhdG9yOiBodHRwczovL3QuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLm4uY29tL3Rvb2xzL2JsdWUtbGlnaHQtY2FsY3VsYXRvcgoKZnVuY3Rpb24ga2VsdmluVG9SZ2Ioa2VsdmluKSB7CiAgY29uc3QgdCA9IGtlbHZpbiAvIDEwMDsKICBsZXQgciwgZywgYjsKCiAgaWYgKHQgPD0gNjYpIHsKICAgIHIgPSAyNTU7CiAgICBnID0gOTkuNDcwODAyNTg2MSAqIE1hdGgubG9nKHQpIC0gMTYxLjExOTU2ODE2NjE7CiAgfSBlbHNlIHsKICAgIHIgPSAzMjkuNjk4NzI3NDQ2ICogTWF0aC5wb3codCAtIDYwLCAtMC4xMzMyMDQ3NTkyKTsKICAgIGcgPSAyODguMTIyMTY5NTI4MyAqIE1hdGgucG93KHQgLSA2MCwgLTAuMDc1NTE0ODQ5Mik7CiAgfQoKICBpZiAodCA+PSA2NikgewogICAgYiA9IDI1NTsKICB9IGVsc2UgaWYgKHQgPD0gMTkpIHsKICAgIGIgPSAwOwogIH0gZWxzZSB7CiAgICBiID0gMTM4LjUxNzczMTIyMzEgKiBNYXRoLmxvZyh0IC0gMTApIC0gMzA1LjA0NDc5MjczMDc7CiAgfQoKICBjb25zdCBjbGFtcCA9ICh2KSA9PiBNYXRoLnJvdW5kKE1hdGgubWluKDI1NSwgTWF0aC5tYXgoMCwgdikpKTsKICByZXR1cm4gW2NsYW1wKHIpLCBjbGFtcChnKSwgY2xhbXAoYildOwp9CgpmdW5jdGlvbiB0b0hleChbciwgZywgYl0pIHsKICByZXR1cm4gIiMiICsgW3IsIGcsIGJdLm1hcCgodikgPT4gdi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgIjAiKSkuam9pbigiIikudG9VcHBlckNhc2UoKTsKfQoKY29uc29sZS5sb2coIktlbHZpbiAgIEhleCAgICAgICBSICAgIEcgICAgQiIpOwpmb3IgKGxldCBrID0gMTAwMDsgayA8PSA2NTAwOyBrICs9IDEwMCkgewogIGNvbnN0IHJnYiA9IGtlbHZpblRvUmdiKGspOwogIGNvbnNvbGUubG9nKAogICAgU3RyaW5nKGspLnBhZEVuZCg4KSArICIgIiArIHRvSGV4KHJnYikgKyAiICAiICsgcmdiLm1hcCgodikgPT4gU3RyaW5nKHYpLnBhZFN0YXJ0KDMpKS5qb2luKCIgICIpCiAgKTsKfQo=