LongCat-2.0-Preview 天气卡片,全程基于国产算力集群训练
- 内容介绍
- 文章标签
- 相关推荐
昨天申请的内测体验,今天通过了,据说是全程基于国产算力集群训练
美团万亿级大模型 LongCat-2.0-Preview 开放测试,全程基于国产算力集群训练 前沿快讯[image] 美团万亿级大模型 LongCat-2.0-Preview 开放测试,全程基于国产算力集群训练 - IT之家
CC里花了12分钟
提示词
你是 Apple Inc 的顶级 UI 设计师,以 iOS 18 的设计风格(毛玻璃效果、高斯模糊、动态渐变、细腻阴影)创建一个单个 HTML 文件(包含完整 CSS 和 JavaScript)。实现横板天气页面,包含 4 个并排的动画天气卡片:
晴天(太阳光线、动态光晕)
大风(飘动云朵、摇曳树木、风线)
暴雨(下落雨滴、形成水洼、闪电)
暴雪(下落雪花、堆积效果)
卡片需深色背景,支持按钮切换天气状态,实现流畅交互和微动效。代码必须可直接运行,美观度优先。
效果
image1920×1039 117 KB
代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather - iOS 18 Style</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
:root{
--glass:rgba(255,255,255,0.06);--gborder:rgba(255,255,255,0.1);
--ghi:rgba(255,255,255,0.16);--tp:rgba(255,255,255,0.95);
--ts:rgba(255,255,255,0.55);--tt:rgba(255,255,255,0.35);
}
html,body{width:100%;height:100%;overflow:hidden;background:#08080f;
font-family:-apple-system,BlinkMacSystemFont,'Inter','SF Pro Display','Helvetica Neue',sans-serif;
color:var(--tp);-webkit-font-smoothing:antialiased}
/* ===== ambient ===== */
#ambient{position:fixed;inset:0;z-index:0;transition:background 1.2s ease;
background:radial-gradient(ellipse 120% 80% at 20% 50%,#1a1040 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 80% 40%,#0d2847 0%,transparent 55%),
radial-gradient(ellipse 80% 90% at 50% 100%,#1a0a2e 0%,transparent 50%),#08080f}
#ambient.sunny{background:radial-gradient(ellipse 120% 80% at 25% 30%,#4a3000 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 75% 50%,#1a2040 0%,transparent 55%),#08080f}
#ambient.windy{background:radial-gradient(ellipse 120% 80% at 30% 40%,#1a2a4a 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 70% 50%,#0d1f3d 0%,transparent 55%),#08080f}
#ambient.rainy{background:radial-gradient(ellipse 120% 80% at 50% 30%,#0a1628 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 60% 60%,#0d1520 0%,transparent 55%),#05050a}
#ambient.snowy{background:radial-gradient(ellipse 120% 80% at 40% 40%,#1a2035 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 60% 50%,#0f1a2e 0%,transparent 55%),#08080f}
.orb{position:fixed;border-radius:50%;filter:blur(90px);opacity:0.35;pointer-events:none;z-index:0;
transition:all 1.5s ease}
.orb1{width:420px;height:420px;top:-12%;left:-6%;background:radial-gradient(circle,rgba(120,80,255,0.3),transparent 70%)}
.orb2{width:360px;height:360px;bottom:-16%;right:-6%;background:radial-gradient(circle,rgba(40,120,255,0.25),transparent 70%)}
.orb3{width:280px;height:280px;top:38%;left:38%;background:radial-gradient(circle,rgba(255,100,50,0.12),transparent 70%)}
/* ===== header ===== */
.hd{position:relative;z-index:10;padding:26px 36px 12px;display:flex;align-items:center;justify-content:space-between}
.hd h1{font-size:26px;font-weight:700;letter-spacing:-0.5px;
background:linear-gradient(135deg,rgba(255,255,255,0.95),rgba(255,255,255,0.6));
-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hd .sub{font-size:12px;color:var(--tt);margin-top:2px}
/* ===== selector ===== */
.sel{position:relative;z-index:10;display:flex;gap:8px;padding:0 36px 18px}
.sel button{padding:7px 18px;border-radius:18px;border:1px solid var(--gborder);
background:var(--glass);color:var(--ts);font-size:12px;font-weight:500;
backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
transition:all .35s cubic-bezier(.4,0,.2,1);font-family:inherit;cursor:pointer}
.sel button:hover{background:rgba(255,255,255,0.1);color:var(--tp);transform:scale(1.04)}
.sel button.on{background:rgba(255,255,255,0.15);color:var(--tp);
border-color:rgba(255,255,255,0.25);box-shadow:0 2px 12px rgba(0,0,0,.3)}
/* ===== cards ===== */
.cards{position:relative;z-index:5;display:flex;gap:18px;padding:0 36px 36px;
height:calc(100vh - 130px);perspective:1200px}
.card{flex:1;min-width:0;border-radius:26px;overflow:hidden;position:relative;
cursor:pointer;border:1px solid var(--gborder);background:var(--glass);
backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);
transition:all .5s cubic-bezier(.4,0,.2,1);transform:translateZ(0);
animation:cardIn .8s cubic-bezier(.4,0,.2,1) both}
.card:nth-child(1){animation-delay:.1s}
.card:nth-child(2){animation-delay:.2s}
.card:nth-child(3){animation-delay:.3s}
.card:nth-child(4){animation-delay:.4s}
@keyframes cardIn{from{opacity:0;transform:translateY(40px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
.card::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
background:linear-gradient(180deg,rgba(255,255,255,0.07) 0%,transparent 38%,rgba(0,0,0,0.35) 100%)}
.card:hover{transform:translateY(-5px) scale(1.02);
box-shadow:0 20px 60px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.15)}
.card.active{flex:1.35;box-shadow:0 24px 80px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.2)}
.scene{position:absolute;inset:0;overflow:hidden}
.info{position:absolute;bottom:0;left:0;right:0;z-index:5;padding:22px 18px;
background:linear-gradient(transparent,rgba(0,0,0,.72) 40%)}
.temp{font-size:48px;font-weight:300;line-height:1;letter-spacing:-2px;margin-bottom:5px}
.lbl{font-size:14px;font-weight:500;color:var(--ts);letter-spacing:-.2px}
.det{font-size:11px;color:var(--tt);margin-top:3px}
/* ===== SUNNY ===== */
.sun-wrap{position:absolute;top:14%;left:50%;transform:translateX(-50%);width:110px;height:110px}
.sun-glow{position:absolute;inset:-45px;border-radius:50%;
background:radial-gradient(circle,rgba(255,200,50,.55) 0%,rgba(255,150,0,.25) 30%,transparent 70%);
animation:sunP 3s ease-in-out infinite}
.sun-core{position:absolute;inset:18px;border-radius:50%;
background:radial-gradient(circle,#fff7e0,#ffd700);
box-shadow:0 0 40px rgba(255,200,50,.8),0 0 80px rgba(255,150,0,.4);
animation:sunC 3s ease-in-out infinite}
@keyframes sunP{0%,100%{transform:scale(1);opacity:.8}50%{transform:scale(1.18);opacity:1}}
@keyframes sunC{0%,100%{box-shadow:0 0 40px rgba(255,200,50,.8),0 0 80px rgba(255,150,0,.4)}
50%{box-shadow:0 0 60px rgba(255,200,50,1),0 0 120px rgba(255,150,0,.6)}}
.sun-rays{position:absolute;inset:0;animation:sunR 20s linear infinite}
@keyframes sunR{from{transform:rotate(0)}to{transform:rotate(360deg)}}
.sun-ray{position:absolute;top:50%;left:50%;width:3px;height:28px;
background:linear-gradient(to top,rgba(255,200,50,.8),transparent);
transform-origin:center -24px;border-radius:2px}
.lparticle{position:absolute;width:4px;height:4px;background:rgba(255,220,100,.8);
border-radius:50%;animation:floatP 4s ease-in-out infinite;
box-shadow:0 0 6px rgba(255,220,100,.6)}
@keyframes floatP{0%,100%{transform:translateY(0) translateX(0);opacity:0}
20%{opacity:1}50%{transform:translateY(-60px) translateX(20px);opacity:.7}80%{opacity:.2}}
/* ===== WINDY ===== */
.cloud{position:absolute;border-radius:50px;
background:linear-gradient(180deg,rgba(180,195,215,.6),rgba(140,155,175,.35));
filter:blur(.5px);animation:cFloat linear infinite}
.cloud::before,.cloud::after{content:'';position:absolute;border-radius:50%;background:inherit}
.c1{width:100px;height:28px;top:14%;left:-20%;animation-duration:12s}
.c1::before{width:38px;height:38px;top:-19px;left:14px}
.c1::after{width:52px;height:52px;top:-28px;left:38px}
.c2{width:78px;height:22px;top:26%;left:-30%;animation-duration:16s;animation-delay:-5s}
.c2::before{width:30px;height:30px;top:-15px;left:11px}
.c2::after{width:40px;height:40px;top:-23px;left:30px}
.c3{width:68px;height:20px;top:9%;left:-15%;animation-duration:10s;animation-delay:-8s}
.c3::before{width:26px;height:26px;top:-13px;left:9px}
.c3::after{width:36px;height:36px;top:-21px;left:26px}
@keyframes cFloat{from{transform:translateX(0)}to{transform:translateX(calc(100vw + 250px))}}
.wind-line{position:absolute;height:2px;
background:linear-gradient(90deg,transparent,rgba(200,215,235,.45),transparent);
border-radius:1px;animation:wMove linear infinite}
@keyframes wMove{0%{transform:translateX(-100%);opacity:0}20%{opacity:1}80%{opacity:1}
100%{transform:translateX(calc(100% + 200px));opacity:0}}
.tree{position:absolute;bottom:0}
.trunk{position:absolute;bottom:0;left:50%;transform:translateX(-50%);
width:7px;background:linear-gradient(180deg,#4a3728,#2a1f16);border-radius:3px 3px 0 0}
.foliage{position:absolute;border-radius:50%;transform-origin:center bottom;
animation:tSway 2s ease-in-out infinite}
@keyframes tSway{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(6deg)}}
/* ===== RAINY ===== */
.raindrop{position:absolute;width:2px;
background:linear-gradient(to bottom,transparent,rgba(120,170,255,.55),rgba(120,170,255,.25));
border-radius:0 0 2px 2px;animation:rFall linear infinite}
@keyframes rFall{0%{transform:translateY(-20px);opacity:0}10%{opacity:1}90%{opacity:1}
100%{transform:translateY(400px);opacity:0}}
.puddle{border-radius:50%;position:absolute;bottom:0;
background:radial-gradient(ellipse,rgba(80,140,255,.28),rgba(80,140,255,.08));
border:1px solid rgba(100,160,255,.12);animation:pRipple 2.5s ease-in-out infinite}
@keyframes pRipple{0%,100%{transform:scaleX(1)}50%{transform:scaleX(1.12)}}
.splash{position:absolute;bottom:6px;width:5px;height:5px;border-radius:50%;
background:rgba(120,170,255,.45);animation:sUp .6s ease-out infinite}
@keyframes sUp{0%{transform:translateY(0) scale(0);opacity:1}
100%{transform:translateY(-14px) scale(1.5);opacity:0}}
.lightning{position:absolute;inset:0;z-index:3;background:rgba(200,180,255,0);
pointer-events:none;animation:lFlash 5s ease-in infinite}
@keyframes lFlash{0%,89%,91%,93%,100%{background:rgba(200,180,255,0)}90%,92%{background:rgba(200,180,255,.15)}}
.bolt{position:absolute;top:3%;left:25%;width:50%;opacity:0;filter:blur(.5px);
animation:bFlash 5s ease-in infinite}
@keyframes bFlash{0%,89.5%,91%,92.5%,100%{opacity:0}90%,90.5%,91.5%,92%{opacity:1}}
/* ===== SNOWY ===== */
.snowflake{position:absolute;animation:sNow linear infinite;pointer-events:none;
color:rgba(220,230,255,.85);text-shadow:0 0 5px rgba(200,220,255,.5)}
@keyframes sNow{0%{transform:translateY(-20px) rotate(0);opacity:0}
10%{opacity:1}90%{opacity:.7}100%{transform:translateY(420px) rotate(360deg);opacity:0}}
.snow-ground{position:absolute;bottom:0;left:0;right:0;
background:linear-gradient(180deg,transparent 0%,rgba(200,215,240,.12) 30%,rgba(200,215,240,.28) 100%);
border-radius:42% 48% 0 0 / 16% 18% 0 0;animation:sAccum 6s ease-in-out infinite alternate}
@keyframes sAccum{from{height:18px}to{height:32px}}
.snow-mound{position:absolute;bottom:0;border-radius:50% 50% 0 0;
background:linear-gradient(180deg,rgba(210,225,250,.38),rgba(200,215,240,.18));
animation:mGrow 8s ease-in-out infinite alternate}
@keyframes mGrow{from{transform:scaleY(.88)}to{transform:scaleY(1.12)}}
/* ===== responsive ===== */
@media(max-width:860px){
.cards{flex-wrap:wrap;height:auto;content:""}
.card{flex:1 1 calc(50% - 9px);min-height:260px}
.card.active{flex:1 1 calc(50% - 9px)}
}
</style>
</head>
<body>
<div id="ambient"></div>
<div class="orb orb1"></div><div class="orb orb2"></div><div class="orb orb3"></div>
<div class="hd">
<div>
<h1>Weather</h1>
<div class="sub">Apple Weather · 2026.04.25</div>
</div>
</div>
<div class="sel">
<button class="on" data-w="sunny">☀️ 晴天</button>
<button data-w="windy">💨 大风</button>
<button data-w="rainy">🌧️ 暴雨</button>
<button data-w="snowy">❄️ 暴雪</button>
</div>
<div class="cards" id="cards">
<!-- SUNNY -->
<div class="card active" data-card="sunny">
<div class="scene" id="sScene"></div>
<div class="info">
<div class="temp">28°</div>
<div class="lbl">晴天 Sunny</div>
<div class="det">体感 30° · 湿度 45%</div>
</div>
</div>
<!-- WINDY -->
<div class="card" data-card="windy">
<div class="scene" id="wScene"></div>
<div class="info">
<div class="temp">18°</div>
<div class="lbl">大风 Windy</div>
<div class="det">风速 45km/h · 阵风 62km/h</div>
</div>
</div>
<!-- RAINY -->
<div class="card" data-card="rainy">
<div class="scene" id="rScene"></div>
<div class="info">
<div class="temp">14°</div>
<div class="lbl">暴雨 Rainy</div>
<div class="det">降水量 48mm · 能见度 2km</div>
</div>
</div>
<!-- SNOWY -->
<div class="card" data-card="snowy">
<div class="scene" id="snScene"></div>
<div class="info">
<div class="temp">-4°</div>
<div class="lbl">暴雪 Snowy</div>
<div class="det">积雪 12cm · 能见度 500m</div>
</div>
</div>
</div>
<script>
const $ = s => document.querySelector(s);
const $$ = s => document.querySelectorAll(s);
const rand = (a, b) => Math.random() * (b - a) + a;
const randInt = (a, b) => Math.floor(rand(a, b));
/* ===== state ===== */
let currentWeather = 'sunny';
$$('.sel button').forEach(btn => {
btn.addEventListener('click', () => {
$$('.sel button').forEach(b => b.classList.remove('on'));
btn.classList.add('on');
setWeather(btn.dataset.w);
});
});
$$('.card').forEach(card => {
card.addEventListener('click', () => {
const w = card.dataset.card;
$$('.sel button').forEach(b => b.classList.toggle('on', b.dataset.w === w));
setWeather(w);
});
});
function setWeather(w) {
currentWeather = w;
$('#ambient').className = w;
$$('.card').forEach(c => c.classList.toggle('active', c.dataset.card === w));
}
/* ===== SUNNY ===== */
function buildSunny() {
const s = $('#sScene');
s.innerHTML = '';
// sun
const wrap = document.createElement('div');
wrap.className = 'sun-wrap';
wrap.innerHTML = '<div class="sun-glow"></div><div class="sun-rays" id="rays"></div><div class="sun-core"></div>';
s.appendChild(wrap);
// rays
const rays = wrap.querySelector('.sun-rays');
for (let i = 0; i < 12; i++) {
const r = document.createElement('div');
r.className = 'sun-ray';
r.style.transform = `rotate(${i * 30}deg)`;
rays.appendChild(r);
}
// particles
for (let i = 0; i < 15; i++) {
const p = document.createElement('div');
p.className = 'lparticle';
p.style.left = rand(10, 90) + '%';
p.style.top = rand(10, 70) + '%';
p.style.animationDelay = rand(0, 4).toFixed(1) + 's';
p.style.animationDuration = rand(3, 6).toFixed(1) + 's';
s.appendChild(p);
}
}
/* ===== WINDY ===== */
function buildWindy() {
const s = $('#wScene');
s.innerHTML = '';
// clouds
[1, 2, 3].forEach(i => {
const c = document.createElement('div');
c.className = `cloud c${i}`;
s.appendChild(c);
});
// wind lines
for (let i = 0; i < 8; i++) {
const wl = document.createElement('div');
wl.className = 'wind-line';
wl.style.top = rand(5, 80) + '%';
wl.style.width = rand(60, 180) + 'px';
wl.style.animationDuration = rand(2, 5).toFixed(1) + 's';
wl.style.animationDelay = rand(0, 4).toFixed(1) + 's';
s.appendChild(wl);
}
// trees
const treePositions = [15, 45, 75];
treePositions.forEach((x, idx) => {
const tree = document.createElement('div');
tree.className = 'tree';
tree.style.left = x + '%';
const h = rand(70, 120);
const trunk = document.createElement('div');
trunk.className = 'trunk';
trunk.style.height = h + 'px';
tree.appendChild(trunk);
const fCount = randInt(2, 4);
for (let j = 0; j < fCount; j++) {
const f = document.createElement('div');
f.className = 'foliage';
const size = rand(30, 55);
f.style.width = size + 'px';
f.style.height = size * 0.7 + 'px';
f.style.bottom = (h * 0.5 + j * h * 0.22) + 'px';
f.style.left = '50%';
f.style.transform = 'translateX(-50%)';
f.style.background = `radial-gradient(ellipse, rgba(${50+idx*20},${120+idx*15},${50+idx*10},.7), rgba(${30+idx*15},${80+idx*10},${30+idx*8},.5))`;
f.style.animationDelay = rand(0, 1).toFixed(1) + 's';
f.style.animationDuration = rand(1.5, 3).toFixed(1) + 's';
tree.appendChild(f);
}
s.appendChild(tree);
});
}
/* ===== RAINY ===== */
function buildRainy() {
const s = $('#rScene');
s.innerHTML = '';
// dark cloud
const dc = document.createElement('div');
dc.style.cssText = 'position:absolute;top:3%;left:10%;width:80%;height:35px;border-radius:25px;' +
'background:linear-gradient(180deg,rgba(60,70,90,.7),rgba(40,50,70,.5));filter:blur(2px)';
s.appendChild(dc);
const dc2 = document.createElement('div');
dc2.style.cssText = 'position:absolute;top:0%;left:25%;width:50%;height:50px;border-radius:50%;' +
'background:rgba(55,65,85,.6);filter:blur(3px)';
s.appendChild(dc2);
// raindrops
for (let i = 0; i < 60; i++) {
const rd = document.createElement('div');
rd.className = 'raindrop';
rd.style.left = rand(0, 100) + '%';
rd.style.height = rand(12, 28) + 'px';
rd.style.animationDuration = rand(0.4, 0.9).toFixed(2) + 's';
rd.style.animationDelay = rand(0, 2).toFixed(2) + 's';
rd.style.opacity = rand(0.3, 0.8).toFixed(1);
s.appendChild(rd);
}
// puddles
const puddles = [
{ left: '10%', width: '28%', delay: 0 },
{ left: '45%', width: '22%', delay: 0.8 },
{ left: '72%', width: '20%', delay: 1.5 },
];
puddles.forEach(p => {
const pd = document.createElement('div');
pd.className = 'puddle';
pd.style.left = p.left;
pd.style.width = p.width;
pd.style.height = '8px';
pd.style.animationDelay = p.delay + 's';
s.appendChild(pd);
// splashes
for (let i = 0; i < 3; i++) {
const sp = document.createElement('div');
sp.className = 'splash';
sp.style.left = rand(20, 80) + '%';
sp.style.animationDelay = rand(0, 0.6).toFixed(2) + 's';
sp.style.animationDuration = rand(0.4, 0.8).toFixed(2) + 's';
pd.appendChild(sp);
}
});
// lightning
const lt = document.createElement('div');
lt.className = 'lightning';
s.appendChild(lt);
const bolt = document.createElement('div');
bolt.className = 'bolt';
bolt.innerHTML = '<svg viewBox="0 0 100 200" fill="none">' +
'<path d="M55 0 L30 80 L50 80 L40 200 L70 90 L50 90 L65 0 Z"' +
' fill="rgba(200,180,255,0.9)" stroke="rgba(180,160,255,0.5)" stroke-width="1"/>' +
'</svg>';
s.appendChild(bolt);
}
/* ===== SNOWY ===== */
function buildSnowy() {
const s = $('#snScene');
s.innerHTML = '';
// snowflakes
const flakeChars = ['❄', '❅', '❆', '•', '∗'];
for (let i = 0; i < 50; i++) {
const sf = document.createElement('div');
sf.className = 'snowflake';
sf.textContent = flakeChars[randInt(0, flakeChars.length)];
sf.style.left = rand(0, 100) + '%';
sf.style.fontSize = rand(8, 24) + 'px';
sf.style.animationDuration = rand(4, 10).toFixed(1) + 's';
sf.style.animationDelay = rand(0, 6).toFixed(1) + 's';
sf.style.opacity = rand(0.4, 0.9).toFixed(1);
s.appendChild(sf);
}
// ground snow
const ground = document.createElement('div');
ground.className = 'snow-ground';
s.appendChild(ground);
// mounds
const mounds = [
{ left: '5%', width: '30%', delay: 0 },
{ left: '38%', width: '25%', delay: 2 },
{ left: '68%', width: '28%', delay: 4 },
];
mounds.forEach(m => {
const md = document.createElement('div');
md.className = 'snow-mound';
md.style.left = m.left;
md.style.width = m.width;
md.style.height = rand(20, 40) + 'px';
md.style.animationDelay = m.delay + 's';
s.appendChild(md);
});
}
/* ===== init ===== */
buildSunny();
buildWindy();
buildRainy();
buildSnowy();
setWeather('sunny');
</script>
</body>
</html>
--【壹】--:
image1475×806 89.8 KB
动态效果:
--【贰】--:
LongCat大模型,没有工具调用,除了聊天,啥也干不了
--【叁】--:
image1920×1010 80.9 KB
3m38s,好像还可以
昨天申请的内测体验,今天通过了,据说是全程基于国产算力集群训练
美团万亿级大模型 LongCat-2.0-Preview 开放测试,全程基于国产算力集群训练 前沿快讯[image] 美团万亿级大模型 LongCat-2.0-Preview 开放测试,全程基于国产算力集群训练 - IT之家
CC里花了12分钟
提示词
你是 Apple Inc 的顶级 UI 设计师,以 iOS 18 的设计风格(毛玻璃效果、高斯模糊、动态渐变、细腻阴影)创建一个单个 HTML 文件(包含完整 CSS 和 JavaScript)。实现横板天气页面,包含 4 个并排的动画天气卡片:
晴天(太阳光线、动态光晕)
大风(飘动云朵、摇曳树木、风线)
暴雨(下落雨滴、形成水洼、闪电)
暴雪(下落雪花、堆积效果)
卡片需深色背景,支持按钮切换天气状态,实现流畅交互和微动效。代码必须可直接运行,美观度优先。
效果
image1920×1039 117 KB
代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather - iOS 18 Style</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
:root{
--glass:rgba(255,255,255,0.06);--gborder:rgba(255,255,255,0.1);
--ghi:rgba(255,255,255,0.16);--tp:rgba(255,255,255,0.95);
--ts:rgba(255,255,255,0.55);--tt:rgba(255,255,255,0.35);
}
html,body{width:100%;height:100%;overflow:hidden;background:#08080f;
font-family:-apple-system,BlinkMacSystemFont,'Inter','SF Pro Display','Helvetica Neue',sans-serif;
color:var(--tp);-webkit-font-smoothing:antialiased}
/* ===== ambient ===== */
#ambient{position:fixed;inset:0;z-index:0;transition:background 1.2s ease;
background:radial-gradient(ellipse 120% 80% at 20% 50%,#1a1040 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 80% 40%,#0d2847 0%,transparent 55%),
radial-gradient(ellipse 80% 90% at 50% 100%,#1a0a2e 0%,transparent 50%),#08080f}
#ambient.sunny{background:radial-gradient(ellipse 120% 80% at 25% 30%,#4a3000 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 75% 50%,#1a2040 0%,transparent 55%),#08080f}
#ambient.windy{background:radial-gradient(ellipse 120% 80% at 30% 40%,#1a2a4a 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 70% 50%,#0d1f3d 0%,transparent 55%),#08080f}
#ambient.rainy{background:radial-gradient(ellipse 120% 80% at 50% 30%,#0a1628 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 60% 60%,#0d1520 0%,transparent 55%),#05050a}
#ambient.snowy{background:radial-gradient(ellipse 120% 80% at 40% 40%,#1a2035 0%,transparent 60%),
radial-gradient(ellipse 100% 70% at 60% 50%,#0f1a2e 0%,transparent 55%),#08080f}
.orb{position:fixed;border-radius:50%;filter:blur(90px);opacity:0.35;pointer-events:none;z-index:0;
transition:all 1.5s ease}
.orb1{width:420px;height:420px;top:-12%;left:-6%;background:radial-gradient(circle,rgba(120,80,255,0.3),transparent 70%)}
.orb2{width:360px;height:360px;bottom:-16%;right:-6%;background:radial-gradient(circle,rgba(40,120,255,0.25),transparent 70%)}
.orb3{width:280px;height:280px;top:38%;left:38%;background:radial-gradient(circle,rgba(255,100,50,0.12),transparent 70%)}
/* ===== header ===== */
.hd{position:relative;z-index:10;padding:26px 36px 12px;display:flex;align-items:center;justify-content:space-between}
.hd h1{font-size:26px;font-weight:700;letter-spacing:-0.5px;
background:linear-gradient(135deg,rgba(255,255,255,0.95),rgba(255,255,255,0.6));
-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hd .sub{font-size:12px;color:var(--tt);margin-top:2px}
/* ===== selector ===== */
.sel{position:relative;z-index:10;display:flex;gap:8px;padding:0 36px 18px}
.sel button{padding:7px 18px;border-radius:18px;border:1px solid var(--gborder);
background:var(--glass);color:var(--ts);font-size:12px;font-weight:500;
backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
transition:all .35s cubic-bezier(.4,0,.2,1);font-family:inherit;cursor:pointer}
.sel button:hover{background:rgba(255,255,255,0.1);color:var(--tp);transform:scale(1.04)}
.sel button.on{background:rgba(255,255,255,0.15);color:var(--tp);
border-color:rgba(255,255,255,0.25);box-shadow:0 2px 12px rgba(0,0,0,.3)}
/* ===== cards ===== */
.cards{position:relative;z-index:5;display:flex;gap:18px;padding:0 36px 36px;
height:calc(100vh - 130px);perspective:1200px}
.card{flex:1;min-width:0;border-radius:26px;overflow:hidden;position:relative;
cursor:pointer;border:1px solid var(--gborder);background:var(--glass);
backdrop-filter:blur(40px);-webkit-backdrop-filter:blur(40px);
transition:all .5s cubic-bezier(.4,0,.2,1);transform:translateZ(0);
animation:cardIn .8s cubic-bezier(.4,0,.2,1) both}
.card:nth-child(1){animation-delay:.1s}
.card:nth-child(2){animation-delay:.2s}
.card:nth-child(3){animation-delay:.3s}
.card:nth-child(4){animation-delay:.4s}
@keyframes cardIn{from{opacity:0;transform:translateY(40px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}
.card::before{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
background:linear-gradient(180deg,rgba(255,255,255,0.07) 0%,transparent 38%,rgba(0,0,0,0.35) 100%)}
.card:hover{transform:translateY(-5px) scale(1.02);
box-shadow:0 20px 60px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.15)}
.card.active{flex:1.35;box-shadow:0 24px 80px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.2)}
.scene{position:absolute;inset:0;overflow:hidden}
.info{position:absolute;bottom:0;left:0;right:0;z-index:5;padding:22px 18px;
background:linear-gradient(transparent,rgba(0,0,0,.72) 40%)}
.temp{font-size:48px;font-weight:300;line-height:1;letter-spacing:-2px;margin-bottom:5px}
.lbl{font-size:14px;font-weight:500;color:var(--ts);letter-spacing:-.2px}
.det{font-size:11px;color:var(--tt);margin-top:3px}
/* ===== SUNNY ===== */
.sun-wrap{position:absolute;top:14%;left:50%;transform:translateX(-50%);width:110px;height:110px}
.sun-glow{position:absolute;inset:-45px;border-radius:50%;
background:radial-gradient(circle,rgba(255,200,50,.55) 0%,rgba(255,150,0,.25) 30%,transparent 70%);
animation:sunP 3s ease-in-out infinite}
.sun-core{position:absolute;inset:18px;border-radius:50%;
background:radial-gradient(circle,#fff7e0,#ffd700);
box-shadow:0 0 40px rgba(255,200,50,.8),0 0 80px rgba(255,150,0,.4);
animation:sunC 3s ease-in-out infinite}
@keyframes sunP{0%,100%{transform:scale(1);opacity:.8}50%{transform:scale(1.18);opacity:1}}
@keyframes sunC{0%,100%{box-shadow:0 0 40px rgba(255,200,50,.8),0 0 80px rgba(255,150,0,.4)}
50%{box-shadow:0 0 60px rgba(255,200,50,1),0 0 120px rgba(255,150,0,.6)}}
.sun-rays{position:absolute;inset:0;animation:sunR 20s linear infinite}
@keyframes sunR{from{transform:rotate(0)}to{transform:rotate(360deg)}}
.sun-ray{position:absolute;top:50%;left:50%;width:3px;height:28px;
background:linear-gradient(to top,rgba(255,200,50,.8),transparent);
transform-origin:center -24px;border-radius:2px}
.lparticle{position:absolute;width:4px;height:4px;background:rgba(255,220,100,.8);
border-radius:50%;animation:floatP 4s ease-in-out infinite;
box-shadow:0 0 6px rgba(255,220,100,.6)}
@keyframes floatP{0%,100%{transform:translateY(0) translateX(0);opacity:0}
20%{opacity:1}50%{transform:translateY(-60px) translateX(20px);opacity:.7}80%{opacity:.2}}
/* ===== WINDY ===== */
.cloud{position:absolute;border-radius:50px;
background:linear-gradient(180deg,rgba(180,195,215,.6),rgba(140,155,175,.35));
filter:blur(.5px);animation:cFloat linear infinite}
.cloud::before,.cloud::after{content:'';position:absolute;border-radius:50%;background:inherit}
.c1{width:100px;height:28px;top:14%;left:-20%;animation-duration:12s}
.c1::before{width:38px;height:38px;top:-19px;left:14px}
.c1::after{width:52px;height:52px;top:-28px;left:38px}
.c2{width:78px;height:22px;top:26%;left:-30%;animation-duration:16s;animation-delay:-5s}
.c2::before{width:30px;height:30px;top:-15px;left:11px}
.c2::after{width:40px;height:40px;top:-23px;left:30px}
.c3{width:68px;height:20px;top:9%;left:-15%;animation-duration:10s;animation-delay:-8s}
.c3::before{width:26px;height:26px;top:-13px;left:9px}
.c3::after{width:36px;height:36px;top:-21px;left:26px}
@keyframes cFloat{from{transform:translateX(0)}to{transform:translateX(calc(100vw + 250px))}}
.wind-line{position:absolute;height:2px;
background:linear-gradient(90deg,transparent,rgba(200,215,235,.45),transparent);
border-radius:1px;animation:wMove linear infinite}
@keyframes wMove{0%{transform:translateX(-100%);opacity:0}20%{opacity:1}80%{opacity:1}
100%{transform:translateX(calc(100% + 200px));opacity:0}}
.tree{position:absolute;bottom:0}
.trunk{position:absolute;bottom:0;left:50%;transform:translateX(-50%);
width:7px;background:linear-gradient(180deg,#4a3728,#2a1f16);border-radius:3px 3px 0 0}
.foliage{position:absolute;border-radius:50%;transform-origin:center bottom;
animation:tSway 2s ease-in-out infinite}
@keyframes tSway{0%,100%{transform:rotate(-6deg)}50%{transform:rotate(6deg)}}
/* ===== RAINY ===== */
.raindrop{position:absolute;width:2px;
background:linear-gradient(to bottom,transparent,rgba(120,170,255,.55),rgba(120,170,255,.25));
border-radius:0 0 2px 2px;animation:rFall linear infinite}
@keyframes rFall{0%{transform:translateY(-20px);opacity:0}10%{opacity:1}90%{opacity:1}
100%{transform:translateY(400px);opacity:0}}
.puddle{border-radius:50%;position:absolute;bottom:0;
background:radial-gradient(ellipse,rgba(80,140,255,.28),rgba(80,140,255,.08));
border:1px solid rgba(100,160,255,.12);animation:pRipple 2.5s ease-in-out infinite}
@keyframes pRipple{0%,100%{transform:scaleX(1)}50%{transform:scaleX(1.12)}}
.splash{position:absolute;bottom:6px;width:5px;height:5px;border-radius:50%;
background:rgba(120,170,255,.45);animation:sUp .6s ease-out infinite}
@keyframes sUp{0%{transform:translateY(0) scale(0);opacity:1}
100%{transform:translateY(-14px) scale(1.5);opacity:0}}
.lightning{position:absolute;inset:0;z-index:3;background:rgba(200,180,255,0);
pointer-events:none;animation:lFlash 5s ease-in infinite}
@keyframes lFlash{0%,89%,91%,93%,100%{background:rgba(200,180,255,0)}90%,92%{background:rgba(200,180,255,.15)}}
.bolt{position:absolute;top:3%;left:25%;width:50%;opacity:0;filter:blur(.5px);
animation:bFlash 5s ease-in infinite}
@keyframes bFlash{0%,89.5%,91%,92.5%,100%{opacity:0}90%,90.5%,91.5%,92%{opacity:1}}
/* ===== SNOWY ===== */
.snowflake{position:absolute;animation:sNow linear infinite;pointer-events:none;
color:rgba(220,230,255,.85);text-shadow:0 0 5px rgba(200,220,255,.5)}
@keyframes sNow{0%{transform:translateY(-20px) rotate(0);opacity:0}
10%{opacity:1}90%{opacity:.7}100%{transform:translateY(420px) rotate(360deg);opacity:0}}
.snow-ground{position:absolute;bottom:0;left:0;right:0;
background:linear-gradient(180deg,transparent 0%,rgba(200,215,240,.12) 30%,rgba(200,215,240,.28) 100%);
border-radius:42% 48% 0 0 / 16% 18% 0 0;animation:sAccum 6s ease-in-out infinite alternate}
@keyframes sAccum{from{height:18px}to{height:32px}}
.snow-mound{position:absolute;bottom:0;border-radius:50% 50% 0 0;
background:linear-gradient(180deg,rgba(210,225,250,.38),rgba(200,215,240,.18));
animation:mGrow 8s ease-in-out infinite alternate}
@keyframes mGrow{from{transform:scaleY(.88)}to{transform:scaleY(1.12)}}
/* ===== responsive ===== */
@media(max-width:860px){
.cards{flex-wrap:wrap;height:auto;content:""}
.card{flex:1 1 calc(50% - 9px);min-height:260px}
.card.active{flex:1 1 calc(50% - 9px)}
}
</style>
</head>
<body>
<div id="ambient"></div>
<div class="orb orb1"></div><div class="orb orb2"></div><div class="orb orb3"></div>
<div class="hd">
<div>
<h1>Weather</h1>
<div class="sub">Apple Weather · 2026.04.25</div>
</div>
</div>
<div class="sel">
<button class="on" data-w="sunny">☀️ 晴天</button>
<button data-w="windy">💨 大风</button>
<button data-w="rainy">🌧️ 暴雨</button>
<button data-w="snowy">❄️ 暴雪</button>
</div>
<div class="cards" id="cards">
<!-- SUNNY -->
<div class="card active" data-card="sunny">
<div class="scene" id="sScene"></div>
<div class="info">
<div class="temp">28°</div>
<div class="lbl">晴天 Sunny</div>
<div class="det">体感 30° · 湿度 45%</div>
</div>
</div>
<!-- WINDY -->
<div class="card" data-card="windy">
<div class="scene" id="wScene"></div>
<div class="info">
<div class="temp">18°</div>
<div class="lbl">大风 Windy</div>
<div class="det">风速 45km/h · 阵风 62km/h</div>
</div>
</div>
<!-- RAINY -->
<div class="card" data-card="rainy">
<div class="scene" id="rScene"></div>
<div class="info">
<div class="temp">14°</div>
<div class="lbl">暴雨 Rainy</div>
<div class="det">降水量 48mm · 能见度 2km</div>
</div>
</div>
<!-- SNOWY -->
<div class="card" data-card="snowy">
<div class="scene" id="snScene"></div>
<div class="info">
<div class="temp">-4°</div>
<div class="lbl">暴雪 Snowy</div>
<div class="det">积雪 12cm · 能见度 500m</div>
</div>
</div>
</div>
<script>
const $ = s => document.querySelector(s);
const $$ = s => document.querySelectorAll(s);
const rand = (a, b) => Math.random() * (b - a) + a;
const randInt = (a, b) => Math.floor(rand(a, b));
/* ===== state ===== */
let currentWeather = 'sunny';
$$('.sel button').forEach(btn => {
btn.addEventListener('click', () => {
$$('.sel button').forEach(b => b.classList.remove('on'));
btn.classList.add('on');
setWeather(btn.dataset.w);
});
});
$$('.card').forEach(card => {
card.addEventListener('click', () => {
const w = card.dataset.card;
$$('.sel button').forEach(b => b.classList.toggle('on', b.dataset.w === w));
setWeather(w);
});
});
function setWeather(w) {
currentWeather = w;
$('#ambient').className = w;
$$('.card').forEach(c => c.classList.toggle('active', c.dataset.card === w));
}
/* ===== SUNNY ===== */
function buildSunny() {
const s = $('#sScene');
s.innerHTML = '';
// sun
const wrap = document.createElement('div');
wrap.className = 'sun-wrap';
wrap.innerHTML = '<div class="sun-glow"></div><div class="sun-rays" id="rays"></div><div class="sun-core"></div>';
s.appendChild(wrap);
// rays
const rays = wrap.querySelector('.sun-rays');
for (let i = 0; i < 12; i++) {
const r = document.createElement('div');
r.className = 'sun-ray';
r.style.transform = `rotate(${i * 30}deg)`;
rays.appendChild(r);
}
// particles
for (let i = 0; i < 15; i++) {
const p = document.createElement('div');
p.className = 'lparticle';
p.style.left = rand(10, 90) + '%';
p.style.top = rand(10, 70) + '%';
p.style.animationDelay = rand(0, 4).toFixed(1) + 's';
p.style.animationDuration = rand(3, 6).toFixed(1) + 's';
s.appendChild(p);
}
}
/* ===== WINDY ===== */
function buildWindy() {
const s = $('#wScene');
s.innerHTML = '';
// clouds
[1, 2, 3].forEach(i => {
const c = document.createElement('div');
c.className = `cloud c${i}`;
s.appendChild(c);
});
// wind lines
for (let i = 0; i < 8; i++) {
const wl = document.createElement('div');
wl.className = 'wind-line';
wl.style.top = rand(5, 80) + '%';
wl.style.width = rand(60, 180) + 'px';
wl.style.animationDuration = rand(2, 5).toFixed(1) + 's';
wl.style.animationDelay = rand(0, 4).toFixed(1) + 's';
s.appendChild(wl);
}
// trees
const treePositions = [15, 45, 75];
treePositions.forEach((x, idx) => {
const tree = document.createElement('div');
tree.className = 'tree';
tree.style.left = x + '%';
const h = rand(70, 120);
const trunk = document.createElement('div');
trunk.className = 'trunk';
trunk.style.height = h + 'px';
tree.appendChild(trunk);
const fCount = randInt(2, 4);
for (let j = 0; j < fCount; j++) {
const f = document.createElement('div');
f.className = 'foliage';
const size = rand(30, 55);
f.style.width = size + 'px';
f.style.height = size * 0.7 + 'px';
f.style.bottom = (h * 0.5 + j * h * 0.22) + 'px';
f.style.left = '50%';
f.style.transform = 'translateX(-50%)';
f.style.background = `radial-gradient(ellipse, rgba(${50+idx*20},${120+idx*15},${50+idx*10},.7), rgba(${30+idx*15},${80+idx*10},${30+idx*8},.5))`;
f.style.animationDelay = rand(0, 1).toFixed(1) + 's';
f.style.animationDuration = rand(1.5, 3).toFixed(1) + 's';
tree.appendChild(f);
}
s.appendChild(tree);
});
}
/* ===== RAINY ===== */
function buildRainy() {
const s = $('#rScene');
s.innerHTML = '';
// dark cloud
const dc = document.createElement('div');
dc.style.cssText = 'position:absolute;top:3%;left:10%;width:80%;height:35px;border-radius:25px;' +
'background:linear-gradient(180deg,rgba(60,70,90,.7),rgba(40,50,70,.5));filter:blur(2px)';
s.appendChild(dc);
const dc2 = document.createElement('div');
dc2.style.cssText = 'position:absolute;top:0%;left:25%;width:50%;height:50px;border-radius:50%;' +
'background:rgba(55,65,85,.6);filter:blur(3px)';
s.appendChild(dc2);
// raindrops
for (let i = 0; i < 60; i++) {
const rd = document.createElement('div');
rd.className = 'raindrop';
rd.style.left = rand(0, 100) + '%';
rd.style.height = rand(12, 28) + 'px';
rd.style.animationDuration = rand(0.4, 0.9).toFixed(2) + 's';
rd.style.animationDelay = rand(0, 2).toFixed(2) + 's';
rd.style.opacity = rand(0.3, 0.8).toFixed(1);
s.appendChild(rd);
}
// puddles
const puddles = [
{ left: '10%', width: '28%', delay: 0 },
{ left: '45%', width: '22%', delay: 0.8 },
{ left: '72%', width: '20%', delay: 1.5 },
];
puddles.forEach(p => {
const pd = document.createElement('div');
pd.className = 'puddle';
pd.style.left = p.left;
pd.style.width = p.width;
pd.style.height = '8px';
pd.style.animationDelay = p.delay + 's';
s.appendChild(pd);
// splashes
for (let i = 0; i < 3; i++) {
const sp = document.createElement('div');
sp.className = 'splash';
sp.style.left = rand(20, 80) + '%';
sp.style.animationDelay = rand(0, 0.6).toFixed(2) + 's';
sp.style.animationDuration = rand(0.4, 0.8).toFixed(2) + 's';
pd.appendChild(sp);
}
});
// lightning
const lt = document.createElement('div');
lt.className = 'lightning';
s.appendChild(lt);
const bolt = document.createElement('div');
bolt.className = 'bolt';
bolt.innerHTML = '<svg viewBox="0 0 100 200" fill="none">' +
'<path d="M55 0 L30 80 L50 80 L40 200 L70 90 L50 90 L65 0 Z"' +
' fill="rgba(200,180,255,0.9)" stroke="rgba(180,160,255,0.5)" stroke-width="1"/>' +
'</svg>';
s.appendChild(bolt);
}
/* ===== SNOWY ===== */
function buildSnowy() {
const s = $('#snScene');
s.innerHTML = '';
// snowflakes
const flakeChars = ['❄', '❅', '❆', '•', '∗'];
for (let i = 0; i < 50; i++) {
const sf = document.createElement('div');
sf.className = 'snowflake';
sf.textContent = flakeChars[randInt(0, flakeChars.length)];
sf.style.left = rand(0, 100) + '%';
sf.style.fontSize = rand(8, 24) + 'px';
sf.style.animationDuration = rand(4, 10).toFixed(1) + 's';
sf.style.animationDelay = rand(0, 6).toFixed(1) + 's';
sf.style.opacity = rand(0.4, 0.9).toFixed(1);
s.appendChild(sf);
}
// ground snow
const ground = document.createElement('div');
ground.className = 'snow-ground';
s.appendChild(ground);
// mounds
const mounds = [
{ left: '5%', width: '30%', delay: 0 },
{ left: '38%', width: '25%', delay: 2 },
{ left: '68%', width: '28%', delay: 4 },
];
mounds.forEach(m => {
const md = document.createElement('div');
md.className = 'snow-mound';
md.style.left = m.left;
md.style.width = m.width;
md.style.height = rand(20, 40) + 'px';
md.style.animationDelay = m.delay + 's';
s.appendChild(md);
});
}
/* ===== init ===== */
buildSunny();
buildWindy();
buildRainy();
buildSnowy();
setWeather('sunny');
</script>
</body>
</html>
--【壹】--:
image1475×806 89.8 KB
动态效果:
--【贰】--:
LongCat大模型,没有工具调用,除了聊天,啥也干不了
--【叁】--:
image1920×1010 80.9 KB
3m38s,好像还可以

