Monochrome icons
-
This modification changes the hue of all web panel icons and makes them monochrome. The panel becomes overtly busy and the colors are all over the place with web panels, therefore it makes sense toning them down somewhat and letting them blend in more. We could do this with pure CSS of course, but this mod calculates the hue‐change and automatically adapts when switching, editing, and installing themes.
monochrome-icons.js
// Monochrome icons // version 2024.11.1 // https://forum.vivaldi.net/post/791344 // Makes web panel thumbnails monochrome depending on theme colors. (async function monochrome_icons() { "use strict"; function convert(srgb) { const val = srgb.slice(11, -1).trim().split(/\s+/); const r = Math.round(parseFloat(val[0]) * 255); const g = Math.round(parseFloat(val[1]) * 255); const b = Math.round(parseFloat(val[2]) * 255); const calc = (Math.atan2(Math.sqrt(3) * (g - b), 2 * r - g - b) * 180) / Math.PI; return (calc - 38.71).toFixed(2); } function theme(css) { const color = document.getElementById("main"); color.style = "color: color-mix(in hsl, var(--colorFgFadedMost) 70%, var(--colorHighlightBg));"; const srgb = getComputedStyle(color).getPropertyValue("color"); color.removeAttribute("style"); const hue = convert(srgb); console.info(`hue-change: ${hue}°`); css.innerHTML = ` .button-toolbar-webpanel img { filter: brightness(0.77) sepia(1) hue-rotate(${hue}deg); } #browser.isblurred.dim-blurred .button-toolbar-webpanel img { filter: brightness(0.77) sepia(1) hue-rotate(${hue}deg) opacity(0.65) !important; } `; } const add_style = (id) => { const style = document.createElement("style"); style.setAttribute("type", "text/css"); style.id = id; document.head.appendChild(style); return document.getElementById(id); }; const wait = () => { return new Promise((resolve) => { const check = document.getElementById("browser"); if (check) return resolve(check); else { const startup = new MutationObserver(() => { const el = document.getElementById("browser"); if (el) { startup.disconnect(); resolve(el); } }); startup.observe(document.body, { childList: true, subtree: true }); } }); }; const lazy = (el, observer) => { observer.observe(el, { attributes: true, attributeFilter: ["style"] }); }; await wait().then((browser) => { const css = add_style("vm-mi-style"); theme(css); const lazy_obs = new MutationObserver(() => { lazy_obs.disconnect(); setTimeout(() => { theme(css); lazy(browser, lazy_obs); }, 300); }); lazy(browser, lazy_obs); }); })();
Currently this modification changes web panel icons only, but you might as well expand it to include extension icons by adding
.toolbar-extensions img
to the CSS. Generally it can be applied to all images in the UI.History
2024.11.0 Release
2024.11.1 Mix color on main instead of menu (bug hunted down by @AltCode) -
Looks like a great mod!
... But unfortunately, I'm getting the following error on the console when I try to run it:
Uncaught (in promise) TypeError: Cannot set properties of null (setting 'style') at theme (monochrome-icons.js:21:17) at monochrome-icons.js:68:5 at async monochrome_icons (monochrome-icons.js:66:3)
I get this error on a fresh profile too, btw.
EDIT: I managed to fix it by changing line 20 into the following:
const color = document.querySelector("#main");
Great mod!
-
Good effort.
The calculation is more off in my themes than your examples though
--colorFg
= #898480
Returns = #a08270
-
@AltCode Good point,
.vivaldi
is the menu button and it doesn’t have to be there… Will change this around.@sjudenim The color is a mix between the faded foreground and the highlight color in hsl color space. It will have different results depending on the colors, but should always fit the general vibe of the theme.
-
@luetage Oops, yeah. On macOS that button is certainly never there
-
@luetage
The calculation results look a bit strange in my theme
-
@tam710562 Could you share the theme please?
About the calculation: The color is generated by mixing
--colorFgFadedMost
and--colorHighlightBg
7 to 3 in hsl colorspace. The icon’s sepia version’s hue is then rotated until it reaches the new target hue. It looks like your fg color has a red hue. If you want just the hue of your highlight color, change out--colorFgFadedMost
for--colorHighlightBg
; or change the percentage, or change the color space. -
@luetage This is the theme I am using
{ "accentFromPage": true, "accentOnWindow": false, "accentSaturationLimit": 1, "alpha": 1, "backgroundImage": "chrome://vivaldi-data/desktop-image/0", "backgroundPosition": "stretch", "blur": 0, "colorAccentBg": "#760103", "colorBg": "#2e2e2e", "colorFg": "#cdc8c0", "colorHighlightBg": "#4f75fc", "colorWindowBg": "#1D1E21", "contrast": 0, "dimBlurred": true, "engineVersion": 1, "id": "ddd5ea1b-38e1-47f6-992e-6322e129c00c", "name": "Vivaldi Dark", "preferSystemAccent": false, "radius": 0, "simpleScrollbar": false, "transparencyTabBar": false, "transparencyTabs": false, "url": "", "version": 1 }
Maybe I understand why the result is that color.
-
Yeah, I tried out the theme and took a screenshot. The binary clock widget uses the same color mix for its circles for comparison.
The interesting thing is that we don't get the same result, although we use the same theme and the same mod. This is the default Vivaldi dark theme ☛
-
That colour mix doesn't seem to have any affect on the final result. I tried different combinations and even removed it, they all gave the same result
-
@sjudenim Can’t be. This would mean hue is not defined, the function would throw an error and you would have default icons. To reproduce I would need steps. The theme you are using and the exact edits to the code. What happens when you switch through your existing themes? Does the hue change?
-
I meant that I replaced the colour mix and put just a single base colour. The results always seem to over colourize regardless. Adjusting the saturation seems to help
-
@sjudenim The color mix produces srgb format, the rest of the code depends on that. So you should keep the color mix, else the program has to be rewritten. But you can of course mix other colors, or mix just a single color. But when you edit the mix in any way, the result should change, speak the hue angle. You can check that in the console, it logs the change. And yes, of course you can play with saturation, brightness, and opacity in the CSS. I still am not sure why tam710562 gets a different result, that’s why I would be interested in looking into it. But I need the themes and the setup. Theoretically this shouldn’t depend on platform.
-
With a bunch of tinkering I've gotten to a result that is close enough. The only down side is that with some themes it isn't as bright as the other icons but I'm fine with that since adding brightness then makes darker ones to light
"color: color-mix(in hsl, var(--colorAccentFg) 50%, var(--colorFg));";
.button-toolbar-webpanel img { filter: brightness(0.77) sepia(1) hue-rotate(${hue}deg) saturate(.3); }
-
This looks indeed pretty awesome.
Unfortunately it doesn't work on my end
Vivaldi Version is: 7.0.3495.10 (Stable channel) stable (64-bit)Dev tools return this error:
monochrome-icons.js:57 Uncaught (in promise) TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'. at monochrome-icons.js:57:17 at new Promise (<anonymous>) at wait (monochrome-icons.js:46:12) at monochrome_icons (monochrome-icons.js:66:9) at monochrome-icons.js:78:3
-
@captcapslock1338 That’s the function which waits for the browser to load. It adds an observer to
document.body
. This should be a node. What happens when you open a new Vivaldi window after the original one? The difference is that modifications are loaded last in additional browser windows. Could give a hint.It should work nevertheless. Are you sure you copied the whole code? It’s easy to miss a bracket. Use the button to copy the code in the top right of the code view when in doubt.
-
That is AWESOME mate, just a quick question:
Can we improve the contrast (More darker dark areas and lighter whites)? if yes how?
here is my setup: -
@ekozcifci Yes, you can for example increase the brightness in line 29. You could also add contrast to the filter and play around with that ☛ https://developer.mozilla.org/en-US/docs/Web/CSS/filter-function/contrast
-
I made a mod for truly monochrome icons: https://github.com/JoyHak/customize-vivaldi-buttons