DeepSeek V4 Pro 前端表现-天气卡片

2026-04-29 10:403阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

以 iOS 18 的设计风格做一个带有动画效果的天气卡片,要求是使用 HTML、CSS 和基础 JavaScript,使用横板天气页面(拥有 4 个天气卡片 (晴天,大风,暴雨,暴雪))。应足够美观,实现一定的交互效果。

image1264×533 53.4 KB

<!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 { --card-radius: 24px; --transition-speed: 0.4s; --bg-gradient-start: #e8eef5; --bg-gradient-mid: #dce4f0; --bg-gradient-end: #eef1f7; --sunny-accent: #f59e4b; --sunny-bg: #fff8f0; --sunny-glow: #ffe4c4; --windy-accent: #7b9eb3; --windy-bg: #f2f6f9; --windy-glow: #d4e2ec; --storm-accent: #5b6e8a; --storm-bg: #f0f2f7; --storm-glow: #c8d6e5; --snow-accent: #a3bfd4; --snow-bg: #f4f8fb; --snow-glow: #e2eef7; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Helvetica Neue', sans-serif; min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(160deg, #dfe9f3 0%, #e8eef5 20%, #f0f4f8 40%, #eef2f6 60%, #e4ebf3 80%, #dce5ef 100%); background-attachment: fixed; position: relative; overflow-x: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; padding: 20px; } /* 背景光晕动画 */ .bg-orb { position: fixed; border-radius: 50%; filter: blur(120px); opacity: 0.35; pointer-events: none; z-index: 0; animation: orbDrift 20s ease-in-out infinite; } .bg-orb.orb-1 { width: 500px; height: 500px; background: #ffe4c4; top: -15%; left: -10%; animation-delay: 0s; } .bg-orb.orb-2 { width: 400px; height: 400px; background: #c8ddf0; top: 50%; right: -8%; animation-delay: -7s; animation-duration: 24s; } .bg-orb.orb-3 { width: 350px; height: 350px; background: #e8d5f5; bottom: -12%; left: 30%; animation-delay: -14s; animation-duration: 22s; } @keyframes orbDrift { 0%, 100% { transform: translate(0, 0) scale(1); } 25% { transform: translate(60px, -40px) scale(1.08); } 50% { transform: translate(-30px, 30px) scale(0.94); } 75% { transform: translate(-50px, -20px) scale(1.05); } } /* 主容器 */ .main-container { position: relative; z-index: 1; width: 100%; max-width: 1350px; display: flex; flex-direction: column; gap: 20px; } /* 顶部标题栏 */ .header { display: flex; align-items: center; justify-content: space-between; padding: 12px 8px 4px; flex-wrap: wrap; gap: 12px; } .header .location-group { display: flex; align-items: center; gap: 10px; } .header .location-icon { width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 255, 255, 0.55); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); display: flex; align-items: center; justify-content: center; font-size: 18px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); border: 1px solid rgba(255, 255, 255, 0.6); } .header .location-name { font-size: 1.5rem; font-weight: 600; color: #1d1d1f; letter-spacing: -0.02em; } .header .date-text { font-size: 0.95rem; color: #6e6e73; font-weight: 500; padding: 8px 16px; background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.55); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04); } /* 卡片网格 */ .cards-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; width: 100%; } /* 单张卡片 */ .weather-card { position: relative; background: rgba(255, 255, 255, 0.48); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border-radius: var(--card-radius); border: 1px solid rgba(255, 255, 255, 0.65); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.7); cursor: pointer; overflow: hidden; transition: transform var(--transition-speed) cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow var(--transition-speed) ease, border-color var(--transition-speed) ease; display: flex; flex-direction: column; min-height: 420px; user-select: none; -webkit-tap-highlight-color: transparent; z-index: 1; } .weather-card:hover { transform: translateY(-8px); box-shadow: 0 16px 40px rgba(0, 0, 0, 0.1), 0 4px 12px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8); border-color: rgba(255, 255, 255, 0.85); z-index: 5; } .weather-card:active { transform: scale(0.975); transition: transform 0.15s ease; } .weather-card.expanded { z-index: 10; box-shadow: 0 24px 55px rgba(0, 0, 0, 0.14), 0 6px 16px rgba(0, 0, 0, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.8); border-color: rgba(255, 255, 255, 0.9); } /* 卡片场景区域(天气动画) */ .card-scene { position: relative; width: 100%; height: 220px; overflow: hidden; border-radius: var(--card-radius) var(--card-radius) 0 0; transition: height var(--transition-speed) ease; } .weather-card.expanded .card-scene { height: 200px; } /* 场景背景色 */ .card-scene.scene-sunny { background: linear-gradient(180deg, #ffe8c8 0%, #fff4e4 40%, #fffaf3 100%); } .card-scene.scene-windy { background: linear-gradient(180deg, #dce8f2 0%, #eaf1f7 40%, #f5f8fb 100%); } .card-scene.scene-storm { background: linear-gradient(180deg, #c8d4e2 0%, #dbe3ee 30%, #e8edf5 60%, #f2f4f8 100%); } .card-scene.scene-snow { background: linear-gradient(180deg, #e2eef8 0%, #eef5fa 40%, #f7fafc 100%); } /* 场景内的光晕 */ .scene-glow { position: absolute; border-radius: 50%; pointer-events: none; filter: blur(40px); opacity: 0.5; animation: glowPulse 4s ease-in-out infinite; } .scene-sunny .scene-glow { width: 120px; height: 120px; background: #fcc870; top: 30px; left: 50%; transform: translateX(-50%); animation-duration: 3.5s; } .scene-windy .scene-glow { width: 100px; height: 60px; background: #b8cfdf; top: 60px; left: 30%; animation-duration: 5s; } .scene-storm .scene-glow { width: 90px; height: 90px; background: #8899b5; top: 50px; left: 45%; animation-duration: 2.8s; opacity: 0.4; } .scene-snow .scene-glow { width: 110px; height: 110px; background: #c8dff0; top: 40px; left: 50%; transform: translateX(-50%); animation-duration: 4.5s; } @keyframes glowPulse { 0%, 100% { opacity: 0.4; transform: translateX(-50%) scale(1); } 50% { opacity: 0.7; transform: translateX(-50%) scale(1.2); } } /* -------- 太阳 (晴天) -------- */ .sun-container { position: absolute; top: 38px; left: 50%; transform: translateX(-50%); width: 80px; height: 80px; z-index: 3; } .sun-core { position: absolute; width: 52px; height: 52px; background: radial-gradient(circle at 40% 38%, #fff7c2 0%, #fdb833 55%, #f08c20 100%); border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 50px rgba(253, 165, 40, 0.55), 0 0 100px rgba(253, 165, 40, 0.3), 0 0 160px rgba(253, 165, 40, 0.15); animation: sunPulse 3s ease-in-out infinite; z-index: 2; } @keyframes sunPulse { 0%, 100% { box-shadow: 0 0 50px rgba(253, 165, 40, 0.55), 0 0 100px rgba(253, 165, 40, 0.3), 0 0 160px rgba(253, 165, 40, 0.15); } 50% { box-shadow: 0 0 70px rgba(253, 165, 40, 0.7), 0 0 130px rgba(253, 165, 40, 0.4), 0 0 190px rgba(253, 165, 40, 0.22); } } .sun-ray { position: absolute; top: 50%; left: 50%; width: 4px; height: 28px; background: rgba(253, 180, 50, 0.5); border-radius: 4px; transform-origin: center bottom; animation: rayRotate 12s linear infinite; } .sun-ray:nth-child(2) { transform: rotate(0deg) translateY(-40px); animation-delay: 0s; height: 30px; } .sun-ray:nth-child(3) { transform: rotate(45deg) translateY(-40px); animation-delay: -1.5s; height: 26px; } .sun-ray:nth-child(4) { transform: rotate(90deg) translateY(-40px); animation-delay: -3s; height: 32px; } .sun-ray:nth-child(5) { transform: rotate(135deg) translateY(-40px); animation-delay: -4.5s; height: 24px; } .sun-ray:nth-child(6) { transform: rotate(180deg) translateY(-40px); animation-delay: -6s; height: 30px; } .sun-ray:nth-child(7) { transform: rotate(225deg) translateY(-40px); animation-delay: -7.5s; height: 27px; } .sun-ray:nth-child(8) { transform: rotate(270deg) translateY(-40px); animation-delay: -9s; height: 33px; } .sun-ray:nth-child(9) { transform: rotate(315deg) translateY(-40px); animation-delay: -10.5s; height: 25px; } @keyframes rayRotate { from { transform: rotate(var(--r, 0deg)) translateY(-40px) rotate(0deg); } to { transform: rotate(var(--r, 0deg)) translateY(-40px) rotate(360deg); } } /* 为每条光线设置旋转变量 */ .sun-ray:nth-child(2) { --r: 0deg; } .sun-ray:nth-child(3) { --r: 45deg; } .sun-ray:nth-child(4) { --r: 90deg; } .sun-ray:nth-child(5) { --r: 135deg; } .sun-ray:nth-child(6) { --r: 180deg; } .sun-ray:nth-child(7) { --r: 225deg; } .sun-ray:nth-child(8) { --r: 270deg; } .sun-ray:nth-child(9) { --r: 315deg; } /* 晴天小云朵 */ .tiny-cloud-sunny { position: absolute; bottom: 35px; right: 28px; z-index: 4; animation: cloudFloat 6s ease-in-out infinite; } @keyframes cloudFloat { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(14px); } } /* -------- 云 (CSS绘制) -------- */ .cloud-css { position: relative; width: 70px; height: 32px; background: rgba(255, 255, 255, 0.85); border-radius: 32px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06); } .cloud-css::before { content: ''; position: absolute; width: 34px; height: 34px; background: rgba(255, 255, 255, 0.85); border-radius: 50%; top: -18px; left: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03); } .cloud-css::after { content: ''; position: absolute; width: 26px; height: 26px; background: rgba(255, 255, 255, 0.8); border-radius: 50%; top: -10px; left: 38px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03); } /* -------- 大风场景 -------- */ .wind-cloud-group { position: absolute; top: 40px; left: 50%; transform: translateX(-50%); z-index: 3; } .wind-lines { position: absolute; top: 50%; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 5; } .wind-line { position: absolute; height: 3px; background: rgba(140, 170, 195, 0.55); border-radius: 3px; animation: windBlow linear infinite; opacity: 0; } .wind-line.wl-1 { top: 90px; left: 10%; width: 50px; animation-duration: 2.2s; animation-delay: 0s; } .wind-line.wl-2 { top: 110px; left: 20%; width: 70px; animation-duration: 2.8s; animation-delay: 0.6s; } .wind-line.wl-3 { top: 130px; left: 5%; width: 40px; animation-duration: 1.9s; animation-delay: 1.2s; } .wind-line.wl-4 { top: 100px; left: 30%; width: 60px; animation-duration: 2.5s; animation-delay: 1.8s; } .wind-line.wl-5 { top: 145px; left: 15%; width: 35px; animation-duration: 3.1s; animation-delay: 0.3s; } .wind-line.wl-6 { top: 120px; left: 8%; width: 55px; animation-duration: 2.4s; animation-delay: 2s; } @keyframes windBlow { 0% { transform: translateX(-30px); opacity: 0; } 15% { opacity: 0.7; } 70% { opacity: 0.6; } 100% { transform: translateX(calc(100% + 60px)); opacity: 0; } } /* -------- 暴雨场景 -------- */ .storm-cloud-group { position: absolute; top: 28px; left: 50%; transform: translateX(-50%); z-index: 3; } .storm-cloud-group .cloud-css { background: rgba(180, 195, 215, 0.75); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); } .storm-cloud-group .cloud-css::before, .storm-cloud-group .cloud-css::after { background: rgba(180, 195, 215, 0.75); } .raindrops { position: absolute; top: 60px; left: 0; width: 100%; height: calc(100% - 60px); pointer-events: none; z-index: 4; } .raindrop { position: absolute; width: 2px; height: 16px; background: linear-gradient(to bottom, rgba(120, 150, 185, 0.3), rgba(100, 140, 180, 0.7)); border-radius: 0 0 4px 4px; animation: rainFall linear infinite; opacity: 0; } .raindrop.rd-1 { left: 18%; animation-duration: .7s; animation-delay: 0s; } .raindrop.rd-2 { left: 30%; animation-duration: .85s; animation-delay: 0.15s; } .raindrop.rd-3 { left: 42%; animation-duration: .65s; animation-delay: 0.3s; } .raindrop.rd-4 { left: 54%; animation-duration: .9s; animation-delay: 0.45s; } .raindrop.rd-5 { left: 65%; animation-duration: .75s; animation-delay: 0.1s; } .raindrop.rd-6 { left: 22%; animation-duration: .8s; animation-delay: 0.5s; } .raindrop.rd-7 { left: 48%; animation-duration: .7s; animation-delay: 0.35s; } .raindrop.rd-8 { left: 60%; animation-duration: .95s; animation-delay: 0.25s; } .raindrop.rd-9 { left: 35%; animation-duration: .78s; animation-delay: 0.55s; } .raindrop.rd-10 { left: 70%; animation-duration: .72s; animation-delay: 0.4s; } @keyframes rainFall { 0% { transform: translateY(-30px); opacity: 0; } 10% { opacity: 0.8; } 85% { opacity: 0.5; } 100% { transform: translateY(150px); opacity: 0; } } /* 闪电 */ .lightning { position: absolute; top: 55px; left: 40%; width: 3px; height: 50px; background: rgba(255, 255, 220, 0.9); border-radius: 2px; z-index: 5; opacity: 0; animation: lightningFlash 4s ease-in-out infinite; filter: blur(1px); box-shadow: 0 0 20px rgba(255, 255, 200, 0.7), 0 0 40px rgba(255, 255, 180, 0.4); } .lightning::after { content: ''; position: absolute; top: 20px; left: 6px; width: 2px; height: 25px; background: rgba(255, 255, 210, 0.8); border-radius: 2px; transform: rotate(25deg); } @keyframes lightningFlash { 0%, 90%, 96%, 100% { opacity: 0; } 91% { opacity: 0.9; } 92% { opacity: 0.2; } 93% { opacity: 0.85; } 94% { opacity: 0.1; } 95% { opacity: 0.6; } } /* -------- 暴雪场景 -------- */ .snow-cloud-group { position: absolute; top: 30px; left: 50%; transform: translateX(-50%); z-index: 3; } .snow-cloud-group .cloud-css { background: rgba(225, 235, 245, 0.8); } .snow-cloud-group .cloud-css::before, .snow-cloud-group .cloud-css::after { background: rgba(225, 235, 245, 0.8); } .snowflakes { position: absolute; top: 55px; left: 0; width: 100%; height: calc(100% - 55px); pointer-events: none; z-index: 5; } .snowflake { position: absolute; background: rgba(255, 255, 255, 0.9); border-radius: 50%; animation: snowFall linear infinite; opacity: 0; box-shadow: 0 0 6px rgba(255, 255, 255, 0.5); } .snowflake.sf-1 { left: 15%; width: 6px; height: 6px; animation-duration: 3.5s; animation-delay: 0s; } .snowflake.sf-2 { left: 28%; width: 4px; height: 4px; animation-duration: 4.2s; animation-delay: 0.8s; } .snowflake.sf-3 { left: 40%; width: 7px; height: 7px; animation-duration: 3.8s; animation-delay: 1.5s; } .snowflake.sf-4 { left: 55%; width: 5px; height: 5px; animation-duration: 4.6s; animation-delay: 0.4s; } .snowflake.sf-5 { left: 68%; width: 6px; height: 6px; animation-duration: 3.3s; animation-delay: 2s; } .snowflake.sf-6 { left: 20%; width: 3px; height: 3px; animation-duration: 5s; animation-delay: 1.1s; } .snowflake.sf-7 { left: 48%; width: 5px; height: 5px; animation-duration: 3.9s; animation-delay: 2.5s; } .snowflake.sf-8 { left: 62%; width: 7px; height: 7px; animation-duration: 4.4s; animation-delay: 0.7s; } .snowflake.sf-9 { left: 33%; width: 4px; height: 4px; animation-duration: 4.8s; animation-delay: 0.2s; } .snowflake.sf-10 { left: 72%; width: 5px; height: 5px; animation-duration: 3.6s; animation-delay: 1.8s; } @keyframes snowFall { 0% { transform: translateY(-25px) translateX(0) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translateY(60px) translateX(18px) rotate(180deg); opacity: 0.7; } 90% { opacity: 0.3; } 100% { transform: translateY(155px) translateX(-10px) rotate(360deg); opacity: 0; } } /* 地面微光(暴雪) */ .snow-ground { position: absolute; bottom: 0; left: 0; width: 100%; height: 30px; background: linear-gradient(to top, rgba(220, 235, 250, 0.5) 0%, transparent 100%); z-index: 1; border-radius: 0 0 var(--card-radius) 0; } /* -------- 卡片信息区域 -------- */ .card-info { padding: 16px 20px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; position: relative; z-index: 2; } .card-temp { font-size: 3.2rem; font-weight: 600; letter-spacing: -0.03em; line-height: 1; color: #1d1d1f; transition: color var(--transition-speed) ease; } .card-temp .degree { font-size: 1.6rem; font-weight: 500; vertical-align: super; margin-left: 2px; color: #6e6e73; } .card-weather-name { font-size: 1.15rem; font-weight: 500; color: #3a3a3c; letter-spacing: -0.01em; } .card-subtitle { font-size: 0.85rem; color: #8e8e93; font-weight: 400; } /* 展开详情 */ .card-details { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.35s ease, margin-top 0.4s ease; margin-top: 0; } .weather-card.expanded .card-details { max-height: 120px; opacity: 1; margin-top: 12px; } .detail-item { display: flex; align-items: center; gap: 7px; font-size: 0.82rem; color: #5c5c5e; font-weight: 500; } .detail-item .detail-icon { width: 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 13px; background: rgba(0, 0, 0, 0.04); flex-shrink: 0; } .detail-value { font-weight: 600; color: #1d1d1f; } /* 卡片选中指示器 */ .card-indicator { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); width: 32px; height: 4px; background: rgba(0, 0, 0, 0.15); border-radius: 4px; transition: all var(--transition-speed) ease; opacity: 0; } .weather-card.expanded .card-indicator { opacity: 1; width: 40px; background: rgba(0, 0, 0, 0.25); } /* -------- 响应式设计 -------- */ @media (max-width: 1100px) { .cards-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; } .weather-card { min-height: 380px; } .card-scene { height: 190px; } .card-temp { font-size: 2.8rem; } } @media (max-width: 640px) { .cards-grid { grid-template-columns: 1fr 1fr; gap: 12px; } .weather-card { min-height: 340px; } .card-scene { height: 160px; } .card-temp { font-size: 2.4rem; } .card-info { padding: 12px 14px 16px; } .header .location-name { font-size: 1.2rem; } .header .date-text { font-size: 0.8rem; padding: 6px 12px; } .sun-container { top: 25px; width: 60px; height: 60px; } .sun-core { width: 38px; height: 38px; } .sun-ray { height: 18px; width: 3px; } .sun-ray:nth-child(2) { transform: rotate(0deg) translateY(-28px); } .sun-ray:nth-child(3) { transform: rotate(45deg) translateY(-28px); } .sun-ray:nth-child(4) { transform: rotate(90deg) translateY(-28px); } .sun-ray:nth-child(5) { transform: rotate(135deg) translateY(-28px); } .sun-ray:nth-child(6) { transform: rotate(180deg) translateY(-28px); } .sun-ray:nth-child(7) { transform: rotate(225deg) translateY(-28px); } .sun-ray:nth-child(8) { transform: rotate(270deg) translateY(-28px); } .sun-ray:nth-child(9) { transform: rotate(315deg) translateY(-28px); } @keyframes rayRotate { from { transform: rotate(var(--r, 0deg)) translateY(-28px) rotate(0deg); } to { transform: rotate(var(--r, 0deg)) translateY(-28px) rotate(360deg); } } .cloud-css { width: 50px; height: 22px; border-radius: 22px; } .cloud-css::before { width: 24px; height: 24px; top: -13px; left: 8px; } .cloud-css::after { width: 18px; height: 18px; top: -7px; left: 28px; } } @media (max-width: 420px) { .cards-grid { grid-template-columns: 1fr; gap: 14px; } .weather-card { min-height: 300px; flex-direction: row; border-radius: 20px; } .card-scene { width: 140px; height: auto; min-height: 140px; border-radius: 20px 0 0 20px; flex-shrink: 0; } .card-info { padding: 16px; justify-content: center; } .card-temp { font-size: 2.2rem; } .weather-card.expanded .card-scene { height: auto; } .card-details { grid-template-columns: 1fr; gap: 6px; } .weather-card.expanded .card-details { max-height: 200px; } .card-indicator { bottom: 8px; } } </style> </head> <body> <!-- 背景光晕 --> <div class="bg-orb orb-1"></div> <div class="bg-orb orb-2"></div> <div class="bg-orb orb-3"></div> <!-- 主容器 --> <div class="main-container"> <!-- 顶部标题 --> <div class="header"> <div class="location-group"> <div class="location-icon">📍</div> <span class="location-name">北京 · 中国</span> </div> <span class="date-text" id="dateDisplay"></span> </div> <!-- 卡片网格 --> <div class="cards-grid" id="cardsGrid"> <!-- 晴天卡片 --> <div class="weather-card" data-weather="sunny"> <div class="card-scene scene-sunny"> <div class="scene-glow"></div> <div class="sun-container"> <div class="sun-core"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> </div> <div class="tiny-cloud-sunny"> <div class="cloud-css" style="width:50px;height:22px;border-radius:22px;"></div> </div> </div> <div class="card-info"> <div class="card-temp">28<span class="degree">°C</span></div> <div class="card-weather-name">☀️ 晴天</div> <div class="card-subtitle">阳光明媚 · 适合出行</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">30°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">35%</span></span> </div> <div class="detail-item"> <span class="detail-icon">☀️</span> <span>紫外线 <span class="detail-value">强</span></span> </div> <div class="detail-item"> <span class="detail-icon">🍃</span> <span>风速 <span class="detail-value">2级</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 大风卡片 --> <div class="weather-card" data-weather="windy"> <div class="card-scene scene-windy"> <div class="scene-glow"></div> <div class="wind-cloud-group"> <div class="cloud-css" style="width:65px;height:28px;border-radius:28px;"></div> </div> <div class="wind-lines"> <div class="wind-line wl-1"></div> <div class="wind-line wl-2"></div> <div class="wind-line wl-3"></div> <div class="wind-line wl-4"></div> <div class="wind-line wl-5"></div> <div class="wind-line wl-6"></div> </div> </div> <div class="card-info"> <div class="card-temp">15<span class="degree">°C</span></div> <div class="card-weather-name">💨 大风</div> <div class="card-subtitle">风力强劲 · 注意保暖</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">10°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">48%</span></span> </div> <div class="detail-item"> <span class="detail-icon">💨</span> <span>阵风 <span class="detail-value">7级</span></span> </div> <div class="detail-item"> <span class="detail-icon">🍃</span> <span>风速 <span class="detail-value">5级</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 暴雨卡片 --> <div class="weather-card" data-weather="storm"> <div class="card-scene scene-storm"> <div class="scene-glow"></div> <div class="storm-cloud-group"> <div class="cloud-css" style="width:72px;height:30px;border-radius:30px;"></div> </div> <div class="lightning"></div> <div class="raindrops"> <div class="raindrop rd-1"></div> <div class="raindrop rd-2"></div> <div class="raindrop rd-3"></div> <div class="raindrop rd-4"></div> <div class="raindrop rd-5"></div> <div class="raindrop rd-6"></div> <div class="raindrop rd-7"></div> <div class="raindrop rd-8"></div> <div class="raindrop rd-9"></div> <div class="raindrop rd-10"></div> </div> </div> <div class="card-info"> <div class="card-temp">18<span class="degree">°C</span></div> <div class="card-weather-name">⛈️ 暴雨</div> <div class="card-subtitle">雷电交加 · 减少外出</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">16°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">92%</span></span> </div> <div class="detail-item"> <span class="detail-icon">🌧️</span> <span>降水量 <span class="detail-value">45mm</span></span> </div> <div class="detail-item"> <span class="detail-icon">⚡</span> <span>雷电 <span class="detail-value">频繁</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 暴雪卡片 --> <div class="weather-card" data-weather="snow"> <div class="card-scene scene-snow"> <div class="scene-glow"></div> <div class="snow-cloud-group"> <div class="cloud-css" style="width:68px;height:29px;border-radius:29px;"></div> </div> <div class="snowflakes"> <div class="snowflake sf-1"></div> <div class="snowflake sf-2"></div> <div class="snowflake sf-3"></div> <div class="snowflake sf-4"></div> <div class="snowflake sf-5"></div> <div class="snowflake sf-6"></div> <div class="snowflake sf-7"></div> <div class="snowflake sf-8"></div> <div class="snowflake sf-9"></div> <div class="snowflake sf-10"></div> </div> <div class="snow-ground"></div> </div> <div class="card-info"> <div class="card-temp">-5<span class="degree">°C</span></div> <div class="card-weather-name">❄️ 暴雪</div> <div class="card-subtitle">大雪纷飞 · 注意防寒</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">-9°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">78%</span></span> </div> <div class="detail-item"> <span class="detail-icon">❄️</span> <span>降雪量 <span class="detail-value">25mm</span></span> </div> <div class="detail-item"> <span class="detail-icon">🌬️</span> <span>能见度 <span class="detail-value">0.5km</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> </div> </div> <script> (function() { // 日期更新 const dateDisplay = document.getElementById('dateDisplay'); const now = new Date(); const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; const weekday = weekdays[now.getDay()]; const month = now.getMonth() + 1; const day = now.getDate(); dateDisplay.textContent = `${weekday} · ${month}月${day}日`; // 卡片展开/收起逻辑 const cardsGrid = document.getElementById('cardsGrid'); const cards = cardsGrid.querySelectorAll('.weather-card'); let currentlyExpanded = null; cards.forEach(card => { card.addEventListener('click', function(e) { // 如果点击的是已展开的卡片,则收起 if (this === currentlyExpanded) { this.classList.remove('expanded'); currentlyExpanded = null; return; } // 收起之前展开的卡片 if (currentlyExpanded) { currentlyExpanded.classList.remove('expanded'); } // 展开当前卡片 this.classList.add('expanded'); currentlyExpanded = this; // 添加涟漪效果 createRipple(e, this); }); // hover时微调动画速度(通过CSS变量) card.addEventListener('mouseenter', function() { this.style.setProperty('--transition-speed', '0.35s'); }); card.addEventListener('mouseleave', function() { this.style.setProperty('--transition-speed', '0.4s'); }); }); // 点击空白区域收起所有卡片 document.addEventListener('click', function(e) { if (!e.target.closest('.weather-card') && currentlyExpanded) { currentlyExpanded.classList.remove('expanded'); currentlyExpanded = null; } }); // 涟漪效果 function createRipple(event, card) { const ripple = document.createElement('span'); ripple.className = 'click-ripple'; const rect = card.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; width: ${size}px; height: ${size}px; left: ${x}px; top: ${y}px; border-radius: 50%; background: rgba(255,255,255,0.35); pointer-events: none; z-index: 20; animation: rippleOut 0.7s ease-out forwards; `; card.appendChild(ripple); ripple.addEventListener('animationend', function() { ripple.remove(); }); } // 动态添加涟漪动画的keyframes const rippleStyle = document.createElement('style'); rippleStyle.textContent = ` @keyframes rippleOut { 0% { transform: scale(0); opacity: 0.6; } 100% { transform: scale(2.5); opacity: 0; } } `; document.head.appendChild(rippleStyle); // 触摸设备支持 cards.forEach(card => { card.addEventListener('touchstart', function() { this.style.transform = 'scale(0.97)'; this.style.transition = 'transform 0.15s ease'; }); card.addEventListener('touchend', function() { this.style.transform = ''; this.style.transition = ''; }); }); console.log('🌤️ iOS 18 风格天气卡片已就绪'); console.log(' ☀️ 晴天 | 💨 大风 | ⛈️ 暴雨 | ❄️ 暴雪'); console.log(' 💡 点击卡片查看详细天气信息'); })(); </script> </body> </html> 网友解答:


--【壹】--:

感觉不是普通, 是低于目前主流模型的水平, 这太阳,这大风,这暴雨,这暴雪


--【贰】--:

感觉效果一般般,没有啥特别惊艳的感觉,那个太阳也太太阳了


--【叁】--:

在哪里可以进行测试呀,我去huggingface 看到了

问题描述:

以 iOS 18 的设计风格做一个带有动画效果的天气卡片,要求是使用 HTML、CSS 和基础 JavaScript,使用横板天气页面(拥有 4 个天气卡片 (晴天,大风,暴雨,暴雪))。应足够美观,实现一定的交互效果。

image1264×533 53.4 KB

<!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 { --card-radius: 24px; --transition-speed: 0.4s; --bg-gradient-start: #e8eef5; --bg-gradient-mid: #dce4f0; --bg-gradient-end: #eef1f7; --sunny-accent: #f59e4b; --sunny-bg: #fff8f0; --sunny-glow: #ffe4c4; --windy-accent: #7b9eb3; --windy-bg: #f2f6f9; --windy-glow: #d4e2ec; --storm-accent: #5b6e8a; --storm-bg: #f0f2f7; --storm-glow: #c8d6e5; --snow-accent: #a3bfd4; --snow-bg: #f4f8fb; --snow-glow: #e2eef7; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Helvetica Neue', sans-serif; min-height: 100vh; display: flex; align-items: center; justify-content: center; background: linear-gradient(160deg, #dfe9f3 0%, #e8eef5 20%, #f0f4f8 40%, #eef2f6 60%, #e4ebf3 80%, #dce5ef 100%); background-attachment: fixed; position: relative; overflow-x: hidden; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; padding: 20px; } /* 背景光晕动画 */ .bg-orb { position: fixed; border-radius: 50%; filter: blur(120px); opacity: 0.35; pointer-events: none; z-index: 0; animation: orbDrift 20s ease-in-out infinite; } .bg-orb.orb-1 { width: 500px; height: 500px; background: #ffe4c4; top: -15%; left: -10%; animation-delay: 0s; } .bg-orb.orb-2 { width: 400px; height: 400px; background: #c8ddf0; top: 50%; right: -8%; animation-delay: -7s; animation-duration: 24s; } .bg-orb.orb-3 { width: 350px; height: 350px; background: #e8d5f5; bottom: -12%; left: 30%; animation-delay: -14s; animation-duration: 22s; } @keyframes orbDrift { 0%, 100% { transform: translate(0, 0) scale(1); } 25% { transform: translate(60px, -40px) scale(1.08); } 50% { transform: translate(-30px, 30px) scale(0.94); } 75% { transform: translate(-50px, -20px) scale(1.05); } } /* 主容器 */ .main-container { position: relative; z-index: 1; width: 100%; max-width: 1350px; display: flex; flex-direction: column; gap: 20px; } /* 顶部标题栏 */ .header { display: flex; align-items: center; justify-content: space-between; padding: 12px 8px 4px; flex-wrap: wrap; gap: 12px; } .header .location-group { display: flex; align-items: center; gap: 10px; } .header .location-icon { width: 36px; height: 36px; border-radius: 50%; background: rgba(255, 255, 255, 0.55); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); display: flex; align-items: center; justify-content: center; font-size: 18px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06); border: 1px solid rgba(255, 255, 255, 0.6); } .header .location-name { font-size: 1.5rem; font-weight: 600; color: #1d1d1f; letter-spacing: -0.02em; } .header .date-text { font-size: 0.95rem; color: #6e6e73; font-weight: 500; padding: 8px 16px; background: rgba(255, 255, 255, 0.5); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); border-radius: 20px; border: 1px solid rgba(255, 255, 255, 0.55); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04); } /* 卡片网格 */ .cards-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; width: 100%; } /* 单张卡片 */ .weather-card { position: relative; background: rgba(255, 255, 255, 0.48); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px); border-radius: var(--card-radius); border: 1px solid rgba(255, 255, 255, 0.65); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.06), 0 1px 3px rgba(0, 0, 0, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.7); cursor: pointer; overflow: hidden; transition: transform var(--transition-speed) cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow var(--transition-speed) ease, border-color var(--transition-speed) ease; display: flex; flex-direction: column; min-height: 420px; user-select: none; -webkit-tap-highlight-color: transparent; z-index: 1; } .weather-card:hover { transform: translateY(-8px); box-shadow: 0 16px 40px rgba(0, 0, 0, 0.1), 0 4px 12px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.8); border-color: rgba(255, 255, 255, 0.85); z-index: 5; } .weather-card:active { transform: scale(0.975); transition: transform 0.15s ease; } .weather-card.expanded { z-index: 10; box-shadow: 0 24px 55px rgba(0, 0, 0, 0.14), 0 6px 16px rgba(0, 0, 0, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.8); border-color: rgba(255, 255, 255, 0.9); } /* 卡片场景区域(天气动画) */ .card-scene { position: relative; width: 100%; height: 220px; overflow: hidden; border-radius: var(--card-radius) var(--card-radius) 0 0; transition: height var(--transition-speed) ease; } .weather-card.expanded .card-scene { height: 200px; } /* 场景背景色 */ .card-scene.scene-sunny { background: linear-gradient(180deg, #ffe8c8 0%, #fff4e4 40%, #fffaf3 100%); } .card-scene.scene-windy { background: linear-gradient(180deg, #dce8f2 0%, #eaf1f7 40%, #f5f8fb 100%); } .card-scene.scene-storm { background: linear-gradient(180deg, #c8d4e2 0%, #dbe3ee 30%, #e8edf5 60%, #f2f4f8 100%); } .card-scene.scene-snow { background: linear-gradient(180deg, #e2eef8 0%, #eef5fa 40%, #f7fafc 100%); } /* 场景内的光晕 */ .scene-glow { position: absolute; border-radius: 50%; pointer-events: none; filter: blur(40px); opacity: 0.5; animation: glowPulse 4s ease-in-out infinite; } .scene-sunny .scene-glow { width: 120px; height: 120px; background: #fcc870; top: 30px; left: 50%; transform: translateX(-50%); animation-duration: 3.5s; } .scene-windy .scene-glow { width: 100px; height: 60px; background: #b8cfdf; top: 60px; left: 30%; animation-duration: 5s; } .scene-storm .scene-glow { width: 90px; height: 90px; background: #8899b5; top: 50px; left: 45%; animation-duration: 2.8s; opacity: 0.4; } .scene-snow .scene-glow { width: 110px; height: 110px; background: #c8dff0; top: 40px; left: 50%; transform: translateX(-50%); animation-duration: 4.5s; } @keyframes glowPulse { 0%, 100% { opacity: 0.4; transform: translateX(-50%) scale(1); } 50% { opacity: 0.7; transform: translateX(-50%) scale(1.2); } } /* -------- 太阳 (晴天) -------- */ .sun-container { position: absolute; top: 38px; left: 50%; transform: translateX(-50%); width: 80px; height: 80px; z-index: 3; } .sun-core { position: absolute; width: 52px; height: 52px; background: radial-gradient(circle at 40% 38%, #fff7c2 0%, #fdb833 55%, #f08c20 100%); border-radius: 50%; top: 50%; left: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 50px rgba(253, 165, 40, 0.55), 0 0 100px rgba(253, 165, 40, 0.3), 0 0 160px rgba(253, 165, 40, 0.15); animation: sunPulse 3s ease-in-out infinite; z-index: 2; } @keyframes sunPulse { 0%, 100% { box-shadow: 0 0 50px rgba(253, 165, 40, 0.55), 0 0 100px rgba(253, 165, 40, 0.3), 0 0 160px rgba(253, 165, 40, 0.15); } 50% { box-shadow: 0 0 70px rgba(253, 165, 40, 0.7), 0 0 130px rgba(253, 165, 40, 0.4), 0 0 190px rgba(253, 165, 40, 0.22); } } .sun-ray { position: absolute; top: 50%; left: 50%; width: 4px; height: 28px; background: rgba(253, 180, 50, 0.5); border-radius: 4px; transform-origin: center bottom; animation: rayRotate 12s linear infinite; } .sun-ray:nth-child(2) { transform: rotate(0deg) translateY(-40px); animation-delay: 0s; height: 30px; } .sun-ray:nth-child(3) { transform: rotate(45deg) translateY(-40px); animation-delay: -1.5s; height: 26px; } .sun-ray:nth-child(4) { transform: rotate(90deg) translateY(-40px); animation-delay: -3s; height: 32px; } .sun-ray:nth-child(5) { transform: rotate(135deg) translateY(-40px); animation-delay: -4.5s; height: 24px; } .sun-ray:nth-child(6) { transform: rotate(180deg) translateY(-40px); animation-delay: -6s; height: 30px; } .sun-ray:nth-child(7) { transform: rotate(225deg) translateY(-40px); animation-delay: -7.5s; height: 27px; } .sun-ray:nth-child(8) { transform: rotate(270deg) translateY(-40px); animation-delay: -9s; height: 33px; } .sun-ray:nth-child(9) { transform: rotate(315deg) translateY(-40px); animation-delay: -10.5s; height: 25px; } @keyframes rayRotate { from { transform: rotate(var(--r, 0deg)) translateY(-40px) rotate(0deg); } to { transform: rotate(var(--r, 0deg)) translateY(-40px) rotate(360deg); } } /* 为每条光线设置旋转变量 */ .sun-ray:nth-child(2) { --r: 0deg; } .sun-ray:nth-child(3) { --r: 45deg; } .sun-ray:nth-child(4) { --r: 90deg; } .sun-ray:nth-child(5) { --r: 135deg; } .sun-ray:nth-child(6) { --r: 180deg; } .sun-ray:nth-child(7) { --r: 225deg; } .sun-ray:nth-child(8) { --r: 270deg; } .sun-ray:nth-child(9) { --r: 315deg; } /* 晴天小云朵 */ .tiny-cloud-sunny { position: absolute; bottom: 35px; right: 28px; z-index: 4; animation: cloudFloat 6s ease-in-out infinite; } @keyframes cloudFloat { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(14px); } } /* -------- 云 (CSS绘制) -------- */ .cloud-css { position: relative; width: 70px; height: 32px; background: rgba(255, 255, 255, 0.85); border-radius: 32px; box-shadow: 0 4px 16px rgba(0, 0, 0, 0.06); } .cloud-css::before { content: ''; position: absolute; width: 34px; height: 34px; background: rgba(255, 255, 255, 0.85); border-radius: 50%; top: -18px; left: 12px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03); } .cloud-css::after { content: ''; position: absolute; width: 26px; height: 26px; background: rgba(255, 255, 255, 0.8); border-radius: 50%; top: -10px; left: 38px; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03); } /* -------- 大风场景 -------- */ .wind-cloud-group { position: absolute; top: 40px; left: 50%; transform: translateX(-50%); z-index: 3; } .wind-lines { position: absolute; top: 50%; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 5; } .wind-line { position: absolute; height: 3px; background: rgba(140, 170, 195, 0.55); border-radius: 3px; animation: windBlow linear infinite; opacity: 0; } .wind-line.wl-1 { top: 90px; left: 10%; width: 50px; animation-duration: 2.2s; animation-delay: 0s; } .wind-line.wl-2 { top: 110px; left: 20%; width: 70px; animation-duration: 2.8s; animation-delay: 0.6s; } .wind-line.wl-3 { top: 130px; left: 5%; width: 40px; animation-duration: 1.9s; animation-delay: 1.2s; } .wind-line.wl-4 { top: 100px; left: 30%; width: 60px; animation-duration: 2.5s; animation-delay: 1.8s; } .wind-line.wl-5 { top: 145px; left: 15%; width: 35px; animation-duration: 3.1s; animation-delay: 0.3s; } .wind-line.wl-6 { top: 120px; left: 8%; width: 55px; animation-duration: 2.4s; animation-delay: 2s; } @keyframes windBlow { 0% { transform: translateX(-30px); opacity: 0; } 15% { opacity: 0.7; } 70% { opacity: 0.6; } 100% { transform: translateX(calc(100% + 60px)); opacity: 0; } } /* -------- 暴雨场景 -------- */ .storm-cloud-group { position: absolute; top: 28px; left: 50%; transform: translateX(-50%); z-index: 3; } .storm-cloud-group .cloud-css { background: rgba(180, 195, 215, 0.75); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); } .storm-cloud-group .cloud-css::before, .storm-cloud-group .cloud-css::after { background: rgba(180, 195, 215, 0.75); } .raindrops { position: absolute; top: 60px; left: 0; width: 100%; height: calc(100% - 60px); pointer-events: none; z-index: 4; } .raindrop { position: absolute; width: 2px; height: 16px; background: linear-gradient(to bottom, rgba(120, 150, 185, 0.3), rgba(100, 140, 180, 0.7)); border-radius: 0 0 4px 4px; animation: rainFall linear infinite; opacity: 0; } .raindrop.rd-1 { left: 18%; animation-duration: .7s; animation-delay: 0s; } .raindrop.rd-2 { left: 30%; animation-duration: .85s; animation-delay: 0.15s; } .raindrop.rd-3 { left: 42%; animation-duration: .65s; animation-delay: 0.3s; } .raindrop.rd-4 { left: 54%; animation-duration: .9s; animation-delay: 0.45s; } .raindrop.rd-5 { left: 65%; animation-duration: .75s; animation-delay: 0.1s; } .raindrop.rd-6 { left: 22%; animation-duration: .8s; animation-delay: 0.5s; } .raindrop.rd-7 { left: 48%; animation-duration: .7s; animation-delay: 0.35s; } .raindrop.rd-8 { left: 60%; animation-duration: .95s; animation-delay: 0.25s; } .raindrop.rd-9 { left: 35%; animation-duration: .78s; animation-delay: 0.55s; } .raindrop.rd-10 { left: 70%; animation-duration: .72s; animation-delay: 0.4s; } @keyframes rainFall { 0% { transform: translateY(-30px); opacity: 0; } 10% { opacity: 0.8; } 85% { opacity: 0.5; } 100% { transform: translateY(150px); opacity: 0; } } /* 闪电 */ .lightning { position: absolute; top: 55px; left: 40%; width: 3px; height: 50px; background: rgba(255, 255, 220, 0.9); border-radius: 2px; z-index: 5; opacity: 0; animation: lightningFlash 4s ease-in-out infinite; filter: blur(1px); box-shadow: 0 0 20px rgba(255, 255, 200, 0.7), 0 0 40px rgba(255, 255, 180, 0.4); } .lightning::after { content: ''; position: absolute; top: 20px; left: 6px; width: 2px; height: 25px; background: rgba(255, 255, 210, 0.8); border-radius: 2px; transform: rotate(25deg); } @keyframes lightningFlash { 0%, 90%, 96%, 100% { opacity: 0; } 91% { opacity: 0.9; } 92% { opacity: 0.2; } 93% { opacity: 0.85; } 94% { opacity: 0.1; } 95% { opacity: 0.6; } } /* -------- 暴雪场景 -------- */ .snow-cloud-group { position: absolute; top: 30px; left: 50%; transform: translateX(-50%); z-index: 3; } .snow-cloud-group .cloud-css { background: rgba(225, 235, 245, 0.8); } .snow-cloud-group .cloud-css::before, .snow-cloud-group .cloud-css::after { background: rgba(225, 235, 245, 0.8); } .snowflakes { position: absolute; top: 55px; left: 0; width: 100%; height: calc(100% - 55px); pointer-events: none; z-index: 5; } .snowflake { position: absolute; background: rgba(255, 255, 255, 0.9); border-radius: 50%; animation: snowFall linear infinite; opacity: 0; box-shadow: 0 0 6px rgba(255, 255, 255, 0.5); } .snowflake.sf-1 { left: 15%; width: 6px; height: 6px; animation-duration: 3.5s; animation-delay: 0s; } .snowflake.sf-2 { left: 28%; width: 4px; height: 4px; animation-duration: 4.2s; animation-delay: 0.8s; } .snowflake.sf-3 { left: 40%; width: 7px; height: 7px; animation-duration: 3.8s; animation-delay: 1.5s; } .snowflake.sf-4 { left: 55%; width: 5px; height: 5px; animation-duration: 4.6s; animation-delay: 0.4s; } .snowflake.sf-5 { left: 68%; width: 6px; height: 6px; animation-duration: 3.3s; animation-delay: 2s; } .snowflake.sf-6 { left: 20%; width: 3px; height: 3px; animation-duration: 5s; animation-delay: 1.1s; } .snowflake.sf-7 { left: 48%; width: 5px; height: 5px; animation-duration: 3.9s; animation-delay: 2.5s; } .snowflake.sf-8 { left: 62%; width: 7px; height: 7px; animation-duration: 4.4s; animation-delay: 0.7s; } .snowflake.sf-9 { left: 33%; width: 4px; height: 4px; animation-duration: 4.8s; animation-delay: 0.2s; } .snowflake.sf-10 { left: 72%; width: 5px; height: 5px; animation-duration: 3.6s; animation-delay: 1.8s; } @keyframes snowFall { 0% { transform: translateY(-25px) translateX(0) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translateY(60px) translateX(18px) rotate(180deg); opacity: 0.7; } 90% { opacity: 0.3; } 100% { transform: translateY(155px) translateX(-10px) rotate(360deg); opacity: 0; } } /* 地面微光(暴雪) */ .snow-ground { position: absolute; bottom: 0; left: 0; width: 100%; height: 30px; background: linear-gradient(to top, rgba(220, 235, 250, 0.5) 0%, transparent 100%); z-index: 1; border-radius: 0 0 var(--card-radius) 0; } /* -------- 卡片信息区域 -------- */ .card-info { padding: 16px 20px 20px; display: flex; flex-direction: column; gap: 6px; flex: 1; position: relative; z-index: 2; } .card-temp { font-size: 3.2rem; font-weight: 600; letter-spacing: -0.03em; line-height: 1; color: #1d1d1f; transition: color var(--transition-speed) ease; } .card-temp .degree { font-size: 1.6rem; font-weight: 500; vertical-align: super; margin-left: 2px; color: #6e6e73; } .card-weather-name { font-size: 1.15rem; font-weight: 500; color: #3a3a3c; letter-spacing: -0.01em; } .card-subtitle { font-size: 0.85rem; color: #8e8e93; font-weight: 400; } /* 展开详情 */ .card-details { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 16px; max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.35s ease, margin-top 0.4s ease; margin-top: 0; } .weather-card.expanded .card-details { max-height: 120px; opacity: 1; margin-top: 12px; } .detail-item { display: flex; align-items: center; gap: 7px; font-size: 0.82rem; color: #5c5c5e; font-weight: 500; } .detail-item .detail-icon { width: 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 13px; background: rgba(0, 0, 0, 0.04); flex-shrink: 0; } .detail-value { font-weight: 600; color: #1d1d1f; } /* 卡片选中指示器 */ .card-indicator { position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%); width: 32px; height: 4px; background: rgba(0, 0, 0, 0.15); border-radius: 4px; transition: all var(--transition-speed) ease; opacity: 0; } .weather-card.expanded .card-indicator { opacity: 1; width: 40px; background: rgba(0, 0, 0, 0.25); } /* -------- 响应式设计 -------- */ @media (max-width: 1100px) { .cards-grid { grid-template-columns: repeat(2, 1fr); gap: 16px; } .weather-card { min-height: 380px; } .card-scene { height: 190px; } .card-temp { font-size: 2.8rem; } } @media (max-width: 640px) { .cards-grid { grid-template-columns: 1fr 1fr; gap: 12px; } .weather-card { min-height: 340px; } .card-scene { height: 160px; } .card-temp { font-size: 2.4rem; } .card-info { padding: 12px 14px 16px; } .header .location-name { font-size: 1.2rem; } .header .date-text { font-size: 0.8rem; padding: 6px 12px; } .sun-container { top: 25px; width: 60px; height: 60px; } .sun-core { width: 38px; height: 38px; } .sun-ray { height: 18px; width: 3px; } .sun-ray:nth-child(2) { transform: rotate(0deg) translateY(-28px); } .sun-ray:nth-child(3) { transform: rotate(45deg) translateY(-28px); } .sun-ray:nth-child(4) { transform: rotate(90deg) translateY(-28px); } .sun-ray:nth-child(5) { transform: rotate(135deg) translateY(-28px); } .sun-ray:nth-child(6) { transform: rotate(180deg) translateY(-28px); } .sun-ray:nth-child(7) { transform: rotate(225deg) translateY(-28px); } .sun-ray:nth-child(8) { transform: rotate(270deg) translateY(-28px); } .sun-ray:nth-child(9) { transform: rotate(315deg) translateY(-28px); } @keyframes rayRotate { from { transform: rotate(var(--r, 0deg)) translateY(-28px) rotate(0deg); } to { transform: rotate(var(--r, 0deg)) translateY(-28px) rotate(360deg); } } .cloud-css { width: 50px; height: 22px; border-radius: 22px; } .cloud-css::before { width: 24px; height: 24px; top: -13px; left: 8px; } .cloud-css::after { width: 18px; height: 18px; top: -7px; left: 28px; } } @media (max-width: 420px) { .cards-grid { grid-template-columns: 1fr; gap: 14px; } .weather-card { min-height: 300px; flex-direction: row; border-radius: 20px; } .card-scene { width: 140px; height: auto; min-height: 140px; border-radius: 20px 0 0 20px; flex-shrink: 0; } .card-info { padding: 16px; justify-content: center; } .card-temp { font-size: 2.2rem; } .weather-card.expanded .card-scene { height: auto; } .card-details { grid-template-columns: 1fr; gap: 6px; } .weather-card.expanded .card-details { max-height: 200px; } .card-indicator { bottom: 8px; } } </style> </head> <body> <!-- 背景光晕 --> <div class="bg-orb orb-1"></div> <div class="bg-orb orb-2"></div> <div class="bg-orb orb-3"></div> <!-- 主容器 --> <div class="main-container"> <!-- 顶部标题 --> <div class="header"> <div class="location-group"> <div class="location-icon">📍</div> <span class="location-name">北京 · 中国</span> </div> <span class="date-text" id="dateDisplay"></span> </div> <!-- 卡片网格 --> <div class="cards-grid" id="cardsGrid"> <!-- 晴天卡片 --> <div class="weather-card" data-weather="sunny"> <div class="card-scene scene-sunny"> <div class="scene-glow"></div> <div class="sun-container"> <div class="sun-core"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> <div class="sun-ray"></div> </div> <div class="tiny-cloud-sunny"> <div class="cloud-css" style="width:50px;height:22px;border-radius:22px;"></div> </div> </div> <div class="card-info"> <div class="card-temp">28<span class="degree">°C</span></div> <div class="card-weather-name">☀️ 晴天</div> <div class="card-subtitle">阳光明媚 · 适合出行</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">30°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">35%</span></span> </div> <div class="detail-item"> <span class="detail-icon">☀️</span> <span>紫外线 <span class="detail-value">强</span></span> </div> <div class="detail-item"> <span class="detail-icon">🍃</span> <span>风速 <span class="detail-value">2级</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 大风卡片 --> <div class="weather-card" data-weather="windy"> <div class="card-scene scene-windy"> <div class="scene-glow"></div> <div class="wind-cloud-group"> <div class="cloud-css" style="width:65px;height:28px;border-radius:28px;"></div> </div> <div class="wind-lines"> <div class="wind-line wl-1"></div> <div class="wind-line wl-2"></div> <div class="wind-line wl-3"></div> <div class="wind-line wl-4"></div> <div class="wind-line wl-5"></div> <div class="wind-line wl-6"></div> </div> </div> <div class="card-info"> <div class="card-temp">15<span class="degree">°C</span></div> <div class="card-weather-name">💨 大风</div> <div class="card-subtitle">风力强劲 · 注意保暖</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">10°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">48%</span></span> </div> <div class="detail-item"> <span class="detail-icon">💨</span> <span>阵风 <span class="detail-value">7级</span></span> </div> <div class="detail-item"> <span class="detail-icon">🍃</span> <span>风速 <span class="detail-value">5级</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 暴雨卡片 --> <div class="weather-card" data-weather="storm"> <div class="card-scene scene-storm"> <div class="scene-glow"></div> <div class="storm-cloud-group"> <div class="cloud-css" style="width:72px;height:30px;border-radius:30px;"></div> </div> <div class="lightning"></div> <div class="raindrops"> <div class="raindrop rd-1"></div> <div class="raindrop rd-2"></div> <div class="raindrop rd-3"></div> <div class="raindrop rd-4"></div> <div class="raindrop rd-5"></div> <div class="raindrop rd-6"></div> <div class="raindrop rd-7"></div> <div class="raindrop rd-8"></div> <div class="raindrop rd-9"></div> <div class="raindrop rd-10"></div> </div> </div> <div class="card-info"> <div class="card-temp">18<span class="degree">°C</span></div> <div class="card-weather-name">⛈️ 暴雨</div> <div class="card-subtitle">雷电交加 · 减少外出</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">16°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">92%</span></span> </div> <div class="detail-item"> <span class="detail-icon">🌧️</span> <span>降水量 <span class="detail-value">45mm</span></span> </div> <div class="detail-item"> <span class="detail-icon">⚡</span> <span>雷电 <span class="detail-value">频繁</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> <!-- 暴雪卡片 --> <div class="weather-card" data-weather="snow"> <div class="card-scene scene-snow"> <div class="scene-glow"></div> <div class="snow-cloud-group"> <div class="cloud-css" style="width:68px;height:29px;border-radius:29px;"></div> </div> <div class="snowflakes"> <div class="snowflake sf-1"></div> <div class="snowflake sf-2"></div> <div class="snowflake sf-3"></div> <div class="snowflake sf-4"></div> <div class="snowflake sf-5"></div> <div class="snowflake sf-6"></div> <div class="snowflake sf-7"></div> <div class="snowflake sf-8"></div> <div class="snowflake sf-9"></div> <div class="snowflake sf-10"></div> </div> <div class="snow-ground"></div> </div> <div class="card-info"> <div class="card-temp">-5<span class="degree">°C</span></div> <div class="card-weather-name">❄️ 暴雪</div> <div class="card-subtitle">大雪纷飞 · 注意防寒</div> <div class="card-details"> <div class="detail-item"> <span class="detail-icon">🌡️</span> <span>体感 <span class="detail-value">-9°</span></span> </div> <div class="detail-item"> <span class="detail-icon">💧</span> <span>湿度 <span class="detail-value">78%</span></span> </div> <div class="detail-item"> <span class="detail-icon">❄️</span> <span>降雪量 <span class="detail-value">25mm</span></span> </div> <div class="detail-item"> <span class="detail-icon">🌬️</span> <span>能见度 <span class="detail-value">0.5km</span></span> </div> </div> <div class="card-indicator"></div> </div> </div> </div> </div> <script> (function() { // 日期更新 const dateDisplay = document.getElementById('dateDisplay'); const now = new Date(); const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; const weekday = weekdays[now.getDay()]; const month = now.getMonth() + 1; const day = now.getDate(); dateDisplay.textContent = `${weekday} · ${month}月${day}日`; // 卡片展开/收起逻辑 const cardsGrid = document.getElementById('cardsGrid'); const cards = cardsGrid.querySelectorAll('.weather-card'); let currentlyExpanded = null; cards.forEach(card => { card.addEventListener('click', function(e) { // 如果点击的是已展开的卡片,则收起 if (this === currentlyExpanded) { this.classList.remove('expanded'); currentlyExpanded = null; return; } // 收起之前展开的卡片 if (currentlyExpanded) { currentlyExpanded.classList.remove('expanded'); } // 展开当前卡片 this.classList.add('expanded'); currentlyExpanded = this; // 添加涟漪效果 createRipple(e, this); }); // hover时微调动画速度(通过CSS变量) card.addEventListener('mouseenter', function() { this.style.setProperty('--transition-speed', '0.35s'); }); card.addEventListener('mouseleave', function() { this.style.setProperty('--transition-speed', '0.4s'); }); }); // 点击空白区域收起所有卡片 document.addEventListener('click', function(e) { if (!e.target.closest('.weather-card') && currentlyExpanded) { currentlyExpanded.classList.remove('expanded'); currentlyExpanded = null; } }); // 涟漪效果 function createRipple(event, card) { const ripple = document.createElement('span'); ripple.className = 'click-ripple'; const rect = card.getBoundingClientRect(); const size = Math.max(rect.width, rect.height); const x = event.clientX - rect.left - size / 2; const y = event.clientY - rect.top - size / 2; ripple.style.cssText = ` position: absolute; width: ${size}px; height: ${size}px; left: ${x}px; top: ${y}px; border-radius: 50%; background: rgba(255,255,255,0.35); pointer-events: none; z-index: 20; animation: rippleOut 0.7s ease-out forwards; `; card.appendChild(ripple); ripple.addEventListener('animationend', function() { ripple.remove(); }); } // 动态添加涟漪动画的keyframes const rippleStyle = document.createElement('style'); rippleStyle.textContent = ` @keyframes rippleOut { 0% { transform: scale(0); opacity: 0.6; } 100% { transform: scale(2.5); opacity: 0; } } `; document.head.appendChild(rippleStyle); // 触摸设备支持 cards.forEach(card => { card.addEventListener('touchstart', function() { this.style.transform = 'scale(0.97)'; this.style.transition = 'transform 0.15s ease'; }); card.addEventListener('touchend', function() { this.style.transform = ''; this.style.transition = ''; }); }); console.log('🌤️ iOS 18 风格天气卡片已就绪'); console.log(' ☀️ 晴天 | 💨 大风 | ⛈️ 暴雨 | ❄️ 暴雪'); console.log(' 💡 点击卡片查看详细天气信息'); })(); </script> </body> </html> 网友解答:


--【壹】--:

感觉不是普通, 是低于目前主流模型的水平, 这太阳,这大风,这暴雨,这暴雪


--【贰】--:

感觉效果一般般,没有啥特别惊艳的感觉,那个太阳也太太阳了


--【叁】--:

在哪里可以进行测试呀,我去huggingface 看到了