星颖资源网

 找回密码
 立即注册
查看: 7|回复: 0

qwen3-max-2026-01-23,kimi-k2.5天气卡片测试

[复制链接]

2万

主题

1万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
110880
发表于 2026-1-27 14:14:23 | 显示全部楼层 |阅读模式
你是一位就职于苹果公司的顶级前端工程师。请创建一个包含CSS和JavaScript的HTML文件,用于生成动画天气卡片。卡片需要以不同动画效果直观展示以下天气状况:
风力(如:飘动的云朵、摇曳的树木或风线)
降雨(如:下落的雨滴、形成的水洼)
晴天(如:闪耀的光线、明亮的背景)
下雪(如:飘落的雪花、积雪效果)
所有天气卡片需要并排显示,背景采用深色设计。所有HTML、CSS和JavaScript代码都需包含在这个单一文件中。JavaScript部分需包含切换不同天气状态的功能(例如通过函数或按钮组),以演示每种天气的动画效果。
将前端显示效果优化得更精致流畅,打造出价值20元/月的精品天气应用既视感。
kimi-k2.5:
  1. <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Premium Weather Experience</title> <script src="https://cdn.tailwindcss.com"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> <style> /* Apple-like Typography & Utilities */ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; background-color: #000; color: white; overflow-x: hidden; margin: 0; } /* Glassmorphism Utilities */ .glass-panel { background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); } .glass-card { background: linear-gradient(180deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); box-shadow: 0 10px 30px rgba(0,0,0,0.3), inset 0 0 0 1px rgba(255,255,255,0.1); transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; position: relative; } .glass-card:hover { transform: translateY(-5px) scale(1.02); box-shadow: 0 20px 40px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(255,255,255,0.2); z-index: 10; } .glass-card.active { border-color: rgba(255, 255, 255, 0.5); box-shadow: 0 0 30px rgba(255, 255, 255, 0.2); } /* Animations */ @keyframes float { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-10px); } } @keyframes drift { from { transform: translateX(-20%); } to { transform: translateX(120%); } } @keyframes shine { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes sway { 0% { transform: rotate(0deg); } 25% { transform: rotate(5deg); } 75% { transform: rotate(-5deg); } 100% { transform: rotate(0deg); } } @keyframes lightning { 0%, 90%, 100% { opacity: 0; } 92% { opacity: 0.6; background-color: #fff; } 93% { opacity: 0; } 94% { opacity: 0.4; } 96% { opacity: 0; } } /* Specific Element Styles */ .sun-rays { background: radial-gradient(circle, rgba(255,255,200,0.8) 0%, rgba(255,200,50,0) 70%); } .cloud-shape { background: linear-gradient(to bottom, #fff 5%, #f1f1f1 100%); border-radius: 100px; box-shadow: 0 8px 5px rgba(0, 0, 0, 0.1); position: absolute; } .cloud-shape::after, .cloud-shape::before { content: ''; position: absolute; background: inherit; border-radius: 50%; } /* Toggle Switch */ .toggle-checkbox:checked { right: 0; border-color: #68D391; } .toggle-checkbox:checked + .toggle-label { background-color: #68D391; } canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } /* Ambient Gradients per Card */ .bg-wind { background: linear-gradient(180deg, #2c3e50 0%, #4ca1af 100%); } .bg-rain { background: linear-gradient(180deg, #203a43 0%, #2c5364 100%); } .bg-sun { background: linear-gradient(180deg, #f2994a 0%, #f2c94c 100%); } .bg-snow { background: linear-gradient(180deg, #83a4d4 0%, #b6fbff 100%); } </style> </head> <body class="min-h-screen flex flex-col items-center justify-center selection:bg-white selection:text-black"> <!-- Background Ambient Mesh --> <div class="fixed inset-0 z-[-1] opacity-30"> <div class="absolute top-[-10%] left-[-10%] w-[50%] h-[50%] bg-blue-600 rounded-full blur-[120px] animate-pulse"></div> <div class="absolute bottom-[-10%] right-[-10%] w-[50%] h-[50%] bg-purple-600 rounded-full blur-[120px] animate-pulse" style="animation-delay: 2s;"></div> </div> <!-- Main Container --> <div class="container mx-auto px-4 py-12 max-w-7xl"> <!-- Header --> <header class="text-center mb-12"> <h1 class="text-4xl md:text-5xl font-bold tracking-tight mb-2 bg-clip-text text-transparent bg-gradient-to-r from-white to-gray-400"> Weather<span class="font-light">OS</span> </h1> <p class="text-gray-400 text-sm tracking-widest uppercase">沉浸式气象模拟</p> </header> <!-- Cards Grid --> <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 w-full"> <!-- Card 1: Windy (CSS Animation) --> <div id="card-wind" class="glass-card h-[400px] rounded-3xl relative cursor-pointer group" onclick="setWeather('wind')"> <div class="absolute inset-0 bg-wind opacity-40 transition-opacity duration-700 group-hover:opacity-60"></div> <div class="absolute inset-0 flex flex-col justify-between p-6 z-10"> <div class="flex justify-between items-start"> <span class="text-xs font-bold tracking-widest bg-white/20 px-2 py-1 rounded backdrop-blur-sm"> windy </span> <i class="fas fa-wind text-white/80 text-xl"></i> </div> <div class="flex-grow relative overflow-hidden mt-4"> <!-- CSS Clouds --> <div class="cloud-shape w-24 h-8 top-10 left-[-20%] animate-[drift_8s_linear_infinite] opacity-80"></div> <div class="cloud-shape w-32 h-10 top-24 left-[-40%] animate-[drift_12s_linear_infinite] opacity-60 scale-75"></div> <!-- Wind Lines --> <div class="absolute top-1/2 left-0 w-full h-full"> <div class="h-[1px] bg-white/30 w-16 absolute top-[20%] animate-[drift_2s_linear_infinite]"></div> <div class="h-[1px] bg-white/20 w-24 absolute top-[40%] animate-[drift_3s_linear_infinite] delay-75"></div> <div class="h-[1px] bg-white/40 w-12 absolute top-[60%] animate-[drift_1.5s_linear_infinite] delay-150"></div> </div> <!-- Tree/Swaying Element --> <div class="absolute bottom-0 right-4 text-white/40 origin-bottom animate-[sway_3s_ease-in-out_infinite]"> <i class="fas fa-tree text-6xl"></i> </div> </div> <div class="relative z-20"> <div class="text-4xl font-thin">24°</div> <div class="text-sm text-gray-300">强风 / 多云</div> </div> </div> </div> <!-- Card 2: Rainy (Canvas Animation) --> <div id="card-rain" class="glass-card h-[400px] rounded-3xl relative cursor-pointer group" onclick="setWeather('rain')"> <div class="absolute inset-0 bg-rain opacity-40 transition-opacity duration-700 group-hover:opacity-60"></div> <div class="absolute inset-0 flex flex-col justify-between p-6 z-10"> <div class="flex justify-between items-start"> <span class="text-xs font-bold tracking-widest bg-black/30 px-2 py-1 rounded backdrop-blur-sm"> rain </span> <i class="fas fa-cloud-showers-heavy text-white/80 text-xl"></i> </div> <!-- Canvas Container --> <canvas id="canvas-rain" class="absolute inset-0 w-full h-full z-0"></canvas> <div class="relative z-20"> <div class="text-4xl font-thin">18°</div> <div class="text-sm text-gray-300">中雨 / 潮湿</div> </div> </div> </div> <!-- Card 3: Sunny (CSS Animation) --> <div id="card-sun" class="glass-card h-[400px] rounded-3xl relative cursor-pointer group" onclick="setWeather('sun')"> <div class="absolute inset-0 bg-sun opacity-40 transition-opacity duration-700 group-hover:opacity-60"></div> <div class="absolute inset-0 flex flex-col justify-between p-6 z-10"> <div class="flex justify-between items-start"> <span class="text-xs font-bold tracking-widest bg-white/30 px-2 py-1 rounded backdrop-blur-sm"> sunny </span> <i class="fas fa-sun text-white/80 text-xl"></i> </div> <div class="flex-grow relative flex items-center justify-center"> <!-- Sun --> <div class="relative w-24 h-24"> <div class="absolute inset-0 bg-yellow-300 rounded-full blur-md animate-pulse"></div> <div class="absolute inset-0 bg-gradient-to-tr from-yellow-400 to-orange-400 rounded-full shadow-[0_0_40px_rgba(255,200,0,0.6)]"></div> <!-- Rays --> <div class="absolute inset-[-50%] border-[20px] border-dashed border-yellow-200/30 rounded-full animate-[shine_20s_linear_infinite]"></div> </div> </div> <div class="relative z-20"> <div class="text-4xl font-thin">31°</div> <div class="text-sm text-gray-800/80 font-medium">晴朗 / 紫外线强</div> </div> </div> </div> <!-- Card 4: Snowy (Canvas Animation) --> <div id="card-snow" class="glass-card h-[400px] rounded-3xl relative cursor-pointer group" onclick="setWeather('snow')"> <div class="absolute inset-0 bg-snow opacity-40 transition-opacity duration-700 group-hover:opacity-60"></div> <div class="absolute inset-0 flex flex-col justify-between p-6 z-10"> <div class="flex justify-between items-start"> <span class="text-xs font-bold tracking-widest bg-white/40 text-blue-900 px-2 py-1 rounded backdrop-blur-sm"> snow </span> <i class="fas fa-snowflake text-blue-900/60 text-xl"></i> </div> <!-- Canvas Container --> <canvas id="canvas-snow" class="absolute inset-0 w-full h-full z-0"></canvas> <!-- Landscape Accumulation --> <div class="absolute bottom-0 left-0 w-full h-12 bg-white/80 blur-xl"></div> <div class="relative z-20 text-blue-900"> <div class="text-4xl font-thin">-4°</div> <div class="text-sm text-blue-800/70">大雪 / 能见度低</div> </div> </div> </div> </div> <!-- Control Panel --> <div class="mt-12 glass-panel p-6 rounded-2xl flex flex-col md:flex-row items-center justify-between gap-4 max-w-3xl mx-auto"> <div class="flex gap-4"> <button onclick="setWeather('wind')" class="weather-btn px-4 py-2 rounded-lg bg-white/10 hover:bg-white/20 transition text-sm font-medium border border-transparent hover:border-white/30" data-type="wind">风力模拟</button> <button onclick="setWeather('rain')" class="weather-btn px-4 py-2 rounded-lg bg-white/10 hover:bg-white/20 transition text-sm font-medium border border-transparent hover:border-white/30" data-type="rain">降雨模拟</button> <button onclick="setWeather('sun')" class="weather-btn px-4 py-2 rounded-lg bg-white/10 hover:bg-white/20 transition text-sm font-medium border border-transparent hover:border-white/30" data-type="sun">晴天模拟</button> <button onclick="setWeather('snow')" class="weather-btn px-4 py-2 rounded-lg bg-white/10 hover:bg-white/20 transition text-sm font-medium border border-transparent hover:border-white/30" data-type="snow">降雪模拟</button> </div> <div class="flex items-center gap-3 border-l border-white/10 pl-4"> <span class="text-xs text-gray-400">环境音效</span> <button id="audio-toggle" class="w-10 h-6 rounded-full bg-gray-700 relative transition-colors duration-300 focus:outline-none"> <div id="audio-knob" class="w-4 h-4 bg-white rounded-full absolute top-1 left-1 transition-transform duration-300 shadow-md"></div> </button> </div> </div> </div> <script> // --- State Management --- const state = { activeWeather: null, audioEnabled: false, intervals: [] }; // --- Audio Context (Tone.js) --- let windSynth, rainNoise, sunSynth; let isAudioInit = false; async function initAudio() { if (isAudioInit) return; await Tone.start(); // Wind: Filtered Noise windSynth = new Tone.Noise("pink").start(); const windFilter = new Tone.AutoFilter({ frequency: "8m", min: 400, max: 1200, depth: 0.8 }).toDestination().start(); windSynth.connect(windFilter); windSynth.volume.value = -Infinity; // Start silent // Rain: Brown Noise rainNoise = new Tone.Noise("brown").toDestination().start(); rainNoise.volume.value = -Infinity; // Sun: Drone sunSynth = new Tone.Oscillator(200, "sine").toDestination().start(); sunSynth.volume.value = -Infinity; isAudioInit = true; } function toggleAudio() { initAudio(); state.audioEnabled = !state.audioEnabled; const knob = document.getElementById('audio-knob'); const btn = document.getElementById('audio-toggle'); if (state.audioEnabled) { knob.style.transform = 'translateX(16px)'; btn.classList.remove('bg-gray-700'); btn.classList.add('bg-green-500'); updateAudio(state.activeWeather); } else { knob.style.transform = 'translateX(0)'; btn.classList.add('bg-gray-700'); btn.classList.remove('bg-green-500'); // Mute all if(windSynth) windSynth.volume.rampTo(-Infinity, 1); if(rainNoise) rainNoise.volume.rampTo(-Infinity, 1); if(sunSynth) sunSynth.volume.rampTo(-Infinity, 1); } } document.getElementById('audio-toggle').addEventListener('click', toggleAudio); function updateAudio(type) { if (!state.audioEnabled || !isAudioInit) return; // Reset all windSynth.volume.rampTo(-Infinity, 2); rainNoise.volume.rampTo(-Infinity, 2); sunSynth.volume.rampTo(-Infinity, 2); switch(type) { case 'wind': windSynth.volume.rampTo(-10, 2); break; case 'rain': rainNoise.volume.rampTo(-12, 2); break; case 'sun': sunSynth.volume.rampTo(-20, 2); break; case 'snow': // Snow is quiet break; } } // --- Canvas Animations --- // 1. Rain System const rainCanvas = document.getElementById('canvas-rain'); const rainCtx = rainCanvas.getContext('2d'); let rainDrops = []; function resizeCanvas(canvas) { const parent = canvas.parentElement; canvas.width = parent.clientWidth; canvas.height = parent.clientHeight; } class Drop { constructor() { this.reset(); } reset() { this.x = Math.random() * rainCanvas.width; this.y = Math.random() * -rainCanvas.height; this.speed = Math.random() * 5 + 10; this.len = Math.random() * 10 + 10; this.opacity = Math.random() * 0.5 + 0.1; } update() { this.y += this.speed; if (this.y > rainCanvas.height) this.reset(); } draw() { rainCtx.beginPath(); rainCtx.strokeStyle = `rgba(174, 194, 224, ${this.opacity})`; rainCtx.lineWidth = 1; rainCtx.moveTo(this.x, this.y); rainCtx.lineTo(this.x, this.y + this.len); rainCtx.stroke(); } } function initRain() { resizeCanvas(rainCanvas); rainDrops = []; for(let i=0; i<100; i++) rainDrops.push(new Drop()); } function animateRain() { if (state.activeWeather !== 'rain') return; rainCtx.clearRect(0, 0, rainCanvas.width, rainCanvas.height); rainDrops.forEach(drop => { drop.update(); drop.draw(); }); requestAnimationFrame(animateRain); } // 2. Snow System const snowCanvas = document.getElementById('canvas-snow'); const snowCtx = snowCanvas.getContext('2d'); let snowFlakes = []; class Flake { constructor() { this.reset(); } reset() { this.x = Math.random() * snowCanvas.width; this.y = Math.random() * -snowCanvas.height; this.size = Math.random() * 3 + 1; this.speed = Math.random() * 1 + 0.5; this.wind = Math.random() * 0.5 - 0.25; } update() { this.y += this.speed; this.x += this.wind; if (this.y > snowCanvas.height) this.reset(); } draw() { snowCtx.beginPath(); snowCtx.fillStyle = `rgba(255, 255, 255, 0.8)`; snowCtx.arc(this.x, this.y, this.size, 0, Math.PI * 2); snowCtx.fill(); } } function initSnow() { resizeCanvas(snowCanvas); snowFlakes = []; for(let i=0; i<150; i++) snowFlakes.push(new Flake()); } function animateSnow() { if (state.activeWeather !== 'snow') return; snowCtx.clearRect(0, 0, snowCanvas.width, snowCanvas.height); snowFlakes.forEach(flake => { flake.update(); flake.draw(); }); requestAnimationFrame(animateSnow); } // --- Main Logic --- function setWeather(type) { state.activeWeather = type; // Update UI Buttons document.querySelectorAll('.weather-btn').forEach(btn => { if(btn.dataset.type === type) { btn.classList.add('bg-white', 'text-black'); btn.classList.remove('bg-white/10', 'text-white'); } else { btn.classList.remove('bg-white', 'text-black'); btn.classList.add('bg-white/10', 'text-white'); } }); // Update Audio updateAudio(type); // Trigger Animations if (type === 'rain') { initRain(); animateRain(); } else if (type === 'snow') { initSnow(); animateSnow(); } // Add active class to card for visual emphasis document.querySelectorAll('.glass-card').forEach(card => card.classList.remove('active')); document.getElementById(`card-${type}`).classList.add('active'); } // Handle Resize window.addEventListener('resize', () => { if (state.activeWeather === 'rain') initRain(); if (state.activeWeather === 'snow') initSnow(); }); // Initialize window.addEventListener('DOMContentLoaded', () => { setWeather('sun'); // Default }); </script> </body> </html>
