Just finished a Pomodoro timer with variable activity and rest time

I Made This :snoo_wink:

I thought of taking Gemini 2.5 Pro for a ride with a timer application. The initial prompt was -
Create a timer using Javascript that runs continuously from the start and displays time in hr:mm:ss until reset key is pressed. After Reset is pressed the time starts again from 0.  

The timer beeps an audio alarm for every one minute elapsed. The audio is a chime that beeps for 2 seconds. 

It goofed up initially and started beeping randomly after 50-55 seconds. When prompted it corrected. Then we went on to make a Pomodoro Timer with user-given activity and rest times.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pomodoro Timer</title>
    <style>
        body {
            font-family: sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: #f0f0f0;
        }

        .timer-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 20px;
            border: 2px solid #333;
            border-radius: 5px;
            background-color: #fff;
        }

        #timer-label {
            font-size: 1.2em;
            margin-bottom: 5px;
            color: #555;
        }

        #timer {
            font-size: 2em;
            margin-bottom: 10px;
            color: #333;
        }

        #activityInput, #restInput {
            padding: 10px;
            font-size: 1em;
            margin-bottom: 10px;
            border: 1px solid #ccc;
            border-radius: 5px;
            width: 150px;
            margin-right: 10px;
        }

        .input-container {
            display: flex;
            margin-bottom: 10px;
        }

        #startBtn, #stopBtn, #resetBtn {
            padding: 10px 20px;
            font-size: 1em;
            cursor: pointer;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            margin-top: 10px;
            transition: background-color 0.3s ease;
        }

        #startBtn:hover, #stopBtn:hover, #resetBtn:hover {
            background-color: #367c39;
        }

        #startBtn:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
            opacity: 0.6;
        }

        #alarmSound, #whiteNoise {
            display: none; /* Hide the audio elements */
        }
    </style>
