diff --git a/CHANGELOG.md b/CHANGELOG.md index dea05fa91..4d4e35769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - added option `kaboom({ focus: false })` to disable focus on start - fixed `rand()` typing for numbers - fixed mouse position in fullscreen +- added `Color#toHSL()` ### v3000.1.10 - fix test code accidentally getting shipped (where a screenshot will be downloaded every time you press space) diff --git a/src/math.ts b/src/math.ts index 606856924..55e0920c1 100644 --- a/src/math.ts +++ b/src/math.ts @@ -213,28 +213,7 @@ export class Color { } static fromHSL(h: number, s: number, l: number) { - - if (s == 0){ - return new Color(255 * l, 255 * l, 255 * l) - } - - const hue2rgb = (p, q, t) => { - 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 - } - - const q = l < 0.5 ? l * (1 + s) : l + s - l * s - const p = 2 * l - q - const r = hue2rgb(p, q, h + 1 / 3) - const g = hue2rgb(p, q, h) - const b = hue2rgb(p, q, h - 1 / 3) - - return new Color(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)) - + return Color.fromArray(hsl2rgb(h, s, l)) } static RED = new Color(255, 0, 0) @@ -278,6 +257,10 @@ export class Color { ) } + toHSL(): [number, number, number] { + return rgb2hsl(this.r, this.g, this.b) + } + eq(other: Color): boolean { return this.r === other.r && this.g === other.g @@ -311,7 +294,47 @@ export function rgb(...args): Color { return new Color(...args) } -export const hsl2rgb = (h, s, l) => Color.fromHSL(h, s, l) +export const hsl2rgb = (h, s, l) => { + if (s == 0) return [255 * l, 255 * l, 255 * l] + const hue2rgb = (p, q, t) => { + 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 + } + const q = l < 0.5 ? l * (1 + s) : l + s - l * s + const p = 2 * l - q + const r = hue2rgb(p, q, h + 1 / 3) + const g = hue2rgb(p, q, h) + const b = hue2rgb(p, q, h - 1 / 3) + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)] +} + +// TODO: use range of [0, 360] [0, 100] [0, 100]? +export const rgb2hsl = (r, g, b): [number, number, number] => { + r /= 255 + g /= 255 + b /= 255 + const max = Math.max(r, g, b), min = Math.min(r, g, b) + let h = (max + min) / 2 + let s = h + const l = h + if (max == min) { + h = s = 0 + } else { + const d = max - min + s = l > 0.5 ? d / (2 - max - min) : d / (max + min) + switch (max) { + case r: h = (g - b) / d + (g < b ? 6 : 0); break + case g: h = (b - r) / d + 2; break + case b: h = (r - g) / d + 4; break + } + h /= 6 + } + return [ h, s, l ] +} export class Quad { x: number = 0 diff --git a/src/types.ts b/src/types.ts index 43833112b..e0dcd40cf 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3819,6 +3819,12 @@ export declare class Color { */ lerp(dest: Color, t: number): Color eq(c: Color): boolean + /** + * Convert color into HSL format. + * + * @since v3000.2 + */ + toHSL(): [number, number, number] toString(): string /** * Return the hex string of color.