JavaScript-30-Day-2
Tags: javascript, css, webdev, github
Published: 2021-06-02 16:15:43


<h1><center> JS+CSS Clock  <center></h1>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b87atmkh91clkkwv2ll6.png)

[Project demo](https://cenacrharsh.github.io/JS-30-DAY-2/)

In lesson 2 of JavaScript30 I made a real time clock with seconds, minutes and hour hand. This lesson focused mainly on CSS and JS. CSS styles were used to make the clock look like a real clock using transition and transform properties and ticking effect was also added while JavaScript was used to fetch the current time and to rotate the hands of the clock in accordance with the current time.

<h3>Things I Learned</h3>

<h4>CSS</h4>

-first thing we did was to change the axis of rotation which by default is the middle i.e 50%, so we'll change it to 100% along the x-axis so that so that the pivot is moved to the very right hand side (the origin).
```javascript
 transform-origin: 100%;
```

-divs are block by default from right to left (horizontal) due to which the hands were pointing to 9'o clock by default so we'll rotate the entire thing by 90deg so that the hands are set to 12'o clock, we'll use rotate for this.
```javascript
transform: rotate(90deg);
```

-by default the hands move automatically so to add an effect of moving hands we use transition property, we go a step further to add a ticking
we add cubic bezier to the transition timing function.
```javascript
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
```

<h4>JavaScript</h4>

-we create a setDate function and we make it run every second using setInterval.
```javascript
setInterval(setDate, 1000);
```

-now we need to convert seconds (similar for minutes and hours) to degrees for which we convert it into something that is base 100 that is 0%->0deg and 100%->360deg.We do this by dividing the seconds by 60 which gives us the percentage and then we multiply it by 360 to convert it to degrees. But this will not work correctly because of the rotate 90deg we added in the beginning and to compensate for this lag we'll add a 90deg to the calculated result.Then we use JS to give the second hand the calculated rotation.
```javascript
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = (seconds / 60) * 360 + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
```
The complete JS code looks like this
```javascript
<script>
      const secondHand = document.querySelector(".second-hand");
      const minuteHand = document.querySelector(".min-hand");
      const hourHand = document.querySelector(".hour-hand");

      function setDate() {
        const now = new Date();

        const seconds = now.getSeconds();
        const secondsDegrees = (seconds / 60) * 360 + 90;
        secondHand.style.transform = `rotate(${secondsDegrees}deg)`;

        const minutes = now.getMinutes();
        const minutesDegrees = (minutes / 60) * 360 + 90;
        minuteHand.style.transform = `rotate(${minutesDegrees}deg)`;

        const hours = now.getHours();
        const hoursDegrees = (hours / 12) * 360 + 90;
        hourHand.style.transform = `rotate(${hoursDegrees}deg)`;
      }

      setInterval(setDate, 1000);
    </script>
```

This code however has one issue. When any hand transitions from final state to initial state, because the number of degrees reduce, the hand makes a (reverse) anti-clockwise motion to reach the 0 degree mark (they jitter and rotate backwards because they're going from 400 something degrees to 90).
Because the transition is set at 0.05s, a slight hint of this animation is visible.
So we need to do something so that the hands move forward and not backward. We can do this in 2 ways:

1) tally the amount of degrees so that it keeps counting
2) take away the transition temporarily using JS and then remove it afterwards using some if statements inside the setDate function.

I'll use the second method.

-we'll change the transition to ‘all 0s’ using javascript.I created a class called .bypass
It contains the following line of code
```javascript
transition: all 0s;
```

At every 0, I add the class and at every 1, I remove the class thus returning the hand to the cubic bezier curve at 0.05s

```javascript
if(seconds===0)
secondHand.classList.add(‘bypass’);
if(seconds===1)
secondHand.classList.remove(‘bypass’);
```
This fixed the issue.

<h3>Conclusion</h3>
Overall it was a very fun lesson which helped me better understand CSS transitions and transforms.

GitHub repo:
{% github cenacrharsh/JS-30-DAY-2 no-readme %}
[Twitter](https://twitter.com/cenacr007_harsh)
[Linkedin](https://www.linkedin.com/in/kumarharsh22/)