export default class TimeLine { constructor(sdk, speed) { this.sdk = { ...sdk }; this.progress = document.getElementById('progress'); this.handle = document.getElementById('handle'); this.timeline = document.getElementById('timeline'); this.currentTime = document.getElementById('currentTime'); this.timelineCon = document.getElementsByClassName('timeline-container')[0]; this.speed = speed; this.animationId; this.startTime = Date.now(); this.manualPosition = null; this.isDragging = false; this.pauseed = false; this.time = ''; this.update = this.update.bind(this); TimeLine.init(this) } static init(that) { for (let i = 0; i <= 24; i++) { if (i % 6 === 0) { const label = document.createElement('div'); label.className = 'time-mark'; label.textContent = `${i}:00`; label.style.left = `${(i / 24) * 100}%`; document.getElementsByClassName('time-marks')[0].appendChild(label) } } that.startTime = Date.now() - ((that.manualPosition || 0) * 86400 * 1000 / that.speed); that.timeline.addEventListener('mousedown', (e) => { that.isDragging = true; e.preventDefault(); }); that.timeline.addEventListener('mousemove', (e) => { if (!that.isDragging) return; const rect = that.timeline.getBoundingClientRect(); let pos = (e.clientX - rect.left) / rect.width; pos = Math.max(0, Math.min(1, pos)); that.manualPosition = pos; that.progress.style.width = `${pos * 100}%`; const seconds = pos * 86400; that.currentTime.textContent = that.formatTime(seconds); }); that.update(); document.getElementById('timePause').addEventListener('click', function () { that.pauseed = !that.pauseed; if (that.pauseed) { document.getElementById('timePause').textContent = '播放'; that.animationId && cancelAnimationFrame(that.animationId); that.pausedTime = Date.now(); // 记录暂停时刻 that.sdk.viewer.clock.shouldAnimate = false } else { document.getElementById('timePause').textContent = '暂停'; that.manualPosition = null const pausedDuration = Date.now() - that.pausedTime; that.startTime += pausedDuration; // 补偿暂停期间的时间差 that.sdk.viewer.clock.shouldAnimate = true that.update(); // 重启动画循环 } }); } moveComplay(func) { let that = this that.timeline.addEventListener('mouseup', () => { that.isDragging = false; if (that.manualPosition !== null) { // that.sdk.viewer.clock.shouldAnimate = true that.startTime = Date.now() - (that.manualPosition * 86400 * 1000 / that.speed); that.manualPosition = null; if (!that.pauseed) { that.update() func(that.time) } else { that.pausedTime = Date.now(); // 记录暂停时刻 func(that.currentTime.textContent) } } }); } formatTime(seconds) { const hrs = Math.floor(seconds / 3600).toString().padStart(2, '0'); const mins = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0'); const secs = Math.floor(seconds % 60).toString().padStart(2, '0'); return `${hrs}:${mins}:${secs}`; } update() { if (this.manualPosition !== null) return; const elapsed = (Date.now() - this.startTime) * this.speed; const totalSeconds = elapsed / 1000; const daySeconds = totalSeconds % 86400; const percentage = daySeconds / 86400; this.progress.style.width = `${percentage * 100}%`; this.time = this.formatTime(daySeconds) this.currentTime.textContent = this.time; this.animationId = requestAnimationFrame(this.update); } setSpeed(v) { const currentProgress = this.manualPosition ?? (Date.now() - this.startTime) * this.speed / (86400 * 1000); this.speed = v; this.startTime = Date.now() - (currentProgress * 86400 * 1000 / this.speed); this.manualPosition = null; this.update(); } updateTime() { this.startTime = Date.now() - (this.manualPosition * 86400 * 1000 / this.speed); this.manualPosition = null; this.update(); } clear() { this.animationId && cancelAnimationFrame(this.animationId); this.progress.style.width = '0%'; this.currentTime.textContent = '00:00:00'; } }