From 504dbd1cd862a143e8b5189467d836408c3ad1d2 Mon Sep 17 00:00:00 2001 From: SethBurkart123 Date: Wed, 11 Oct 2023 21:26:53 +1100 Subject: [PATCH] fix palerColor with gradients --- src/SEQTA.js | 104 ++++++++++-------- src/background.js | 1 - src/inject/injected/sidebar-animation.css | 4 +- src/seqta/ui/Colors.js | 16 ++- .../ui/{Background.js => ImageBackgrounds.js} | 0 src/seqta/utils/StorageListener.js | 9 +- 6 files changed, 82 insertions(+), 52 deletions(-) rename src/seqta/ui/{Background.js => ImageBackgrounds.js} (100%) diff --git a/src/SEQTA.js b/src/SEQTA.js index 3af82ca9..5fab4b68 100644 --- a/src/SEQTA.js +++ b/src/SEQTA.js @@ -13,7 +13,7 @@ import coursesicon from "./seqta/icons/coursesIcon.js"; import StorageListener from "./seqta/utils/StorageListener.js"; import { updateBgDurations } from "./seqta/ui/Animation.js"; import { updateAllColors } from "./seqta/ui/Colors.js"; -import { appendBackgroundToUI } from "./seqta/ui/Background.js"; +import { appendBackgroundToUI } from "./seqta/ui/ImageBackgrounds.js"; export let isChrome = window.chrome; let SettingsClicked = false; @@ -658,58 +658,70 @@ export function AppendElementsToDisabledPage() { } export function lightenAndPaleColor(inputColor, lightenFactor = 0.75, paleFactor = 0.55) { - // Step 1: Convert RGBA to separate R, G and B values - const [r, g, b] = inputColor.match(/\d+/g).map(Number); + console.log(`Input color: ${inputColor}`); + if (inputColor.includes("gradient")) return findMatchingColor(inputColor); - // Step 2: Convert RGB to HSL - let r1 = r / 255, g1 = g / 255, b1 = b / 255; - const max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1); - let h, s, l = (max + min) / 2; + // Step 1: Convert the input RGB color to a 'color' object + const colorObj = Color(`rgb(${inputColor.match(/\d+/g).join(",")})`); - 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 r1: h = (g1 - b1) / d + (g1 < b1 ? 6 : 0); break; - case g1: h = (b1 - r1) / d + 2; break; - case b1: h = (r1 - g1) / d + 4; break; - - } - h /= 6; - } + // Step 2: Convert to HSL and get the object + const hslObj = colorObj.hsl().object(); // Step 3: Adjust saturation and lightness - s -= s * paleFactor; - l += (1 - l) * lightenFactor; + const adjustedS = hslObj.s * (1 - paleFactor); + const adjustedL = hslObj.l + (100 - hslObj.l) * lightenFactor; - // Step 4: Convert HSL back to RGB - 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; - }; + // Step 4: Create a new 'color' object with the adjusted HSL values + const newColorObj = Color.hsl(hslObj.h, adjustedS, adjustedL); - let r2, g2, b2; - if (s === 0) { - r2 = g2 = b2 = l; - } else { - const q = l < 0.5 ? l * (1 + s) : l + s - l * s; - const p = 2 * l - q; - r2 = hue2rgb(p, q, h + 1/3); - g2 = hue2rgb(p, q, h); - b2 = hue2rgb(p, q, h - 1/3); + // Step 5: Convert back to RGB + const result = newColorObj.rgb().string(); + + console.log(`Input color: ${inputColor} | Output color: ${result}`); + + return result; +} + +// Utility function to average an array of Color objects +function averageColors(colors) { + let avgR = 0, avgG = 0, avgB = 0; + colors.forEach(color => { + avgR += color.red(); + avgG += color.green(); + avgB += color.blue(); + }); + return Color.rgb(avgR / colors.length, avgG / colors.length, avgB / colors.length); +} + +// Main function to find a matching color for a CSS gradient +function findMatchingColor(cssGradient) { + try { + // Step 1: Parse the gradient to extract color stops (case-insensitive) + const regex = /#[0-9a-fA-F]{6}|rgb\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*[\d.]+\s*\)/gi; + const colorStops = cssGradient.match(regex); + + if (!colorStops) { + throw new Error("No valid color stops found in the provided CSS gradient."); + } + + // Normalize and trim the color stops + const normalizedColorStops = colorStops.map(color => color.toLowerCase().replace(/\s+/g, "")); + + // Convert the color stops to Color objects + const colorObjects = normalizedColorStops.map(color => Color(color)); + + // Step 2: Average the color stops + const baseColor = averageColors(colorObjects); + + // Step 3: Lighten and desaturate the base color + const matchingColor = baseColor.lighten(0.7).desaturate(0.5); + + // Step 4: Return the matching color in HEX format + return matchingColor.hex(); + } catch (err) { + console.error(`Error: ${err.message}`); + return null; } - - // Step 5: Format Output - const result = `rgb(${Math.round(r2 * 255)}, ${Math.round(g2 * 255)}, ${Math.round(b2 * 255)})`; - - return `${result}`; } export function ColorLuminance(color, lum = 0) { diff --git a/src/background.js b/src/background.js index 8fec1a66..0a205dde 100644 --- a/src/background.js +++ b/src/background.js @@ -310,7 +310,6 @@ function migrateOldStorage() { chrome.runtime.onInstalled.addListener(function (event) { chrome.storage.local.remove(["justupdated"]); UpdateCurrentValues(); - chrome.storage.local.set({ justupdated: true }); if ( event.reason == "install" ) { chrome.storage.local.set({ justupdated: true }); migrateOldStorage(); diff --git a/src/inject/injected/sidebar-animation.css b/src/inject/injected/sidebar-animation.css index 51bf4a01..3ddfdf70 100644 --- a/src/inject/injected/sidebar-animation.css +++ b/src/inject/injected/sidebar-animation.css @@ -1,7 +1,7 @@ -/* #menu ul.noscroll li label { +#menu ul.noscroll li label { transform: translateX(-10%); } #menu li.active>.sub { transform: translateX(0); -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/src/seqta/ui/Colors.js b/src/seqta/ui/Colors.js index c580d6c2..654e4f31 100644 --- a/src/seqta/ui/Colors.js +++ b/src/seqta/ui/Colors.js @@ -20,6 +20,7 @@ export function updateAllColors(storedSetting, newColor = null) { // Mode-based properties, applied if storedSetting is provided let modeProps = {}; + console.log(DarkMode); if (DarkMode !== null) { modeProps = DarkMode ? { "--background-primary": "#232323", @@ -29,10 +30,12 @@ export function updateAllColors(storedSetting, newColor = null) { "--background-primary": "#ffffff", "--background-secondary": "#e5e7eb", "--text-primary": "black", - "--better-pale": lightenAndPaleColor(selectedColor) // Wrap this in try-catch if needed + "--better-pale": lightenAndPaleColor(selectedColor) }; } + console.log("modeProps:", modeProps); + // Dynamic properties, always applied const rgbThreshold = GetThresholdofHex(selectedColor); const isBright = rgbThreshold > 210; @@ -50,3 +53,14 @@ export function updateAllColors(storedSetting, newColor = null) { document.querySelector("link[rel*='icon']").href = getChromeURL("icons/icon-48.png"); } } + +export function getDarkMode() { + return new Promise((resolve, reject) => { + chrome.storage.local.get("DarkMode", (result) => { + if (chrome.runtime.lastError) { + return reject(chrome.runtime.lastError); + } + resolve(result.DarkMode); + }); + }); +} \ No newline at end of file diff --git a/src/seqta/ui/Background.js b/src/seqta/ui/ImageBackgrounds.js similarity index 100% rename from src/seqta/ui/Background.js rename to src/seqta/ui/ImageBackgrounds.js diff --git a/src/seqta/utils/StorageListener.js b/src/seqta/utils/StorageListener.js index e04c78c1..27e949af 100644 --- a/src/seqta/utils/StorageListener.js +++ b/src/seqta/utils/StorageListener.js @@ -10,10 +10,11 @@ import { enableNotificationCollector, } from "../../SEQTA.js"; import { updateBgDurations } from "../ui/Animation.js"; -import { updateAllColors } from "../ui/Colors.js"; +import { getDarkMode, updateAllColors } from "../ui/Colors.js"; export default class StorageListener { constructor() { + this.darkMode = getDarkMode(); chrome.storage.onChanged.addListener(this.handleStorageChanges.bind(this)); } @@ -29,6 +30,10 @@ export default class StorageListener { ); } + if (changes.DarkMode) { + this.darkMode = changes.DarkMode.newValue; + } + if (changes?.customshortcuts?.newValue) { this.handleCustomShortcutsChange( changes.customshortcuts.oldValue, @@ -56,7 +61,7 @@ export default class StorageListener { handleSelectedColorChange(newColor) { try { - updateAllColors(null, newColor); + updateAllColors(this.darkMode, newColor); } catch (err) { console.error(err); }