WWW.YOUINFO.SITE
标签聚合 卡卡

/tag/卡卡

LinuxDo 最新话题 · 2026-06-10 07:52:40+08:00 · tech

说实话一般,而且页面卡卡的掉帧 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>天气 · iOS 18 风格</title> <style> :root { --spring: cubic-bezier(.32, .72, .25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; -webkit-tap-highlight-color: transparent; } html, body { height: 100%; } body { font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro SC", "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif; background: #070a14; color: #fff; display: flex; align-items: center; justify-content: center; overflow: hidden; -webkit-font-smoothing: antialiased; } /* ========== 背景氛围光斑 ========== */ .ambient { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; } .blob { position: absolute; border-radius: 50%; filter: blur(110px); opacity: .55; animation: blobFloat 16s ease-in-out infinite alternate; } .b1 { width: 520px; height: 520px; background: #27408f; top: -180px; left: -120px; } .b2 { width: 460px; height: 460px; background: #5b2a7a; bottom: -160px; right: -100px; animation-delay: -5s; } .b3 { width: 380px; height: 380px; background: #175e5e; bottom: 6%; left: 34%; animation-delay: -10s; opacity: .4; } @keyframes blobFloat { to { transform: translate(70px, 50px) scale(1.18); } } /* ========== 顶部栏 ========== */ .stage { width: min(1240px, 94vw); position: relative; z-index: 1; } .topbar { display: flex; align-items: flex-end; justify-content: space-between; margin: 0 6px 20px; } .topbar h1 { font-size: 34px; font-weight: 700; letter-spacing: 1px; } .sub { margin-top: 6px; font-size: 14px; color: rgba(255,255,255,.62); display: flex; align-items: center; gap: 8px; } .sub svg { opacity: .9; } .glass-chip { display: flex; align-items: center; gap: 9px; padding: 10px 16px; border-radius: 999px; background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.15); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; } .live-dot { width: 8px; height: 8px; border-radius: 50%; background: #34d399; box-shadow: 0 0 10px #34d399; animation: pulseDot 2s infinite; } @keyframes pulseDot { 50% { opacity: .35; } } /* ========== 卡片容器 ========== */ .cards { display: flex; gap: 18px; height: min(600px, 68vh); min-height: 480px; perspective: 1600px; } .card { position: relative; flex: 1; border-radius: 32px; overflow: hidden; cursor: pointer; user-select: none; outline: none; border: 1px solid rgba(255,255,255,.28); box-shadow: 0 24px 48px -12px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.35); transition: flex-grow .7s var(--spring), min-height .7s var(--spring), box-shadow .45s ease, border-color .45s ease, transform .25s ease-out; animation: cardIn .9s cubic-bezier(.22, 1, .36, 1) backwards; transform-style: preserve-3d; } .card:nth-child(1) { animation-delay: .05s; } .card:nth-child(2) { animation-delay: .15s; } .card:nth-child(3) { animation-delay: .25s; } .card:nth-child(4) { animation-delay: .35s; } @keyframes cardIn { from { opacity: 0; transform: translateY(44px) scale(.96); } } .card:hover { box-shadow: 0 30px 60px -14px rgba(0,0,0,.62); } .card:not(.active):hover { transform: translateY(-8px); } .card:focus-visible { border-color: rgba(255,255,255,.85); } .card.active { flex-grow: 2.6; border-color: rgba(255,255,255,.5); box-shadow: 0 34px 70px -16px rgba(0,0,0,.68), inset 0 1px 0 rgba(255,255,255,.45); } /* 底部压暗,保证文字可读性 */ .card::after { content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(to top, rgba(8,15,30,.45), rgba(8,15,30,0) 48%); } /* 四种天气底色 */ .sunny { background: linear-gradient(180deg, #1f6dd1 0%, #4f9be6 40%, #9ccdf0 72%, #ffd9a0 100%); } .windy { background: linear-gradient(180deg, #23606e 0%, #3d8d8a 48%, #7cc4ad 82%, #b9e2cf 100%); } .rainstorm { background: linear-gradient(180deg, #151d2c 0%, #243349 52%, #3a516c 100%); } .blizzard { background: linear-gradient(180deg, #46688f 0%, #6e93b4 45%, #a9c7da 78%, #e6f2f8 100%); } /* ========== 卡片内容 ========== */ .content { position: relative; z-index: 3; height: 100%; display: flex; flex-direction: column; padding: 22px; } .row-top { display: flex; justify-content: space-between; gap: 8px; } .chip { display: inline-flex; align-items: center; gap: 6px; padding: 6px 11px; font-size: 12px; font-weight: 600; border-radius: 999px; white-space: nowrap; background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.22); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); } .chip.warn { background: rgba(255,159,67,.28); border-color: rgba(255,159,67,.5); } .chip.danger { background: rgba(255,107,107,.3); border-color: rgba(255,107,107,.52); } .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--c,#fff); box-shadow: 0 0 8px var(--c,#fff); } .bottom { margin-top: auto; } .w-eng { font-size: 11px; letter-spacing: 3px; opacity: .7; font-weight: 600; } .w-name { font-size: 20px; font-weight: 600; letter-spacing: 2px; margin-top: 2px; text-shadow: 0 2px 12px rgba(0,0,0,.3); } .temp { font-weight: 200; line-height: 1.05; letter-spacing: -2px; font-size: clamp(56px, 6.2vw, 78px); text-shadow: 0 4px 24px rgba(0,0,0,.28); transition: font-size .6s var(--spring); font-variant-numeric: tabular-nums; } .card:not(.active) .temp { font-size: clamp(40px, 4.2vw, 52px); font-weight: 300; } .range { font-size: 13.5px; color: rgba(255,255,255,.88); margin-top: 2px; text-shadow: 0 1px 8px rgba(0,0,0,.3); } /* 展开区域 */ .reveal { max-height: 0; opacity: 0; transform: translateY(16px); overflow: hidden; transition: max-height .7s var(--spring), opacity .5s ease .08s, transform .65s var(--spring); } .card.active .reveal { max-height: 340px; opacity: 1; transform: none; } .desc { font-size: 13px; color: rgba(255,255,255,.78); margin-top: 10px; } .metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-top: 14px; } .metric { text-align: center; padding: 10px 6px; border-radius: 16px; overflow: hidden; background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.18); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); } .metric .k { font-size: 11px; color: rgba(255,255,255,.68); } .metric .v { font-size: 14px; font-weight: 600; margin-top: 3px; } .hours { display: flex; gap: 8px; margin-top: 10px; } .hour { flex: 1; text-align: center; padding: 9px 4px; border-radius: 14px; background: rgba(255,255,255,.1); border: 1px solid rgba(255,255,255,.14); } .hour .t { font-size: 11px; color: rgba(255,255,255,.65); } .hour .v { font-size: 13px; font-weight: 600; margin-top: 4px; } /* 鼠标跟随高光 */ .glare { position: absolute; inset: 0; z-index: 2; pointer-events: none; opacity: 0; transition: opacity .35s; background: radial-gradient(420px circle at var(--mx,50%) var(--my,50%), rgba(255,255,255,.2), transparent 46%); } .card:hover .glare { opacity: 1; } /* ========== 场景动画层 ========== */ .scene { position: absolute; inset: 0; z-index: 1; pointer-events: none; } /* 云朵(通用) */ .cloud { position: absolute; width: 130px; height: 42px; background: #fff; border-radius: 40px; filter: drop-shadow(0 16px 22px rgba(0,0,0,.22)); } .cloud::before, .cloud::after { content: ''; position: absolute; background: inherit; border-radius: 50%; } .cloud::before { width: 56px; height: 56px; top: -27px; left: 20px; } .cloud::after { width: 36px; height: 36px; top: -17px; right: 22px; } .cloud.sm { width: 84px; height: 28px; } .cloud.sm::before { width: 38px; height: 38px; top: -18px; left: 12px; } .cloud.sm::after { width: 26px; height: 26px; top: -12px; right: 12px; } @keyframes cloudBob { from { transform: translateX(-12px); } to { transform: translateX(12px); } } /* —— 晴天 —— */ .sun-anchor { position: absolute; top: 132px; left: 50%; width: 0; height: 0; } .sun { position: absolute; left: -46px; top: -46px; width: 92px; height: 92px; border-radius: 50%; background: radial-gradient(circle at 35% 32%, #fff8d6, #ffd94e 48%, #ffae33 78%, #ff9d1f); animation: sunPulse 4.5s ease-in-out infinite; } @keyframes sunPulse { 0%, 100% { transform: scale(1); box-shadow: 0 0 34px 6px rgba(255,205,80,.8), 0 0 90px 28px rgba(255,170,60,.32); } 50% { transform: scale(1.06); box-shadow: 0 0 48px 12px rgba(255,205,80,.95), 0 0 120px 40px rgba(255,170,60,.45); } } .rays { position: absolute; left: 0; top: 0; animation: spin 28s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .ray { position: absolute; left: -2.5px; top: -9px; width: 5px; height: 18px; border-radius: 3px; background: linear-gradient(to top, rgba(255,228,130,.95), rgba(255,228,130,0)); transform: rotate(var(--a)) translateY(-76px); transform-origin: 2.5px 9px; } .sunny .c1 { top: 228px; left: 12%; opacity: .85; animation: cloudBob 9s ease-in-out infinite alternate; } .sunny .c2 { top: 58px; right: 8%; opacity: .6; animation: cloudBob 12s ease-in-out infinite alternate-reverse; } /* —— 大风 —— */ .windline { position: absolute; height: 3px; border-radius: 4px; opacity: 0; background: linear-gradient(90deg, rgba(255,255,255,0), rgba(255,255,255,.85), rgba(255,255,255,0)); animation: windMove linear infinite; } @keyframes windMove { 0% { transform: translateX(0); opacity: 0; } 10% { opacity: .85; } 80% { opacity: .85; } 100% { transform: translateX(840px); opacity: 0; } } .leaf { position: absolute; width: 11px; height: 11px; border-radius: 0 60% 0 60%; background: linear-gradient(135deg, #9fdc85, #4f9e4f); animation: leafFly linear infinite; } @keyframes leafFly { to { transform: translate(840px, 90px) rotate(680deg); } } .windy .cloud.main { top: 128px; left: 50%; margin-left: -65px; background: #eef7f4; animation: cloudBob 4s ease-in-out infinite alternate; } .windy .cloud.back { top: 92px; left: 50%; margin-left: -126px; background: #d7e8e2; opacity: .75; animation: cloudBob 5.5s ease-in-out infinite alternate-reverse; } /* —— 暴雨 —— */ .rain { position: absolute; inset: -60px; transform: rotate(9deg); } .drop { position: absolute; top: -30px; width: 2px; border-radius: 2px; background: linear-gradient(to bottom, rgba(173,216,255,0), rgba(173,216,255,.75)); animation: fall linear infinite; } @keyframes fall { to { transform: translateY(780px); } } .rainstorm .cloud.main { top: 118px; left: 50%; margin-left: -65px; background: #39465a; } .rainstorm .cloud.back { top: 90px; left: 50%; margin-left: -118px; background: #26303f; opacity: .92; animation: cloudBob 7s ease-in-out infinite alternate; } .bolt { position: absolute; top: 150px; left: 50%; margin-left: -15px; width: 30px; height: 48px; background: linear-gradient(#ffe879, #ffb62e); clip-path: polygon(58% 0, 0 55%, 38% 55%, 28% 100%, 100% 38%, 52% 38%); filter: drop-shadow(0 0 14px rgba(255,210,80,.9)); opacity: 0; animation: boltIdle 7s linear infinite; } @keyframes boltIdle { 0%, 85%, 100% { opacity: 0; } 87% { opacity: 1; } 89% { opacity: .15; } 91% { opacity: .9; } 95% { opacity: 0; } } .flash-layer { position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: 0; background: radial-gradient(circle at 50% 0%, rgba(255,255,255,.95), rgba(255,255,255,0) 72%); } .card.flashing .flash-layer { animation: skyFlash .85s ease-out; } .card.flashing .bolt { animation: boltFlash .85s ease both; } @keyframes skyFlash { 0% { opacity: 0; } 8% { opacity: .85; } 16% { opacity: .15; } 26% { opacity: .6; } 42% { opacity: .1; } 56% { opacity: .3; } 100% { opacity: 0; } } @keyframes boltFlash { 0% { opacity: 0; } 6% { opacity: 1; } 14% { opacity: .2; } 22% { opacity: 1; } 60% { opacity: .85; } 100% { opacity: 0; } } /* —— 暴雪 —— */ .flake { position: absolute; top: -12px; border-radius: 50%; background: #fff; animation: snow linear infinite; } @keyframes snow { to { transform: translate(var(--dx, 50px), 760px); } } .blizzard .windline { filter: opacity(.45); } .blizzard .cloud.main { top: 112px; left: 50%; margin-left: -65px; background: #f3f8fc; animation: cloudBob 6s ease-in-out infinite alternate; } .blizzard .cloud.back { top: 84px; left: 50%; margin-left: -116px; background: #c9d9e6; opacity: .8; animation: cloudBob 8s ease-in-out infinite alternate-reverse; } .snow-ground { position: absolute; left: -12%; right: -12%; height: 84px; border-radius: 50% 50% 0 0 / 56px; } .g2 { background: rgba(210,230,243,.75); bottom: -26px; left: -20%; right: -4%; } .g1 { background: rgba(255,255,255,.92); bottom: -40px; } .hint { text-align: center; margin-top: 18px; font-size: 13px; color: rgba(255,255,255,.45); letter-spacing: 1px; } /* ========== 响应式 & 无障碍 ========== */ @media (max-width: 880px) { body { overflow: auto; padding: 28px 0; align-items: flex-start; } .cards { flex-direction: column; height: auto; min-height: 0; } .card { flex: none; min-height: 150px; } .card.active { min-height: 430px; } .metrics { grid-template-columns: repeat(2, 1fr); } } @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .2s !important; } } </style> </head> <body> <div class="ambient"> <div class="blob b1"></div><div class="blob b2"></div><div class="blob b3"></div> </div> <div class="stage"> <header class="topbar"> <div> <h1>天气</h1> <div class="sub"> <svg width="13" height="13" viewBox="0 0 24 24" fill="none"> <path d="M12 21s-7-5.1-7-11a7 7 0 1 1 14 0c0 5.9-7 11-7 11z" stroke="white" stroke-opacity=".7" stroke-width="2"/> <circle cx="12" cy="10" r="2.6" fill="white" fill-opacity=".85"/> </svg> <span>北京市 · 朝阳区</span><span>·</span><span id="dateText"></span> </div> </div> <div class="glass-chip"><span class="live-dot"></span><span id="clockText">--:--:--</span></div> </header> <main class="cards"> <!-- ☀️ 晴天 --> <article class="card sunny active" tabindex="0" role="button" aria-expanded="true"> <div class="scene"> <div class="sun-anchor"><div class="rays"></div><div class="sun"></div></div> <div class="cloud sm c1"></div><div class="cloud sm c2"></div> </div> <div class="content"> <div class="row-top"> <span class="chip"><i class="dot" style="--c:#ffd54d"></i>晴</span> <span class="chip warn">紫外线 强</span> </div> <div class="bottom"> <p class="w-eng">SUNNY</p><h2 class="w-name">晴天</h2> <div class="temp"><span class="temp-num" data-target="28">0</span>°</div> <p class="range">最高 31° · 最低 22° · 体感 30°</p> <div class="reveal"><div> <p class="desc">阳光明媚,紫外线较强,外出请注意防晒与补水。</p> <div class="metrics"> <div class="metric"><p class="k">湿度</p><p class="v">42%</p></div> <div class="metric"><p class="k">风速</p><p class="v">8 km/h</p></div> <div class="metric"><p class="k">气压</p><p class="v">1013 hPa</p></div> <div class="metric"><p class="k">能见度</p><p class="v">24 km</p></div> </div> <div class="hours"> <div class="hour"><p class="t">现在</p><p class="v">28°</p></div> <div class="hour"><p class="t">15时</p><p class="v">29°</p></div> <div class="hour"><p class="t">16时</p><p class="v">29°</p></div> <div class="hour"><p class="t">17时</p><p class="v">27°</p></div> <div class="hour"><p class="t">18时</p><p class="v">25°</p></div> </div> </div></div> </div> </div> <div class="glare"></div> </article> <!-- 🌬️ 大风 --> <article class="card windy" tabindex="0" role="button" aria-expanded="false"> <div class="scene"> <div class="windfield"></div> <div class="cloud back sm"></div><div class="cloud main"></div> </div> <div class="content"> <div class="row-top"> <span class="chip"><i class="dot" style="--c:#7fe3c4"></i>大风</span> <span class="chip warn">阵风 7 级</span> </div> <div class="bottom"> <p class="w-eng">WINDY</p><h2 class="w-name">大风</h2> <div class="temp"><span class="temp-num" data-target="21">0</span>°</div> <p class="range">最高 23° · 最低 17° · 体感 18°</p> <div class="reveal"><div> <p class="desc">阵风明显,出行请远离临时搭建物,注意高空坠物。</p> <div class="metrics"> <div class="metric"><p class="k">湿度</p><p class="v">55%</p></div> <div class="metric"><p class="k">阵风</p><p class="v">52 km/h</p></div> <div class="metric"><p class="k">风向</p><p class="v">西北</p></div> <div class="metric"><p class="k">能见度</p><p class="v">18 km</p></div> </div> <div class="hours"> <div class="hour"><p class="t">现在</p><p class="v">21°</p></div> <div class="hour"><p class="t">15时</p><p class="v">21°</p></div> <div class="hour"><p class="t">16时</p><p class="v">20°</p></div> <div class="hour"><p class="t">17时</p><p class="v">19°</p></div> <div class="hour"><p class="t">18时</p><p class="v">18°</p></div> </div> </div></div> </div> </div> <div class="glare"></div> </article> <!-- ⛈️ 暴雨 --> <article class="card rainstorm" tabindex="0" role="button" aria-expanded="false"> <div class="scene"> <div class="rain"></div> <div class="bolt"></div> <div class="cloud back sm"></div><div class="cloud main"></div> </div> <div class="flash-layer"></div> <div class="content"> <div class="row-top"> <span class="chip"><i class="dot" style="--c:#6db3ff"></i>暴雨</span> <span class="chip danger">雷电预警</span> </div> <div class="bottom"> <p class="w-eng">STORM</p><h2 class="w-name">暴雨</h2> <div class="temp"><span class="temp-num" data-target="23">0</span>°</div> <p class="range">最高 24° · 最低 20° · 体感 25°</p> <div class="reveal"><div> <p class="desc">雷雨持续,局地伴有强雷电,请减少外出避开积水。</p> <div class="metrics"> <div class="metric"><p class="k">湿度</p><p class="v">92%</p></div> <div class="metric"><p class="k">降水量</p><p class="v">38 mm</p></div> <div class="metric"><p class="k">风速</p><p class="v">24 km/h</p></div> <div class="metric"><p class="k">能见度</p><p class="v">1.2 km</p></div> </div> <div class="hours"> <div class="hour"><p class="t">现在</p><p class="v">23°</p></div> <div class="hour"><p class="t">15时</p><p class="v">22°</p></div> <div class="hour"><p class="t">16时</p><p class="v">22°</p></div> <div class="hour"><p class="t">17时</p><p class="v">21°</p></div> <div class="hour"><p class="t">18时</p><p class="v">21°</p></div> </div> </div></div> </div> </div> <div class="glare"></div> </article> <!-- 🌨️ 暴雪 --> <article class="card blizzard" tabindex="0" role="button" aria-expanded="false"> <div class="scene"> <div class="snowfield"></div> <div class="gusts"></div> <div class="cloud back sm"></div><div class="cloud main"></div> <div class="snow-ground g2"></div><div class="snow-ground g1"></div> </div> <div class="content"> <div class="row-top"> <span class="chip"><i class="dot" style="--c:#cfe9ff"></i>暴雪</span> <span class="chip danger">暴雪预警</span> </div> <div class="bottom"> <p class="w-eng">BLIZZARD</p><h2 class="w-name">暴雪</h2> <div class="temp"><span class="temp-num" data-target="-8">0</span>°</div> <p class="range">最高 -6° · 最低 -15° · 体感 -14°</p> <div class="reveal"><div> <p class="desc">暴雪橙色预警,道路湿滑结冰,请注意保暖与防滑。</p> <div class="metrics"> <div class="metric"><p class="k">湿度</p><p class="v">78%</p></div> <div class="metric"><p class="k">风速</p><p class="v">36 km/h</p></div> <div class="metric"><p class="k">积雪</p><p class="v">12 cm</p></div> <div class="metric"><p class="k">能见度</p><p class="v">0.8 km</p></div> </div> <div class="hours"> <div class="hour"><p class="t">现在</p><p class="v">-8°</p></div> <div class="hour"><p class="t">15时</p><p class="v">-9°</p></div> <div class="hour"><p class="t">16时</p><p class="v">-10°</p></div> <div class="hour"><p class="t">17时</p><p class="v">-11°</p></div> <div class="hour"><p class="t">18时</p><p class="v">-12°</p></div> </div> </div></div> </div> </div> <div class="glare"></div> </article> </main> <p class="hint">点击卡片展开 / 收起详情 · 悬停体验光影与 3D 视差</p> </div> <script> const rand = (a, b) => Math.random() * (b - a) + a; const cards = [...document.querySelectorAll('.card')]; /* ---------- 粒子生成 ---------- */ function spawn(sel, n, fn) { const box = document.querySelector(sel); if (!box) return; for (let i = 0; i < n; i++) box.appendChild(fn(i)); } // 太阳光芒 ×12 spawn('.sunny .rays', 12, i => { const r = document.createElement('i'); r.className = 'ray'; r.style.setProperty('--a', i * 30 + 'deg'); return r; }); // 雨滴 ×64 spawn('.rainstorm .rain', 64, () => { const d = document.createElement('span'); d.className = 'drop'; d.style.left = rand(0, 100) + '%'; d.style.height = rand(10, 20) + 'px'; d.style.opacity = rand(.3, .85); d.style.animationDuration = rand(.55, 1.05) + 's'; d.style.animationDelay = -rand(0, 2) + 's'; return d; }); // 雪花 ×46 spawn('.blizzard .snowfield', 46, () => { const f = document.createElement('span'); f.className = 'flake'; const s = rand(3, 8); f.style.width = f.style.height = s + 'px'; f.style.left = rand(-10, 100) + '%'; f.style.opacity = rand(.45, .95); f.style.setProperty('--dx', rand(30, 140) + 'px'); f.style.animationDuration = rand(4.5, 9) + 's'; f.style.animationDelay = -rand(0, 9) + 's'; if (Math.random() < .3) f.style.filter = 'blur(1px)'; return f; }); // 风线(大风 ×9,暴雪 ×5) const makeWindline = () => { const w = document.createElement('span'); w.className = 'windline'; w.style.top = rand(8, 82) + '%'; w.style.left = '-220px'; w.style.width = rand(80, 200) + 'px'; w.style.animationDuration = rand(1.6, 3.2) + 's'; w.style.animationDelay = -rand(0, 3) + 's'; return w; }; spawn('.windy .windfield', 9, makeWindline); spawn('.blizzard .gusts', 5, makeWindline); // 落叶 ×6 spawn('.windy .windfield', 6, () => { const l = document.createElement('span'); l.className = 'leaf'; l.style.left = '-40px'; l.style.top = rand(18, 72) + '%'; l.style.animationDuration = rand(3, 6) + 's'; l.style.animationDelay = -rand(0, 6) + 's'; return l; }); /* ---------- 卡片交互:点击展开 + 3D 视差 + 高光 ---------- */ cards.forEach(card => { card.addEventListener('click', () => { const on = card.classList.contains('active'); cards.forEach(c => { c.classList.remove('active'); c.setAttribute('aria-expanded', 'false'); }); if (!on) { card.classList.add('active'); card.setAttribute('aria-expanded', 'true'); } }); card.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); card.click(); } }); card.addEventListener('mousemove', e => { const r = card.getBoundingClientRect(); const x = e.clientX - r.left, y = e.clientY - r.top; card.style.setProperty('--mx', x + 'px'); card.style.setProperty('--my', y + 'px'); const ry = ((x / r.width) - .5) * 8; const rx = ((y / r.height) - .5) * -6; card.style.transform = `translateY(-6px) rotateX(${rx}deg) rotateY(${ry}deg)`; }); card.addEventListener('mouseleave', () => { card.style.transform = ''; }); }); /* ---------- 随机闪电 ---------- */ const storm = document.querySelector('.rainstorm'); (function lightning() { setTimeout(() => { storm.classList.add('flashing'); setTimeout(() => storm.classList.remove('flashing'), 900); lightning(); }, rand(2200, 7000)); })(); /* ---------- 温度数字滚动 ---------- */ document.querySelectorAll('.temp-num').forEach(el => { const target = parseInt(el.dataset.target, 10); const t0 = performance.now(), dur = 1500; (function step(now) { const p = Math.min((now - t0) / dur, 1); el.textContent = Math.round(target * (1 - Math.pow(1 - p, 3))); if (p < 1) requestAnimationFrame(step); })(t0); }); /* ---------- 实时时钟 ---------- */ const clockEl = document.getElementById('clockText'); const dateEl = document.getElementById('dateText'); const weeks = ['周日','周一','周二','周三','周四','周五','周六']; function tick() { const d = new Date(), p = n => String(n).padStart(2, '0'); clockEl.textContent = `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}`; dateEl.textContent = `${d.getMonth() + 1}月${d.getDate()}日 ${weeks[d.getDay()]}`; } tick(); setInterval(tick, 1000); </script> </body> </html> 15 个帖子 - 10 位参与者 阅读完整话题

v2ex · 2026-06-02 20:56:15+08:00 · tech

V 站大佬们!我们的实时数字人 OpenTalking 支持视频克隆模式啦! 同时支持调整面部动作幅度,能玩出来很抽象的东西哈哈哈~ ** 麻烦走过路过感兴趣的可以支持我们,在 Github 点个 Star! ** 你们的支持是我们一直保持免费和开源的力量! Github 传送: https://github.com/datascale-ai/opentalking 视频演示: https://www.bilibili.com/video/BV1d6VB6iE15/?vd_source=4820076c616e58ceb357c528a571ff11 欢迎大家体验!多多提意见!

v2ex · 2026-06-02 19:56:30+08:00 · tech

V 站大佬们!我们的实时数字人 OpenTalking 支持视频克隆模式啦! 同时支持调整面部动作幅度,能玩出来很抽象的东西哈哈哈~ ** 麻烦走过路过感兴趣的可以支持我们,在 Github 点个 Star! ** 你们的支持是我们一直保持免费和开源的力量! Github 传送: https://github.com/datascale-ai/opentalking 视频演示: https://www.bilibili.com/video/BV1d6VB6iE15/?vd_source=4820076c616e58ceb357c528a571ff11 欢迎大家体验!多多提意见!

v2ex · 2026-06-02 19:56:30+08:00 · tech

V 站大佬们!我们的实时数字人 OpenTalking 支持视频克隆模式啦! 同时支持调整面部动作幅度,能玩出来很抽象的东西哈哈哈~ ** 麻烦走过路过感兴趣的可以支持我们,在 Github 点个 Star! ** 你们的支持是我们一直保持免费和开源的力量! Github 传送: https://github.com/datascale-ai/opentalking 视频演示: https://www.bilibili.com/video/BV1d6VB6iE15/?vd_source=4820076c616e58ceb357c528a571ff11 欢迎大家体验!多多提意见!

v2ex · 2026-06-02 18:40:56+08:00 · tech

V 站大佬们!我们的实时数字人 OpenTalking 支持视频克隆模式啦! 同时支持调整面部动作幅度,能玩出来很抽象的东西哈哈哈~ ** 麻烦走过路过感兴趣的可以支持我们,在 Github 点个 Star! ** 你们的支持是我们一直保持免费和开源的力量! Github 传送: https://github.com/datascale-ai/opentalking 视频演示: https://www.bilibili.com/video/BV1d6VB6iE15/?vd_source=4820076c616e58ceb357c528a571ff11 欢迎大家体验!多多提意见!

LinuxDo 最新话题 · 2026-06-01 10:52:01+08:00 · tech

各位佬,难道刷L站就我卡?如果不是你们怎么解决的? 无论是打开话题、加载帖子、回复评论都是卡卡的,有时转半天 我公司的win和家里的mac都是这样,佬你们也这样吗? 之前新窗口开帖子还计数的时候我都是打开好几个感兴趣的话题慢慢看,那时候还能接受,自从新窗口打开话题不计数,只能一个个打开、后退的看帖子,这时候就感觉累到不行了,每天都看不了几个话题了 3 个帖子 - 3 位参与者 阅读完整话题

LinuxDo 最新话题 · 2026-05-25 11:46:55+08:00 · tech

奖品详情: TK截流软件卡密卡密卡密(月卡),目前支持区域如图,支持类目,关键词,整店,商品分析(部分区部分接口不可用),做跨境的佬友绝对用得上! 活动时间: 开始时间:[2026 年 5 月 25 日 12:00] 截止时间:[2026 年 5 月 25 日 23:00] 参与方式: 在本帖下回复任意内容。 抽奖规则: 每位用户仅允许参与一次。 使用 官方抽奖工具 随机抽取中奖者。 注意事项: 本活动将在活动截止时间后关闭回帖,以确保公正性。 中奖者将在活动结束后 12 小时内在本帖公布,并通过私信通知领奖方式。 所有规则及抽奖结果由活动发起人和论坛 管理团队 最终解释。 期待您的积极参与,祝您好运!如有任何疑问,欢迎随时联系抽奖发起人。 3 个帖子 - 3 位参与者 阅读完整话题