New Year Countdown
Tags: webdev, javascript, html, css
Published: 2023-01-01 14:02:53

Hola! How're you doing? I'm hoping for the best. I wish you a lovely happy new year. This is gonna be my 1st post in this new year 2023 'Tis.  

This is not a project but just a cool time pass with vanilla javascript. I've always wanted a countdown timer to catch up with seconds while capturing the moment Iron man snaps in the Avengers Endgame. [Voila!](https://www.instagram.com/reel/Cm1_opUjbcN/?utm_source=ig_web_copy_link)

[Repo ⚡](https://github.com/JagadeeshKJ/new-year-countdown)
[Live 🚀](https://new-year-countdown-six.vercel.app/)

**Let's Start Building!**

The boilerplate for this project is simple as it looks in this hierarchy of files.

.
├── index.html
├── script.js
└── style.css

**HTML**

```
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="style.css" />
    <title>Happy New Year</title>
  </head>

  <body>
    <div id="year" class="year"></div>

    <h1>New Year Countdown</h1>

    <div id="countdown" class="countdown">
      <div class="time">
        <h2 id="days">00</h2>
        <small>days</small>
      </div>
      <div class="time">
        <h2 id="hours">00</h2>
        <small>hours</small>
      </div>
      <div class="time">
        <h2 id="minutes">00</h2>
        <small>minutes</small>
      </div>
      <div class="time">
        <h2 id="seconds">00</h2>
        <small>seconds</small>
      </div>
    </div>

    <img
      src="./img/spinner.gif"
      alt="Loading..."
      id="loading"
      class="loading"
    />

    <script src="script.js"></script>
  </body>
</html>

```

The <div> with the id of "year" and class of "year" will display the current year. The <h1> tag displays the title of the countdown. 

The <div> with the id of "countdown" and class of "countdown" contains four other <div>s that each contain an <h2> tag with an id of either days, hours, minutes, or seconds. 

These will display the number of days, hours, minutes, and seconds until New Year's Day. 

The <img> tag displays a loading spinner while the script is running and the script itself is located in a file called "script.js".

**Script.js**

```
const days = document.getElementById('days');
const hours = document.getElementById('hours');
const minutes = document.getElementById('minutes');
const seconds = document.getElementById('seconds');
const countdown = document.getElementById('countdown');
const year = document.getElementById('year');
const loading = document.getElementById('loading');

const currentYear = new Date().getFullYear();

const newYearTime = new Date(`January 01 ${currentYear + 1} 00:00:00`);

// Set background year
year.innerText = currentYear + 1;

// Update countdown time
function updateCountdown() {
  const currentTime = new Date();
  const diff = newYearTime - currentTime;

  const d = Math.floor(diff / 1000 / 60 / 60 / 24);
  const h = Math.floor(diff / 1000 / 60 / 60) % 24;
  const m = Math.floor(diff / 1000 / 60) % 60;
  const s = Math.floor(diff / 1000) % 60;

  // Add values to DOM
  days.innerHTML = d;
  hours.innerHTML = h < 10 ? '0' + h : h;
  minutes.innerHTML = m < 10 ? '0' + m : m;
  seconds.innerHTML = s < 10 ? '0' + s : s;
}

// Show spinner before countdown
setTimeout(() => {
  loading.remove();
  countdown.style.display = 'flex';
}, 1000);

// Run every second
setInterval(updateCountdown, 1000);

```

This code is setting up a countdown timer for the new year. It starts by declaring variables for each of the elements in the HTML document that will be used in the countdown. 

It then sets the current year and creates a new Date object for the new year. The updateCountdown() function is then declared which calculates the difference between the current time and the new year time, and stores it in days, hours, minutes, and seconds. 

The values are then added to the DOM using innerHTML. A setTimeout() function is used to remove a loading spinner before displaying the countdown, and a setInterval() function is used to run updateCountdown() every second.

**Styles**

```
@import url('https://fonts.googleapis.com/css?family=Muli&display=swap');

* {
  box-sizing: border-box;
}

body {
  background-image: url('https://images.unsplash.com/photo-1467810563316-b5476525c0f9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1349&q=80');
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  height: 100vh;
  color: #fff;
  font-family: 'Muli';
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin: 0;
  overflow: hidden;
}

/* Add a dark overlay */
body::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

body * {
  z-index: 1;
}

h1 {
  font-size: 60px;
  margin: -80px 0 40px;
}

.year {
  font-size: 200px;
  z-index: -1;
  opacity: 0.2;
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
}

.countdown {
  /* display: flex; */
  display: none;
  transform: scale(2);
}

.time {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  margin: 15px;
}

.time h2 {
  margin: 0 0 5px;
}

@media (max-width: 500px) {
  h1 {
    font-size: 45px;
  }

  .time {
    margin: 5px;
  }

  .time h2 {
    font-size: 12px;
    margin: 0;
  }

  .time small {
    font-size: 10px;
  }
}

```

The @import statement at the top of the code imports a font from Google Fonts called 'Muli'. 

The rest of the code sets up styling for the body element, including background image, color, font family, and another styling.

It also sets up styling for elements within the body such as h1 and .year. 

Finally, it includes a media query to adjust styling for smaller screens.

And the final output looks something like this.


![voila](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a2gnbcwztz164w4fkn46.png)

That's it for the start of a year fellas. A wise man once said, "start small". I'll see you soon.