您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automaticly color changer, Written by ai
当前为
// ==UserScript== // @name Web3 OKX Color Theme Changer // @namespace http://tampermonkey.net/ // @version 1.2 // @description Automaticly color changer, Written by ai // @author mamiis // @match https://*.okx.com/* // @grant none // @license MIT // ==/UserScript== (function(){ 'use strict'; const UP_COLOR = {r:20, g:167, b:255}; // hedef mavi const DOWN_COLOR = {r:126,g:87, b:194}; // hedef mor const TRANSFORM_ALPHA = true; // Geliştirilmiş grafik filtre ayarları const CHART_FILTERS = { green: { hue: 210, // Mavi tonu saturation: 1.6, brightness: 1.05 }, red: { hue: 280, // Mor tonu saturation: 1.3, brightness: 1.1 } }; // Regex'ler const hexRegex = /#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g; const rgbRegex = /rgba?\([^\)]+\)/gi; const hslRegex = /hsla?\([^\)]+\)/gi; // yardımcı DOM elemanı const _tmp = document.createElement('div'); _tmp.style.position = 'absolute'; _tmp.style.left = '-9999px'; _tmp.style.width = _tmp.style.height = '1px'; document.documentElement.appendChild(_tmp); /* ---------- renk parse / convert yardımcıları ---------- */ function clamp(v, a=0, b=255){ return Math.max(a, Math.min(b, v)); } function parseHexColor(str){ let s = str.replace('#',''); if(s.length === 3){ s = s.split('').map(ch => ch+ch).join(''); } else if(s.length === 4){ s = s.split('').map(ch => ch+ch).join(''); } let r=0,g=0,b=0,a=1; if(s.length === 6){ r = parseInt(s.substr(0,2),16); g = parseInt(s.substr(2,2),16); b = parseInt(s.substr(4,2),16); } else if(s.length === 8){ r = parseInt(s.substr(0,2),16); g = parseInt(s.substr(2,2),16); b = parseInt(s.substr(4,2),16); a = parseInt(s.substr(6,2),16) / 255; } return {r,g,b,a}; } function parseRgbString(str){ const nums = str.match(/[\d\.%]+/g); if(!nums) return null; let [r,g,b,a] = [0,0,0,1]; if(nums.length >= 3){ const parseComponent = (v) => { if(v.endsWith('%')) return Math.round(parseFloat(v) * 2.55); return Math.round(parseFloat(v)); }; r = parseComponent(nums[0]); g = parseComponent(nums[1]); b = parseComponent(nums[2]); } if(nums.length >= 4) a = parseFloat(nums[3]); return {r,g,b,a}; } function parseHslString(str){ const parts = str.match(/[\d\.%]+/g); if(!parts) return null; let h = parseFloat(parts[0]); let s = parseFloat(parts[1]) / 100; let l = parseFloat(parts[2]) / 100; let a = parts.length >= 4 ? parseFloat(parts[3]) : 1; const rgb = hslToRgb(h, s, l); return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b), a}; } function hslToRgb(h, s, l){ h = ((h % 360) + 360) % 360; const c = (1 - Math.abs(2*l - 1)) * s; const x = c * (1 - Math.abs((h / 60) % 2 - 1)); const m = l - c/2; let r=0,g=0,b=0; if(h < 60) { r=c; g=x; b=0; } else if(h < 120) { r=x; g=c; b=0; } else if(h < 180) { r=0; g=c; b=x; } else if(h < 240) { r=0; g=x; b=c; } else if(h < 300) { r=x; g=0; b=c; } else { r=c; g=0; b=x; } return { r: (r+m)*255, g: (g+m)*255, b: (b+m)*255 }; } 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=0,s=0,l=(max+min)/2; if(max !== min){ 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)) * 60; break; case g: h = ((b - r) / d + 2) * 60; break; case b: h = ((r - g) / d + 4) * 60; break; } } return {h, s, l}; } function parseColorString(str){ if(!str) return null; str = str.trim(); if(str.toLowerCase() === 'transparent' || str === 'none') return {r:0,g:0,b:0,a:0}; try{ if(str[0] === '#') return parseHexColor(str); if(str.toLowerCase().startsWith('rgb')) return parseRgbString(str); if(str.toLowerCase().startsWith('hsl')) return parseHslString(str); _tmp.style.color = ''; _tmp.style.color = str; const cs = getComputedStyle(_tmp).color; return parseRgbString(cs); }catch(e){ return null; } } function rgbaToCss(o){ const a = (typeof o.a === 'number') ? o.a : 1; return `rgba(${Math.round(o.r)}, ${Math.round(o.g)}, ${Math.round(o.b)}, ${+a.toFixed(3)})`; } /* ---------- renk tespit mantığı ---------- */ function shouldConvertByHue(rgba){ if(!rgba) return null; if(rgba.a === 0) return null; const {h,s,l} = rgbToHsl(rgba.r, rgba.g, rgba.b); if(s > 0.08 && h >= 70 && h <= 170) return 'greenish'; if(s > 0.08 && (h <= 25 || h >= 335)) return 'reddish'; return null; } function convertBasedOnDetection(rgba){ const det = shouldConvertByHue(rgba); if(!det) return rgba; let {h, s, l} = rgbToHsl(rgba.r, rgba.g, rgba.b); if(det === 'greenish'){ h = CHART_FILTERS.green.hue; s *= CHART_FILTERS.green.saturation; l *= CHART_FILTERS.green.brightness; } if(det === 'reddish'){ h = CHART_FILTERS.red.hue; s *= CHART_FILTERS.red.saturation; l *= CHART_FILTERS.red.brightness; } s = clamp(s, 0, 1); l = clamp(l, 0, 1); const rgb = hslToRgb(h, s, l); return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b), a: rgba.a}; } /* ---------- text içindeki renk tokenlarını değiştir ---------- */ function replaceColorTokensInText(text){ if(!text || typeof text !== 'string') return text; let out = text; out = out.replace(hexRegex, (m) => { const p = parseColorString(m); if(!p) return m; const conv = convertBasedOnDetection(p); if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)){ return rgbaToCss(conv); } return m; }); out = out.replace(rgbRegex, (m) => { const p = parseColorString(m); if(!p) return m; const conv = convertBasedOnDetection(p); if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)){ return rgbaToCss(conv); } return m; }); out = out.replace(hslRegex, (m) => { const p = parseColorString(m); if(!p) return m; const conv = convertBasedOnDetection(p); if(conv && (conv.r !== p.r || conv.g !== p.g || conv.b !== p.b || conv.a !== p.a)){ return rgbaToCss(conv); } return m; }); return out; } /* ---------- stylesheet / style tag işleme ---------- */ function processCssRuleList(rules){ for(let i=0;i<rules.length;i++){ const rule = rules[i]; try{ if(rule.type === CSSRule.STYLE_RULE){ const style = rule.style; for(let j=0;j<style.length;j++){ const prop = style[j]; const val = style.getPropertyValue(prop); const newVal = replaceColorTokensInText(val); if(newVal !== val){ try{ style.setProperty(prop, newVal, style.getPropertyPriority(prop)); }catch(e){} } } } else if(rule.cssRules && rule.cssRules.length){ processCssRuleList(rule.cssRules); } }catch(e){ continue; } } } function processStyleSheets(){ for(const sheet of document.styleSheets){ try{ if(!sheet.cssRules) continue; processCssRuleList(sheet.cssRules); }catch(e){ continue; } } } function processStyleTags(){ document.querySelectorAll('style').forEach(tag=>{ try{ const old = tag.textContent; const neu = replaceColorTokensInText(old); if(neu !== old) tag.textContent = neu; }catch(e){} }); } /* ---------- inline attrs ve SVG fill/stroke ---------- */ function processInlineAndSvg(root=document){ root.querySelectorAll('[style]').forEach(el=>{ try{ const old = el.getAttribute('style'); const neu = replaceColorTokensInText(old); if(neu !== old) el.setAttribute('style', neu); }catch(e){} }); root.querySelectorAll('[fill],[stroke]').forEach(el=>{ ['fill','stroke'].forEach(attr=>{ try{ if(el.hasAttribute(attr)){ const old = el.getAttribute(attr); const neu = replaceColorTokensInText(old); if(neu !== old) el.setAttribute(attr, neu); } }catch(e){} }); }); } /* ---------- computed styles ---------- */ const computedCheckProps = [ 'background-color','color', 'border-top-color','border-right-color','border-bottom-color','border-left-color', 'outline-color','caret-color','column-rule-color' ]; function isTransparentValue(v){ if(!v) return true; v = v.trim(); return v === 'transparent' || v === 'rgba(0, 0, 0, 0)' || v === 'initial' || v === 'none'; } function processComputedStylesBatch(elements, start=0){ const batch = 250; const end = Math.min(elements.length, start + batch); for(let i=start;i<end;i++){ const el = elements[i]; try{ const cs = getComputedStyle(el); computedCheckProps.forEach(prop=>{ try{ const val = cs.getPropertyValue(prop); if(!val || isTransparentValue(val)) return; const parsed = parseColorString(val); if(!parsed) return; const conv = convertBasedOnDetection(parsed); if(conv && (conv.r !== parsed.r || conv.g !== parsed.g || conv.b !== parsed.b || conv.a !== parsed.a)){ el.style.setProperty(prop, rgbaToCss(conv), 'important'); } }catch(e){} }); try{ const bs = cs.getPropertyValue('box-shadow'); if(bs && bs !== 'none' && /#|rgba?\(|hsla?\(/i.test(bs)){ const newBs = replaceColorTokensInText(bs); if(newBs !== bs) el.style.setProperty('box-shadow', newBs, 'important'); } }catch(e){} try{ const bg = cs.getPropertyValue('background-image'); if(bg && bg !== 'none' && /#|rgba?\(|hsla?\(/i.test(bg)){ const newBg = replaceColorTokensInText(bg); if(newBg !== bg) el.style.setProperty('background-image', newBg, 'important'); } }catch(e){} }catch(e){} } if(end < elements.length){ setTimeout(()=> processComputedStylesBatch(elements, end), 20); } } function processAllComputedStylesRoot(root=document){ const elements = Array.from(root.querySelectorAll('*')); processComputedStylesBatch(elements, 0); } /* ---------- canvas context patch ---------- */ function patchCanvasContext(ctx){ try{ if(!ctx) return; if(ctx.__colorPatched) return; ctx.__colorPatched = true; const convertMaybe = (v) => { if(typeof v !== 'string') return v; const parsed = parseColorString(v); if(!parsed) return v; const conv = convertBasedOnDetection(parsed); if(conv && (conv.r !== parsed.r || conv.g !== parsed.g || conv.b !== parsed.b || conv.a !== parsed.a)){ return rgbaToCss(conv); } return v; }; let _fill = ctx.fillStyle; let _stroke = ctx.strokeStyle; Object.defineProperty(ctx, 'fillStyle', { configurable: true, enumerable: true, get(){ return _fill; }, set(v){ _fill = convertMaybe(v); } }); Object.defineProperty(ctx, 'strokeStyle', { configurable: true, enumerable: true, get(){ return _stroke; }, set(v){ _stroke = convertMaybe(v); } }); let _shadow = ctx.shadowColor; Object.defineProperty(ctx, 'shadowColor', { configurable: true, enumerable: true, get(){ return _shadow; }, set(v){ _shadow = convertMaybe(v); } }); }catch(e){} } // Canvas context override (chart canvas hariç) const origGetCtx = HTMLCanvasElement.prototype.getContext; HTMLCanvasElement.prototype.getContext = function(type, ...args){ const ctx = origGetCtx.apply(this, [type, ...args]); try{ if(type === '2d' && ctx){ try{ if(this.closest && this.closest('.tv-lightweight-charts')) { return ctx; } }catch(e){} patchCanvasContext(ctx); } }catch(e){} return ctx; }; /* ---------- GELİŞTİRİLMİŞ GRAFİK RENK KONTROLÜ ---------- */ function applyChartColorFilters() { try { const chartStyle = document.createElement('style'); chartStyle.textContent = ` /* TradingView chart renk filtreleri */ .tv-lightweight-charts { filter: none !important; } /* Yeşil mumları maviye çevir */ .tv-lightweight-charts [fill="#25a750"], .tv-lightweight-charts [stroke="#25a750"], .tv-lightweight-charts [fill*="25a750"], .tv-lightweight-charts [stroke*="25a750"] { fill: ${rgbaToCss(UP_COLOR)} !important; stroke: ${rgbaToCss(UP_COLOR)} !important; } /* Kırmızı mumları mora çevir */ .tv-lightweight-charts [fill="#ca3f64"], .tv-lightweight-charts [stroke="#ca3f64"], .tv-lightweight-charts [fill*="ca3f64"], .tv-lightweight-charts [stroke*="ca3f64"] { fill: ${rgbaToCss(DOWN_COLOR)} !important; stroke: ${rgbaToCss(DOWN_COLOR)} !important; } /* Canvas tabanlı grafikler için CSS filtre*/ .tv-lightweight-charts canvas { filter: hue-rotate(0deg) saturate(1.2) !important; } /* Arka plan renkleri */ .tv-lightweight-charts [fill*="rgba(37, 167, 80"], .tv-lightweight-charts [style*="25a750"] { fill: ${rgbaToCss({...UP_COLOR, a: 0.3})} !important; } .tv-lightweight-charts [fill*="rgba(202, 63, 100"], .tv-lightweight-charts [style*="ca3f64"] { fill: ${rgbaToCss({...DOWN_COLOR, a: 0.3})} !important; } /* Boost ikonları */ .nav-item.nav-boost-item.nav-right-item > a.nav-item.nav-boost.icon { background-color: ${rgbaToCss({...UP_COLOR,a:0.15})} !important; } .nav-item.nav-boost-item.nav-right-item img.nav-boost-icon { filter: hue-rotate(210deg) saturate(1.6) brightness(1.05) !important; } `; document.head.appendChild(chartStyle); } catch (e) { console.error('Chart style hatası:', e); } } /* ---------- GRAFİK CANVAS RENK DEĞİŞİMİ ---------- */ function monitorChartColors() { // Canvas fill/stroke override for chart colors const origFill = CanvasRenderingContext2D.prototype.fill; const origStroke = CanvasRenderingContext2D.prototype.stroke; const origFillRect = CanvasRenderingContext2D.prototype.fillRect; CanvasRenderingContext2D.prototype.fill = function() { if (this.fillStyle && typeof this.fillStyle === 'string') { const parsed = parseColorString(this.fillStyle); if (parsed) { const converted = convertBasedOnDetection(parsed); if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) { this.fillStyle = rgbaToCss(converted); } } } origFill.apply(this, arguments); }; CanvasRenderingContext2D.prototype.stroke = function() { if (this.strokeStyle && typeof this.strokeStyle === 'string') { const parsed = parseColorString(this.strokeStyle); if (parsed) { const converted = convertBasedOnDetection(parsed); if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) { this.strokeStyle = rgbaToCss(converted); } } } origStroke.apply(this, arguments); }; CanvasRenderingContext2D.prototype.fillRect = function(x, y, w, h) { if (this.fillStyle && typeof this.fillStyle === 'string') { const parsed = parseColorString(this.fillStyle); if (parsed) { const converted = convertBasedOnDetection(parsed); if (converted && (converted.r !== parsed.r || converted.g !== parsed.g || converted.b !== parsed.b)) { this.fillStyle = rgbaToCss(converted); } } } origFillRect.apply(this, arguments); }; } /* ---------- mutation observer & iş akışı ---------- */ function processNodeAndChildren(node){ try{ if(node.nodeType !== 1) return; processInlineAndSvg(node); processAllComputedStylesRoot(node); }catch(e){} } const mo = new MutationObserver((mutations)=>{ const added = []; for(const m of mutations){ if(m.type === 'attributes'){ const target = m.target; try{ if(m.attributeName === 'style' || m.attributeName === 'class' || m.attributeName === 'fill' || m.attributeName === 'stroke'){ processNodeAndChildren(target); } }catch(e){} } if(m.addedNodes && m.addedNodes.length){ m.addedNodes.forEach(n => { if(n.nodeType === 1) added.push(n); }); } } if(added.length){ setTimeout(()=> added.forEach(n => processNodeAndChildren(n)), 10); } }); function kickAll(){ try{ processStyleSheets(); processStyleTags(); processInlineAndSvg(document); processAllComputedStylesRoot(document); applyChartColorFilters(); }catch(e){} } function init() { kickAll(); mo.observe(document.body || document.documentElement, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class', 'fill', 'stroke'] }); monitorChartColors(); // Sayfa yüklendikten sonra tekrar çalıştır window.addEventListener('load', () => { setTimeout(kickAll, 500); setTimeout(kickAll, 2000); setTimeout(kickAll, 5000); }); // URL değişimlerini izle let lastUrl = location.href; setInterval(() => { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(kickAll, 1000); } }, 1000); } // Başlat if(document.body){ init(); } else { window.addEventListener('DOMContentLoaded', init); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址