티스토리 뷰

Drum Kit에 이어 두번째 챌린지인 CSS+JS Clock을 만들어보겠다.

 

먼저 완성 웹페이지부터 보도록 하자.

웹페이지

 

CSS + JS Clock

 

taehwan920.github.io

 

⏰ Day 2 - CSS + JS Clock ⏰


본 챌린지는 아래에 숫자로 써있는 시계는 없고, 그냥 가운데 하얀 시계만 돌아가는 식이었다.

 

이번엔 HTML / CSS / JS 코드를 같이 보도록 하겠다.

 

📃 <HTML> 📃

1
2
3
4
5
6
7
<main>
    <div class="clock-face">
        <div class="hand hour-hand"></div>
        <div class="hand min-hand"></div>
        <div class="hand second-hand"></div>
    </div>
</main>
 
 

 

 

🌈 <CSS> 🌈

1
2
3
4
5
6
7
8
9
10
.hand {
    width:50%;
height: 6px;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.07, 2.54, 0.58, 1);
}
Colored by Color Scripter
 

CSS파트에서 중요한건

 1) transform-origin: 100%을 사용해 시곗바늘이 중앙에서 돌 수 있도록 구심점을 잡아주는 것.

 2) transition-timing-function으로 시곗바늘의 느낌을 살리는 것이다.

우선 크롬 개발자 도구에 가서 transition-timing-function을 아무거나 간단한 걸로 설정한 뒤, 

 

 

cubic-bezier 옆에있는 지렁이 모양 아이콘을 클릭하면

 

 

 

이런 설정창이 나온다. 보라색 공을 이리저리 옮기면 애니메이션 조정이 가능해진다.

 

 

저 지렁이 모양 아이콘을 클릭하면 마우스로 애니메이션 모션 설정 시뮬레이션이 가능한 창이 뜬다.

본인 마음에 들게 설정하고 그 CSS 설정을 복붙해서 옮기도록 하자.

