How to create an Analog Clock with Text Labels? Follow the steps below and use CSS, HTML and JS(babel).

Today I’m gonna post about Creating an Analog Clock with Text labels with the help of HTML, CSS and Js(babel). It’s good looking and prettily animated.

Clocks like this can be used as a widget in your portfolios or on any website as a widget. It has seconds hand too. Nothing too complex, just follow the steps below. Let’s check out the preview first.

Preview of Analog Clock with Text

You might also like this.

How to create an Analog Clock with text labels?

Analog Clock with text labels

Firstly, we will create 3 files, one for HTML, one for SCSS and other for Jsx. Be sure to use babel here, if you are unable to use it, just directly use any babel decompiler to get pure JS.

HTML.

In HTML file, we will create simple div elements giving them simple classNames like a clock, dial, time-display etc. Remember to create one element for every single thing in a clock-like minute hand, hour hand, or second hand. Especially the outer ring.

CSS

In CSS, we will give it a display of grid having pre-defined grid template areas. After that separate styling for each clock hands. then some simple styling for the text labels that are a must.

JS(babel).

In JS, we will first give string representations of time numbers. Then get the appropriate elements to tag to be used for hourDisplay, minuteDisplay, dayDisplay etc. After assigning correct elements, we will then return all of them to their function.

Now, we will get the current date and time, the function that we will use it to achieve will be called getCurrentTime. And then we will re-render these elements and populate the DOM elements.

Source Code.

HTML

<!DOCTYPE html>
<!-- code by EvilWebDev -->
<html>
<head>
  <meta charset="UTF-8">
  <title> Analog Clock with Text Labels | Evil WebDev</title>
      <link rel="stylesheet" href="style.scss">
      <script src="src/main.js" type="text/babel"></script>
</head>
<body>
  
<main>
  <div id="clock">
    <div class="dial"></div>
    <ul id="time-display" class="display-text">
      <li id="hour-display"></li>
      <li id="minute-display"></li>
    </ul>
    <ul id="calendar-display" class="display-text">
      <li id="day-display"></li>
      <li id="month-display"></li>
      <li id="date-display"></li>
    </ul>
    <div id="second-hand" class="hand">
      <div class="ring"></div>
    </div>
    <div id="minute-hand" class="hand"></div>
    <div id="hour-hand" class="hand"></div>
  </div>
</main>
  
</body>
</html>

SCSS

main {
  display: grid;
  grid-template-areas:
    "l t r"
    "l content r"
    "l b r";
  grid-template-columns: 1fr max-content 1fr;
  grid-template-rows: 1fr max-content 1fr;
  width: 100vw;
  height: 100vh;
  background: #b4c4cc;
}

#clock {
  position: relative;
  grid-area: content;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  border: double 10px #39454b;
  background: linear-gradient(-45deg, #39454b 20%, #101017);
  box-shadow: 15px 15px 5px #919ea5;
}

.dial {
  position: absolute;
  top: calc(50% - 10px);
  left: calc(50% - 10px);
  width: 20px;
  height: 20px;
  box-sizing: border-box;
  border-radius: 50%;
  border: dotted 1px #101017;
  background: #4c5c64;
  z-index: 1;
}

/* Clock hands */
.hand {
  position: absolute;
  transform-origin: 0px center;
  /* Fix aliasing caused by transform: rotate() */
  outline: 1px solid transparent;
}

#hour-hand {
  /* center hand */
  top: calc(50% - 2px);
  left: 50%;
  width: 80px;
  height: 2px;
  border: 1px solid #fff;
  border-radius: 3px;
  background: #b7ddf0;
  z-index: 2;
}

#minute-hand {
  /* center hand */
  top: calc(50% - 2px);
  left: 50%;
  width: 120px;
  height: 2px;
  border: 1px solid #fff;
  border-radius: 3px;
  background: #b7ddf0;
  z-index: 3;
}

#second-hand {
  /* center hand */
  top: calc(50% - 1px);
  left: 80px;
  width: 200px;
  height: 2px;
  border-radius: 1px;
  background: #b7ddf0;
  transform-origin: 70px center;
  z-index: 5;
}

#second-hand .ring {
  width: 12px;
  height: 10px;
  margin-top: -5px;
  margin-left: 15px;
  background: transparent;
  border: 1px solid #b7ddf0;
  border-radius: 50%;
  z-index: 11;
}

/* Long form text displays */
.display-text li {
  list-style-type: none;
  font-size: 16px;
  line-height: 20px;
  font-family: Arial, Helvetica, sans-serif;
  text-transform: uppercase;
  color: #fff;
}

