From 5cc14f99fda4cc91760cf95f584c7b3e9b62486c Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 30 May 2022 19:14:40 +0200 Subject: [PATCH] Incorrect calculation of the saturation --- ts/WoltLabSuite/Core/ColorUtil.ts | 74 ++++++++++++------- .../files/js/WoltLabSuite/Core/ColorUtil.js | 57 ++++++++++---- 2 files changed, 91 insertions(+), 40 deletions(-) diff --git a/ts/WoltLabSuite/Core/ColorUtil.ts b/ts/WoltLabSuite/Core/ColorUtil.ts index cd3335a2e2..d2c7618e74 100644 --- a/ts/WoltLabSuite/Core/ColorUtil.ts +++ b/ts/WoltLabSuite/Core/ColorUtil.ts @@ -8,13 +8,6 @@ * @module WoltLabSuite/Core/ColorUtil */ -type HSVL = { - h: number; - s: number; - v: number; - l: number; -}; - /** * Converts a HSL color into RGB. * @@ -115,11 +108,11 @@ export function hsvToRgb(h: number, s: number, v: number): RGB { } /** - * Converts a RGB color into HSVL. + * Converts a RGB color into HSL. * - * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV + * @see https://www.rapidtables.com/convert/color/rgb-to-hsl.html */ -function rgbToHsvl(r: number, g: number, b: number): HSVL { +export function rgbToHsl(r: number, g: number, b: number): HSL { let h: number, s: number; r /= 255; @@ -151,38 +144,69 @@ function rgbToHsvl(r: number, g: number, b: number): HSVL { } } + const l = (max + min) / 2; + if (max === 0) { s = 0; } else { - s = diff / max; + s = diff / (1 - Math.abs(2 * l - 1)); } - const l = (max + min) / 2; - return { h: Math.round(h), s: Math.round(s * 100), - v: Math.round(max * 100), l: Math.round(l * 100), }; } -/** - * Converts a RGB color into HSL. - */ -export function rgbToHsl(r: number, g: number, b: number): HSL { - const { h, s, l } = rgbToHsvl(r, g, b); - - return { h, s, l }; -} - /** * Converts a RGB color into HSV. + * + * @see https://www.rapidtables.com/convert/color/rgb-to-hsv.html */ export function rgbToHsv(r: number, g: number, b: number): HSV { - const { h, s, v } = rgbToHsvl(r, g, b); + let h: number, s: number; + + r /= 255; + g /= 255; + b /= 255; + + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const diff = max - min; - return { h, s, v }; + h = 0; + if (max !== min) { + switch (max) { + case r: + h = 60 * ((g - b) / diff); + break; + + case g: + h = 60 * (2 + (b - r) / diff); + break; + + case b: + h = 60 * (4 + (r - g) / diff); + break; + } + + if (h < 0) { + h += 360; + } + } + + if (max === 0) { + s = 0; + } else { + s = diff / max; + } + + return { + h: Math.round(h), + s: Math.round(s * 100), + v: Math.round(max * 100), + }; } /** diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js b/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js index 9f70e448c1..5848215e56 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/ColorUtil.js @@ -98,11 +98,11 @@ define(["require", "exports"], function (require, exports) { } exports.hsvToRgb = hsvToRgb; /** - * Converts a RGB color into HSVL. + * Converts a RGB color into HSL. * - * @see https://secure.wikimedia.org/wikipedia/de/wiki/HSV-Farbraum#Transformation_von_RGB_und_HSV + * @see https://www.rapidtables.com/convert/color/rgb-to-hsl.html */ - function rgbToHsvl(r, g, b) { + function rgbToHsl(r, g, b) { let h, s; r /= 255; g /= 255; @@ -127,34 +127,61 @@ define(["require", "exports"], function (require, exports) { h += 360; } } + const l = (max + min) / 2; if (max === 0) { s = 0; } else { - s = diff / max; + s = diff / (1 - Math.abs(2 * l - 1)); } - const l = (max + min) / 2; return { h: Math.round(h), s: Math.round(s * 100), - v: Math.round(max * 100), l: Math.round(l * 100), }; } - /** - * Converts a RGB color into HSL. - */ - function rgbToHsl(r, g, b) { - const { h, s, l } = rgbToHsvl(r, g, b); - return { h, s, l }; - } exports.rgbToHsl = rgbToHsl; /** * Converts a RGB color into HSV. + * + * @see https://www.rapidtables.com/convert/color/rgb-to-hsv.html */ function rgbToHsv(r, g, b) { - const { h, s, v } = rgbToHsvl(r, g, b); - return { h, s, v }; + let h, s; + r /= 255; + g /= 255; + b /= 255; + const max = Math.max(Math.max(r, g), b); + const min = Math.min(Math.min(r, g), b); + const diff = max - min; + h = 0; + if (max !== min) { + switch (max) { + case r: + h = 60 * ((g - b) / diff); + break; + case g: + h = 60 * (2 + (b - r) / diff); + break; + case b: + h = 60 * (4 + (r - g) / diff); + break; + } + if (h < 0) { + h += 360; + } + } + if (max === 0) { + s = 0; + } + else { + s = diff / max; + } + return { + h: Math.round(h), + s: Math.round(s * 100), + v: Math.round(max * 100), + }; } exports.rgbToHsv = rgbToHsv; /** -- 2.20.1