💻 <JavaScript> 💻

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 hours = now.getHours();
    const hoursDegrees = ((hours / 12* 360+ 90;
    hourHand.style.transform = `rotate(${hoursDegrees}deg)`
   
    const minutes = now.getMinutes();
    const minutesDegrees = ((minutes / 60* 360+ 90;
    minuteHand.style.transform = `rotate(${minutesDegrees}deg)`
   
    const seconds = now.getSeconds();
    const secondsDegrees = ((seconds / 60* 360+ 90;
    secondHand.style.transform = `rotate(${secondsDegrees}deg)`
};
 
setInterval(setDate, 1000);
 
 

JS코드는, 선택자로 엘리먼트를 지정해서 각 시곗바늘 별로 돌아가는 각도만 지정해주고,

시곗바늘이 초마다 움직이도록 웹페이지를 갱신해줘야하기 때문에 setInterval로 setDate함수를 1초마다 재실행하도록 코드를 입력한다. 여기서 각 시곗바늘 각도 변수에 +90을 해주지 않으면 시곗바늘이 12시방향이 아닌 9시방향을 기준으로 돌아가기때문에 꼭 각도에 90을 더해줘야한다.

이것으로 Wes Bos의 Day2 챌린지는 끝이다.

 

😏 내가 추가한 코드

위의 코드로만 코딩을 하면 몇 가지 문제점이 남는다.

 1) 웹페이지에 들어가면 시곗바늘이 처음에 이상한 위치에 가있다가 제자리를 찾는다

 2) 초침이 59초까지 간 뒤 0초를 가리키기 직전에 갑자기 한순간 훼까닥 하고 이상한 곳을 가리키다 제자리를 찾아간다.

 3) 저 시계만으로는 정확한 시간을 알 수가 없다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function setDate() {
    const now = new Date();
 
    const hours = now.getHours();
    const hoursDegrees = ((hours / 12* 360+ 90;
    if (hoursDegrees === 90) {
        hourHand.style.transition = 'all 0.001s';
        hourHand.style.transform = `rotate(${hoursDegrees}deg)`
    } else {
        hourHand.style.transform = `rotate(${hoursDegrees}deg)`;
    };
 
    const minutes = now.getMinutes();
    const minutesDegrees = ((minutes / 60* 360+ 90;
    if (minutesDegrees === 90) {
        minuteHand.style.transition = 'all 0.001s';
        minuteHand.style.transform = `rotate(${minutesDegrees}deg)`
    } else {
        minuteHand.style.transform = `rotate(${minutesDegrees}deg)`;
    };
 
    const seconds = now.getSeconds();
    const secondsDegrees = ((seconds / 60* 360+ 90;
    if (secondsDegrees === 90) {
        secondHand.style.transition = 'all 0.001s';
        secondHand.style.transform = `rotate(${secondsDegrees}deg)`
    } else {
        secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
    };
};
 
setDate();
setInterval(setDate, 1000);
 
 

챌린지 자바스크립트 코드를 위와 같이 수정하여 문제점 1)과 2)를 한번에 해결했다.

 

👌 문제점 1)은 setInterval이 웹페이지가 로드된 시점에서는 발동을 하지않기 때문에, 먼저 웹페이지가 로드됐을 때 바로 시간이 표시 될 수 있도록 setDate함수를 한번 실행해 주고 그 뒤엔 알아서 setInterval 함수가 쭉 갱신을 해 의도된대로 작동하도록 하였다.

 

👌문제점 2)는 Line 7, 16, 25에 있는 각 시곗바늘.style.transition 재설정 코드로 해결할 수 있었다. 바늘이 59초를 가리킬땐 각도가 444deg까지 갔다가 0초가 되는 순간 450deg가 아니라 90deg로 되면서 반시계방향으로 훅 움직이는데, 애니메이션 소요시간이 0.05s로 설정돼있었기 때문에 벌어진 일이었다.

엄청나게 빠르면 잔상마저 보이지 않게 될 것이다.

그래서 시곗바늘의 transform각도가 90deg가 될때만 transition 시간 설정을 0.001s로 바꿔주니 문제가 해결되었다.

 

👌문제점 3)은 다음의 코드를 추가하는 걸로 해결했다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function digitClock() {
    const now = new Date();
    const hours = now.getHours();
    const minutes = now.getMinutes();
    const seconds = now.getSeconds();
 
    const digitFace = document.querySelector('.digit-clock');
    const newH = hours >= 10 ? hours : `0${hours}`;
    const newM = minutes >= 10 ? minutes : `0${minutes}`;
    const newS = seconds >= 10 ? seconds : `0${seconds}`;
    digitFace.innerHTML = `${newH} : ${newM} : ${newS}`;
};
 
digitClock();
setInterval(digitClock, 1000);
Colored by Color Scripter
 
 

새로 div엘리먼트를 하나 추가한 뒤 innerHTML로 시간을 기입하는 방식으로 했다. 

Line 7,8,9로 각 시, 분, 초를 구할 때 만약 10보다 작을경우 앞에 0을 붙여서 무조건 두자리수로 표기될 수 있도록 조건식을 걸어줬다.

 

setDate함수와 마찬가지로 마지막엔 웹페이지 로드 시 표기가 되어있지 않거나 하는 일을 방지하기 위해 함수를 한번 실행해준 뒤 setInterval로 계속 갱신해주도록 했다.

 

😂 아쉬운 점

시침, 분침, 초침의 길이를 각각 다르게해서 좀 더 알아보기 쉽도록 하고싶었으나

각 시곗바늘의 width를 조정하면 이상한방향으로 줄어들어서 결국 구현해내지 못했다.

CSS를 좀 더 공부해서 나중에라도 구현해낼 수 있도록 해야겠다.

'Programming Language > JavaScript' 카테고리의 다른 글

30 JavaScript Day 4 - Array Cardio  (0) 2020.03.23
30 JavaScript Day 3 - Playing with CSS & JS  (0) 2020.03.23
30 JavaScript Day 1 - Drum Kit  (0) 2020.03.15
What is this?  (0) 2020.02.23
ReactJS로 게임만들기  (0) 2020.02.23
공지사항
최근에 올라온 글