1+ const START_DATE = new Date ( "December 8, 2025 00:00:00" ) . getTime ( ) ;
2+ const TARGET_DATE = new Date ( "March 9, 2026 00:00:00" ) . getTime ( ) ;
3+
4+ const daysElement = document . getElementById ( "days" ) ;
5+ const hoursElement = document . getElementById ( "hours" ) ;
6+ const minutesElement = document . getElementById ( "minutes" ) ;
7+ const secondsElement = document . getElementById ( "seconds" ) ;
8+ const completedMessage = document . getElementById ( "completedMessage" ) ;
9+ const percentageElement = document . getElementById ( "percentage" ) ;
10+ const progressFill = document . getElementById ( "progressFill" ) ;
11+ const progressMarker = document . getElementById ( "progressMarker" ) ;
12+ const elapsedTimeElement = document . getElementById ( "elapsedTime" ) ;
13+ const remainingTimeElement = document . getElementById ( "remainingTime" ) ;
14+
15+ let countdownInterval = null ;
16+ let previousTime = {
17+ days : null ,
18+ hours : null ,
19+ minutes : null ,
20+ seconds : null
21+ } ;
22+
23+ function updateProgressBar ( ) {
24+ const now = Date . now ( ) ;
25+ const totalDuration = TARGET_DATE - START_DATE ;
26+ const elapsed = Math . max ( 0 , now - START_DATE ) ;
27+
28+ let progressPercent = Math . min ( ( elapsed / totalDuration ) * 100 , 100 ) ;
29+
30+ if ( progressPercent < 0 ) progressPercent = 0 ;
31+ if ( progressPercent > 100 ) progressPercent = 100 ;
32+
33+ progressFill . style . width = `${ progressPercent } %` ;
34+ progressMarker . style . left = `${ progressPercent } %` ;
35+ percentageElement . textContent = `${ progressPercent . toFixed ( 5 ) } %` ;
36+
37+ const daysElapsed = Math . floor ( elapsed / ( 1000 * 60 * 60 * 24 ) ) ;
38+ const daysRemaining = Math . floor ( ( TARGET_DATE - now ) / ( 1000 * 60 * 60 * 24 ) ) ;
39+
40+ elapsedTimeElement . textContent = `${ Math . max ( 0 , daysElapsed ) } days` ;
41+ remainingTimeElement . textContent = `${ Math . max ( 0 , daysRemaining ) } days` ;
42+
43+ return progressPercent ;
44+ }
45+
46+ function updateCountdown ( ) {
47+ const now = Date . now ( ) ;
48+ const distance = TARGET_DATE - now ;
49+
50+ if ( distance <= 0 ) {
51+ handleCountdownComplete ( ) ;
52+ return ;
53+ }
54+
55+ const days = Math . floor ( distance / ( 1000 * 60 * 60 * 24 ) ) ;
56+ const hours = Math . floor ( ( distance % ( 1000 * 60 * 60 * 24 ) ) / ( 1000 * 60 * 60 ) ) ;
57+ const minutes = Math . floor ( ( distance % ( 1000 * 60 * 60 ) ) / ( 1000 * 60 ) ) ;
58+ const seconds = Math . floor ( ( distance % ( 1000 * 60 ) ) / 1000 ) ;
59+
60+ updateTimeElement ( daysElement , days , previousTime . days ) ;
61+ updateTimeElement ( hoursElement , hours , previousTime . hours ) ;
62+ updateTimeElement ( minutesElement , minutes , previousTime . minutes ) ;
63+ updateTimeElement ( secondsElement , seconds , previousTime . seconds ) ;
64+
65+ previousTime = { days, hours, minutes, seconds } ;
66+
67+ updateProgressBar ( ) ;
68+ }
69+
70+ function updateTimeElement ( element , newValue , previousValue ) {
71+ const formattedValue = newValue < 10 ? `0${ newValue } ` : `${ newValue } ` ;
72+
73+ if ( element . textContent !== formattedValue && previousValue !== null ) {
74+ element . textContent = formattedValue ;
75+ element . classList . add ( 'changed' ) ;
76+
77+ setTimeout ( ( ) => {
78+ element . classList . remove ( 'changed' ) ;
79+ } , 500 ) ;
80+ } else if ( previousValue === null ) {
81+ element . textContent = formattedValue ;
82+ }
83+ }
84+
85+ function handleCountdownComplete ( ) {
86+ if ( countdownInterval ) {
87+ clearInterval ( countdownInterval ) ;
88+ countdownInterval = null ;
89+ }
90+
91+ daysElement . textContent = "00" ;
92+ hoursElement . textContent = "00" ;
93+ minutesElement . textContent = "00" ;
94+ secondsElement . textContent = "00" ;
95+
96+ completedMessage . style . display = "block" ;
97+
98+ progressFill . style . width = "100%" ;
99+ progressMarker . style . left = "100%" ;
100+ percentageElement . textContent = "100%" ;
101+ remainingTimeElement . textContent = "0 days" ;
102+
103+ progressFill . style . animation = "shimmer 1s infinite linear" ;
104+ }
105+
106+ function initializeCountdown ( ) {
107+ updateProgressBar ( ) ;
108+ updateCountdown ( ) ;
109+
110+ countdownInterval = setInterval ( updateCountdown , 1000 ) ;
111+ }
112+
113+ function handleVisibilityChange ( ) {
114+ if ( document . hidden ) {
115+ if ( countdownInterval ) {
116+ clearInterval ( countdownInterval ) ;
117+ countdownInterval = null ;
118+ }
119+ } else {
120+ updateProgressBar ( ) ;
121+ updateCountdown ( ) ;
122+
123+ if ( ! countdownInterval ) {
124+ countdownInterval = setInterval ( updateCountdown , 1000 ) ;
125+ }
126+ }
127+ }
128+
129+ document . addEventListener ( 'DOMContentLoaded' , initializeCountdown ) ;
130+ document . addEventListener ( 'visibilitychange' , handleVisibilityChange ) ;
131+
132+ window . addEventListener ( 'focus' , ( ) => {
133+ if ( document . visibilityState === 'visible' ) {
134+ updateCountdown ( ) ;
135+ updateProgressBar ( ) ;
136+ }
137+ } ) ;
138+
139+ window . addEventListener ( 'error' , ( event ) => {
140+ console . error ( 'Countdown Timer Error:' , event . error ) ;
141+
142+ daysElement . textContent = "91" ;
143+ hoursElement . textContent = "00" ;
144+ minutesElement . textContent = "00" ;
145+ secondsElement . textContent = "00" ;
146+ percentageElement . textContent = "0.0%" ;
147+ } ) ;
0 commit comments