|
1 | 1 | # Exercise 2: JS + CSS Clock
|
2 |
| -Nitish Dayal, Software & Applications Developer - [Contact](http://nitishdayal.me) |
3 |
| -Last Commit Date: Dec 9, 2016 |
4 | 2 |
|
5 |
| -Given an web page with an analog clock created out of CSS, update the CSS |
6 |
| - and write the JavaScript necessary to make the clock functional. |
| 3 | +> Nitish Dayal, Software & Applications Developer - [Contact](http://nitishdayal.me) |
| 4 | +> Last Commit Date: May 12, 2017 |
| 5 | +
|
| 6 | +Given a web page with an analog clock created with CSS, write the |
| 7 | + JavaScript necessary to make the clock functional. Make alterations to the CSS |
| 8 | + as necessary. |
7 | 9 |
|
8 | 10 | ## Guide
|
9 | 11 |
|
10 | 12 | The HTML file has 3 `div` elements which correspond with the second, minute, and
|
11 |
| - hour hand on a clock. We'll create references to these elements and dynamically |
12 |
| - update certain CSS properties to change their positions so they reflect the |
13 |
| - current time. Easy peasy. |
| 13 | + hour hand on a clock |
| 14 | + |
| 15 | + ```html |
| 16 | + <!-- ...previous elements --> |
| 17 | + <div class="hand hour-hand"></div> |
| 18 | + <div class="hand min-hand"></div> |
| 19 | + <div class="hand second-hand"></div> |
| 20 | + <!-- next elements... --> |
| 21 | + ``` |
| 22 | + |
| 23 | +The necessary JavaScript code shouldn't be too crazy; |
| 24 | + we'll create references to these elements and dynamically |
| 25 | + update certain CSS properties to change their positions so they reflect the |
| 26 | + current time. Easy peasy. |
14 | 27 |
|
15 | 28 | **Steps:**
|
16 | 29 |
|
17 |
| -- CSS: |
18 |
| - |
19 |
| - 1. Set the `transform-origin` CSS property of the `.hand` class at 100%; the default |
20 |
| - value is 50% (or the midway point of the HTML element), but if we leave it there |
21 |
| - the clock hands will tranform from their individal centers as opposed to the |
22 |
| - center of the clock. Changing the value to 100% shifts the _origin point of the |
23 |
| - transformations_ to the furthest x-axis point of the HTML element. |
24 |
| - 2. The hands are all laying flat; we need them to be vertical. Rotate all of the |
25 |
| - hands by 90 degrees so that they are upright. |
26 |
| - 3. Set the `transition` CSS property of `.hand` to `all 0.05s`; this tells the browser |
27 |
| - to gradually apply any changes to the element's styling over a 0.05 second period. |
28 |
| - 4. Set the `transition-timing-function` CSS property of `.hand` to whatever function |
29 |
| - you prefer, or define your own using the `cubic-bezier()` property value. |
30 |
| - |
31 |
| -- JavaScript |
32 |
| - |
33 |
| - 1. Declare & define variables for each clock hand and reference the corresponding _HTML |
34 |
| - element_. |
35 |
| - 2. Create a function which will be responsible for updating the position of all the |
36 |
| - clock hands. |
37 |
| - - Calculate the necessary rotation using the _current numerical time value_ for each hand |
38 |
| - and dividing it by the max value possible to get the percentage, multiplying the result |
39 |
| - of that by 360 (each hand can rotate 360 degrees) to get the numerical value for the |
40 |
| - rotation, and increasing that by another 90 degrees to compensate for the shift |
41 |
| - originally applied by the CSS styling on page load. |
42 |
| - 3. Call the function defined in step 2 every second. |
| 30 | +- **CSS**: |
| 31 | + |
| 32 | + 1. The hands are all laying flat; we need them to be vertical. Rotate all of the |
| 33 | + hands by 90 degrees so that they are upright by giving the `.hand` class a |
| 34 | + `transform` rule with the value `rotate(90deg)`. |
| 35 | + |
| 36 | + 1. Set the `transform-origin` CSS property of the `.hand` class to `100%`; the default |
| 37 | + value is `50%` (or the midway point of the HTML element), but if we leave it there |
| 38 | + the clock hands will transform from the respective centers of their lines as opposed to the |
| 39 | + center of the clock. (If that doesn't make sense, try it out in your code. Set the value for |
| 40 | + `transform-origin` rule completely and check again. Finally, try it again with `50%`.). |
| 41 | + Changing the value to 100% shifts the _point of origin for the transformation_ |
| 42 | + to the furthest point on the x-axis of the HTML element. |
| 43 | + |
| 44 | + 1. Set the `transition` CSS property of `.hand` to `all 0.05s`; this tells the browser |
| 45 | + to gradually apply any changes to the element's styling over a 0.05 second period. |
| 46 | + |
| 47 | + 1. Set the `transition-timing-function` CSS property of `.hand` to whatever function |
| 48 | + you prefer, or define your own using the `cubic-bezier()` property value. |
| 49 | + |
| 50 | +- **JavaScript**: |
| 51 | + |
| 52 | + 1. Declare & define variables for each clock hand and reference the corresponding _HTML |
| 53 | + element_. |
| 54 | + |
| 55 | + EX: `const secondHand = document.querySelector('.second-hand');` |
| 56 | + |
| 57 | + 1. Create a function which will be responsible for calculating the number of degrees that we need |
| 58 | + to rotate each clock hand by. It should accept two arguments: the _current numerical value_ of the |
| 59 | + clock hand, and the max value possible of the clock hand (if you want the number of degrees needed for |
| 60 | + the second hand and the current time is 03:15:18, you would pass in (18, 60) where 18 is the current |
| 61 | + value of the second hand, and 60 is the maximum possible value). |
| 62 | + |
| 63 | + - Divide the current numerical value of the clock hand by it's max possible value to get the rotation as |
| 64 | + a percentage, then multiply the result of that by 360 (each hand can rotate 360 degrees) to convert |
| 65 | + the value from a percentage to an integer, and increase that result by another 90 degrees to compensate |
| 66 | + for the shift originally applied by the CSS styling on page load. |
| 67 | + |
| 68 | + ```javascript |
| 69 | + const calcDegrees = (time, max) => ((time / max) * 360) + 90; |
| 70 | + ``` |
| 71 | + |
| 72 | + 1. Create a function that will automatically run every second; in the body of the function, |
| 73 | + create a variable and define it as a new Date object. Then, create three variables which will |
| 74 | + hold references to the rotation amount to be applied to each clock hand. To get the rotation amount, |
| 75 | + define the variables as the return value from calling the `calcDegrees` function; each call should |
| 76 | + pass in the correct values in relation to whichever clock hand they are supposed to represent. |
| 77 | + |
| 78 | + 1. Still within the body of the function from step 3, update the `transform` rule for each |
| 79 | + clock hand to their corresponding updated values. |
| 80 | + |
| 81 | + ```javascript |
| 82 | + /* Steps 3 & 4 */ |
| 83 | + |
| 84 | + // Call function once every second |
| 85 | + setInterval(() => { |
| 86 | + // Create new Date object |
| 87 | + const now = new Date(); |
| 88 | + // Get current seconds, minutes, & hours and calculate the degree shift |
| 89 | + const |
| 90 | + secondHandDegrees = calcDegrees(now.getSeconds(), 60), |
| 91 | + minuteHandDegrees = calcDegrees(now.getMinutes(), 60), |
| 92 | + hourHandDegrees = calcDegrees(now.getHours(), 12); |
| 93 | + // Apply rotation to the clock hands corresponding with current time value |
| 94 | + secondHand.style.transform = `rotate(${secondHandDegrees}deg)`; |
| 95 | + minuteHand.style.transform = `rotate(${minuteHandDegrees}deg)`; |
| 96 | + hourHand.style.transform = `rotate(${hourHandDegrees}deg)`; |
| 97 | + }, 1000); // 1000ms === 1s |
| 98 | + |
| 99 | + ``` |
43 | 100 |
|
44 | 101 | Yaaaaaay! All done!
|
0 commit comments