面向天文直播的指定时段触发式HTML5时间进度条开发需求
实现天文事件实时进度条(以2019水星凌日为例)
我明白你想要的是一个基于真实天文事件时间线的实时进度条,而不是固定时长的加载条——之前你用的ldBar是针对固定duration的场景,自然没法适配动态的时间范围。下面我给你一个完整的实现,直接就能用,还包含时间标记和实时更新功能:
完整代码实现
<!DOCTYPE HTML> <html lang="en"> <head> <title>Mercury Transit 2019-11-11</title> <meta charset="UTF-8" /> <style> * { box-sizing: border-box; font-family: Arial, sans-serif; } .event-progress-container { width: 90%; max-width: 800px; margin: 2rem auto; } .progress-bar-wrapper { position: relative; height: 40px; background-color: #e0e0e0; border-radius: 20px; overflow: hidden; margin: 1rem 0; } .progress-bar-fill { height: 100%; width: 0%; background-color: #2196F3; transition: width 0.5s ease; position: relative; } .progress-time-marker { position: absolute; top: 100%; transform: translateX(-50%); font-size: 0.8rem; margin-top: 0.5rem; padding: 0.2rem 0.4rem; background: rgba(0,0,0,0.7); color: white; border-radius: 4px; } .progress-status { text-align: center; font-size: 1.1rem; color: #333; } .tick-mark { position: absolute; top: 0; bottom: 0; width: 1px; background-color: rgba(0,0,0,0.2); transform: translateX(-50%); } </style> </head> <body> <div class="event-progress-container"> <h1>Mercury Transit 2019-11-11</h1> <p>This bar shows the progress of the event from start at <strong>12:35:27 UT</strong>, to finish at <strong>18:04:14 UT</strong>.</p> <div class="progress-bar-wrapper" id="progressWrapper"> <div class="progress-bar-fill" id="progressFill"></div> </div> <div class="progress-status" id="statusText"></div> </div> <script> // 定义事件的UT起止时间(注意:JavaScript的Date默认是本地时间,所以要转成UTC) const eventStart = new Date(Date.UTC(2019, 10, 11, 12, 35, 27)); // 月份是0-based,10代表11月 const eventEnd = new Date(Date.UTC(2019, 10, 11, 18, 4, 14)); const totalDurationMs = eventEnd.getTime() - eventStart.getTime(); const progressFill = document.getElementById('progressFill'); const progressWrapper = document.getElementById('progressWrapper'); const statusText = document.getElementById('statusText'); // 生成时间刻度标记 function generateTimeMarkers() { // 每小时生成一个刻度(可以根据事件时长调整密度) const hoursBetween = Math.ceil((eventEnd - eventStart) / (1000 * 60 * 60)); for (let i = 0; i <= hoursBetween; i++) { const markerTime = new Date(eventStart.getTime() + i * 60 * 60 * 1000); const percentage = ((markerTime - eventStart) / totalDurationMs) * 100; // 添加刻度线 const tick = document.createElement('div'); tick.className = 'tick-mark'; tick.style.left = `${percentage}%`; progressWrapper.appendChild(tick); // 添加时间标签 const marker = document.createElement('div'); marker.className = 'progress-time-marker'; marker.style.left = `${percentage}%`; // 格式化UT时间为HH:mm marker.textContent = `${markerTime.getUTCHours().toString().padStart(2, '0')}:${markerTime.getUTCMinutes().toString().padStart(2, '0')} UT`; progressWrapper.appendChild(marker); } } // 更新进度条状态 function updateProgress() { const now = new Date(); let progressPercent = 0; let status = ''; if (now < eventStart) { // 事件未开始 progressPercent = 0; const timeUntilStart = eventStart - now; const hours = Math.floor(timeUntilStart / (1000 * 60 * 60)); const minutes = Math.floor((timeUntilStart % (1000 * 60 * 60)) / (1000 * 60)); status = `Event starts in ${hours}h ${minutes}m`; } else if (now > eventEnd) { // 事件已结束 progressPercent = 100; status = 'Event has finished'; } else { // 事件进行中 const elapsedMs = now - eventStart; progressPercent = (elapsedMs / totalDurationMs) * 100; const remainingMs = eventEnd - now; const hours = Math.floor(remainingMs / (1000 * 60 * 60)); const minutes = Math.floor((remainingMs % (1000 * 60 * 60)) / (1000 * 60)); status = `In progress - ${Math.round(progressPercent)}% complete, ${hours}h ${minutes}m remaining`; } // 更新进度条宽度 progressFill.style.width = `${progressPercent}%`; // 更新状态文本 statusText.textContent = status; } // 初始化:生成刻度并首次更新进度 generateTimeMarkers(); updateProgress(); // 每30秒更新一次进度(可以根据需求调整频率) setInterval(updateProgress, 30000); </script> </body> </html>
关键功能说明
- UT时间处理:用
Date.UTC()直接创建UTC时间,避免本地时区干扰,这对天文事件来说至关重要 - 动态进度计算:实时对比当前时间与事件起止时间,自动处理未开始、进行中、已结束三种状态
- 时间刻度与标记:自动生成小时级的刻度线和UT时间标签,你可以根据事件时长调整刻度密度(比如改成每30分钟一个标记)
- 平滑过渡:进度条宽度变化添加了
transition动画,避免跳动感 - 状态提示:底部显示当前事件状态,包括倒计时或剩余时间
适配其他天文事件的方法
只需要修改eventStart和eventEnd这两个变量即可:
// 示例:2024年日食(假设起止时间) const eventStart = new Date(Date.UTC(2024, 3, 8, 18, 18, 0)); // 4月8日,UT18:18 const eventEnd = new Date(Date.UTC(2024, 3, 8, 23, 49, 0)); // 4月8日,UT23:49
这个实现不需要依赖任何外部库,纯原生HTML/CSS/JS就能运行,完全适配从几分钟到几小时的各类天文直播场景~
内容的提问来源于stack exchange,提问作者Diego Rodríguez Peregrin
相关产品推荐
相关产品推荐

