make sass functions available in js & color playlist visualizer

This commit is contained in:
Send_Nukez 2022-01-23 11:03:40 +01:00
parent 36fe1f5a2f
commit 316e7581cf
12 changed files with 3982 additions and 143 deletions

3
.babelrc Normal file
View file

@ -0,0 +1,3 @@
{
"presets": ["@babel/env"]
}

View file

@ -8,3 +8,4 @@ Improved:
- Add `embedWidgetGenerator` modals to custom modal styles. (Things like the [spicetify-marketplace](https://github.com/CharlieS1103/spicetify-marketplace) options) - Add `embedWidgetGenerator` modals to custom modal styles. (Things like the [spicetify-marketplace](https://github.com/CharlieS1103/spicetify-marketplace) options)
- Changed custom app tab styles to fit in with the theme - Changed custom app tab styles to fit in with the theme
- Changed notification styles to fit in with other elements of the theme - Changed notification styles to fit in with other elements of the theme
- The visualizer icon when playing a song from a playlist is now colored

3723
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -6,6 +6,8 @@
"url": "https://github.com/JulienMaille/dribbblish-dynamic-theme/issues" "url": "https://github.com/JulienMaille/dribbblish-dynamic-theme/issues"
}, },
"devDependencies": { "devDependencies": {
"@babel/preset-env": "^7.16.5",
"@babel/register": "^7.16.5",
"@material-icons/svg": "^1.0.22", "@material-icons/svg": "^1.0.22",
"clean-webpack-plugin": "^4.0.0", "clean-webpack-plugin": "^4.0.0",
"sass": "^1.43.5", "sass": "^1.43.5",
@ -14,7 +16,7 @@
"webpack-cli": "^4.9.0" "webpack-cli": "^4.9.0"
}, },
"scripts": { "scripts": {
"build": "webpack --mode=development" "build": "webpack"
}, },
"dependencies": { "dependencies": {
"chroma-js": "^2.1.2", "chroma-js": "^2.1.2",

131
src/icons/equaliser.svg Normal file
View file

@ -0,0 +1,131 @@
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 24'>
<defs>
<style>
@keyframes play {
0% {
transform: scaleY(1);
}
3.3% {
transform: scaleY(0.9583);
}
6.6% {
transform: scaleY(0.9166);
}
9.9% {
transform: scaleY(0.8333);
}
13.3% {
transform: scaleY(0.7083);
}
16.6% {
transform: scaleY(0.5416);
}
19.9% {
transform: scaleY(0.4166);
}
23.3% {
transform: scaleY(0.25);
}
26.6% {
transform: scaleY(0.1666);
}
29.9% {
transform: scaleY(0.125);
}
33.3% {
transform: scaleY(0.125);
}
36.6% {
transform: scaleY(0.1666);
}
39.9% {
transform: scaleY(0.1666);
}
43.3% {
transform: scaleY(0.2083);
}
46.6% {
transform: scaleY(0.2916);
}
49.9% {
transform: scaleY(0.375);
}
53.3% {
transform: scaleY(0.5);
}
56.6% {
transform: scaleY(0.5833);
}
59.9% {
transform: scaleY(0.625);
}
63.3% {
transform: scaleY(0.6666);
}
66.6% {
transform: scaleY(0.6666);
}
69.9% {
transform: scaleY(0.6666);
}
73.3% {
transform: scaleY(0.6666);
}
76.6% {
transform: scaleY(0.7083);
}
79.9% {
transform: scaleY(0.75);
}
83.3% {
transform: scaleY(0.8333);
}
86.6% {
transform: scaleY(0.875);
}
89.9% {
transform: scaleY(0.9166);
}
93.3% {
transform: scaleY(0.9583);
}
96.6% {
transform: scaleY(1);
}
}
svg[icon-type="dribbblish"][icon-name="equaliser"] > rect[i="0"] {
transform-origin: bottom;
animation: play 0.9s -0.51s infinite;
}
svg[icon-type="dribbblish"][icon-name="equaliser"] > rect[i="1"] {
transform-origin: bottom;
animation: play 0.9s infinite;
}
svg[icon-type="dribbblish"][icon-name="equaliser"] > rect[i="2"] {
transform-origin: bottom;
animation: play 0.9s -0.15s infinite;
}
svg[icon-type="dribbblish"][icon-name="equaliser"] > rect[i="3"] {
transform-origin: bottom;
animation: play 0.9s -0.75s infinite;
}
</style>
</defs>
<rect fill="currentColor" i="0" class='cls-1' width='4' height='24'/>
<rect fill="currentColor" i="1" class='cls-1' x='6' width='4' height='24'/>
<rect fill="currentColor" i="2" class='cls-1' x='12' width='4' height='24'/>
<rect fill="currentColor" i="3" class='cls-1' x='18' width='4' height='24'/>
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -17,8 +17,8 @@ export default class Icons {
/** @type {Object.<String, Object.<IconStyle, String>>} */ /** @type {Object.<String, Object.<IconStyle, String>>} */
#icons; #icons;
constructor() { constructor(icons) {
this.#icons = process.env.DRIBBBLISH_ICONS; this.#icons = icons ?? process.env.DRIBBBLISH_ICONS;
} }
/** /**
@ -90,14 +90,16 @@ export default class Icons {
if (options.className != "") svg.attributes.class = options.className; if (options.className != "") svg.attributes.class = options.className;
// Add Styles // Add Styles
// Create CSSStyleDeclaration by creating an element since there is no constructor for it const styles = {};
const styles = document.createElement("a").style;
if (options.scale != 1) { if (options.scale != 1) {
styles.transform = `scale(${options.scale})`; styles["transform"] = `scale(${options.scale})`;
styles.transformOrigin = "center"; styles["transform-origin"] = "center";
} }
const styleStr = Object.entries(styles)
.map(([prop, val]) => `${prop}: ${val};`)
.join(" ");
svg.children = svg.children.map((child) => { svg.children = svg.children.map((child) => {
if (styles.cssText != "") child.attributes.style = styles.cssText; if (styleStr != "") child.attributes.style = styleStr;
return child; return child;
}); });

13
src/js/SassUtil.js Normal file
View file

@ -0,0 +1,13 @@
export function lightOffset(n, offset) {
return `calc(${n} + ${offset} * var(--is_light))`;
}
export function spiceColor(key, alpha = 1, _lightOffset = 0) {
if (alpha == 1) {
return `var(--spice-${key})`;
} else if (_lightOffset == 0) {
return `rgba(var(--spice-rgb-${key}), ${alpha})`;
} else {
return `rgba(var(--spice-rgb-${key}), ${lightOffset(alpha, _lightOffset)})`;
}
}

View file

@ -12,6 +12,7 @@ $("html").attr("dribbblish-js-installed", "");
import { waitForElement, copyToClipboard, capitalizeFirstLetter, getClosestToNum, randomFromArray, debounce } from "./Util"; import { waitForElement, copyToClipboard, capitalizeFirstLetter, getClosestToNum, randomFromArray, debounce } from "./Util";
import { default as _Dribbblish } from "./Dribbblish"; import { default as _Dribbblish } from "./Dribbblish";
import "./Folders"; import "./Folders";
import { spiceColor } from "./SassUtil";
// To expose to external scripts // To expose to external scripts
const Dribbblish = new _Dribbblish(); const Dribbblish = new _Dribbblish();
@ -47,8 +48,8 @@ Dribbblish.on("ready", () => {
? { ? {
icon: "settings", icon: "settings",
color: { color: {
fg: "var(--spice-subtext)", fg: spiceColor("subtext"),
bg: "rgba(var(--spice-rgb-subtext), calc(0.1 + var(--is_light) * 0.05))" bg: spiceColor("subtext", 0.1, 0.05)
}, },
order: 999, order: 999,
tooltip: "Open Dribbblish Settings", tooltip: "Open Dribbblish Settings",

View file

@ -44,16 +44,3 @@ $props-to-transition: ("sidebar", "main", "text", "button");
transition: all var(--song-transition-speed) linear; transition: all var(--song-transition-speed) linear;
transition-property: $props; transition-property: $props;
} }
// $key: the key of the color, e.g. "main"
// $alpha: tha alpha in rgba()
// $light-offset: added when in light mode
@function spiceColor($key, $alpha: 1, $light-offset: 0) {
@if $alpha == 1 {
@return var(--spice-#{$key});
} @else if $light-offset == 0 {
@return rgba(var(--spice-rgb-#{$key}), $alpha);
} @else {
@return rgba(var(--spice-rgb-#{$key}), lightOffset($alpha, $light-offset));
}
}

View file

@ -3,11 +3,6 @@
@return #{"invert("}$v#{")"}; @return #{"invert("}$v#{")"};
} }
// returns $n and adds $offset when the theme is light
@function lightOffset($n, $offset) {
@return calc($n + $offset * var(--is_light));
}
@mixin spiceShadow() { @mixin spiceShadow() {
box-shadow: 0px 0px 8px spiceColor("subtext", 0.1, 0.1); box-shadow: 0px 0px 8px spiceColor("subtext", 0.1, 0.1);
} }

View file

@ -135,9 +135,15 @@
box-shadow: 0 4px 20px #21212130; box-shadow: 0 4px 20px #21212130;
} }
.main-trackList-rowMarker {
color: spiceColor("text");
}
.main-trackList-playingIcon { .main-trackList-playingIcon {
-webkit-mask-image: url(icon64("equaliser", '{"size": 14}'));
background-color: currentColor;
content-visibility: hidden;
image-rendering: pixelated; image-rendering: pixelated;
filter: grayscale(1);
} }
.main-trackList-trackListRowGrid { .main-trackList-trackListRowGrid {

View file

@ -1,14 +1,17 @@
const webpack = require("webpack"); import webpack from "webpack";
const sass = require("sass"); import sass from "sass";
const { CleanWebpackPlugin } = require("clean-webpack-plugin"); import { CleanWebpackPlugin } from "clean-webpack-plugin";
const path = require("path"); import path from "path";
const fs = require("fs"); import fs from "fs";
const icons = {}; import Icons from "./src/js/Icons";
import { lightOffset, spiceColor } from "./src/js/SassUtil";
const _icons = {};
function addIcon(name, style, path) { function addIcon(name, style, path) {
name = name.replace(/_/g, "-"); name = name.replace(/_/g, "-");
if (!icons.hasOwnProperty(name)) icons[name] = {}; if (!_icons.hasOwnProperty(name)) _icons[name] = {};
icons[name][style] = fs.readFileSync(path, { encoding: "utf8" }); _icons[name][style] = fs.readFileSync(path, { encoding: "utf8" });
} }
// Add Material Icons // Add Material Icons
let iconDir = path.resolve(__dirname, "node_modules/@material-icons/svg/svg"); let iconDir = path.resolve(__dirname, "node_modules/@material-icons/svg/svg");
@ -23,8 +26,11 @@ for (const icon of fs.readdirSync(iconDir)) {
addIcon(icon.replace(/\..*?$/, ""), "custom", path.resolve(iconDir, icon)); addIcon(icon.replace(/\..*?$/, ""), "custom", path.resolve(iconDir, icon));
} }
const icons = new Icons(_icons);
/** @type {import('webpack').Configuration} */ /** @type {import('webpack').Configuration} */
module.exports = { const config = {
mode: "development",
entry: [path.resolve(__dirname, "src/js/main.js"), path.resolve(__dirname, "src/styles/main.scss"), path.resolve(__dirname, "src/styles/Colors.scss")], entry: [path.resolve(__dirname, "src/js/main.js"), path.resolve(__dirname, "src/styles/main.scss"), path.resolve(__dirname, "src/styles/Colors.scss")],
output: { output: {
path: path.resolve(__dirname, "dist"), path: path.resolve(__dirname, "dist"),
@ -50,9 +56,20 @@ module.exports = {
sourceMap: true, sourceMap: true,
sassOptions: { sassOptions: {
functions: { functions: {
"lightOffset($n, $offset)": (n, offset) => {
return new sass.types.String(lightOffset(n.getValue(), offset.getValue()));
},
"spiceColor($key, $alpha: 1, $light-offset: 0)": (key, alpha, _lightOffset) => {
return new sass.types.String(spiceColor(key.getValue(), alpha.getValue(), _lightOffset.getValue()));
},
"font64($font)": (font) => { "font64($font)": (font) => {
const file = path.resolve(__dirname, "src/fonts", font.getValue()); const file = path.resolve(__dirname, "src/fonts", font.getValue());
return new sass.types.String(`"data:font/truetype;charset=utf-8;base64,${fs.readFileSync(file, { encoding: "base64" })}"`); return new sass.types.String(`"data:font/truetype;charset=utf-8;base64,${fs.readFileSync(file, { encoding: "base64" })}"`);
},
'icon64($name, $options: "{}")': (name, options) => {
name = name.getValue();
options = JSON.parse(options.getValue());
return new sass.types.String(icons.get(name, { ...options, base64: true }));
} }
} }
} }
@ -79,7 +96,7 @@ module.exports = {
.replace(/^---(.*?\r?\n)+---(.*?\r?\n)*?(?=\S)/, "") // Replace GitHub header .replace(/^---(.*?\r?\n)+---(.*?\r?\n)*?(?=\S)/, "") // Replace GitHub header
.replace(/\*\*Desktop Setup\*\*\r?\n(- .*?\r?\n)+\r?\n/, "") // Replace **Desktop Setup** block .replace(/\*\*Desktop Setup\*\*\r?\n(- .*?\r?\n)+\r?\n/, "") // Replace **Desktop Setup** block
), ),
"process.env.DRIBBBLISH_ICONS": JSON.stringify(icons), "process.env.DRIBBBLISH_ICONS": JSON.stringify(_icons),
"process.env.DRIBBBLISH_VERSION": JSON.stringify(process.env.DRIBBBLISH_VERSION ?? "Dev"), "process.env.DRIBBBLISH_VERSION": JSON.stringify(process.env.DRIBBBLISH_VERSION ?? "Dev"),
"process.env.COMMIT_HASH": JSON.stringify(process.env.COMMIT_HASH ?? "local") "process.env.COMMIT_HASH": JSON.stringify(process.env.COMMIT_HASH ?? "local")
}), }),
@ -89,3 +106,5 @@ module.exports = {
}) })
] ]
}; };
export default config;