You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将渐变背景动画与实时时间同步

实现日月动画与实时时间同步的方案

你已经完成了包含日月元素的天空背景动画效果,现在要让动画和实时时间绑定,让日月位置、天空背景真实反映当前时段,下面是具体实现方案:

实现思路

不再依赖CSS的循环动画,而是通过JavaScript计算当前时间在一天中的占比,将这个占比映射为日月轨道的旋转角度和各时段背景的透明度,同时定时更新状态保持同步。

具体步骤

1. 调整CSS样式

移除.sky__dawn、.sky__noon等元素上的infinite循环动画,同时去掉.orbit的循环动画(保留关键帧作为透明度计算的参考),改为通过JS动态控制元素的透明度和旋转角度。

2. 编写时间同步逻辑

  • 获取当前时间,计算从0点到现在的总分钟数,除以一天的总分钟数(1440)得到时间占比
  • 根据时间占比计算太阳轨道的旋转角度:对应日出(0点后)到日落(12点后)的位置,12点后隐藏太阳
  • 计算月亮轨道的旋转角度:对应12点后出现到次日0点隐藏的位置,和太阳反向运动
  • 模拟原CSS动画的透明度变化,根据时间占比设置各时段背景的透明度

3. 定时更新状态

设置每分钟更新一次状态,确保动画和时间始终同步。


修改后的完整代码

CSS

@keyframes sunrise {
    from { transform: rotate(-45deg); }
    to { transform: rotate(315deg); }
}

@keyframes moonrise {
    from { transform: rotate(0deg); }
    to { transform: rotate(180deg); }
}

@keyframes dawn {
    0% { opacity: 0; }
    10% { opacity: 1; }
    60% { opacity: 0; }
}

@keyframes noon {
    0% { opacity: 0; }
    50% { opacity: 1; }
    75% { opacity: 0; }
}

@keyframes dusk {
    0% { opacity: 0; }
    50% { opacity: 0; }
    70% { opacity: 1; }
    90% { opacity: 0; }
}

@keyframes midnight {
    0% { opacity: 1; }
    25% { opacity: 0; }
    50% { opacity: 0; }
    80% { opacity: 1; }
}

body {
    background-color: rgb(37, 29, 24);
    margin: 0;
}

.sky {
    width: 100vw;
    height: 100vh;
    position: relative;
    top: 0;
    left: 0;
    overflow: hidden;
}

.sky__phase {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    transition: opacity 0.5s ease;
}

.sky__dawn {
    background: linear-gradient(0deg, rgba(254, 215, 102, 1) 0%, rgba(205, 237, 246, 1) 100%);
}

.sky__noon {
    background: linear-gradient(0deg, rgba(205, 237, 246, 1) 0%, rgba(36, 123, 160, 1) 100%);
}

.sky__dusk {
    background: linear-gradient(0deg, rgba(255, 32, 110, 1) 0%, rgba(10, 0, 94, 1) 100%);
}

.sky__midnight {
    background: linear-gradient(0deg, rgba(2, 0, 20, 1) 0%, rgba(10, 0, 94, 1) 100%);
}

.orbit {
    position: relative;
    width: 500px;
    height: 500px;
    margin: 200px auto;
    transform-origin: center;
}

.moon-orbit {
    position: absolute;
    width: 100%;
    height: 100%;
    transform-origin: center;
}

@media (min-width: 768px) {
    .orbit {
        width: 100px;
        height: 700px;
        margin: 150px auto;
    }
}

@media screen and (min-width: 1080px) and (max-width: 1920px) {
    .orbit {
        width: 600px;
        height: 1100px;
        margin: 1000px auto;
    }
}

.sun {
    position: absolute;
    top: -40px;
    left: -40px;
    width: 80px;
    height: 80px;
    background-color: rgb(254, 215, 102);
    border-radius: 50%;
    box-shadow: 0 0 14px 14px rgba(254, 215, 102, 0.2);
}

.moon {
    position: absolute;
    bottom: -40px;
    right: -40px;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background-color: #fff;
    box-shadow: 0 0 7px 7px rgba(255, 255, 255, 0.2);
}

HTML

<div class="sky">
    <div class="sky__phase sky__dawn"></div>
    <div class="sky__phase sky__noon"></div>
    <div class="sky__phase sky__dusk"></div>
    <div class="sky__phase sky__midnight"></div>
    <div class="orbit">
        <div class="sun"></div>
        <div class="moon-orbit">
            <div class="moon"></div>
        </div>
    </div>
</div>

JavaScript

function updateSky() {
    const now = new Date();
    const totalMinutes = now.getHours() * 60 + now.getMinutes();
    const dayPercentage = totalMinutes / 1440; // 一天共1440分钟

    // 控制太阳旋转与显示:0-12小时显示,对应-45deg到315deg
    const sunRotation = dayPercentage <= 0.5 ? (-45 + dayPercentage * 360) : 315;
    document.querySelector('.orbit').style.transform = `rotate(${sunRotation}deg)`;
    document.querySelector('.sun').style.opacity = dayPercentage >= 0.5 ? 0 : 1;

    // 控制月亮旋转与显示:12-24小时显示,对应180deg到0deg
    const moonRotation = dayPercentage >= 0.5 ? (180 - (dayPercentage - 0.5) * 360) : 180;
    document.querySelector('.moon-orbit').style.transform = `rotate(${moonRotation}deg)`;
    document.querySelector('.moon').style.opacity = dayPercentage < 0.5 ? 0 : 1;

    // 设置各时段背景透明度
    document.querySelector('.sky__dawn').style.opacity = getDawnOpacity(dayPercentage);
    document.querySelector('.sky__noon').style.opacity = getNoonOpacity(dayPercentage);
    document.querySelector('.sky__dusk').style.opacity = getDuskOpacity(dayPercentage);
    document.querySelector('.sky__midnight').style.opacity = getMidnightOpacity(dayPercentage);
}

// 模拟原dawn动画的透明度变化
function getDawnOpacity(percent) {
    const dayFraction = percent * 100;
    if (dayFraction <= 10) return dayFraction / 10;
    if (dayFraction <= 60) return 1 - (dayFraction - 10) / 50;
    return 0;
}

// 模拟原noon动画的透明度变化
function getNoonOpacity(percent) {
    const dayFraction = percent * 100;
    if (dayFraction <= 50) return dayFraction / 100;
    if (dayFraction <= 75) return 1 - (dayFraction - 50) / 25;
    return 0;
}

// 模拟原dusk动画的透明度变化
function getDuskOpacity(percent) {
    const dayFraction = percent * 100;
    if (dayFraction <= 50) return 0;
    if (dayFraction <= 70) return (dayFraction - 50) / 20;
    if (dayFraction <= 90) return 1 - (dayFraction - 70) / 20;
    return 0;
}

// 模拟原midnight动画的透明度变化
function getMidnightOpacity(percent) {
    const dayFraction = percent * 100;
    if (dayFraction <= 25) return 1 - dayFraction / 25;
    if (dayFraction <= 80) return 0;
    return (dayFraction - 80) / 20;
}

// 页面加载时初始化
updateSky();
// 每分钟更新一次,保持时间同步
setInterval(updateSky, 60000);

内容的提问来源于stack exchange,提问作者mindprojx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:02:34