Small JS Countdown timer where user has to type string of numbers to stop it and win

Joined
Feb 16, 2024
Messages
13
Reaction score
0
Hi,

I'm working on a tiny countdown timer JS project. I found that little piece of code on Internet, and it works well.

let count = 60;
const timer = setInterval(function() {
count--;
console.log(count);
if (count === 0) {
clearInterval(timer);
console.log("Time's up!");
}
}, 1000);

Now I don't understand how to add a prompt so the player can type a string of numbers to stop it or even having JS to setup a code randomly. I considered implementing some RNG/Math random feature, but I have no idea how to build and proceed with it. I'm absolutely puzzled and can't find a clear example of the Internet. Reading classes on the JS Institute does not help me develop something at the most fundamental level.

I am looking for a code at the very beginner level, very sober and simple (Functions, Loops but no template strings). Please, any ideas?
 
Last edited:
Joined
Jul 4, 2023
Messages
406
Reaction score
47
Since the prompt returns the value entered by the user as a string, code need to convert it to an integer.
JavaScript:
let count = parseInt(prompt('Enter the number greater than 0:'));
JavaScript:
let count = parseInt(prompt('Enter the number greater than 0:'));
const timer = setInterval(function() {
  count--;
  console.clear();
  console.log(count);
  if (count === 0) {
    clearInterval(timer);
    console.info("Time's up!");
  }
}, 1000);
e.g. for a random number range from 1 to 60
JavaScript:
let count = Math.floor(Math.random() * 60) + 1;
 
Joined
Feb 16, 2024
Messages
13
Reaction score
0
I tried to run the code but it gives me an error. I also believe I mispoke.

The program should generate random code made of four numbers everytime it's being ran.

I click on Run, program generates for example 4321 but if you run it again, it should be another code and so on, the countdown starts just after, and user is offered a prompt when he can perhaps try 5 times before getting a game over.

Is that something easy to implement?
 
Joined
Jul 4, 2023
Messages
406
Reaction score
47
Is that something easy to implement?
My code proposal, it looks as easy implementation? 🤔
You tell me. ;)

[ working code on-line ]
JavaScript:
const NUMBER_OF_TRIALS = 5;
const secret_code = (Math.floor(Math.random() * 8999) + 1000).toString(); // 4 digits number only

let trials_left = NUMBER_OF_TRIALS, prompt_ = '', answer = '';
let pattern_guessed = Array(secret_code.toString().length).fill('-');
let start_time = new Date().getTime();

do {
  prompt_ = `
    Game time: ${calculateTime(start_time)}
    Trial: ${(trials_left - 1 === 0) ? 'last one' : (trials_left - 1) + ' left'}
    Guessed: ${pattern_guessed.join('')}
    Try to guess the secret code:
  `;
 
  answer = prompt(prompt_) ?? '';
  for (let index=0; index<answer.length; index++)
    if (answer[index] === secret_code[index])
      pattern_guessed[index] = answer[index];
 
  if (pattern_guessed.join('') === secret_code) {
    alert(`
      Congratulations!
      You guessed the secret code: ${secret_code}
      Attempts made: ${(NUMBER_OF_TRIALS - (trials_left - 1))}
      In time: ${calculateTime(start_time)}
    `);
    break;
  }
} while (trials_left-- > 1);

if (pattern_guessed.join('') !== secret_code) {
  alert(`
    Game over!
    You were not able to guess the secret code: ${secret_code}
    Guessed by you: ${pattern_guessed.join('')}
    Game time: ${calculateTime(start_time)}
  `);
}

function calculateTime(start_time) {
  const elapsed_time = Math.floor((new Date().getTime() - start_time) / 1000);
  return  Math.floor(elapsed_time / 60) + ':' + (elapsed_time % 60).toString().padStart(2, '0');
}
 
Joined
Feb 16, 2024
Messages
13
Reaction score
0
Is there a different way to put it?

Programming is the most difficult thing I have seen in IT. As a total beginner how could I build this project in an easier way?

Basically I would like my timer to behave like a digital watch but in the other way from 00.00.60 -> 00.00.00 with a permanent display of the time going by.

Something along that, but the way around as a timer. I am looking for the most basic way and easier way to do it.

<!DOCTYPE html>
<html>
<body>

<h1>The Window Object</h1>
<h2>The setInterval() Method</h2>

<p id="demo"></p>

<script>
setInterval(myTimer, 1000);

function myTimer() {
const date = new Date();
document.getElementById("demo").innerHTML = date.toLocaleTimeString();
}
</script>

</body>
</html>
 
