How to create an Analog clock using React

How to create an Analog clock using React

Learn to make a wall clock with react js

What is the play about?

Analog clock is one of the many plays that I developed at ReactPlay to get my hands dirty in the world of open source. It is just a digital representation of an old-styled wall clock made with reactjs.

In this play, you will get to learn how to work with Date and time, how to synchronize the time, how to extract the hour, minute, and seconds info, and use this info to get the correct angle to move the clock hands toward the right direction. In the end, you will be able to make a beautiful wall clock.

But first, what is ReactPlay?

ReactPlay is an open-source platform to create, collaborate and showcase tiny bite-sized projects called plays. It is an excellent opportunity to showcase, get feedback, and collaborate with fellow developers to get a real-world experience.

Screenshot from 2022-06-26 20-27-59.png

TLDR; Learn to make a beautiful wall clock in reactjs. Live Demo Github

How did I come up with the play idea?

Well, It's not a revolutionary idea. I saw it somewhere on the internet and I was inspired by the idea that I could also make something similar. The static clock interface wasn't difficult but the challenge I faced was how do I make those clock hands move? with a little bit of googling, I was convinced that I could make use of css transform:rotate() property to rotate those hands. I just need to get the correct angles to rotate those moves.

Implementation

Since this is a react project we will be focusing on interactivity and not design. However, feel free to check out the github repo

To begin with, we have a circular container called a clock and inside this circular container, we have three divs designed as hour-hand, minute-hand, and second-hand. Pretty simple, isn't it?

<div className="clock">
    <div  className="hour-hand" ></div>
     <div className="minute-hand"></div>
    <div className="second-hand"></div>
 </div>

Alright, I have the design but it doesn't do anything.

So, the next goal is to get the time and keep it synchronized each second.

In the code snippet below, We are using javascript Date object to get the time. setInterval function to update the time every second, and clearInterval to clear this interval, or else this will keep running in the background even if the user goes to some other plays. which may affect the performance.

 const [date, setDate] = useState(new Date());
  useEffect(() => {
    const interval = setInterval(() => {
      setDate(new Date());
    }, 1000);

    return () => clearInterval(interval);
  }, []);

new Date() object give us date and timeMon Jun 27 2022 08:36:32 GMT+0530 (India Standard Time) {} we don't need the date hence we need to just extract the time. getHours(), getMinutes(), and getSeconds() are js methods to get the hours, minutes and seconds respectively out of date object.

Important Logic

In order to complete a circle round each hand has to move 360 degrees. for ex.,

  • the hour hand rotates 360 degrees in 12 hours. hence, 360/12 = 30degree each hour.
  • the minute hand rotates 360 degrees in 60 minutes. hence, 360/60 = 6 degree each minute.
  • and the second hands also rotate 360 degrees in 60 seconds. hence, the second-hand needs to rotate 6 degrees each second.
 const hour = date.getHours() * 30  // Move 30degree on first hour, 60 degree on second and so on. 
 const minute = date.getMinutes() * 6 //same as above.
 const second = date.getSeconds() * 6 //same as above.

Since we, now have the angles of each hand. We, just need to incorporate the angles into the design.

<div className="clock">
      <div className="hour-hand"
       style={{ transform: "rotate(" + hour + "deg)" }}
       ></div>
       <div className="minute-hand" 
       style={{ transform: "rotate(" + minute + "deg)" }}
       ></div>
       <div className="second-hand"
       style={{ transform: "rotate(" + second + "deg)"}}
       ></div>
  </div>

Conclusion

It was an awesome experience to create and share this play with you. I thank you for stopping by. Please feel free to reach out on twitter or leave your constructive feedback in the comment section.

Connect with me

Did you find this article valuable?

Support ReactPlay Blog by becoming a sponsor. Any amount is appreciated!