有没有人和我一样,被 Claude Code 的价格劝退了? 实话实说,CC 的代码理解能力真的强,分析项目、重构代码一把好手,但现在稍微正经一点的开发任务,单次就要 5 美元,天天用钱包真的扛不住,咬咬牙换成了 OpenAI Codex。 我现在用cc让他理解一下我的需求,让它给出方案,代码就不让它写了,找了CodeX写,手上多几个大模型工具写代码,互相切。现在cc已经是备用了,可能后期慢慢会脱离CC,转战到其他大模型。说白了还不是兜里没钱,玩不起了! 1 个帖子 - 1 位参与者 阅读完整话题
说实话一般,而且页面卡卡的掉帧 <!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 位参与者 阅读完整话题
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
现在一水儿的“Vibe 了一个 XXX ”,说实话我想看点不那么 AI 的创意。
玩了一段时间说实话,游戏打击感感觉还不错,新赛季的剧情短板也提升了很多,虽然bug还有不少,但是整体感觉是一款不错的游戏。 但是挺奇怪的,这游戏好像一直都没有太大的流量,找攻略都不容易 ,有佬知道这游戏 没流量 (攻略少)的原因吗。 15 个帖子 - 9 位参与者 阅读完整话题
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!
这年初在 Awwwards 上刷到 Messenger 项目,真的一眼惊艳。说实话,Web 游戏这几年很少看到让人眼前一亮的突破,但这个作品实在太“游戏”了——艺术与技术完美融合,忍不住反复看了好几遍。 好奇驱动下,我于 2026 年 6 月参考原作 messenger.abeto.co 并复刻了 Web 端版本。后台逻辑保持一致(每房间上限 10 人),感谢原作资源。仅限研究 / 技术体验,非商用。 🔗 体验复刻的地址: messenger ,快来通关!