From 05d2b6f67e5f8ccaf1bdbb3b5d62bac0d2fc2f31 Mon Sep 17 00:00:00 2001 From: Hakadao Date: Mon, 5 Aug 2024 02:30:13 +0800 Subject: [PATCH] refactor: update hexToHSL function to convert hex color to HSLA --- src/contentScripts/views/App.vue | 6 +-- src/utils/main.ts | 67 +++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 13 deletions(-) diff --git a/src/contentScripts/views/App.vue b/src/contentScripts/views/App.vue index 3ea704e8..35dee5dd 100644 --- a/src/contentScripts/views/App.vue +++ b/src/contentScripts/views/App.vue @@ -9,7 +9,7 @@ import { useDark } from '~/composables/useDark' import { OVERLAY_SCROLL_BAR_SCROLL } from '~/constants/globalEvents' import { AppPage, LanguageType } from '~/enums/appEnums' import { accessKey, settings } from '~/logic' -import { getUserID, hexToRGBA, isHomePage, scrollToTop } from '~/utils/main' +import { getUserID, hexToHSL, isHomePage, scrollToTop } from '~/utils/main' import emitter from '~/utils/mitt' const { isDark } = useDark() @@ -149,12 +149,12 @@ function setAppThemeColor() { if (bewlyElement) { bewlyElement.style.setProperty('--bew-theme-color', settings.value.themeColor) for (let i = 0; i < 9; i++) - bewlyElement.style.setProperty(`--bew-theme-color-${i + 1}0`, hexToRGBA(settings.value.themeColor, i * 0.1 + 0.1)) + bewlyElement.style.setProperty(`--bew-theme-color-${i + 1}0`, hexToHSL(settings.value.themeColor, i * 0.1 + 0.1)) } document.documentElement.style.setProperty('--bew-theme-color', settings.value.themeColor) for (let i = 0; i < 9; i++) - document.documentElement.style.setProperty(`--bew-theme-color-${i + 1}0`, hexToRGBA(settings.value.themeColor, i * 0.1 + 0.1)) + document.documentElement.style.setProperty(`--bew-theme-color-${i + 1}0`, hexToHSL(settings.value.themeColor, i * 0.1 + 0.1)) } function handleBackToTop(targetScrollTop = 0 as number) { diff --git a/src/utils/main.ts b/src/utils/main.ts index 2304df35..79d9980e 100644 --- a/src/utils/main.ts +++ b/src/utils/main.ts @@ -48,21 +48,68 @@ export function openLinkToNewTab(url: string) { } /** - * Convert a hex color value to RGBA, thanks ChatGPT 🫡 + * Convert a hex color value to HSLA, thanks ChatGPT 🫡 * @param hex hex color value * @param alpha color opacity - * @returns RGBA or RGB color string + * @returns HSLA or HSL color string */ -export function hexToRGBA(hex: string, alpha: number): string { - const r = Number.parseInt(hex.slice(1, 3), 16) - const g = Number.parseInt(hex.slice(3, 5), 16) - const b = Number.parseInt(hex.slice(5, 7), 16) +export function hexToHSL(hex: string, alpha: number | null = null): string { + // Remove the hash at the start if it's there + hex = hex.replace(/^#/, '') - if (alpha) - return `rgba(${r}, ${g}, ${b}, ${alpha})` + // Ensure the input is valid + if (hex.length !== 6) { + throw new Error('Invalid HEX color.') + } - else - return `rgb(${r}, ${g}, ${b})` + // Parse the r, g, b values + let r = Number.parseInt(hex.substring(0, 2), 16) + let g = Number.parseInt(hex.substring(2, 4), 16) + let b = Number.parseInt(hex.substring(4, 6), 16) + + // Convert r, g, b to percentages + r /= 255 + g /= 255 + b /= 255 + + // Find the greatest and smallest channel values + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) + let h: number = 0 + let s: number = 0 + let l: number = (max + min) / 2 + + // Calculate the hue + if (max === min) { + h = s = 0 // achromatic + } + 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 + } + + // Convert to degrees and percentages + h = Math.round(h * 360) + s = Math.round(s * 100) + l = Math.round(l * 100) + + if (alpha !== null) + return `hsla(${h}, ${s}%, ${l}%, ${alpha})` + return `hsla(${h}, ${s}%, ${l}%)` } /**