Created
April 30, 2026 11:00
-
-
Save carddass2018-svg/1097ebd6b5fc62afb47a8bfe4b49595c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="zh-Hant"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
| <title>龍珠閃卡 - 零漏光最終版</title> | |
| <style> | |
| body { background: #000; margin: 0; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; font-family: sans-serif; } | |
| /* 啟動層 */ | |
| #auth-overlay { position: fixed; inset: 0; background: #000; z-index: 9999; display: flex; flex-direction: column; align-items: center; justify-content: center; } | |
| #auth-btn { background: #f1c40f; border: none; padding: 20px 40px; border-radius: 12px; font-size: 20px; font-weight: bold; } | |
| /* 設定面板 */ | |
| #set-btn { position: fixed; top: 15px; left: 15px; z-index: 1000; background: rgba(0,0,0,0.7); color: #fff; border: 1px solid #555; padding: 10px; border-radius: 8px; display: none; } | |
| .panel { position: fixed; top: 0; left: 0; width: 100%; background: #111; padding: 20px; border-bottom: 2px solid #333; z-index: 999; box-sizing: border-box; transform: translateY(-100%); transition: 0.3s; color: #fff; } | |
| .panel.active { transform: translateY(0); } | |
| .row { margin-bottom: 12px; font-size: 13px; } | |
| input[type="file"] { width: 100%; margin-top: 5px; color: #0f0; } | |
| /* 卡片展示區 */ | |
| .stage { perspective: 1200px; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; } | |
| #card { width: 82vw; max-width: 320px; aspect-ratio: 1 / 1.4; position: relative; border-radius: 18px; overflow: hidden; background: #000; box-shadow: 0 0 50px #000; } | |
| .layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } | |
| #c-base { width: 100%; height: 100%; object-fit: cover; z-index: 1; } | |
| /* 強化遮罩層:加入暴力對比切斷 */ | |
| #foil-wrap { | |
| z-index: 2; | |
| mix-blend-mode: color-dodge; | |
| -webkit-mask-size: 100% 100%; | |
| mask-size: 100% 100%; | |
| -webkit-mask-repeat: no-repeat; | |
| /* 核心:將遮罩黑白化到極致,完全切斷灰色漏光 */ | |
| filter: contrast(1000%) brightness(100%); | |
| will-change: filter; | |
| } | |
| #c-foil { background-size: cover; background-position: center; opacity: 0.15; } | |
| #c-shine { z-index: 3; background: linear-gradient(110deg, transparent 40%, rgba(255,255,255,0.4) 50%, transparent 60%); background-size: 250% 250%; mix-blend-mode: overlay; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="auth-overlay"> | |
| <button id="auth-btn" onclick="initMotion()">啟動 iPhone 零漏光版</button> | |
| </div> | |
| <button id="set-btn" onclick="document.getElementById('p').classList.toggle('active')">⚙️ 設定</button> | |
| <div class="panel" id="p"> | |
| <div class="row">1. 選擇原圖: <input type="file" accept="image/*" onchange="up(event,'b')"></div> | |
| <div class="row">2. 選擇遮罩: <input type="file" accept="image/*" onchange="up(event,'m')"></div> | |
| <div class="row">3. 選擇閃紋: <input type="file" accept="image/*" onchange="up(event,'f')"></div> | |
| <button onclick="document.getElementById('p').classList.remove('active')" style="width:100%; padding:12px; background:#333; border:none; border-radius:8px; color:#fff;">完成欣賞</button> | |
| </div> | |
| <div class="stage"> | |
| <div id="card"> | |
| <img id="c-base" src="https://asobi-center.com"> | |
| <div id="foil-wrap" class="layer"> | |
| <div id="c-foil" class="layer"></div> | |
| </div> | |
| <div id="c-shine" class="layer"></div> | |
| </div> | |
| </div> | |
| <!-- 隱形畫布用作處理圖片 --> | |
| <canvas id="cvs" style="display:none;"></canvas> | |
| <script> | |
| const foil = document.getElementById('c-foil'); | |
| const wrap = document.getElementById('foil-wrap'); | |
| const base = document.getElementById('c-base'); | |
| const shine = document.getElementById('c-shine'); | |
| const cvs = document.getElementById('cvs'); | |
| const ctx = cvs.getContext('2d'); | |
| function up(event, type) { | |
| const file = event.target.files[0]; | |
| if (!file) return; | |
| const reader = new FileReader(); | |
| reader.onload = (e) => { | |
| const img = new Image(); | |
| img.onload = () => { | |
| // 將圖片畫入 Canvas 轉化為穩定數據流 | |
| cvs.width = img.width; | |
| cvs.height = img.height; | |
| ctx.drawImage(img, 0, 0); | |
| const dataUrl = cvs.toDataURL('image/png'); | |
| if(type === 'b') base.src = dataUrl; | |
| if(type === 'f') foil.style.backgroundImage = `url('${dataUrl}')`; | |
| if(type === 'm') { | |
| // iPhone Safari 必須強制重新套用 webkit 屬性 | |
| wrap.style.webkitMaskImage = `url('${dataUrl}')`; | |
| wrap.style.maskImage = `url('${dataUrl}')`; | |
| } | |
| }; | |
| img.src = e.target.result; | |
| }; | |
| reader.readAsDataURL(file); | |
| } | |
| function initMotion() { | |
| if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') { | |
| DeviceOrientationEvent.requestPermission().then(res => { | |
| if (res === 'granted') startApp(); | |
| }); | |
| } else { startApp(); } | |
| } | |
| function startApp() { | |
| document.getElementById('auth-overlay').style.display = 'none'; | |
| document.getElementById('set-btn').style.display = 'block'; | |
| window.addEventListener('deviceorientation', (e) => { | |
| let lr = e.gamma || 0; | |
| let fb = (e.beta || 45) - 45; | |
| foil.style.filter = `hue-rotate(${lr * 10}deg) brightness(${0.9 + Math.abs(lr)/60}) contrast(1.5)`; | |
| foil.style.opacity = Math.min(0.15 + (Math.abs(lr)/100), 0.6); | |
| shine.style.backgroundPosition = `${50 + lr * 2}% ${50 + fb * 2}%`; | |
| }); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment