iNNOKENTIY21

Silver Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Код: // ==UserScript== // @name RuBoard — Readability // @namespace iNNOKENTIY21.RuBoard // @version 2025-06-07 // @description Для темных тем. Улучшает читаемость для слишком тёмного текста на тёмном фоне. Делает текст светлее и чуть менее насыщенным. // @author iNNOKENTIY21 // @match *://forum.ru-board.com/* // @icon data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAJ1BMVEUsZLkAN4f///8UR50COYkYS6IoXbQmWbIqYbcfUKoNQZUGO40kVrEyZFNIAAAAWUlEQVQYlV3OWQ7AIAhFUR+CY/e/3opahRL9uMeYEIKd8ojrVBtcS4eFFEcbyJExgXS0gQ/07vcLwkTAuPtL7TAwTmMHYceBElfRBF2p4czaqf+gsocit/EC3nIBrTjkbJkAAAAASUVORK5CYII= // @grant none // ==/UserScript== (function () { 'use strict'; // Функция для преобразования цвета (название, hex, rgb, и.т.д.) в HSL function toHsl(color) { const cvs = document.createElement('canvas'); cvs.width = cvs.height = 1; const ctx = cvs.getContext('2d'); ctx.fillStyle = color; ctx.fillRect(0, 0, 1, 1); const computed = ctx.getImageData(0, 0, 1, 1).data; const r = computed[0]; const g = computed[1]; const b = computed[2]; return rgbToHsl(r, g, b); } // Функция для преобразования цвета из RGB в HSL function rgbToHsl(r, g, b) { r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b), min = Math.min(r, g, b); let h, s, l = (max + min) / 2; if (max === min) { h = s = 0; } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h * 360, s * 100, l * 100]; } // Функция для получения цвета фона элемента, или его родителей (первый найденный непрозрачный цвет). function getBackgroundColor(element) { let currentElement = element; while (currentElement) { const style = getComputedStyle(currentElement); const backgroundColor = style.backgroundColor; if (backgroundColor !== 'rgba(0, 0, 0, 0)' && backgroundColor !== 'transparent') { return backgroundColor; } currentElement = currentElement.parentElement; } return 'rgba(0, 0, 0, 1)'; } // Функция для получения цветов переднего и заднего плана в HSL function getColorValues(element) { const style = getComputedStyle(element); const foregroundColor = toHsl(style.color); const backgroundColor = toHsl(getBackgroundColor(element)); return { foregroundColor, backgroundColor }; } // Функция для получения уровня читаемости function isReadable(foregroundColor, backgroundColor, treshold = 4.5) { const [h1, s1, l1] = foregroundColor; const [h2, s2, l2] = backgroundColor; const luminance = (color) => { const [h, s, l] = color; return l / 100; }; const lum1 = luminance(foregroundColor); const lum2 = luminance(backgroundColor); const contrastRatio = (Math.max(lum1, lum2) + 0.05) / (Math.min(lum1, lum2) + 0.05); return contrastRatio; } function improveReadability(element, treshold, lighten, desaturate) { const elements = document.querySelectorAll(element) elements.forEach(el => { const { foregroundColor, backgroundColor } = getColorValues(el); const contrastRatio = isReadable(foregroundColor, backgroundColor); if (contrastRatio < treshold) { const adjustmentFactor = (treshold - contrastRatio) / treshold; let brightnessIncrease; switch (true) { case (contrastRatio < treshold * 0.7): brightnessIncrease = lighten * 3; break; case (contrastRatio < treshold): brightnessIncrease = lighten * 0.5; break; default: brightnessIncrease = 0; break; } foregroundColor[1] = Math.max(0, foregroundColor[1] - desaturate * adjustmentFactor); foregroundColor[2] = Math.min(100, foregroundColor[2] + brightnessIncrease * adjustmentFactor); el.style.color = `hsl(${foregroundColor[0]}, ${foregroundColor[1]}%, ${foregroundColor[2]}%)`; } }); } // Финал. Вызов функции сделать хорошо! improveReadability('font[color]', 10, 20, 20); })(); |
|