You are browsing as a guest. Sign up (or log in) to start making projects!

2h 24m 35s logged

Devlog #4: Building my Timer

Hey everyone! Welcome back to another update for Forever.

The app now has a functional, **Timer **! When the timer starts, the rest of the app becomes blur, and only the timer is visible along with some interactive buttons.

Here is how I built this interface and how the timer works, and what I updated in my task list code!


The design

I wanted to make it look better so i made it so that once the start studying button is clicked, the rest of the app disappears and becomes blur and only the timer shows up in the middle of the screen.

  • The Blur Effect: When you click “Start Studying” the main dashboard is blurred using a CSS backdrop blur wrapper and the timer appears by removing the display hidden from the timer div (watch.classList.remove('hidden')).

  • Smart Controls: I added two primary buttons: Pause/Resume and Stop.

    • When the timer is ongoing, the main action button says “Pause”.
    • If you click on “Pause” the clock stops and transforms the button into a green “Resume” button.
    • Clicking “Stop” instantly closes the overlay, resets the view, and brings the dashboard back into clear view.

Updates on the Task List

Alongside the timer, I made a quick update to my checkbox:

  • I switched out the default list markers and replaced them with radio (checkbox.type = 'radio') to better fit the dashboard styling.
  • I also updated the X button text to display a “delete”.

The code

The stopwatch doesn’t just count up manually. It compares the constant exact system time using Date.now() against when you pressed start. This builds a highly accurate stopwatch!

Here is the JavaScript code handling the timer:

let startTime = 0;
let elapsedTime = 0;
let timerInterval = null;
let isRunning = false;

const display = document.getElementById("display");
const button = document.getElementById("starttime");
const buttonSR = document.getElementById("res-stop");
const buttonStop = document.getElementById("Stop");

// Formats milliseconds into HH:MM:SS.mm
function formatTime(ms) {
  const hrs = Math.floor(ms / 3600000);
  const mins = Math.floor((ms % 3600000) / 60000);
  const secs = Math.floor((ms % 60000) / 1000);
  const msecs = Math.floor((ms % 1000) / 10); // Two-digit milliseconds

  const pad = (num) => String(num).padStart(2, "0");

  return `${pad(hrs)}:${pad(mins)}:${pad(secs)}.${pad(msecs)}`;
}

// Toggles the stopwatch state from the start screen
button.addEventListener("click", () => {
  watch.classList.remove('hidden');
  if (!isRunning) {
    startTime = Date.now() - elapsedTime;
    timerInterval = setInterval(() => {
      elapsedTime = Date.now() - startTime;
      display.textContent = formatTime(elapsedTime);
    }, 10); // Updates every 10 milliseconds for precision
    
    buttonSR.textContent = "Pause";
    buttonSR.style.backgroundColor = "#ffff"; 
    isRunning = true;
  } 
});

// Controls pausing and resuming mid-session
buttonSR.addEventListener("click", () => {
  if (!isRunning) {
    watch.classList.remove('hidden');
    startTime = Date.now() - elapsedTime;
    timerInterval = setInterval(() => {
      elapsedTime = Date.now() - startTime;
      display.textContent = formatTime(elapsedTime);
    }, 10);
    
    buttonSR.textContent = "Pause";
    buttonSR.style.backgroundColor = "#ffff"; 
    isRunning = true;
  } else {
    clearInterval(timerInterval);
    buttonSR.textContent = "Resume";
    buttonSR.style.backgroundColor = "#28a745"; // Green resume color
    isRunning = false;
  }
});

// Closes the modal overlay and exits focus mode
buttonStop.addEventListener("click", () => {
  watch.classList.add('hidden');
});
0
4

Comments 0

No comments yet. Be the first!