-
CSS + JS Clock ⏱Web/JS30 2020. 9. 20. 01:13반응형
CSS와 JS를 이용해서 움직이는 시계를 만들어보는 예제이다.
역시나 크게 복잡하지 않은, 시간에 맞춰서 시침, 분침, 초침을 움직이기만 하면 되는 예제이다.
transform과 transition에 관한 공부였다.
우선은 CSS에 관한 내용부터.

일단은 초기 세팅을 이렇게 해놨는데, 초침을 회전시켜보면 다음과 같이 회전된다.

이는 transform origin이 요소의 정중앙으로 설정되어있기 때문인데,
사실 대부분의 경우에는 회전이던 이동이던 중심이 정중앙이어야 하는 경우가 많다.
하지만 이 예제의 경우에는 시계의 초침을 만들어야 하기 때문에, 회전의 중심이 끝으로 가야 한다.
그래서, transform-origin이라는 속성을 이용해줘서 회전 중심을 이동시켜준다.
default 값은 50%이지만 100%로 수정해준다.
transform-origin : 100%;그리고, 시계는 항상 12시 방향이 default니까 각도도 돌려주자.
transform : rotate(90deg);그 다음, 자연스러운 시계 이동을 위해 다음와 같은 성질을 사용한다.
transition : all 0.05s; transition-timing-function : cubic-bezier(0.1, 2.7, 0.58, 1);transition-timing-function이라는 성질을 처음 알았다.
근데 값들을 보니 ease-in, ease-out 같은 익숙한 값이더라.
그냥 transition에 붙여 쓰기만 했는데 이번에 이름을 처음 알게 됐네.
그리고 cubic-bezier라는 값을 쓸 수 있다는 것을 처음 알았다.
말 그대로 transition이 변하는 정도를 베지어 곡선을 이용해서 설정해주는데,
시계 초침이 움직일 때 째깍하면서 좌우로 흔들리는 움직임을 흉내내기위해 베지어 곡선을 사용해준 것이다.

잘 안보이긴 하는데, 초침이 움직일 때마다 좌우로 흔들리는 모습을 확인할 수 있다. 아주 자세히 보면.
사실 베지어 곡선은 네 점의 값을 직접 입력해주는 것보다는 위의 GIF에서 보이는 것처럼
개발자 도구의 elements탭에서 cubic-bezier 앞의 네모를 클릭해주면 직접 곡선 모양을 제어하면서 값을 바꿀 수 있다.
여러 모로 transition에 관해 새로 배운 점이 많은 듯.
자바스크립트 코드는 대부분 내장객체인 Date에 관한 내용이다.
시간에 따라 각도를 계산해주는 공식 말고는 딱히 새로 배운 내용은 없는 듯.
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 minutes = now.getMinutes(); const hours = now.getHours(); const secondsDegrees = (seconds / 60) * 360 + 90; secondHand.style.transform = `rotate(${secondsDegrees}deg)`; const minutesDegrees = (minutes / 60) * 360 + 90; minuteHand.style.transform = `rotate(${minutesDegrees}deg)`; const hoursDegrees = (hours / 12) * 360 + 90; hourHand.style.transform = `rotate(${hoursDegrees}deg)`; } setInterval(setDate, 1000);시침, 분침, 초침을 각각 가져와서 현재 시각의 시, 분, 초 만큼 돌아가게끔 공식을 적용해주면 된다.
참고로, degrees를 구할 때 맨 마지막에 90을 더해주는 이유는, 위에서 봤듯이
처음에 세팅된 각도와 12시의 각도가 90도만큼 차이가 나기 때문.
(아까 CSS로 지정해줬던 건 사실 쓸모없어졌다. 여기서 rotate를 다시 설정해주면 그 CSS코드는 무시되더라.)
이렇게 하면 끝난 것 같지만, 사실 문제가 하나 있다.
seconds나 minutes가 60이 되면, 0으로 다시 돌아가면서 생기는 문제인데
분침, 초침이 다시 0일 때의 각도로 돌아가기 위해 -360도만큼 휙 돌아가버린다는 것.
이 문제를 해결해주기 위해서는
CSS 코드에서 transition : all 0.05s를 없애주고, 나중에 추가해주거나
자바스크립트 공식을 약간 수정해주는 방법이 있다고 한다.
근데, 방법이 있다고 해놓고 말을 안해주고 강의가 끝나버렸다...;
그래서 내가 임시 방편으로 해 놓은 건 다음과 같다.
const secondHand = document.querySelector('.second-hand'); const minuteHand = document.querySelector('.min-hand'); const hourHand = document.querySelector('.hour-hand'); let secondCount = 0; let minuteCount = 0; function setDate() { const now = new Date(); const seconds = now.getSeconds(); const minutes = now.getMinutes(); const hours = now.getHours(); if(seconds === 0) secondCount += 60; if(minutes === 0) minuteCount += 60; const secondsDegrees = ((secondCount + seconds) / 60) * 360 + 90; secondHand.style.transform = `rotate(${secondsDegrees}deg)`; const minutesDegrees = ((minuteCount + minutes) / 60) * 360 + 90; minuteHand.style.transform = `rotate(${minutesDegrees}deg)`; const hoursDegrees = ((hourCount + hours) / 12) * 360 + 90; hourHand.style.transform = `rotate(${hoursDegrees}deg)`; } setInterval(setDate, 1000);60이 채워질 때마다 0으로 가게 하지 않고 61, 62, 63, ... 이렇게 다음 숫자로 커지게 한 것.
그러면 각도도 360, 366, 372, ... 이렇게 가면서 초침이 휙 돌아가는 건 고쳐진다.
문제는 분침과 시침은 어떻게 해야할 지를 잘 모르겠다.
분침과 시침은 초침이 60만큼 돌 때까지 0시 혹은 0분에 머무를 수가 있기 때문.
그러면 그 때는 저 0일때 60씩 더해주는 코드가 1초마다 작동하면서
1초에 한 번씩 분침과 시침이 휙휙휙 돌아간다.
이건 고민을 좀 해봐야 할 문제인 듯..
반응형'Web > JS30' 카테고리의 다른 글
Type Ahead ⌨ (0) 2020.09.25 Flex Panel Gallery 🎫 (0) 2020.09.21 Array Cardio Day 1 🎈 (0) 2020.09.21 Update CSS variables with JS 🎨 (0) 2020.09.20 🥁 JS Drum Kit 🥁 (0) 2020.09.18