import {HSL as IHSL, range256} from '../src/d'; import Color from "../src/color"; class HSL implements IHSL { private static hueToRGB(p: number, q: number, t: number): number { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; } public static fromRGB(color: Color): HSL { let {red, green, blue} = color; let alpha = color.getAlphaFraction(); red *= alpha / 255; green *= alpha / 255; blue *= alpha / 255; let max = Math.max(red, green, blue); let min = Math.min(red, green, blue); let hue; let saturation; let lightness = (max + min) / 2; if (max == min) {// achromatic hue = 0; saturation = 0; } else { let d = max - min; saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case red: hue = (green - blue) / d + (green < blue ? 6 : 0); break; case green: hue = (blue - red) / d + 2; break; case blue: hue = (red - green) / d + 4; break; } hue /= 6; } return new HSL(hue, saturation, lightness); } hue: number; saturation: number = 1; lightness: number = 1; constructor(hue, saturation, lightness) { this.hue = hue; this.saturation = saturation; this.lightness = lightness; } toRGB(): Color { if (this.saturation == 0) { let value = Math.round(this.lightness * 255); return new Color([value, value, value]); } else { let q = this.lightness < 0.5 ? this.lightness * (1 + this.saturation) : this.lightness + this.saturation - this.lightness * this.saturation; let p = 2 * this.lightness - q; let r: range256 = (HSL.hueToRGB(p, q, this.hue + 1 / 3) * 255); let g: range256 = (HSL.hueToRGB(p, q, this.hue) * 255); let b: range256 = (HSL.hueToRGB(p, q, this.hue - 1 / 3) * 255); return new Color([r, g, b]); } } toString(): string { let hue = this.hue * 360; let sat = this.saturation * 100; let lig = this.lightness * 100; return `hsl(${hue}, ${sat}%, ${lig}%)`; } } export default HSL;