add option to select color extraction method

This commit is contained in:
Send_Nukez 2021-11-17 03:40:09 +01:00
parent fd01cc02ce
commit 784947e3a5
2 changed files with 66 additions and 41 deletions

View file

@ -33,3 +33,7 @@ export function copyToClipboard(text) {
export function capitalizeFirstLetter(string) { export function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1); return string.charAt(0).toUpperCase() + string.slice(1);
} }
export function getClosestToNum(arr, num) {
return arr.reduce((prev, curr) => (Math.abs(curr - num) < Math.abs(prev - num) ? curr : prev));
}

View file

@ -3,7 +3,7 @@ import chroma from "chroma-js";
import $ from "jquery"; import $ from "jquery";
import moment from "moment"; import moment from "moment";
import { waitForElement, copyToClipboard, capitalizeFirstLetter } from "./Util"; import { waitForElement, copyToClipboard, capitalizeFirstLetter, getClosestToNum } from "./Util";
import ConfigMenu from "./ConfigMenu"; import ConfigMenu from "./ConfigMenu";
import Info from "./Info"; import Info from "./Info";
@ -492,10 +492,10 @@ function toggleDark(setDark) {
setRootColor("subtext", setDark ? "#EAEAEA" : "#3D3D3D"); setRootColor("subtext", setDark ? "#EAEAEA" : "#3D3D3D");
setRootColor("notification", setDark ? "#303030" : "#DDDDDD"); setRootColor("notification", setDark ? "#303030" : "#DDDDDD");
updateColors(sidebarColor, false); updateColors(false);
} }
function checkDarkLightMode(colors) { function checkDarkLightMode() {
const theme = Dribbblish.config.get("theme"); const theme = Dribbblish.config.get("theme");
if (theme == "time") { if (theme == "time") {
const start = 60 * parseInt(Dribbblish.config.get("darkModeOnTime").split(":")[0]) + parseInt(Dribbblish.config.get("darkModeOnTime").split(":")[1]); const start = 60 * parseInt(Dribbblish.config.get("darkModeOnTime").split(":")[0]) + parseInt(Dribbblish.config.get("darkModeOnTime").split(":")[1]);
@ -508,23 +508,53 @@ function checkDarkLightMode(colors) {
if (end < start) dark = start <= time || time < end; if (end < start) dark = start <= time || time < end;
else dark = start <= time && time < end; else dark = start <= time && time < end;
toggleDark(dark); toggleDark(dark);
} else if (theme == "color") {
if (colors && colors.length > 0) toggleDark(isLight(colors[0]));
} }
} }
// Run every Minute to check time and set dark / light mode // Run every Minute to check time and set dark / light mode
setInterval(checkDarkLightMode, 60000); setInterval(checkDarkLightMode, 60000);
Dribbblish.config.register({ Dribbblish.config.register({
area: "Theme", area: "Theme",
type: "checkbox", type: "select",
key: "dynamicColors", key: "colorSelectionMode",
name: "Dynamic", name: "Color Selection Mode",
description: "If the Theme's Color should be extracted from Albumart", description: "Method of selecting colors from the albumart",
defaultValue: true, data: { dynamic: "Dynamic", dynamicLuminance: "Dynamic (Luminance)", static: "Static" },
onChange: (val) => updateColors(), defaultValue: "dynamic",
showChildren: (val) => !val, onChange: () => updateColors(),
showChildren: (val) => {
if (val == "dynamicLuminance") return ["lightModeLuminance", "darkModeLuminance"];
if (val == "static") return ["colorOverride"];
return false;
},
children: [ children: [
{
type: "number",
key: "lightModeLuminance",
name: "Desired Light Mode Luminance",
description: `
Set desired luminance in light mode.
*the selected color will be the one who's luminance is closest to the desired luminance*{.muted}
`,
defaultValue: 0.6,
data: { min: 0, max: 1, step: 0.05 },
fireInitialChange: false,
onChange: () => updateColors()
},
{
type: "number",
key: "darkModeLuminance",
name: "Desired Dark Mode Luminance",
description: `
Set desired luminance in dark mode.
*the selected color will be the one who's luminance is closest to the desired luminance*{.muted}
`,
defaultValue: 0.2,
data: { min: 0, max: 1, step: 0.05 },
fireInitialChange: false,
onChange: () => updateColors()
},
{ {
type: "color", type: "color",
key: "colorOverride", key: "colorOverride",
@ -532,7 +562,7 @@ Dribbblish.config.register({
description: "The Color of the Theme", description: "The Color of the Theme",
defaultValue: "#1ed760", defaultValue: "#1ed760",
fireInitialChange: false, fireInitialChange: false,
onChange: (val) => updateColors() onChange: () => updateColors()
} }
] ]
}); });
@ -540,7 +570,7 @@ Dribbblish.config.register({
Dribbblish.config.register({ Dribbblish.config.register({
area: "Theme", area: "Theme",
type: "select", type: "select",
data: { dark: "Dark", light: "Light", time: "Based on Time", color: "Based on Color" }, data: { dark: "Dark", light: "Light", time: "Based on Time" },
key: "theme", key: "theme",
name: "Theme", name: "Theme",
description: "Select Dark / Bright mode", description: "Select Dark / Bright mode",
@ -560,9 +590,6 @@ Dribbblish.config.register({
case "time": case "time":
checkDarkLightMode(); checkDarkLightMode();
break; break;
case "color":
checkDarkLightMode();
break;
} }
}, },
children: [ children: [
@ -587,19 +614,8 @@ Dribbblish.config.register({
] ]
}); });
var currentSideColor; function updateColors(checkDarkMode = true, sideColHex) {
if (sideColHex == undefined) return registerCoverListener();
function updateColors(sideColHex, checkDarkMode = true) {
if (sideColHex) {
currentSideColor = sideColHex;
} else {
if (!currentSideColor) return; // If `updateColors()` is called early these vars are undefined and would break
sideColHex = currentSideColor;
}
if (!Dribbblish.config.get("dynamicColors")) {
sideColHex = Dribbblish.config.get("colorOverride");
}
let isLightBg = isLight(textColorBg); let isLightBg = isLight(textColorBg);
let textColHex = sideColHex; let textColHex = sideColHex;
@ -653,7 +669,6 @@ async function songchange() {
let bgImage = Spicetify.Player.data.track.metadata.image_url; let bgImage = Spicetify.Player.data.track.metadata.image_url;
if (bgImage === undefined) { if (bgImage === undefined) {
bgImage = "/images/tracklist-row-song-fallback.svg"; bgImage = "/images/tracklist-row-song-fallback.svg";
updateColors("#509bf5");
} }
if (album_uri !== undefined && !album_uri.includes("spotify:show")) { if (album_uri !== undefined && !album_uri.includes("spotify:show")) {
@ -698,19 +713,25 @@ async function pickCoverColor(img) {
sidebarColor = "#509bf5"; sidebarColor = "#509bf5";
if (img.complete) { if (img.complete) {
const dominant = colorThief.getColor(img); const palette = Object.fromEntries([colorThief.getColor(img), ...colorThief.getPalette(img, 24, 5)].map((c) => chroma(c)).map((c) => [c.luminance(), c]));
let palette = colorThief.getPalette(img); const colorSelectionMode = Dribbblish.config.get("colorSelectionMode");
palette.unshift(dominant); if (colorSelectionMode == "dynamic") {
sidebarColor = chroma(dominant).hex(); sidebarColor = Object.values(palette)[0];
for (const col of palette) { for (const col of Object.values(palette)) {
const chrmCol = chroma(col); if (col.luminance() > 0.05 && col.luminance() < 0.9) {
if (chrmCol.luminance() > 0.05 && chrmCol.luminance() < 0.9) { sidebarColor = col.hex();
sidebarColor = chrmCol.hex(); break;
break; }
} }
} else if (colorSelectionMode == "dynamicLuminance") {
const wantedLuminance = $("html").css("--is_light") == "1" ? Dribbblish.config.get("lightModeLuminance") : Dribbblish.config.get("darkModeLuminance");
sidebarColor = palette[getClosestToNum(Object.keys(palette), wantedLuminance)].hex();
} else if (colorSelectionMode == "static") {
sidebarColor = Dribbblish.config.get("colorOverride");
} }
} }
updateColors(sidebarColor);
updateColors(false, sidebarColor);
} }
var coverListener; var coverListener;