|
93 | 93 | .progress-fill { |
94 | 94 | height: 100%; |
95 | 95 | background: white; |
96 | | - transition: width 0.1s linear; |
| 96 | + transition: none; |
97 | 97 | } |
98 | 98 |
|
99 | 99 | .controls { |
|
154 | 154 | <script> |
155 | 155 | let currentPushup = 0; |
156 | 156 | let currentPhase = 'ready'; // ready, countdown, down, hold, up |
157 | | - let timeLeft = 0; |
158 | | - let totalTime = 0; |
| 157 | + let phaseStartTime = 0; |
| 158 | + let phaseDuration = 0; |
159 | 159 | let intervalId = null; |
160 | 160 | let isRunning = false; |
161 | 161 |
|
|
167 | 167 | }; |
168 | 168 |
|
169 | 169 | function updateDisplay() { |
| 170 | + const now = Date.now(); |
| 171 | + const elapsed = (now - phaseStartTime) / 1000; |
| 172 | + const timeLeft = Math.max(0, phaseDuration - elapsed); |
| 173 | + const displayTime = Math.ceil(timeLeft); |
| 174 | + |
170 | 175 | document.getElementById('currentPushup').textContent = currentPushup; |
171 | | - document.getElementById('timer').textContent = timeLeft; |
| 176 | + document.getElementById('timer').textContent = displayTime; |
172 | 177 |
|
173 | 178 | const phaseElement = document.getElementById('phase'); |
174 | 179 | const progressFill = document.getElementById('progressFill'); |
|
183 | 188 | progressFill.style.width = '100%'; |
184 | 189 | document.getElementById('completed').style.display = 'block'; |
185 | 190 | } else if (currentPhase === 'countdown') { |
186 | | - phaseElement.textContent = `GET READY - ${timeLeft}`; |
| 191 | + phaseElement.textContent = `GET READY - ${displayTime}`; |
187 | 192 | phaseElement.className = 'phase countdown'; |
188 | | - const progress = ((totalTime - timeLeft) / totalTime) * 100; |
| 193 | + const progress = Math.min(100, (elapsed / phaseDuration) * 100); |
189 | 194 | progressFill.style.width = `${progress}%`; |
190 | 195 | } else { |
191 | 196 | const phase = phases[currentPhase]; |
192 | 197 | phaseElement.textContent = phase.text; |
193 | 198 | phaseElement.className = `phase ${phase.class}`; |
194 | 199 |
|
195 | | - const progress = ((totalTime - timeLeft) / totalTime) * 100; |
| 200 | + const progress = Math.min(100, (elapsed / phaseDuration) * 100); |
196 | 201 | progressFill.style.width = `${progress}%`; |
197 | 202 | } |
| 203 | + |
| 204 | + // Check if phase should end |
| 205 | + if (elapsed >= phaseDuration && currentPhase !== 'ready' && currentPhase !== 'completed') { |
| 206 | + nextPhase(); |
| 207 | + } |
198 | 208 | } |
199 | 209 |
|
200 | 210 | function nextPhase() { |
|
220 | 230 | } |
221 | 231 | } |
222 | 232 |
|
223 | | - timeLeft = phases[currentPhase].duration; |
224 | | - totalTime = timeLeft; |
225 | | - updateDisplay(); |
226 | | - } |
227 | | - |
228 | | - function tick() { |
229 | | - timeLeft--; |
| 233 | + phaseDuration = phases[currentPhase].duration; |
| 234 | + phaseStartTime = Date.now(); |
230 | 235 | updateDisplay(); |
231 | | - |
232 | | - if (timeLeft <= 0) { |
233 | | - nextPhase(); |
234 | | - } |
235 | 236 | } |
236 | 237 |
|
237 | 238 | function startWorkout() { |
238 | 239 | if (!isRunning) { |
239 | 240 | if (currentPhase === 'ready') { |
240 | 241 | nextPhase(); |
241 | 242 | } |
242 | | - intervalId = setInterval(tick, 1000); |
| 243 | + intervalId = setInterval(updateDisplay, 50); // Update every 50ms for smooth animation |
243 | 244 | isRunning = true; |
244 | 245 | } |
245 | 246 | } |
|
256 | 257 | isRunning = false; |
257 | 258 | currentPushup = 0; |
258 | 259 | currentPhase = 'ready'; |
259 | | - timeLeft = 0; |
260 | | - totalTime = 0; |
| 260 | + phaseStartTime = 0; |
| 261 | + phaseDuration = 0; |
261 | 262 | document.getElementById('completed').style.display = 'none'; |
262 | 263 | updateDisplay(); |
263 | 264 | } |
|
0 commit comments