// ==UserScript== // @name 網頁電影史詩感特效 Pro (圖形化調色面板) // @license MIT // @namespace http://tampermonkey.net/ // @version 4.0 // @description 為網頁添加可自訂材質、智慧隱藏黑邊、以及圖形化即時調色面板的終極電影特效。 // @author AI Assistant // @match *://*/* // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_unregisterMenuCommand // @downloadURL https://update.greasyfork.icu/scripts/551935/%E7%B6%B2%E9%A0%81%E9%9B%BB%E5%BD%B1%E5%8F%B2%E8%A9%A9%E6%84%9F%E7%89%B9%E6%95%88%20Pro%20%28%E5%9C%96%E5%BD%A2%E5%8C%96%E8%AA%BF%E8%89%B2%E9%9D%A2%E6%9D%BF%29.user.js // @updateURL https://update.greasyfork.icu/scripts/551935/%E7%B6%B2%E9%A0%81%E9%9B%BB%E5%BD%B1%E5%8F%B2%E8%A9%A9%E6%84%9F%E7%89%B9%E6%95%88%20Pro%20%28%E5%9C%96%E5%BD%A2%E5%8C%96%E8%AA%BF%E8%89%B2%E9%9D%A2%E6%9D%BF%29.meta.js // ==/UserScript== (function() { 'use strict'; // --- 全域設定與狀態 --- const BAR_HEIGHT_VH = 8; let isEffectEnabled = GM_getValue('cinematicEffectEnabled', true); let currentTexture = GM_getValue('cinematicTexture', 'metal'); // 預設濾鏡數值 (給滑桿用的 0-200 範圍,更直覺) const defaultFilters = { sepia: 25, // 0-100 -> 0-1.0 contrast: 110, // 0-200 -> 0-2.0 saturate: 110, // 0-200 -> 0-2.0 brightness: 98, // 0-200 -> 0-2.0 hue: 0 // 0-360 -> 0-360deg }; let currentFilters = GM_getValue('colorFilters', { ...defaultFilters }); // --- 風格設定 (CSS) --- // 這裡只放靜態的 CSS。動態的 filter 會由 JS 直接控制 const staticCSS = ` /* 黑邊基礎樣式 */ .cinematic-bar { position: fixed; left: 0; width: 100%; z-index: 999999; pointer-events: none; opacity: 0; transition: opacity 0.4s ease-in-out; height: ${BAR_HEIGHT_VH}vh; background-color: #111; } .cinematic-top-bar { top: 0; } .cinematic-bottom-bar { bottom: 0; } .cinematic-bar.active { opacity: 1; } .cinematic-bar.mouse-hover-hide { opacity: 0 !important; } /* 材質選項 */ .texture-metal { background: linear-gradient(to bottom, #222 0%, #111 50%, #222 100%), linear-gradient(to right, rgba(255,255,255,0.03) 0%, rgba(0,0,0,0.1) 100%); } .texture-carbon { background-color: #1a1a1a; background-image: linear-gradient(45deg, #2b2b2b 25%, transparent 25%, transparent 75%, #2b2b2b 75%, #2b2b2b), linear-gradient(-45deg, #2b2b2b 25%, transparent 25%, transparent 75%, #2b2b2b 75%, #2b2b2b); background-size: 10px 10px; } .texture-noise { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIj48ZmlsdGVyIGlkPSJub2lzZSI+PGZlVHVyYnVsZW5jZSB0eXBlPSJmcmFjdGFsTm9pc2UiIGJhc2VGcmVxdWVuY3k9IjAuNjUiIG51bU9jdGF2ZXM9IjMiIHN0aXRjaFRpbGVzPSJzdGl0Y2giLz48L2ZpbHRlcj48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWx0ZXI9InVybCgjam5vaXNlKSIgb3BhY2l0eT0iMC4xNSIvPjwvc3ZnPg=='), linear-gradient(to bottom, #252525, #111); } .texture-gradient { background: linear-gradient(to bottom, #333, #111 70%, #000); box-shadow: 0 0 20px rgba(0,0,0,0.6); } /* 暗角 & 膠片顆粒 */ .cinematic-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 999998; pointer-events: none; opacity: 0; transition: opacity 0.5s ease; background: radial-gradient(ellipse at center, rgba(0,0,0,0) 60%, rgba(0,0,0,0.35) 100%); } .cinematic-overlay.active { opacity: 1; } .cinematic-overlay::after { content: ""; position: absolute; top: -100%; left: -100%; width: 300%; height: 300%; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABTSURBVFhH7c5BDQAwEASh+je9N3gBLgHCFwY4fpmZ9x7gCZ988sknn3zyySeffPLJJ5988sknn3zyySeffPLJJ5988sknn3zyySeffPLJJ5988smnf0g2BwFksyQEtgAAAABJRU5ErkJggg=='); opacity: 0.06; animation: grain 0.4s steps(1) infinite; } @keyframes grain { 0%, 100% { transform: translate(0, 0); } 10% { transform: translate(-5%, -10%); } 20% { transform: translate(-15%, 5%); } 30% { transform: translate(7%, -25%); } 40% { transform: translate(-5%, 25%); } 50% { transform: translate(-15%, 10%); } 60% { transform: translate(15%, 0%); } 70% { transform: translate(0%, 15%); } 80% { transform: translate(3%, 35%); } 90% { transform: translate(-10%, 10%); } } /* --- 設定面板 UI 樣式 --- */ .cinematic-settings-panel { position: fixed; bottom: calc(${BAR_HEIGHT_VH}vh + 20px); /* 剛好在下黑邊的上方 */ right: 20px; z-index: 10000000; background: rgba(20, 20, 20, 0.9); backdrop-filter: blur(10px); color: #eee; padding: 15px 20px; border-radius: 12px; border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 8px 30px rgba(0,0,0,0.5); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; width: 300px; transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.4s ease; transform: translateX(0); } .cinematic-settings-panel.hidden { transform: translateX(calc(100% + 40px)); opacity: 0; pointer-events: none; } .cinematic-settings-panel h3 { margin: 0 0 15px; font-size: 16px; font-weight: 600; text-align: center; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 10px; } .cinematic-settings-panel .control-group { display: flex; align-items: center; margin-bottom: 10px; } .cinematic-settings-panel label { flex: 0 0 80px; font-size: 13px; } .cinematic-settings-panel input[type="range"] { flex-grow: 1; margin: 0 10px; -webkit-appearance: none; background: transparent; } .cinematic-settings-panel input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: rgba(255,255,255,0.2); border-radius: 2px; } .cinematic-settings-panel input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; margin-top: -6px; width: 16px; height: 16px; background: #fff; border-radius: 50%; cursor: pointer; } .cinematic-settings-panel .value-display { font-size: 13px; font-variant-numeric: tabular-nums; width: 35px; text-align: right; } .cinematic-settings-panel .panel-buttons { display: flex; justify-content: space-between; margin-top: 15px; } .cinematic-settings-panel button { background: rgba(255,255,255,0.1); border: none; color: #fff; padding: 6px 12px; border-radius: 6px; cursor: pointer; transition: background 0.2s; font-size: 12px; } .cinematic-settings-panel button:hover { background: rgba(255,255,255,0.2); } `; GM_addStyle(staticCSS); // 建立一個專門用來放動態 filter 的 style 標籤 const filterStyleElement = document.createElement('style'); filterStyleElement.id = 'cinematic-filter-style'; document.head.appendChild(filterStyleElement); // --- 創建 HTML 元素 --- const topBar = document.createElement('div'); topBar.className = 'cinematic-bar cinematic-top-bar'; const bottomBar = document.createElement('div'); bottomBar.className = 'cinematic-bar cinematic-bottom-bar'; const overlay = document.createElement('div'); overlay.className = 'cinematic-overlay'; document.documentElement.appendChild(topBar); document.documentElement.appendChild(bottomBar); document.documentElement.appendChild(overlay); // --- 創建設定面板 UI --- const panel = document.createElement('div'); panel.className = 'cinematic-settings-panel hidden'; // 預設隱藏 let panelHTML = '