RYM Release Page Colorizer

Change specific CSS variables and elements based on album cover colors on RateYourMusic

// ==UserScript==
// @name         RYM Release Page Colorizer
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Change specific CSS variables and elements based on album cover colors on RateYourMusic
// @author       https://greasyfork.org/users/1320826-polachek
// @match        *://rateyourmusic.com/release/*
// @grant        none
// @require      https://cdnjs.cloudflare.com/ajax/libs/color-thief/2.3.0/color-thief.umd.js
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    function addGlobalStyle(css) {
        const style = document.createElement('style');
        style.type = 'text/css';
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);
    }


    function adjustColor(rgb, percent) {
        const r = Math.min(255, Math.max(0, Math.floor(rgb[0] * (1 + percent))));
        const g = Math.min(255, Math.max(0, Math.floor(rgb[1] * (1 + percent))));
        const b = Math.min(255, Math.max(0, Math.floor(rgb[2] * (1 + percent))));
        return [r, g, b];
    }


    function getLuminance(rgb) {
        const a = rgb.map(function (v) {
            v /= 255;
            return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
        });
        return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
    }

    function getContrastRatio(rgb1, rgb2) {
        const lum1 = getLuminance(rgb1);
        const lum2 = getLuminance(rgb2);
        return (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05);
    }