复制代码
qwen3-max-2026-01-23:
  1. <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>精致天气动画卡片</title> <style> :root { --card-bg: rgba(30, 30, 35, 0.85); --card-border: rgba(255, 255, 255, 0.08); --text-primary: #ffffff; --text-secondary: #b0b0c0; --wind-color: #8ac6ff; --rain-color: #6ec6ff; --sun-color: #ffd700; --snow-color: #e0f7ff; --glow-wind: rgba(138, 198, 255, 0.4); --glow-rain: rgba(110, 198, 255, 0.5); --glow-sun: rgba(255, 215, 0, 0.6); --glow-snow: rgba(224, 247, 255, 0.3); --shadow-card: 0 12px 40px rgba(0, 0, 0, 0.45); --shadow-card-hover: 0 15px 50px rgba(0, 0, 0, 0.6); --transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1); } * { margin: 0; padding: 0; box-sizing: border-box; } body { background: linear-gradient(135deg, #0f0f1b, #1a1a2e, #16213e); color: var(--text-primary); font-family: 'Segoe UI', system-ui, -apple-system, sans-serif; min-height: 100vh; display: flex; flex-direction: column; align-items: center; padding: 30px 20px; overflow-x: hidden; position: relative; } body::before { content: ''; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 10% 20%, rgba(30, 60, 100, 0.15) 0%, transparent 30%), radial-gradient(circle at 90% 80%, rgba(60, 30, 100, 0.1) 0%, transparent 35%); z-index: -1; pointer-events: none; } .header { text-align: center; margin-bottom: 40px; max-width: 800px; padding: 0 20px; } .header h1 { font-size: 3.2rem; font-weight: 700; margin-bottom: 16px; background: linear-gradient(90deg, #8ac6ff, #ffd700, #e0f7ff); -webkit-background-clip: text; background-clip: text; color: transparent; letter-spacing: -0.5px; text-shadow: 0 5px 25px rgba(0, 0, 0, 0.3); } .header p { font-size: 1.25rem; color: var(--text-secondary); max-width: 600px; margin: 0 auto; line-height: 1.6; } .cards-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 30px; max-width: 1400px; margin-bottom: 40px; } .weather-card { width: 320px; height: 420px; background: var(--card-bg); border: 1px solid var(--card-border); border-radius: 28px; overflow: hidden; position: relative; box-shadow: var(--shadow-card); transition: var(--transition); display: flex; flex-direction: column; align-items: center; padding: 25px; backdrop-filter: blur(12px); } .weather-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-card-hover); border-color: rgba(255, 255, 255, 0.15); } .weather-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: radial-gradient(circle at 50% 20%, rgba(255, 255, 255, 0.03) 0%, transparent 70%); pointer-events: none; z-index: 1; } .card-header { width: 100%; text-align: center; position: relative; z-index: 10; margin-bottom: 25px; } .card-title { font-size: 2.1rem; font-weight: 700; margin-bottom: 8px; background: linear-gradient(to right, var(--text-primary), #d0d0e0); -webkit-background-clip: text; background-clip: text; color: transparent; } .card-subtitle { font-size: 1.15rem; color: var(--text-secondary); letter-spacing: 0.5px; } .animation-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 2; } /* 风力天气样式 */ .weather-windy .animation-container { background: linear-gradient(145deg, #0f1a3a, #1a2a55, #253a75); } .cloud { position: absolute; background: rgba(255, 255, 255, 0.85); border-radius: 50%; box-shadow: 0 4px 20px rgba(0, 30, 80, 0.4); will-change: transform; } .cloud::after { content: ''; position: absolute; top: 50%; left: 20%; width: 60%; height: 70%; background: inherit; border-radius: 50%; box-shadow: inherit; } .wind-line { position: absolute; height: 3px; background: var(--wind-color); border-radius: 2px; opacity: 0.75; box-shadow: 0 0 8px var(--glow-wind); transform-origin: left center; will-change: transform, opacity; } /* 降雨天气样式 */ .weather-rainy .animation-container { background: linear-gradient(145deg, #0a1525, #152540, #203555); } .raindrop { position: absolute; width: 2.5px; height: 18px; background: linear-gradient(to bottom, rgba(110, 198, 255, 0.1), var(--rain-color)); border-radius: 0 0 2px 2px; box-shadow: 0 0 6px var(--glow-rain); will-change: transform; } .puddle { position: absolute; bottom: 30px; width: 45px; height: 20px; background: rgba(110, 198, 255, 0.12); border-radius: 50%; box-shadow: 0 4px 12px rgba(0, 30, 80, 0.6), inset 0 2px 8px rgba(150, 220, 255, 0.4); will-change: transform, opacity; } .ripple { position: absolute; border: 2px solid rgba(150, 220, 255, 0.5); border-radius: 50%; opacity: 0; will-change: transform, opacity; } /* 晴天天气样式 */ .weather-sunny .animation-container { background: linear-gradient(145deg, #ffd700, #ffa500, #ff8c00); background-size: 400% 400%; animation: gradient-shift 15s ease infinite; } @keyframes gradient-shift { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } .sun { position: absolute; width: 100px; height: 100px; background: radial-gradient(circle, #ffffff 0%, var(--sun-color) 70%, #ff8c00 100%); border-radius: 50%; box-shadow: 0 0 40px var(--glow-sun), 0 0 80px var(--glow-sun), 0 0 120px rgba(255, 215, 0, 0.8); top: 45%; left: 50%; transform: translate(-50%, -50%); will-change: transform; } .sun-ray { position: absolute; width: 6px; height: 45px; background: rgba(255, 255, 255, 0.85); border-radius: 3px; top: 50%; left: 50%; transform-origin: bottom center; box-shadow: 0 0 15px var(--glow-sun); will-change: transform; } .glare { position: absolute; width: 40px; height: 25px; background: rgba(255, 255, 255, 0.9); border-radius: 50%; top: 35%; left: 40%; transform: rotate(30deg); filter: blur(8px); opacity: 0.8; } /* 下雪天气样式 */ .weather-snowy .animation-container { background: linear-gradient(145deg, #0a1a35, #152a50, #203a65); } .snowflake { position: absolute; color: var(--snow-color); font-size: 1.4rem; opacity: 0.92; text-shadow: 0 0 10px rgba(224, 247, 255, 0.7); will-change: transform; user-select: none; } .snow-ground { position: absolute; bottom: 0; left: 0; width: 100%; height: 15%; background: rgba(255, 255, 255, 0.08); border-top: 1px solid rgba(255, 255, 255, 0.15); z-index: 5; } .snow-pile { position: absolute; bottom: 0; height: 8px; background: rgba(255, 255, 255, 0.15); border-radius: 4px 4px 0 0; } /* 控制按钮 */ .controls { display: flex; gap: 15px; margin-top: 15px; flex-wrap: wrap; justify-content: center; } .weather-btn { background: rgba(40, 40, 50, 0.7); color: var(--text-primary); border: 1px solid rgba(255, 255, 255, 0.12); padding: 14px 28px; border-radius: 50px; font-size: 1.15rem; font-weight: 600; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 10px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25); backdrop-filter: blur(8px); } .weather-btn:hover { background: rgba(50, 50, 70, 0.9); transform: translateY(-2px); border-color: rgba(255, 255, 255, 0.25); } .weather-btn:active { transform: translateY(1px); } .weather-btn.active { background: rgba(60, 80, 150, 0.85); border-color: rgba(138, 198, 255, 0.4); box-shadow: 0 0 25px rgba(100, 150, 255, 0.35); } .weather-btn i { font-size: 1.4rem; } .windy-btn { color: var(--wind-color); } .rainy-btn { color: var(--rain-color); } .sunny-btn { color: var(--sun-color); } .snowy-btn { color: var(--snow-color); } .footer { text-align: center; margin-top: 30px; color: var(--text-secondary); font-size: 1.05rem; max-width: 700px; line-height: 1.6; padding: 0 20px; } .footer p { margin: 8px 0; } .highlight { color: var(--wind-color); font-weight: 600; } /* 响应式设计 */ @media (max-width: 1100px) { .cards-container { flex-direction: column; align-items: center; } .weather-card { width: 95%; max-width: 400px; } } @media (max-width: 600px) { .header h1 { font-size: 2.4rem; } .card-title { font-size: 1.8rem; } .card-subtitle { font-size: 1.05rem; } .weather-btn { padding: 12px 24px; font-size: 1.05rem; } .controls { flex-direction: column; align-items: center; } } /* 动画关键帧 */ @keyframes float-cloud { 0%, 100% { transform: translate3d(0, 0, 0); } 25% { transform: translate3d(-15px, 5px, 0); } 50% { transform: translate3d(0, 10px, 0); } 75% { transform: translate3d(15px, 5px, 0); } } @keyframes sway-wind { 0%, 100% { transform: rotate(0deg) scaleX(1); opacity: 0.7; } 25% { transform: rotate(3deg) scaleX(1.05); opacity: 1; } 50% { transform: rotate(0deg) scaleX(1); opacity: 0.7; } 75% { transform: rotate(-3deg) scaleX(0.95); opacity: 0.4; } } @keyframes fall-rain { to { transform: translate3d(-15px, 100vh, 0); } } @keyframes ripple-effect { 0% { transform: scale(0.8); opacity: 0.8; } 100% { transform: scale(2.2); opacity: 0; } } @keyframes rotate-rays { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes fall-snow { 0% { transform: translate3d(var(--tx-start, 0), -20px, 0) rotate(0deg); opacity: 0; } 10% { opacity: var(--snow-opacity, 0.9); } 90% { opacity: var(--snow-opacity, 0.9); } 100% { transform: translate3d(var(--tx-end, 0), 110vh, 0) rotate(720deg); opacity: 0; } } @keyframes gentle-bob { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(8px) rotate(0.5deg); } } </style> </head> <body> <div class="header"> <h1> 精致天气动画卡片</h1> <p>专为追求品质的用户设计 · 流畅动画 · 深色美学 · 每日仅需 <span class="highlight">20元/月</span> 享受极致体验</p> </div> <div class="cards-container"> <!-- 风力卡片 --> <div class="weather-card weather-windy" data-weather="windy"> <div class="card-header"> <h2 class="card-title">风力</h2> <div class="card-subtitle">微风轻拂 · 云卷云舒</div> </div> <div class="animation-container"></div> </div> <!-- 降雨卡片 --> <div class="weather-card weather-rainy" data-weather="rainy"> <div class="card-header"> <h2 class="card-title">降雨</h2> <div class="card-subtitle">细雨绵绵 · 涟漪轻漾</div> </div> <div class="animation-container"></div> </div> <!-- 晴天卡片 --> <div class="weather-card weather-sunny" data-weather="sunny"> <div class="card-header"> <h2 class="card-title">晴天</h2> <div class="card-subtitle">阳光明媚 · 万物生辉</div> </div> <div class="animation-container"></div> </div> <!-- 下雪卡片 --> <div class="weather-card weather-snowy" data-weather="snowy"> <div class="card-header"> <h2 class="card-title">下雪</h2> <div class="card-subtitle">雪花纷飞 · 银装素裹</div> </div> <div class="animation-container"></div> </div> </div> <div class="controls"> <button class="weather-btn windy-btn active" data-weather="windy"> <i></i> 风力模式 </button> <button class="weather-btn rainy-btn" data-weather="rainy"> <i></i> 降雨模式 </button> <button class="weather-btn sunny-btn" data-weather="sunny"> <i></i> 晴天模式 </button> <button class="weather-btn snowy-btn" data-weather="snowy"> <i></i> 下雪模式 </button> </div> <div class="footer"> <p> 专为 <span class="highlight">Apple Vision Pro</span> 与高端设备优化 · 60fps 流畅动画</p> <p> 每个粒子独立物理模拟 · GPU 加速渲染 · 电池友好型设计</p> <p> 由苹果顶级前端工程师团队打造 · 2026年精致天气体验标准</p> </div> <script> document.addEventListener('DOMContentLoaded', () => { // 天气卡片元素 const cards = document.querySelectorAll('.weather-card'); const buttons = document.querySelectorAll('.weather-btn'); // 初始化所有卡片 cards.forEach(card => { const weatherType = card.dataset.weather; renderWeather(card, weatherType); }); // 按钮事件监听 buttons.forEach(button => { button.addEventListener('click', () => { // 更新按钮激活状态 buttons.forEach(btn => btn.classList.remove('active')); button.classList.add('active'); // 获取目标天气类型 const targetWeather = button.dataset.weather; // 更新所有卡片 cards.forEach(card => { // 淡出效果 card.style.opacity = '0.7'; card.style.transform = 'scale(0.98)'; setTimeout(() => { // 清空并重新渲染 const container = card.querySelector('.animation-container'); container.innerHTML = ''; card.className = `weather-card weather-${targetWeather}`; card.dataset.weather = targetWeather; // 重新渲染天气 renderWeather(card, targetWeather); // 淡入效果 card.style.opacity = '1'; card.style.transform = 'scale(1)'; }, 300); }); }); }); // 天气渲染主函数 function renderWeather(card, weatherType) { const container = card.querySelector('.animation-container'); switch(weatherType) { case 'windy': renderWindy(container); break; case 'rainy': renderRainy(container); break; case 'sunny': renderSunny(container); break; case 'snowy': renderSnowy(container); break; } // 添加微妙的浮动动画到卡片 card.style.animation = 'gentle-bob 8s ease-in-out infinite'; } // 风力天气渲染 function renderWindy(container) { // 创建云朵 for (let i = 0; i < 4; i++) { const cloud = document.createElement('div'); cloud.className = 'cloud'; // 随机大小和位置 const size = 45 + Math.random() * 35; const topPos = 15 + Math.random() * 40; const duration = 45 + Math.random() * 30; const delay = Math.random() * 10; cloud.style.width = `${size}px`; cloud.style.height = `${size * 0.6}px`; cloud.style.top = `${topPos}%`; cloud.style.left = `${-20 - Math.random() * 30}%`; cloud.style.opacity = `${0.85 + Math.random() * 0.15}`; cloud.style.animation = `float-cloud ${15 + Math.random() * 10}s ease-in-out ${delay}s infinite`; // 添加移动动画 cloud.animate([ { transform: `translateX(0) translateY(0)` }, { transform: `translateX(${130 + Math.random() * 40}vw) translateY(${Math.sin(i) * 15}px)` } ], { duration: duration * 1000, iterations: Infinity, easing: 'ease-in-out', delay: delay * 1000 }); container.appendChild(cloud); } // 创建风线 for (let i = 0; i < 8; i++) { const line = document.createElement('div'); line.className = 'wind-line'; const width = 60 + Math.random() * 120; const topPos = 20 + Math.random() * 65; const delay = Math.random() * 3; const duration = 3 + Math.random() * 2; line.style.width = `${width}px`; line.style.top = `${topPos}%`; line.style.left = `${-width}px`; line.style.opacity = `${0.3 + Math.random() * 0.5}`; line.style.animation = `sway-wind ${duration}s ease-in-out ${delay}s infinite`; // 风线移动动画 line.animate([ { transform: `translateX(0) rotate(0deg)` }, { transform: `translateX(${100 + width}px) rotate(${Math.random() > 0.5 ? 5 : -5}deg)` } ], { duration: (4 + Math.random() * 3) * 1000, iterations: Infinity, easing: 'linear', delay: delay * 1000 }); container.appendChild(line); } } // 降雨天气渲染 function renderRainy(container) { // 创建雨滴 for (let i = 0; i < 35; i++) { const drop = document.createElement('div'); drop.className = 'raindrop'; // 随机属性 const leftPos = Math.random() * 100; const duration = 0.4 + Math.random() * 0.5; const delay = Math.random() * 2; const opacity = 0.6 + Math.random() * 0.4; drop.style.left = `${leftPos}%`; drop.style.top = `${Math.random() * 100}%`; drop.style.opacity = opacity; drop.style.animation = `fall-rain ${duration}s linear ${delay}s infinite`; container.appendChild(drop); } // 创建水洼 for (let i = 0; i < 6; i++) { const puddle = document.createElement('div'); puddle.className = 'puddle'; const size = 35 + Math.random() * 25; const leftPos = 15 + Math.random() * 70; puddle.style.width = `${size}px`; puddle.style.height = `${size * 0.45}px`; puddle.style.left = `${leftPos}%`; container.appendChild(puddle); // 创建涟漪 for (let j = 0; j < 3; j++) { const ripple = document.createElement('div'); ripple.className = 'ripple'; ripple.style.width = `${size * 0.6}px`; ripple.style.height = `${size * 0.6}px`; ripple.style.left = `${(size - size * 0.6) / 2}px`; ripple.style.top = `${(size * 0.45 - size * 0.6) / 2}px`; ripple.style.animation = `ripple-effect ${2 + j * 0.8}s ease-out ${j * 1.2}s infinite`; puddle.appendChild(ripple); } } } // 晴天天气渲染 function renderSunny(container) { // 太阳主体 const sun = document.createElement('div'); sun.className = 'sun'; container.appendChild(sun); // 添加眩光效果 const glare = document.createElement('div'); glare.className = 'glare'; sun.appendChild(glare); // 创建光芒 const raysContainer = document.createElement('div'); raysContainer.style.position = 'absolute'; raysContainer.style.width = '100%'; raysContainer.style.height = '100%'; raysContainer.style.top = '0'; raysContainer.style.left = '0'; raysContainer.style.animation = 'rotate-rays 25s linear infinite'; // 12道光芒 for (let i = 0; i < 12; i++) { const ray = document.createElement('div'); ray.className = 'sun-ray'; const angle = i * 30; ray.style.transform = `rotate(${angle}deg) translateY(-65px)`; raysContainer.appendChild(ray); } container.appendChild(raysContainer); // 添加微妙的光晕动画 setInterval(() => { const pulse = document.createElement('div'); pulse.style.position = 'absolute'; pulse.style.width = '120px'; pulse.style.height = '120px'; pulse.style.borderRadius = '50%'; pulse.style.background = 'radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)'; pulse.style.top = 'calc(50% - 60px)'; pulse.style.left = 'calc(50% - 60px)'; pulse.style.opacity = '0.7'; pulse.style.pointerEvents = 'none'; pulse.style.zIndex = '3'; container.appendChild(pulse); // 动画并移除 let opacity = 0.7; let scale = 1; const animatePulse = () => { opacity -= 0.03; scale += 0.05; if (opacity <= 0) { pulse.remove(); return; } pulse.style.opacity = opacity; pulse.style.transform = `scale(${scale})`; requestAnimationFrame(animatePulse); }; requestAnimationFrame(animatePulse); }, 800); } // 下雪天气渲染 function renderSnowy(container) { // 创建地面 const ground = document.createElement('div'); ground.className = 'snow-ground'; container.appendChild(ground); // 创建积雪堆 for (let i = 0; i < 8; i++) { const pile = document.createElement('div'); pile.className = 'snow-pile'; const width = 30 + Math.random() * 60; const leftPos = Math.random() * 100; const height = 6 + Math.random() * 12; pile.style.width = `${width}%`; pile.style.left = `${leftPos}%`; pile.style.height = `${height}px`; pile.style.bottom = `${-height/2}px`; pile.style.opacity = `${0.7 + Math.random() * 0.3}`; ground.appendChild(pile); } // 创建雪花 for (let i = 0; i < 60; i++) { const flake = document.createElement('div'); flake.className = 'snowflake'; // 随机雪花字符 const snowflakes = ['', '', '', '', '', '']; flake.textContent = snowflakes[Math.floor(Math.random() * snowflakes.length)]; // 随机属性 const size = 0.6 + Math.random() * 1.2; const leftPos = Math.random() * 100; const duration = 15 + Math.random() * 25; const delay = Math.random() * 15; const opacity = 0.7 + Math.random() * 0.3; const txStart = (Math.random() - 0.5) * 40; const txEnd = txStart + (Math.random() - 0.5) * 60; flake.style.fontSize = `${size}rem`; flake.style.left = `${leftPos}%`; flake.style.opacity = opacity; flake.style.setProperty('--tx-start', `${txStart}px`); flake.style.setProperty('--tx-end', `${txEnd}px`); flake.style.setProperty('--snow-opacity', opacity); flake.style.animation = `fall-snow ${duration}s linear ${delay}s infinite`; container.appendChild(flake); } } // 添加微妙的全局动画优化 document.body.addEventListener('visibilitychange', () => { if (document.hidden) { // 页面不可见时降低动画帧率 document.querySelectorAll('.cloud, .raindrop, .snowflake').forEach(el => { el.style.animationPlayState = 'paused'; }); } else { document.querySelectorAll('.cloud, .raindrop, .snowflake').forEach(el => { el.style.animationPlayState = 'running'; }); } }); // 初始激活第一个按钮 buttons[0].classList.add('active'); }); </script> </body> </html>
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

微信

社群

VIP

AI

顶部

QQ|本站内容来源网友投稿或网络转载,如果有侵权的内容,请联系我们删除。|小黑屋|人人为我,我为人人!| 星颖资源网

GMT+8, 2026-6-8 09:08 , Processed in 0.082985 second(s), 27 queries .

快速回复 返回顶部 返回列表