您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Tries to put similar colors to other parts of steam according to the theme current profile have
// ==UserScript== // @name Colorify - Steam Profiles // @namespace tech.kobb.steam.colorify // @version 0.1 // @description Tries to put similar colors to other parts of steam according to the theme current profile have // @author kb // @match *://*.steamcommunity.com/id/* // @icon https://www.google.com/s2/favicons?sz=64&domain=steamcommunity.com // @grant none // @license GNU GPLv3 // @run-at document-idle // ==/UserScript== (async function() { 'use strict'; // url check if(document.querySelector('.error_ctn')) return; // id exists let p = location.pathname.split('/').splice(1); if(p[p.length-1] === "") p.pop(); if(p[0].toLowerCase() !== 'id' || p.length !== 2) return // valid path p=undefined; //other checks if(getComputedStyle(document.body).getPropertyValue('--btn-outline') === '') return; // no theme applied // ------------------------------------------------ class Color { constructor(r, g, b) { this.set(r, g, b); } toString() { return `rgb(${Math.round(this.r)}, ${Math.round(this.g)}, ${Math.round(this.b)})`; } set(r, g, b) { this.r = this.clamp(r); this.g = this.clamp(g); this.b = this.clamp(b); } hueRotate(angle = 0) { angle = angle / 180 * Math.PI; const sin = Math.sin(angle); const cos = Math.cos(angle); this.multiply([ 0.213 + cos * 0.787 - sin * 0.213, 0.715 - cos * 0.715 - sin * 0.715, 0.072 - cos * 0.072 + sin * 0.928, 0.213 - cos * 0.213 + sin * 0.143, 0.715 + cos * 0.285 + sin * 0.140, 0.072 - cos * 0.072 - sin * 0.283, 0.213 - cos * 0.213 - sin * 0.787, 0.715 - cos * 0.715 + sin * 0.715, 0.072 + cos * 0.928 + sin * 0.072, ]); } grayscale(value = 1) { this.multiply([ 0.2126 + 0.7874 * (1 - value), 0.7152 - 0.7152 * (1 - value), 0.0722 - 0.0722 * (1 - value), 0.2126 - 0.2126 * (1 - value), 0.7152 + 0.2848 * (1 - value), 0.0722 - 0.0722 * (1 - value), 0.2126 - 0.2126 * (1 - value), 0.7152 - 0.7152 * (1 - value), 0.0722 + 0.9278 * (1 - value), ]); } sepia(value = 1) { this.multiply([ 0.393 + 0.607 * (1 - value), 0.769 - 0.769 * (1 - value), 0.189 - 0.189 * (1 - value), 0.349 - 0.349 * (1 - value), 0.686 + 0.314 * (1 - value), 0.168 - 0.168 * (1 - value), 0.272 - 0.272 * (1 - value), 0.534 - 0.534 * (1 - value), 0.131 + 0.869 * (1 - value), ]); } saturate(value = 1) { this.multiply([ 0.213 + 0.787 * value, 0.715 - 0.715 * value, 0.072 - 0.072 * value, 0.213 - 0.213 * value, 0.715 + 0.285 * value, 0.072 - 0.072 * value, 0.213 - 0.213 * value, 0.715 - 0.715 * value, 0.072 + 0.928 * value, ]); } multiply(matrix) { const newR = this.clamp(this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2]); const newG = this.clamp(this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5]); const newB = this.clamp(this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8]); this.r = newR; this.g = newG; this.b = newB; } brightness(value = 1) { this.linear(value); } contrast(value = 1) { this.linear(value, -(0.5 * value) + 0.5); } linear(slope = 1, intercept = 0) { this.r = this.clamp(this.r * slope + intercept * 255); this.g = this.clamp(this.g * slope + intercept * 255); this.b = this.clamp(this.b * slope + intercept * 255); } invert(value = 1) { this.r = this.clamp((value + this.r / 255 * (1 - 2 * value)) * 255); this.g = this.clamp((value + this.g / 255 * (1 - 2 * value)) * 255); this.b = this.clamp((value + this.b / 255 * (1 - 2 * value)) * 255); } hsl() { // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA. const r = this.r / 255; const g = this.g / 255; const b = this.b / 255; const max = Math.max(r, g, b); const 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: h * 100, s: s * 100, l: l * 100, }; } clamp(value) { if (value > 255) { value = 255; } else if (value < 0) { value = 0; } return value; } } class Solver { constructor(target, baseColor) { this.target = target; this.targetHSL = target.hsl(); this.reusedColor = new Color(0, 0, 0); } solve() { const result = this.solveNarrow(this.solveWide()); return { values: result.values, loss: result.loss, filter: this.css(result.values), }; } solveWide() { const A = 5; const c = 15; const a = [60, 180, 18000, 600, 1.2, 1.2]; let best = { loss: Infinity }; for (let i = 0; best.loss > 25 && i < 3; i++) { const initial = [50, 20, 3750, 50, 100, 100]; const result = this.spsa(A, a, c, initial, 1000); if (result.loss < best.loss) { best = result; } } return best; } solveNarrow(wide) { const A = wide.loss; const c = 2; const A1 = A + 1; const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1]; return this.spsa(A, a, c, wide.values, 500); } spsa(A, a, c, values, iters) { const alpha = 1; const gamma = 0.16666666666666666; let best = null; let bestLoss = Infinity; const deltas = new Array(6); const highArgs = new Array(6); const lowArgs = new Array(6); for (let k = 0; k < iters; k++) { const ck = c / Math.pow(k + 1, gamma); for (let i = 0; i < 6; i++) { deltas[i] = Math.random() > 0.5 ? 1 : -1; highArgs[i] = values[i] + ck * deltas[i]; lowArgs[i] = values[i] - ck * deltas[i]; } const lossDiff = this.loss(highArgs) - this.loss(lowArgs); for (let i = 0; i < 6; i++) { const g = lossDiff / (2 * ck) * deltas[i]; const ak = a[i] / Math.pow(A + k + 1, alpha); values[i] = fix(values[i] - ak * g, i); } const loss = this.loss(values); if (loss < bestLoss) { best = values.slice(0); bestLoss = loss; } } return { values: best, loss: bestLoss }; function fix(value, idx) { let max = 100; if (idx === 2 /* saturate */) { max = 7500; } else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) { max = 200; } if (idx === 3 /* hue-rotate */) { if (value > max) { value %= max; } else if (value < 0) { value = max + value % max; } } else if (value < 0) { value = 0; } else if (value > max) { value = max; } return value; } } loss(filters) { // Argument is array of percentages. const color = this.reusedColor; color.set(0, 0, 0); color.invert(filters[0] / 100); color.sepia(filters[1] / 100); color.saturate(filters[2] / 100); color.hueRotate(filters[3] * 3.6); color.brightness(filters[4] / 100); color.contrast(filters[5] / 100); const colorHSL = color.hsl(); return ( Math.abs(color.r - this.target.r) + Math.abs(color.g - this.target.g) + Math.abs(color.b - this.target.b) + Math.abs(colorHSL.h - this.targetHSL.h) + Math.abs(colorHSL.s - this.targetHSL.s) + Math.abs(colorHSL.l - this.targetHSL.l) ); } css(filters) { function fmt(idx, multiplier = 1) { return Math.round(filters[idx] * multiplier); } return `invert(${fmt(0)}%) sepia(${fmt(1)}%) saturate(${fmt(2)}%) hue-rotate(${fmt(3, 3.6)}deg) brightness(${fmt(4)}%) contrast(${fmt(5)}%);`; } } function hexToRgb(hex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; hex = hex.replace(shorthandRegex, (m, r, g, b) => { return r + r + g + g + b + b; }); const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); return result ? [ parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16), ] : null; } /** /|\ Code made by Barrett Sonntag / | \ https://codepen.io/sosuke/pen/Pjoqqp | Credits to this person. */ const getMainColor = () => { const raw = getComputedStyle(document.body).getPropertyValue('--btn-outline'); if(raw.includes("#")) return hexToRgb(raw); else if(raw.includes('rgb')) return raw.split('(')[1].split(')')[0].split(', ').map(c => Number(c)) return null; } const getFilterColor = () => { const col = new Color(...getMainColor()) const solver = new Solver(col); const result = solver.solve(); return result.filter; } const filterColor = getFilterColor() let finished = false; let styles = {} const applyStyles = (selector, s) => { if(finished) return; if(!styles[selector]) styles[selector] = [] styles[selector].push(...s) } const finishStyle = () => { if(finished) return; const styleElem = document.createElement('style') let rawStyle = [ "/*", ...[ "Style autogenerated by userscript", "Making steam [a little bit] better (lol)", "https://kobb.tech", "", "~2023" ].map(e => `\t${e}`), "*/" ].join('\n') for(let [sel,sty] of Object.entries(styles)){ rawStyle+=`${sel} {` for(let [k,v] of sty) rawStyle+=`${k}: ${v}; `; rawStyle+=`}` } styleElem.innerHTML = rawStyle; document.head.appendChild(styleElem); } applyStyles('div#global_header', [ ["background", "transparent"], ["color", "blue"] ]) applyStyles('div#global_header > div.content', [ ["background", "transparent"] ]) applyStyles('div#global_header .menuitem.supernav_active, .persona.online, .whiteLink:hover', [ ['color', 'var(--btn-outline) !important'], ]) applyStyles('div#global_header .menuitem.supernav_active::after, .playerAvatar.online, .modal_top_bar', [ ['background', 'var(--btn-outline) !important'] ]) applyStyles('span[class*="_check"], .pagebtn', [ ['filter', filterColor] ]) finishStyle(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址