Joined
Jul 4, 2023
Messages
406
Reaction score
47
digital watch but in the other way from 00.00.60 -> 00.00.00 with a permanent display of the time going by
HTML:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet"
          href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&display=swap">

    <style>
      body {
        margin: 2rem;
      }
      #my-timer {
        font: 500 1.5rem/1 "Orbitron", system-ui, monospace, sans-serif;
        font-optical-sizing: auto;
        letter-spacing: .15rem;
        transition: color 200ms;
      }
      .left-10 {
        color: red;
      }
    </style>
  </head>
  <body>
    <p id="my-timer"></p>

    <script>
      const timerID = setInterval(myTimer, 1000);
      let seconds = 60;

      function myTimer() {    
        document.getElementById("my-timer").textContent = '00:00:' + seconds.toString().padStart(2, '0');
        if (seconds-- <= 0)
          clearInterval(timerID);
        if (seconds < 10)
          document.getElementById("my-timer").classList.add('left-10');
      }
    </script>
  </body>
</html>

;) [ working code on-line ]
HTML:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet"
          href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&display=swap">

    <style>
      body {
        margin: 2rem;
      }
      #my-timer {
        display: inline-block;
        width: 9rem;
        border: 1px solid black;
        border-radius: .5rem;
        padding: .25rem .5rem;
        font: 500 1.5rem/1 "Orbitron", system-ui, monospace, sans-serif;
        font-optical-sizing: auto;
        letter-spacing: .15rem;
        user-select: none;

        transition: color 200ms;
      }
      button {
        width: 2rem;
        height: 2rem;
        border-radius: .5rem;
        cursor: pointer;
        font: 500 1.3rem/1.01 "Orbitron", system-ui, monospace, sans-serif;
        font-optical-sizing: auto;
        box-shadow: 0px 1px 1px black;

        transition: all 50ms;
      }
      button:active {
        box-shadow: none;
        transform: translatey(+1px);
      }
      .left-10 {
        color: red;
      }
    </style>
  </head>
  <body>
    <div id="my-timer">00:00:00</div>
    <button>&#9205;</button>

    <script>
      const my_timer = document.getElementById('my-timer');
      const button = document.querySelector('button');
      let timer_id;
      let seconds = 60;
      let is_countdown = false;

      button.addEventListener('click', () => {
        if (!is_countdown) {
          button.innerHTML = '&#9208;'; // icon pause
          myTimer();
          timer_id = setInterval(myTimer, 1000);       
        } else {
          button.innerHTML = '&#9205;'; // icon start/play
          clearInterval(timer_id);
        }
        is_countdown = !is_countdown;
      })

      function myTimer() {     
        my_timer.textContent = '00:00:' + seconds.toString().padStart(2, '0');
        if (seconds-- <= 0)
          clearInterval(timer_id);
        if (seconds < 10)
          my_timer.classList.add('left-10');
      }
    </script>
  </body>
</html>

[ UTF-8 Emoji Audio and Video ] [ Font: Orbitron ]
 
Last edited:
Joined
Feb 16, 2024
Messages
13
Reaction score
0
Sorry for my slow reply:

I worked on that, it's easier for me to manipulate it, but I must admit the countdown display format is a bit tough to understand (chat GPT made)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&display=swap">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Countdown Timer</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
#clock {
font-size: 2em;
font-family: 'Orbitron', sans-serif;
}
</style>
</head>
<body>
<div id="clock"></div>

<script>
let count = 180;

function updateClock() {
// Format the countdown display
const minutes = Math.floor(count / 60);
const seconds = count % 60;
const formattedTime = minutes + ":" + (seconds < 10 ? '0' : '') + seconds;

// Display the formatted time
document.getElementById('clock').textContent = formattedTime;

// Decrement the count
count--;

// Check if the countdown has reached zero
if (count < 0) {
clearInterval(timer);
document.getElementById('clock').textContent = "Time's up!";
}
}

// Update the clock every second
const timer = setInterval(updateClock, 1000);

// Initialize the clock display
updateClock();
</script>
</body>
</html>

Otherwise I really like your Orbitron policy and .left-10 red
 
Joined
Jul 4, 2023
Messages
406
Reaction score
47
but I must admit the countdown display format is a bit tough to understand

Check this
JavaScript:
const formattedTime = minutes.toString().padStart(2, '0')
                    + ':'
                    + seconds.toString().padStart(2, '0');

  1. minutes.toString(): Converts the minutes value (which is expected to be a number) to a string. This is necessary because padStart is a string method.
  2. padStart(2, '0'): Pads the start of the minutes string with '0' characters until the string reaches a length of 2. If the minutes value is a single digit (e.g., "5"), this method will convert it to "05".
  3. + ':' +: Concatenates a colon to separate the minutes and seconds in the formatted time string.
  4. seconds.toString(): Converts the seconds value (which is expected to be a number) to a string.
  5. padStart(2, '0'): Pads the start of the seconds string with '0' characters until the string reaches a length of 2. If the seconds value is a single digit (e.g., "7"), this method will convert it to "07".
