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

以 iOS 18 的设计风格做一个带有动画效果的天气卡片,要求是使用 HTML、CSS 和基础 JavaScript,使用横板天气页面(拥有 4 个天气卡片 (晴天,大风,暴雨,暴雪))。应足够美观,实现一定的交互效果。 <!DOCTYPE html> <html lang="zh-CN"> <he...
DeepSeek V4 Pro 前端表现-天气卡片
DeepSeek V4 Pro 前端表现-天气卡片
以 iOS 18 的设计风格做一个带有动画效果的天气卡片,要求是使用 HTML、CSS 和基础 JavaScript,使用横板天气页面(拥有 4 个天气卡片 (晴天,大风,暴雨,暴雪))。应足够美观,实现一定的交互效果。

image

<!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>

4 个帖子 - 4 位参与者

阅读完整话题

来源: linux.do查看原文