</head>
<body>
    <div class="timer-container">
        <div id="timer-label">Activity</div>
        <div id="timer">00:00:00</div>
        <div class="input-container">
            <input type="number" id="activityInput" placeholder="Activity (Minutes)" value="25" min="1">
            <input type="number" id="restInput" placeholder="Rest (Minutes)" value="5" min="1">
        </div>
        <button id="startBtn">Start</button>
        <button id="stopBtn">Stop</button>
        <button id="resetBtn">Reset</button>
        <audio id="alarmSound" src="chime.mp3"></audio>
        <audio id="whiteNoise" src="white_noise.mp3" loop></audio>
    </div>

    <script>
        let timerInterval;
        let startTime;
        let elapsedSeconds = 0;
        let previousSeconds = 0;
        let activityMinutes = 25;
        let restMinutes = 5;
        let isRestTime = false;
        const timerDisplay = document.getElementById('timer');
        const startBtn = document.getElementById('startBtn');
        const stopBtn = document.getElementById('stopBtn');
        const resetBtn = document.getElementById('resetBtn');
        const alarmSound = document.getElementById('alarmSound');
        const whiteNoise = document.getElementById('whiteNoise');
        const activityInput = document.getElementById('activityInput');
        const restInput = document.getElementById('restInput');
        const timerLabel = document.getElementById('timer-label');

        // Load the audio file.
        alarmSound.preload = 'auto';
        whiteNoise.preload = 'auto';

        alarmSound.addEventListener('loadeddata', () => {
            console.log("Alarm sound loaded");
        });

        alarmSound.addEventListener('error', (e) => {
            console.error("Error loading alarm:", e);
        });

        whiteNoise.addEventListener('loadeddata', () => {
            console.log("White noise loaded");
        });

        whiteNoise.addEventListener('error', (e) => {
            console.error("Error loading white noise:", e);
        });


        function formatTime(totalSeconds) {
            const hours = Math.floor(totalSeconds / 3600);
            const minutes = Math.floor((totalSeconds % 3600) / 60);
            const seconds = totalSeconds % 60;

            const formattedHours = String(hours).padStart(2, '0');
            const formattedMinutes = String(minutes).padStart(2, '0');
            const formattedSeconds = String(seconds).padStart(2, '0');

            return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
        }

        function updateTimer() {
            const currentTime = Date.now();
            elapsedSeconds = Math.floor((currentTime - startTime) / 1000);
            timerDisplay.textContent = formatTime(elapsedSeconds);

            const currentMinutes = Math.floor(elapsedSeconds / 60);
            const previousMinutes = Math.floor(previousSeconds / 60);

            if (currentMinutes > 0 && currentMinutes > previousMinutes) {
                if (isRestTime) {
                    playAlarm();
                    whiteNoise.pause();
                    isRestTime = false;
                    elapsedSeconds = 0;
                    startTime = Date.now();
                    timerLabel.textContent = "Activity";
                } else {
                    playAlarm();
                    whiteNoise.play().catch(e => console.error("Error playing white noise:", e));
                    isRestTime = true;
                    elapsedSeconds = 0;
                    startTime = Date.now();
                    timerLabel.textContent = "Rest";
                }
            }
            previousSeconds = elapsedSeconds;
        }

        function startTimer() {
            activityMinutes = parseInt(activityInput.value);
            restMinutes = parseInt(restInput.value);
            if (isNaN(activityMinutes) || activityMinutes <= 0 || isNaN(restMinutes) || restMinutes <= 0) {
                alert("Please enter valid activity and rest times.");
                return;
            }

            if (!startTime) {
                startTime = Date.now();
                playAlarm();
                timerLabel.textContent = "Activity";
            } else {
                startTime = Date.now() - (elapsedSeconds * 1000);
            }
            timerInterval = setInterval(updateTimer, 1000);
            startBtn.disabled = true;
            stopBtn.disabled = false;
            if (isRestTime) {
                whiteNoise.play().catch(e => console.error("Error playing white noise:", e));
            }
        }

        function stopTimer() {
            clearInterval(timerInterval);
            startBtn.disabled = false;
            stopBtn.disabled = true;
            whiteNoise.pause();
        }

        function resetTimer() {
            clearInterval(timerInterval);
            elapsedSeconds = 0;
            previousSeconds = 0;
            timerDisplay.textContent = '00:00:00';
            startTime = null;
            timerInterval = null;
            startBtn.disabled = false;
            stopBtn.disabled = true;
            activityInput.value = '25';
            restInput.value = '5';
            isRestTime = false;
            whiteNoise.pause();
            timerLabel.textContent = "Activity";
        }

        function playAlarm() {
            try {
                alarmSound.currentTime = 0;
                alarmSound.play().then(() => {
                    setTimeout(() => {
                        alarmSound.pause();
                    }, 2000);
                }).catch(e => {
                    console.error("Error playing alarm:", e);
                });
            } catch (error) {
                console.error("Error playing alarm:", error);
            }
        }

        // Add event listener for the start button
        startBtn.addEventListener('click', startTimer);
        stopBtn.addEventListener('click', stopTimer);
        resetBtn.addEventListener('click', resetTimer);

        // Disable stop button and enable start button on initial load
        stopBtn.disabled = true;
        startBtn.disabled = false;
    </script>
</body>
</html>


The code -

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Pomodoro Timer</title> <style> body { font-family: sans-serif; display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f0f0f0; }

.timer-container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
border: 2px solid #333;
border-radius: 5px;
background-color: #fff;
}

#timer-label {
font-size: 1.2em;
margin-bottom: 5px;
color: #555;
}

#timer {
font-size: 2em;
margin-bottom: 10px;
color: #333;
}

#activityInput, #restInput {
padding: 10px;
font-size: 1em;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
width: 150px;
margin-right: 10px;
}

.input-container {
display: flex;
margin-bottom: 10px;
}

#startBtn, #stopBtn, #resetBtn {
padding: 10px 20px;
font-size: 1em;
cursor: pointer;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
margin-top: 10px;
transition: background-color 0.3s ease;
}

#startBtn:hover, #stopBtn:hover, #resetBtn:hover {
background-color: #367c39;
}

#startBtn:disabled {
background-color: #cccccc;
cursor: not-allowed;
opacity: 0.6;
}

#alarmSound, #whiteNoise {
display: none; /* Hide the audio elements */
}
</style>