The result is a time string in the format "MM:SS", where both minutes and seconds are always represented with two digits. For example:
  • If minutes is 3 and seconds is 5, formattedTime will be "03:05".
  • If minutes is 12 and seconds is 45, formattedTime will be "12:45".
This ensures that the time is consistently formatted for display purposes.


full code
HTML:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet"
          href="https://fonts.googleapis.com/css2?family=Orbitron:[email protected]&display=swap">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Countdown Timer</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
      }
      #clock {
        font-size: 2em;
        font-family: 'Orbitron', sans-serif;
      }
    </style>
  </head>
  <body>
    <div id="clock"></div>

    <script>
      let count = 600;

      function updateClock() {
        // Format the countdown display
        const minutes = Math.floor(count / 60);
        const seconds = count % 60;
        const formattedTime = minutes.toString().padStart(2, '0')
                            + ':'
                            + seconds.toString().padStart(2, '0');

        // Display the formatted time
        document.getElementById('clock').textContent = formattedTime;

        // Decrement the count
        count--;

        // Check if the countdown has reached zero
        if (count < 0) {
          clearInterval(timer);
          document.getElementById('clock').textContent = "Time's up!";
        }
      }

      // Update the clock every second
      const timer = setInterval(updateClock, 1000);

      // Initialize the clock display
      updateClock();
    </script>
  </body>
</html>
 
Last edited:
Joined
Jul 4, 2023
Messages
406
Reaction score
47
Since the Orbitron font is not a monospace font, there is a waving effect in the counter text. Here is the one of possible solutions to this problem, place every single digit in every single <span> with fixed width.
HTML:
<div id="clock">
  <span>0</span>
  <span>0</span>
  <span class="colon">:</span>
  <span>0</span>
  <span>0</span>  
</div>

[ full code on-line ]
HTML:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="stylesheet"
          href="https://fonts.cdnfonts.com/css/major-mono-display">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Countdown Timer</title>
    <style>
      body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        overflow: hidden;
      }
      #clock {
        display: flex;
        gap: .02em;
        font-size: 2em;
        font-family: 'major mono display', sans-serif;
        transition: color 100ms 1.5s ease-in-out;
      }
      #clock span {
        display: inline-block;
        width: .7em;
      }
      #clock span.colon {
        width: .5em;
        font-size: 95%;
        margin-left: -.2em;
      }
      #clock span:not(.colon) {
        font-weight: 700;
      }
      .left-10 {
        color: red !important;
      }
      .fall-down-animation {
        animation: fall_down 1s linear(
          0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141 13.6%, 0.25, 0.391, 0.563, 0.765,
          1, 0.891 40.9%, 0.848, 0.813, 0.785, 0.766, 0.754, 0.75, 0.754, 0.766, 0.785,
          0.813, 0.848, 0.891 68.2%, 1 72.7%, 0.973, 0.953, 0.941, 0.938, 0.941, 0.953,
          0.973, 1, 0.988, 0.984, 0.988, 1
        );
      }
      @keyframes fall_down {
        from { transform: scale(8); }
        99% { transform: scale(.98); }
        to { transform: scale(1.05); }
      }
    </style>
  </head>
  <body>
    <div id="clock">
      <span>0</span>
      <span>0</span>
      <span class="colon">:</span>
      <span>0</span>
      <span>0</span>  
    </div>

    <script>
      let count = 15; // 600
      let is_colon = true;

      function updateClock() {
        // Format the countdown display
        const minutes = (Math.floor(count / 60)).toString().padStart(2, '0');
        const seconds = (count % 60).toString().padStart(2, '0');

        // Display the formatted time
        const display = document.querySelectorAll('#clock span');
        display[0].textContent = minutes[0];
        display[1].textContent = minutes[1];
        display[3].textContent = seconds[0];
        display[4].textContent = seconds[1];

        // Decrement the count
        if (is_colon) {
          count--;          
          display[2].textContent = ' ';
        } else {
          display[2].textContent = ':';          
        }        
        is_colon = !is_colon;

        if (count == 11) {
          document.querySelector('#clock').classList.add('left-10');
        }

        // Check if the countdown has reached zero
        if (count < 0 && !is_colon) {
          clearInterval(timer);
          document.querySelector('#clock').classList.add('fall-down-animation');
          document.querySelector('#clock').textContent = "Time's up!";      
        }
      }

      // Update the clock every second
      const timer = setInterval(updateClock, 500);

      // Initialize the clock display
      updateClock();
    </script>
  </body>
</html>
 
Last edited:

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,818
Messages
2,569,727
Members
45,664
Latest member
Phil79581

Latest Threads

Top