#time-display {
  position: absolute;
  top: 25%;
  left: calc(50% - 75px);
  min-width: 150px;
  margin: 0;
  text-align: center;
  transition: 1s ease-in;
}

#time-display li {
  display: block;
}

#calendar-display {
  position: absolute;
  top: 75%;
  left: calc(50% - 75px);
  min-width: 150px;
  margin: 0;
  text-align: center;
}

#calendar-display li {
  display: inline-block;
}

JSX

// Setters
const setTimeString = timeUnit => {
  // String representations of time numbers
  const timeStrings = {
    0: "",
    1: "one",
    2: "two",
    3: "three",
    4: "four",
    5: "five",
    6: "six",
    7: "seven",
    8: "eight",
    9: "nine",
    10: "ten",
    11: "eleven",
    12: "twelve",
    13: "thirteen",
    14: "fourteen",
    15: "fifteen",
    16: "sixteen",
    17: "seventeen",
    18: "eighteen",
    19: "nineteen",
    20: "twenty",
    30: "thirty",
    40: "fourty",
    50: "fifty",
    60: "sixty"
  };

  if (timeUnit < 20) {
    return timeStrings[timeUnit];
  } else {
    const digitOne = timeStrings[Math.floor(timeUnit / 10) * 10];
    const digitTwo = timeStrings[timeUnit % 10]
      ? timeStrings[timeUnit % 10]
      : 0;
    if (digitTwo !== 0) {
      return ${digitOne} ${digitTwo};
    } else {
      return digitOne;
    }
  }
};

(function() {
  // Getters
  const getDomElements = () => {
    const hourDisplay = document.getElementById("hour-display");
    const minuteDisplay = document.getElementById("minute-display");
    const dayDisplay = document.getElementById("day-display");
    const monthDisplay = document.getElementById("month-display");
    const dateDisplay = document.getElementById("date-display");
    const hourHand = document.getElementById("hour-hand");
    const minuteHand = document.getElementById("minute-hand");
    const secondHand = document.getElementById("second-hand");

    return {
      hourDisplay,
      minuteDisplay,
      dayDisplay,
      monthDisplay,
      dateDisplay,
      hourHand,
      minuteHand,
      secondHand
    };
  };

  const getCurrentTime = () => {
    const date = new Date();
    const time = date.getTime();
    const hours = date.getHours();
    const minutes = date.getMinutes();
    const seconds = date.getSeconds();
    const milliseconds = date.getMilliseconds();

    return {
      date,
      time,
      // Adjust hours to 12 hour clock
      hours: hours > 12 ? hours - 12 : hours,
      minutes,
      seconds,
      milliseconds
    };
  };

  const setDateDisplay = currentTime => {
    const nowDateString = currentTime.toDateString();
    const dayString = nowDateString.slice(0, 3);
    const monthString = nowDateString.slice(4, 7);
    const dateString = nowDateString.slice(8, 10);

    return {
      dayString,
      monthString,
      dateString
    };
  };

  // Rendering
  const rotateHand = (timeUnit, factor, hand) => {
    // -90 degress accomodates for initial css layout position
    const position = timeUnit * factor - 90;
    hand.style.transform = rotate(${position}deg);
  };

  const renderClock = () => {
    const domElements = getDomElements();
    const currentTime = getCurrentTime();
    // Hand values for animation
    // Seconds, minutes, hours reflect 100ms setInterval() iteration
    const seconds =
      (currentTime.seconds * 1000 + currentTime.milliseconds) / 1000;
    const minutes = (currentTime.minutes * 60 + seconds) / 60;
    const hours = (currentTime.hours * 60 + minutes) / 60;

    // Display strings for long-form readout
    const hourString = setTimeString(currentTime.hours);
    const minuteString = setTimeString(currentTime.minutes);
    let { dayString, monthString, dateString } = setDateDisplay(
      currentTime.date
    );

    // Populate DOM Elements
    domElements.hourDisplay.innerHTML = hourString;
    domElements.minuteDisplay.innerHTML = minuteString;
    domElements.dayDisplay.innerHTML = ${dayString} | ;
    domElements.monthDisplay.innerHTML = ${monthString} | ;
    domElements.dateDisplay.innerHTML = dateString;

    // Rotate Hands
    rotateHand(seconds, 6, domElements.secondHand);
    rotateHand(minutes, 6, domElements.minuteHand);
    rotateHand(hours, 30, domElements.hourHand);
  };

  const run = () => {
    setInterval(() => {
      renderClock();
    }, 100);
  };

  run();
})();

So this is how we do our Analog Clock. Check the codePen below.

CodePen.

See the Pen Analog Clock with Text Labels by Kamran Tahir (@EvilSpark) on CodePen.

0 CommentsClose Comments

Leave a comment