</head> <body> <div class="timer-container"> <div id="timer-label">Activity</div> <div id="timer">00:00:00</div> <div class="input-container"> <input type="number" id="activityInput" placeholder="Activity (Minutes)" value="25" min="1"> <input type="number" id="restInput" placeholder="Rest (Minutes)" value="5" min="1"> </div> <button id="startBtn">Start</button> <button id="stopBtn">Stop</button> <button id="resetBtn">Reset</button> <audio id="alarmSound" src="chime.mp3"></audio> <audio id="whiteNoise" src="white\_noise.mp3" loop></audio> </div> <script> let timerInterval; let startTime; let elapsedSeconds = 0; let previousSeconds = 0; let activityMinutes = 25; let restMinutes = 5; let isRestTime = false; const timerDisplay = document.getElementById('timer'); const startBtn = document.getElementById('startBtn'); const stopBtn = document.getElementById('stopBtn'); const resetBtn = document.getElementById('resetBtn'); const alarmSound = document.getElementById('alarmSound'); const whiteNoise = document.getElementById('whiteNoise'); const activityInput = document.getElementById('activityInput'); const restInput = document.getElementById('restInput'); const timerLabel = document.getElementById('timer-label'); // Load the audio file. alarmSound.preload = 'auto'; whiteNoise.preload = 'auto'; alarmSound.addEventListener('loadeddata', () => { console.log("Alarm sound loaded"); }); alarmSound.addEventListener('error', (e) => { console.error("Error loading alarm:", e); }); whiteNoise.addEventListener('loadeddata', () => { console.log("White noise loaded"); }); whiteNoise.addEventListener('error', (e) => { console.error("Error loading white noise:", e); }); function formatTime(totalSeconds) { const hours = Math.floor(totalSeconds / 3600); const minutes = Math.floor((totalSeconds % 3600) / 60); const seconds = totalSeconds % 60; const formattedHours = String(hours).padStart(2, '0'); const formattedMinutes = String(minutes).padStart(2, '0'); const formattedSeconds = String(seconds).padStart(2, '0'); return \`${formattedHours}:${formattedMinutes}:${formattedSeconds}\`; } function updateTimer() { const currentTime = Date.now(); elapsedSeconds = Math.floor((currentTime - startTime) / 1000); timerDisplay.textContent = formatTime(elapsedSeconds); const currentMinutes = Math.floor(elapsedSeconds / 60); const previousMinutes = Math.floor(previousSeconds / 60); if (currentMinutes > 0 && currentMinutes > previousMinutes) { if (isRestTime) { playAlarm(); whiteNoise.pause(); isRestTime = false; elapsedSeconds = 0; startTime = Date.now(); timerLabel.textContent = "Activity"; } else { playAlarm(); whiteNoise.play().catch(e => console.error("Error playing white noise:", e)); isRestTime = true; elapsedSeconds = 0; startTime = Date.now(); timerLabel.textContent = "Rest"; } } previousSeconds = elapsedSeconds; } function startTimer() { activityMinutes = parseInt(activityInput.value); restMinutes = parseInt(restInput.value); if (isNaN(activityMinutes) || activityMinutes <= 0 || isNaN(restMinutes) || restMinutes <= 0) { alert("Please enter valid activity and rest times."); return; } if (!startTime) { startTime = Date.now(); playAlarm(); timerLabel.textContent = "Activity"; } else { startTime = Date.now() - (elapsedSeconds \* 1000); } timerInterval = setInterval(updateTimer, 1000); startBtn.disabled = true; stopBtn.disabled = false; if (isRestTime) { whiteNoise.play().catch(e => console.error("Error playing white noise:", e)); } } function stopTimer() { clearInterval(timerInterval); startBtn.disabled = false; stopBtn.disabled = true; whiteNoise.pause(); } function resetTimer() { clearInterval(timerInterval); elapsedSeconds = 0; previousSeconds = 0; timerDisplay.textContent = '00:00:00'; startTime = null; timerInterval = null; startBtn.disabled = false; stopBtn.disabled = true; activityInput.value = '25'; restInput.value = '5'; isRestTime = false; whiteNoise.pause(); timerLabel.textContent = "Activity"; } function playAlarm() { try { alarmSound.currentTime = 0; alarmSound.play().then(() => { setTimeout(() => { alarmSound.pause(); }, 2000); }).catch(e => { console.error("Error playing alarm:", e); }); } catch (error) { console.error("Error playing alarm:", error); } } // Add event listener for the start button startBtn.addEventListener('click', startTimer); stopBtn.addEventListener('click', stopTimer); resetBtn.addEventListener('click', resetTimer); // Disable stop button and enable start button on initial load stopBtn.disabled = true; startBtn.disabled = false; </script> </body> </html>

Impressive, isn't it?

Posted Apr 1, 2025, 10:59 AM UTC

02
Loading comments…