HTML源码 – 人生倒计时单页源码

温馨提示:本文最后更新于2025-09-10 21:52:39,某些文章具有时效性,若有错误或已失效,请在下方留言或联系站长
图片[1]-HTML源码 – 人生倒计时单页源码-林儿の博客

AI写的人生倒计时单页源码 可视化您的人生旅程,珍惜每一刻时光

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>人生时间进度仪表盘</title>
    <style>
        /* 插件容器样式 - 添加lpd前缀避免与主题样式冲突 */
        .lpd-container {
            max-width: 1200px; /* 设置最大宽度 */
            margin: 30px auto; /* 居中显示 */
            padding: 20px;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
            box-sizing: border-box;
            border-radius: 12px;
            background: #f6f8fa;
            color: #111;
            box-shadow: 0 4px 20px rgba(0,0,0,0.08);
        }

        .lpd-container {
            --lpd-bg:#f6f8fa;
            --lpd-card:#ffffff;
            --lpd-muted:#666;
            --lpd-text:#111;
            --lpd-accent:#7c6cff;
            --lpd-accept-weak:#a79cff;
            --lpd-danger:#ff6b6b;
            --lpd-ok:#22c55e;
            --lpd-shadow:0 8px 25px rgba(0,0,0,.1), inset 0 1px 0 rgba(255,255,255,.6);
            --lpd-radius:16px;
            background: var(--lpd-bg);
            color: var(--lpd-text);
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            transition: all .3s ease;
        }

        .lpd-container[data-theme="dark"]{
            --lpd-bg:#0b1220;
            --lpd-card:#121b2d;
            --lpd-muted:#94a3b8;
            --lpd-text:#e5e7eb;
            --lpd-accent:#7c6cff;
            --lpd-accept-weak:#a79cff;
            --lpd-danger:#ff6b6b;
            --lpd-ok:#22c55e;
            --lpd-shadow:0 8px 25px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.02);
        }

        .lpd-head{
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 10px; /* 减小底部间距 */
            flex-wrap: wrap;
            gap: 15px;
        }
        .lpd-title{
            font-size: 22px;
            font-weight: 700;
            letter-spacing: .5px;
            margin: 0;
            color: var(--lpd-text);
            flex: 1;
            min-width: 200px;
        }
        
        /* 添加二级标题样式 */
        .lpd-subtitle {
            text-align: center;
            font-size: 16px;
            color: var(--lpd-muted);
            margin-top: 8px;
            margin-bottom: 20px;
            width: 100%;
        }
        
        .lpd-theme-toggle{
            cursor: pointer;
            font-size: 18px;
            padding: 10px 15px;
            border-radius: 8px;
            user-select: none;
            background: var(--lpd-card);
            box-shadow: var(--lpd-shadow);
            border: none;
            display: flex;
            align-items: center;
            justify-content: center;
            min-width: 60px;
            transition: transform 0.2s;
        }
        .lpd-theme-toggle:active {
            transform: scale(0.95);
        }
        .lpd-grid{
            display: grid;
            grid-template-columns: repeat(12, 1fr);
            gap: 18px;
        }
        .lpd-card{
            grid-column: span 12;
            background: var(--lpd-card);
            border-radius: var(--lpd-radius);
            box-shadow: var(--lpd-shadow);
            padding: 20px;
            position: relative;
            overflow: hidden;
            transition: all .3s ease;
            box-sizing: border-box;
        }
        .lpd-card h3{
            margin: 0 0 14px 0;
            font-size: 18px;
            opacity: .95;
            color: var(--lpd-text);
        }

        .lpd-countdown-large{
            font-size: 80px;
            line-height: 1;
            font-weight: 800;
            color: var(--lpd-accent);
            text-shadow: 0 4px 15px rgba(124,108,255,.25);
        }
        .lpd-unit{
            opacity: .9;
            font-size: 16px;
            margin-left: 8px;
            color: var(--lpd-text);
        }
        .lpd-mini-grid{
            display: grid;
            grid-template-columns: repeat(4, minmax(0, 1fr));
            gap: 12px;
            margin-top: 20px;
        }
        .lpd-mini{
            background: var(--lpd-card);
            border-radius: 14px;
            padding: 12px 8px;
            text-align: center;
            box-shadow: var(--lpd-shadow);
            transition: all .3s ease;
        }
        .lpd-mini .lpd-num{
            font-size: 26px;
            font-weight: 800;
            color: var(--lpd-text);
        }
        .lpd-mini .lpd-lab{
            font-size: 11px;
            color: var(--lpd-muted);
            letter-spacing: .15em;
            opacity: .9;
            margin-top: 4px;
        }

        .lpd-kpi-grid{
            display: grid;
            grid-template-columns: repeat(2, minmax(0, 1fr));
            gap: 12px;
        }
        .lpd-kpi{
            background: var(--lpd-card);
            border-radius: 14px;
            padding: 18px;
            box-shadow: var(--lpd-shadow);
            transition: all .3s ease;
        }
        .lpd-kpi .lpd-big{
            font-size: 28px;
            font-weight: 800;
            margin-bottom: 6px;
            color: var(--lpd-text);
        }
        .lpd-kpi .lpd-sub{
            color: var(--lpd-muted);
            font-size: 12px;
            letter-spacing: .1em;
        }

        /* 顶部横向进度条样式 */
        .lpd-top-progress {
            width: 100%;
            height: 24px;
            background: rgba(0,0,0,0.06);
            border-radius: 12px;
            margin: 15px 0 25px;
            overflow: hidden;
            position: relative;
            box-shadow: var(--lpd-shadow);
        }
        
        .lpd-container[data-theme="dark"] .lpd-top-progress {
            background: rgba(255,255,255,0.06);
        }
        
        .lpd-top-progress-fill {
            height: 100%;
            background: linear-gradient(90deg, #7c6cff, #8fb1ff);
            border-radius: 12px;
            transition: width 0.8s cubic-bezier(.2,.9,.25,1);
            position: relative;
        }
        
        .lpd-top-progress-text {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: 700;
            color: white;
            text-shadow: 0 1px 2px rgba(0,0,0,0.3);
        }

        .lpd-muted{
            color: var(--lpd-muted);
        }
        .lpd-num-inline{
            font-variant-numeric: tabular-nums;
        }

        /* 配置显示区域 */
        .lpd-config-display {
            background: var(--lpd-card);
            border-radius: var(--lpd-radius);
            padding: 18px;
            margin-bottom: 20px;
            box-shadow: var(--lpd-shadow);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .lpd-config-item {
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .lpd-config-label {
            font-size: 13px;
            color: var(--lpd-muted);
            margin-bottom: 5px;
        }
        .lpd-config-value {
            font-size: 16px;
            font-weight: 600;
            color: var(--lpd-accent);
        }

        /* 移动端优化 */
        @media (max-width: 768px){
            .lpd-container {
                padding: 15px;
                margin: 20px 0;
                max-width: 100%; /* 移动端全宽 */
            }
            
            .lpd-head {
                flex-direction: row;
                align-items: center;
                justify-content: space-between;
            }
            
            .lpd-theme-toggle {
                position: static;
                margin: 0;
                order: 2;
                flex-shrink: 0;
            }
            
            .lpd-title {
                order: 1;
                min-width: unset;
                margin-right: 15px;
                font-size: 20px;
            }
            
            .lpd-countdown-large {
                font-size: 60px;
            }
            
            /* 移动端活了多久显示两列 */
            .lpd-kpi-grid {
                grid-template-columns: repeat(2, 1fr);
            }
            
            .lpd-kpi .lpd-big {
                font-size: 24px;
            }
            .lpd-config-display {
                flex-direction: column;
                gap: 12px;
                align-items: flex-start;
            }
            .lpd-card {
                padding: 16px;
            }
            
            .lpd-top-progress {
                height: 20px;
                margin: 10px 0 20px;
            }
            
            .lpd-top-progress-text {
                font-size: 12px;
            }
            
            /* 移动端网格布局调整 */
            .lpd-grid {
                grid-template-columns: 1fr;
                gap: 15px;
            }
            
            .lpd-card.lpd-span-5,
            .lpd-card.lpd-span-4,
            .lpd-card.lpd-span-3 {
                grid-column: span 1;
            }
            
            .lpd-mini-grid {
                grid-template-columns: repeat(2, 1fr);
            }
            
            .lpd-mini .lpd-num {
                font-size: 22px;
            }
        }

        @media (min-width: 769px) and (max-width: 1024px){
            .lpd-card.lpd-span-5{
                grid-column: span 6;
            }
            .lpd-card.lpd-span-4{
                grid-column: span 6;
            }
            .lpd-card.lpd-span-3{
                grid-column: span 4;
            }
        }

        @media (min-width:1025px){
            .lpd-card.lpd-span-5{
                grid-column: span 5;
            }
            .lpd-card.lpd-span-4{
                grid-column: span 4;
            }
            .lpd-card.lpd-span-3{
                grid-column: span 3;
            }
            .lpd-countdown-large{
                font-size: 90px;
            }
        }

        .lpd-footer{
            margin-top: 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            color: var(--lpd-muted);
            font-size: 11px;
            padding-top: 15px;
            border-top: 1px solid rgba(0,0,0,0.05);
        }

        .lpd-container[data-theme="dark"] .lpd-footer {
            border-top: 1px solid rgba(255,255,255,0.05);
        }
    </style>
</head>
<body>
    <div class="lpd-container">
        <div class="lpd-head">
            <div>
                <h2 class="lpd-title">人生时间进度仪表盘</h2>
                <!-- 添加二级标题 -->
                <div class="lpd-subtitle">可视化您的人生旅程,珍惜每一刻时光</div>
            </div>
            <div id="lpdThemeToggle" class="lpd-theme-toggle">🌙</div>
        </div>

        <!-- 顶部横向进度条 -->
        <div class="lpd-top-progress">
            <div class="lpd-top-progress-fill" id="lpdTopProgressFill">
                <div class="lpd-top-progress-text" id="lpdTopProgressText">44.0%</div>
            </div>
        </div>

        <!-- 配置显示区域 -->
        <div class="lpd-config-display">
            <div class="lpd-config-item">
                <div class="lpd-config-label">出生日期</div>
                <div id="lpdBirthDateDisplay" class="lpd-config-value">2025年1月1日</div>
            </div>
            <div class="lpd-config-item">
                <div class="lpd-config-label">预期寿命</div>
                <div id="lpdLifeExpectancyDisplay" class="lpd-config-value">80 岁</div>
            </div>
        </div>

        <div class="lpd-grid">
            <section class="lpd-card lpd-span-5">
                <h3>距离生日还有</h3>
                <div><span id="lpdDLeft" class="lpd-countdown-large lpd-num-inline">296</span><span class="lpd-unit">天</span></div>
                <div class="lpd-mini-grid">
                    <div class="lpd-mini"><div id="lpdDLeft_d" class="lpd-num lpd-num-inline">296</div><div class="lpd-lab">天</div></div>
                    <div class="lpd-mini"><div id="lpdDLeft_h" class="lpd-num lpd-num-inline">02</div><div class="lpd-lab">时</div></div>
                    <div class="lpd-mini"><div id="lpdDLeft_m" class="lpd-num lpd-num-inline">57</div><div class="lpd-lab">分</div></div>
                    <div class="lpd-mini"><div id="lpdDLeft_s" class="lpd-num lpd-num-inline">41</div><div class="lpd-lab">秒</div></div>
                </div>
            </section>

            <section class="lpd-card lpd-span-4">
                <h3>活了多久</h3>
                <div class="lpd-kpi-grid">
                    <div class="lpd-kpi"><div id="lpdLived_days" class="lpd-big lpd-num-inline">12,853</div><div class="lpd-sub">天</div></div>
                    <div class="lpd-kpi"><div id="lpdLived_hours" class="lpd-big lpd-num-inline">308,493</div><div class="lpd-sub">小时</div></div>
                    <div class="lpd-kpi"><div id="lpdAge_years" class="lpd-big lpd-num-inline">35</div><div class="lpd-sub">岁</div></div>
                    <div class="lpd-kpi"><div id="lpdBirthdays" class="lpd-big lpd-num-inline">35</div><div class="lpd-sub">个生日</div></div>
                </div>
            </section>

            <section class="lpd-card lpd-span-3">
                <h3>人生进度</h3>
                <div class="lpd-muted" style="margin-bottom:8px;text-align:center">预期 <span id="lpdExpect_years" class="lpd-num-inline">80</span> 岁</div>
                
                <div style="text-align: center; font-size: 24px; font-weight: 800; color: var(--lpd-accent); margin: 15px 0;" id="lpdProgress">44.0%</div>
                
                <div style="margin-top:10px;font-size:14px;text-align:center">
                    <div class="lpd-muted">剩余大约 <span id="lpdRemain_years" class="lpd-num-inline">44.8</span> 年</div>
                    <div class="lpd-muted" style="margin-top:6px"><span id="lpdRemain_days" class="lpd-num-inline">16,366</span> 天</div>
                </div>
            </section>
        </div>

        <div class="lpd-footer">
            <div>⏱️ 实时刷新中</div>
            <div id="lpdLastUpdated">上次更新:2025/9/10 21:02:19</div>
        </div>
    </div>

    <script>
        // ===== 配置区 =====
        // 在这里直接修改出生日期和预期寿命
        const LPD_CONFIG = {
            birthDate: "2025-01-01", // 出生日期 (格式: YYYY-MM-DD)
            lifeExpectancy: 80       // 预期寿命(年)
        };
        // =================

        // 确保DOM完全加载后再执行
        document.addEventListener('DOMContentLoaded', function() {
            const LPD_DAY = 24 * 60 * 60 * 1000, LPD_HOUR = 60 * 60 * 1000, LPD_MIN = 60 * 1000;
            const LPD_avgYear = 365.2425;

            function lpdPad(n){return n.toString().padStart(2,'0')}
            function lpdFmtTime(dt){return new Date(dt).toLocaleString(undefined,{hour12:false})}
            function lpdIsLeap(y){return (y%4===0 && y%100!==0) || (y%400===0)}
            function lpdSafeBirthdayThisYear(birth, year){
                const m=birth.getMonth(),d=birth.getDate();
                if(m===1 && d===29 && !lpdIsLeap(year)) return new Date(year,1,28,0,0,0);
                return new Date(year,m,d,0,0,0);
            }
            function lpdNextBirthdayFrom(now,birth){
                const thisYear=lpdSafeBirthdayThisYear(birth,now.getFullYear());
                if(thisYear.getTime()>now.getTime()) return thisYear;
                return lpdSafeBirthdayThisYear(birth,now.getFullYear()+1);
            }
            function lpdCalcAgeYears(now,birth){
                let age=now.getFullYear()-birth.getFullYear();
                const bdThis=lpdSafeBirthdayThisYear(birth,now.getFullYear());
                if(now<bdThis) age-=1;
                return Math.max(age,0);
            }
            function lpdClamp(v,a,b){return Math.min(Math.max(v,a),b)}

            // 主题切换
            const lpdThemeToggle=document.getElementById('lpdThemeToggle');
            function lpdApplyTheme(auto=false){
                let h=new Date().getHours();
                if(auto){
                    if(h>=19||h<7){
                        document.querySelector('.lpd-container').setAttribute('data-theme','dark');
                        if(lpdThemeToggle) lpdThemeToggle.textContent='☀️';
                    }else{
                        document.querySelector('.lpd-container').setAttribute('data-theme','light');
                        if(lpdThemeToggle) lpdThemeToggle.textContent='🌙';
                    }
                }else{
                    let cur=document.querySelector('.lpd-container').getAttribute('data-theme')||'light';
                    if(cur==='light'){
                        document.querySelector('.lpd-container').setAttribute('data-theme','dark');
                        if(lpdThemeToggle) lpdThemeToggle.textContent='☀️';
                    }else{
                        document.querySelector('.lpd-container').setAttribute('data-theme','light');
                        if(lpdThemeToggle) lpdThemeToggle.textContent='🌙';
                    }
                }
            }
            
            if(lpdThemeToggle) {
                lpdThemeToggle.addEventListener('click',()=>lpdApplyTheme(false));
            }
            lpdApplyTheme(true);

            // 显示配置信息
            const lpdBirthDateDisplay = document.getElementById('lpdBirthDateDisplay');
            const lpdLifeExpectancyDisplay = document.getElementById('lpdLifeExpectancyDisplay');
            
            // 格式化日期显示
            function lpdFormatDateDisplay(dateStr) {
                const date = new Date(dateStr);
                return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`;
            }
            
            if(lpdBirthDateDisplay) {
                lpdBirthDateDisplay.textContent = lpdFormatDateDisplay(LPD_CONFIG.birthDate);
            }
            if(lpdLifeExpectancyDisplay) {
                lpdLifeExpectancyDisplay.textContent = `${LPD_CONFIG.lifeExpectancy} 岁`;
            }

            const lpdDLeft=document.getElementById('lpdDLeft');
            const lpdDLeft_d=document.getElementById('lpdDLeft_d');
            const lpdDLeft_h=document.getElementById('lpdDLeft_h');
            const lpdDLeft_m=document.getElementById('lpdDLeft_m');
            const lpdDLeft_s=document.getElementById('lpdDLeft_s');
            const lpdLived_days=document.getElementById('lpdLived_days');
            const lpdLived_hours=document.getElementById('lpdLived_hours');
            const lpdAge_years=document.getElementById('lpdAge_years');
            const lpdBirthdays=document.getElementById('lpdBirthdays');
            const lpdProgressEl=document.getElementById('lpdProgress');
            const lpdExpect_years=document.getElementById('lpdExpect_years');
            const lpdRemain_years=document.getElementById('lpdRemain_years');
            const lpdRemain_days=document.getElementById('lpdRemain_days');
            const lpdLastUpdated=document.getElementById('lpdLastUpdated');
            const lpdTopProgressFill = document.getElementById('lpdTopProgressFill');
            const lpdTopProgressText = document.getElementById('lpdTopProgressText');

            function lpdTick(){
                const now=new Date();
                const birth=new Date(LPD_CONFIG.birthDate+"T00:00:00");
                const livedMs=now-birth;
                const days=Math.floor(livedMs/LPD_DAY);
                const hours=Math.floor(livedMs/LPD_HOUR);
                const age=lpdCalcAgeYears(now,birth);
                const bdays=age;
                
                if(lpdLived_days) lpdLived_days.textContent=days.toLocaleString();
                if(lpdLived_hours) lpdLived_hours.textContent=hours.toLocaleString();
                if(lpdAge_years) lpdAge_years.textContent=age.toString();
                if(lpdBirthdays) lpdBirthdays.textContent=bdays.toString();

                const nextBd=lpdNextBirthdayFrom(now,birth);
                const diff=nextBd-now;
                const d=Math.floor(diff/LPD_DAY);
                const h=Math.floor((diff%LPD_DAY)/LPD_HOUR);
                const m=Math.floor((diff%LPD_HOUR)/LPD_MIN);
                const s=Math.floor((diff%LPD_MIN)/1000);
                
                if(lpdDLeft) lpdDLeft.textContent=d;
                if(lpdDLeft_d) lpdDLeft_d.textContent=d;
                if(lpdDLeft_h) lpdDLeft_h.textContent=lpdPad(h);
                if(lpdDLeft_m) lpdDLeft_m.textContent=lpdPad(m);
                if(lpdDLeft_s) lpdDLeft_s.textContent=lpdPad(s);

                if(lpdExpect_years) lpdExpect_years.textContent=LPD_CONFIG.lifeExpectancy;
                const totalDays=LPD_CONFIG.lifeExpectancy*LPD_avgYear;
                const prog=lpdClamp(days/totalDays,0,1);
                const percent=(prog*100).toFixed(1)+'%';
                
                // 更新顶部横向进度条
                if(lpdTopProgressFill) {
                    lpdTopProgressFill.style.width = (prog*100)+'%';
                }
                if(lpdTopProgressText) {
                    lpdTopProgressText.textContent = percent;
                }
                
                if(lpdProgressEl) lpdProgressEl.textContent=percent;

                const remainD=Math.max(Math.round(totalDays-days),0);
                const remainY=(remainD/LPD_avgYear).toFixed(1);
                if(lpdRemain_days) lpdRemain_days.textContent=remainD.toLocaleString();
                if(lpdRemain_years) lpdRemain_years.textContent=remainY;

                if(lpdLastUpdated) lpdLastUpdated.textContent='上次更新:'+lpdFmtTime(now);
                requestAnimationFrame(lpdTick);
            }
            
            // 确保所有元素都存在再开始计时
            if(lpdTopProgressFill && lpdDLeft && lpdLived_days) {
                requestAnimationFrame(lpdTick);
            } else {
                console.error('人生进度仪表盘初始化失败:某些必要元素未找到');
            }
        });
    </script>
</body>
</html>

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容