Improve color settings UX and re-add vibrant as option

This commit is contained in:
Send_Nukez 2021-11-17 20:22:53 +01:00
parent 784947e3a5
commit e1d393e2a0
2 changed files with 84 additions and 45 deletions

View file

@ -18,10 +18,11 @@
}, },
"dependencies": { "dependencies": {
"chroma-js": "^2.1.2", "chroma-js": "^2.1.2",
"colorthief": "^2.3.2",
"jquery": "^3.6.0", "jquery": "^3.6.0",
"markdown-it": "^12.2.0", "markdown-it": "^12.2.0",
"markdown-it-attrs": "^4.1.0", "markdown-it-attrs": "^4.1.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"colorthief": "^2.3.2" "node-vibrant": "^3.1.6"
} }
} }

View file

@ -1,3 +1,4 @@
import * as Vibrant from "node-vibrant";
import ColorThief from "colorthief"; import ColorThief from "colorthief";
import chroma from "chroma-js"; import chroma from "chroma-js";
import $ from "jquery"; import $ from "jquery";
@ -473,7 +474,6 @@ function getImageLightness(img) {
// parse to hex because "--spice-sidebar" is `rgb()` // parse to hex because "--spice-sidebar" is `rgb()`
let textColorBg = chroma($("html").css("--spice-main")).hex(); let textColorBg = chroma($("html").css("--spice-main")).hex();
let sidebarColor = chroma($("html").css("--spice-sidebar")).hex();
function setRootColor(name, color) { function setRootColor(name, color) {
$("html").css(`--spice-${name}`, chroma(color).hex()); $("html").css(`--spice-${name}`, chroma(color).hex());
@ -517,44 +517,22 @@ setInterval(checkDarkLightMode, 60000);
Dribbblish.config.register({ Dribbblish.config.register({
area: "Theme", area: "Theme",
type: "select", type: "select",
key: "colorSelectionMode", key: "colorSelectionAlgorithm",
name: "Color Selection Mode", name: "Color Selection Algorithm",
description: "Method of selecting colors from the albumart", description: `
data: { dynamic: "Dynamic", dynamicLuminance: "Dynamic (Luminance)", static: "Static" }, Algorithm of selecting colors from the albumart
defaultValue: "dynamic", - **Colorthief:** Gets more fitting colors{.muted}
- **Vibrant:** Gets more vibrant colors (was the default up to v3.1.1){.muted}
- **Static:** Select a static color to be used{.muted}
`,
data: { colorthief: "Colorthief", vibrant: "Vibrant", static: "Static" },
defaultValue: "colorthief",
onChange: () => updateColors(), onChange: () => updateColors(),
showChildren: (val) => { showChildren: (val) => {
if (val == "dynamicLuminance") return ["lightModeLuminance", "darkModeLuminance"];
if (val == "static") return ["colorOverride"]; if (val == "static") return ["colorOverride"];
return false; return ["colorSelectionMode"];
}, },
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",
@ -563,6 +541,52 @@ Dribbblish.config.register({
defaultValue: "#1ed760", defaultValue: "#1ed760",
fireInitialChange: false, fireInitialChange: false,
onChange: () => updateColors() onChange: () => updateColors()
},
{
area: "Theme",
type: "select",
key: "colorSelectionMode",
name: "Color Selection Mode",
description: `
Method of selecting colors from the albumart
- **Default:** Choose closest matching{.muted}
- **Luminance:** Choose matching current theme (lighter/darker){.muted}
`,
data: { default: "Default", luminance: "Luminance" },
defaultValue: "default",
onChange: () => updateColors(),
showChildren: (val) => {
if (val == "dynamicLuminance") return ["lightModeLuminance", "darkModeLuminance"];
return false;
},
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()
}
]
} }
] ]
}); });
@ -711,27 +735,41 @@ async function pickCoverColor(img) {
$("html").css("--image-brightness", getImageLightness(img) / 255); $("html").css("--image-brightness", getImageLightness(img) / 255);
sidebarColor = "#509bf5"; let color = "#509bf5";
if (img.complete) { if (img.complete) {
const palette = Object.fromEntries([colorThief.getColor(img), ...colorThief.getPalette(img, 24, 5)].map((c) => chroma(c)).map((c) => [c.luminance(), c])); const colorSelectionAlgorithm = Dribbblish.config.get("colorSelectionAlgorithm");
const colorSelectionMode = Dribbblish.config.get("colorSelectionMode"); const colorSelectionMode = Dribbblish.config.get("colorSelectionMode");
if (colorSelectionMode == "dynamic") { let palette = {};
sidebarColor = Object.values(palette)[0];
if (colorSelectionAlgorithm == "colorthief") {
palette = Object.fromEntries([colorThief.getColor(img), ...colorThief.getPalette(img, 24, 5)].map((c) => chroma(c)).map((c) => [c.luminance(), c]));
} else if (colorSelectionAlgorithm == "vibrant") {
const swatches = await new Promise((resolve, reject) => new Vibrant(img, 5).getPalette().then(resolve).catch(reject));
for (var col of ["Vibrant", "DarkVibrant", "Muted", "LightVibrant"]) {
if (swatches[col]) {
const c = chroma(swatches[col].getHex());
palette[c.luminance()] = c;
}
}
} else if (colorSelectionAlgorithm == "static") {
palette[1] = chroma(Dribbblish.config.get("colorOverride"));
}
if (colorSelectionMode == "default") {
color = Object.values(palette)[0];
for (const col of Object.values(palette)) { for (const col of Object.values(palette)) {
if (col.luminance() > 0.05 && col.luminance() < 0.9) { if (col.luminance() > 0.05 && col.luminance() < 0.9) {
sidebarColor = col.hex(); color = col.hex();
break; break;
} }
} }
} else if (colorSelectionMode == "dynamicLuminance") { } else if (colorSelectionMode == "luminance") {
const wantedLuminance = $("html").css("--is_light") == "1" ? Dribbblish.config.get("lightModeLuminance") : Dribbblish.config.get("darkModeLuminance"); const wantedLuminance = $("html").css("--is_light") == "1" ? Dribbblish.config.get("lightModeLuminance") : Dribbblish.config.get("darkModeLuminance");
sidebarColor = palette[getClosestToNum(Object.keys(palette), wantedLuminance)].hex(); color = palette[getClosestToNum(Object.keys(palette), wantedLuminance)].hex();
} else if (colorSelectionMode == "static") {
sidebarColor = Dribbblish.config.get("colorOverride");
} }
} }
updateColors(false, sidebarColor); updateColors(false, color);
} }
var coverListener; var coverListener;