function adjustForContrast(bgColor, fontColor) {
    let ratio = getContrastRatio(bgColor, fontColor);
    let adjustment = 0.1; 
    let maxIterations = 20; 
    let iterations = 0; 

    const bgLuminance = getLuminance(bgColor);
    const fontLuminance = getLuminance(fontColor);

    while (ratio < 4.5 && iterations < maxIterations) { 
        fontColor = adjustColor(fontColor, (bgLuminance > fontLuminance) ? -adjustment : adjustment);
        ratio = getContrastRatio(bgColor, fontColor);
        iterations++; 
    }

    return fontColor;
}



    addGlobalStyle(`
        *, *::before, *::after {
            border: none !important;
        }
    `);

    window.addEventListener('load', function() {
        const albumCover = document.querySelector('div[class^="coverart_"] img');

        if (albumCover) {
            albumCover.crossOrigin = "Anonymous";

            albumCover.onload = function() {
                const colorThief = new ColorThief();
                const palette = colorThief.getPalette(albumCover, 5);
                const dominantColor = palette[0];
                const fontColor = palette[1];

                const dominantColorRGB = `rgb(${dominantColor[0]}, ${dominantColor[1]}, ${dominantColor[2]})`;
                const fontColorRGB = `rgb(${fontColor[0]}, ${fontColor[1]}, ${fontColor[2]})`;

                const darkerColor = adjustColor(dominantColor, -0.05);
                const darkerColorRGB = `rgb(${darkerColor[0]}, ${darkerColor[1]}, ${darkerColor[2]})`;

                const adjustedFontColor = adjustForContrast(dominantColor, fontColor);
                const adjustedFontColorRGB = `rgb(${adjustedFontColor[0]}, ${adjustedFontColor[1]}, ${adjustedFontColor[2]})`;

                addGlobalStyle(`
                    body, body * {
                        color: ${adjustedFontColorRGB};
                    }
                    a.sametitle:hover {
                        color: ${darkerColorRGB} !important;
                    }
                    #ui_search_input_main_search::placeholder {
                        color: ${adjustedFontColorRGB} !important;
                    }
                `);

                const htmlElement = document.documentElement;
                htmlElement.style.setProperty('--mono-0', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-1', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-4', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-7', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-8', adjustedFontColorRGB);
                htmlElement.style.setProperty('--monof', dominantColorRGB);
                htmlElement.style.setProperty('--mono-a', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-fb', dominantColorRGB);
                htmlElement.style.setProperty('--mono-f0', darkerColorRGB);
                htmlElement.style.setProperty('--mono-f2', darkerColorRGB);
                htmlElement.style.setProperty('--mono-f3', darkerColorRGB);
                htmlElement.style.setProperty('--mono-f4', dominantColorRGB);
                htmlElement.style.setProperty('--mono-f8', darkerColorRGB);
                htmlElement.style.setProperty('--mono-db', darkerColorRGB);
                htmlElement.style.setProperty('--mono-d8', darkerColorRGB);
                htmlElement.style.setProperty('--mono-e', darkerColorRGB);
                htmlElement.style.setProperty('--mono-d', dominantColorRGB);
                htmlElement.style.setProperty('--mono-ef', dominantColorRGB);
                htmlElement.style.setProperty('--mono-abs-3', dominantColorRGB);
                htmlElement.style.setProperty('--mono-abs-8', darkerColorRGB);
                htmlElement.style.setProperty('--mono-abs-a', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-abs-d', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-abs-f', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-4', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-5', adjustedFontColorRGB);
                htmlElement.style.setProperty('--mono-6', adjustedFontColorRGB);
                htmlElement.style.setProperty('--surface-primary-light', darkerColorRGB);
                htmlElement.style.setProperty('--surface-secondary-light', darkerColorRGB);
                htmlElement.style.setProperty('--surface-tertiary', dominantColorRGB);
                htmlElement.style.setProperty('--background', dominantColorRGB);
                htmlElement.style.setProperty('--gen-bg-lightgreen', darkerColorRGB);
                htmlElement.style.setProperty('--btn-primary-background-default', darkerColorRGB);
                htmlElement.style.setProperty('--btn-primary-background-hover', dominantColorRGB);
                htmlElement.style.setProperty('--btn-primary-background-active', adjustedFontColorRGB);
                htmlElement.style.setProperty('--btn-expand-background-default', darkerColorRGB);
                htmlElement.style.setProperty('--btn-secondary-background-hover-light', dominantColorRGB);
                htmlElement.style.setProperty('--btn-secondary-background-default-light', darkerColorRGB);
                htmlElement.style.setProperty('--header-item-link', adjustedFontColorRGB);
                htmlElement.style.setProperty('--btn-primary-text', adjustedFontColorRGB);
                htmlElement.style.setProperty('--btn-secondary-text', adjustedFontColorRGB);
                htmlElement.style.setProperty('--btn-expand-background-hover', dominantColorRGB);
                htmlElement.style.setProperty('--btn-expand-background-disabled', darkerColorRGB);
                htmlElement.style.setProperty('--link-text-default-light', dominantColorRGB);
                htmlElement.style.setProperty('--link-text-hover', darkerColorRGB);
                htmlElement.style.setProperty('--gen-blue-dark', adjustedFontColorRGB);
                htmlElement.style.setProperty('--gen-blue-darker', adjustedFontColorRGB);
                htmlElement.style.setProperty('--gen-blue-darkest', adjustedFontColorRGB);
                htmlElement.style.setProperty('--link-text-default', adjustedFontColorRGB);
                htmlElement.style.setProperty('--text-primary', adjustedFontColorRGB);
                htmlElement.style.setProperty('--header-item-link', adjustedFontColorRGB);
                htmlElement.style.setProperty('--text-secondary', adjustedFontColorRGB);


                const themeLightElement = document.querySelector('html.theme_light');
                if (themeLightElement) {
                    themeLightElement.style.setProperty('--mono-f', dominantColorRGB);
                    themeLightElement.style.setProperty('--mono-fb', dominantColorRGB);
                    themeLightElement.style.setProperty('--mono-f2', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-f3', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-f8', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-db', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-d8', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-4', adjustedFontColorRGB);
                    themeLightElement.style.setProperty('--mono-e', darkerColorRGB);
                    themeLightElement.style.setProperty('--mono-ef', dominantColorRGB);
                    themeLightElement.style.setProperty('--mono-abs-3', dominantColorRGB);
                    themeLightElement.style.setProperty('--surface-primary-light', darkerColorRGB);
                    themeLightElement.style.setProperty('--surface-secondary-light', darkerColorRGB);
                    themeLightElement.style.setProperty('--surface-tertiary', dominantColorRGB);
                    themeLightElement.style.setProperty('--background', dominantColorRGB);
                    themeLightElement.style.setProperty('--gen-bg-lightgreen', darkerColorRGB);
                }

                const releaseLeftColumn = document.querySelector('.release_left_column');
                if (releaseLeftColumn) {
                    releaseLeftColumn.style.backgroundColor = dominantColorRGB;
                    releaseLeftColumn.style.color = contrastFontColor;
                }

                const pageReleaseArtFrame = document.querySelector('.page_release_art_frame');
                if (pageReleaseArtFrame) {
                    pageReleaseArtFrame.style.backgroundColor = dominantColorRGB;
                    pageReleaseArtFrame.style.color = contrastFontColor;
                }

                const exceptions = ['.color-square', '.catalog_btn'];

                const allTextElements = document.querySelectorAll('body, body *');
                allTextElements.forEach(function(element) {
                    const isException = exceptions.some(selector => element.matches(selector));
                    if (!isException) {
                        element.style.color = adjustedFontColorRGB;
                    }
                });
            };


            if (albumCover.complete) {
                albumCover.onload();
            }
        } else {
            console.log("Capa do álbum não encontrada.");
        }
    });



    function getContrastYIQ(rgb) {
        const yiq = ((rgb[0] * 299) + (rgb[1] * 587) + (rgb[2] * 114)) / 1000;
        return (yiq >= 128) ? 'black' : 'white';
    }
})();