[HTML, CSS, JS] 디지털 시계 만들기 (feat. 알람)

소고기는레어·2022년 1월 18일
9

Project 🗂

목록 보기
13/15
post-thumbnail

https://clockbyrarebeef.netlify.app/

언제부터인가 실용적이고 보편적인 웹사이트를 제작하는 것 보다 이전에 만든 3D 정육면체나 이번에 만든 시계처럼 실용성은 없지만 재밌는 것을 만들고 싶다는 생각이 계속 든다. 좀 더 정상적인 웹사이트도 만들어 봐야하지 않겠냐는 생각도 들지만 아직 난 이쪽이 더 재밌게 느껴진다.

그래서 만들었다. 리퀴드 크리스탈 폰트를 사용한 디지털 시계를 만들었는데, 시계를 보던 중 문득 직접 만들어보면 재밌겠다는 생각이 들었기 때문이다.

참고로 리퀴드 크리스탈 폰트는 위 이미지의 폰트처럼 여러개의 막대로 이루어진 폰트를 말한다.

보통의 디지털 시계는 시간을 출력하는 기능 외에 알람, 스톱워치, 타이머 등의 기능도 갖고 있는데, 이 중 알람 기능을 내 시계에 탑재해 보았다.


시계 외형 구현

심플한 탁상 시계를 컨셉으로 잡고 가로로 긴 직사각형 디자인을 채택했다. 가장 보편적인 디자인이기도 하다.

시계의 액정은 요일 부분, 날짜 부분, 시간 부분으로 구성되어 있다.
시계탭 & 알람탭 간의 이동과 알람 시간 설정 등을 조작할 수 있도록 시계 상단에 버튼을 배치하였다. 버튼들은 상황에 맞게 튀어나오고 들어간다.

실제 디지털 시계의 숫자를 보면 불이 들어와 있지 않은 막대도 연하게 구분이 되는 것을 볼 수 있는데, 이를 표현하기 위해 날짜와 시간은 각각 회색의 "8888 / 88 / 88" 과 "88:88:88" 텍스트를 뒤에 깔아두었다.
요일의 경우는 텍스트를 따로 깔지 않고 해당하는 요일만 색상을 빨간색으로 변하도록 하였다.

날짜의 좌측을 보면 희미하게 "ON" 이라고 적혀있는데, 알람이 활성화 될 경우 녹색으로 불이 들어오는 부분이다.


시계 기능 구현


이번 프로젝트에서 가장 중요한 부분이다. 당연하다.

요일, 날짜, 시간은 Date 객체를 통해 불러왔다.

const date = new Date();

// 시간 0~23
date.getHours();
// 분 0~59
date.getMinutes();
// 초 0~59
date.getSeconds();
// 연도 4자리
date.getFullYear();
// 월 0~11, 값에 +1하면 현재 월
date.getMonth();
// 일 1~31
date.getDate();
// 요일 0~6, 0은 일요일 6은 토요일
date.getDay();

Date 객체에서 불러오는 날짜와 시간은 number 타입이다.
만약 오전 1시일 경우 "01"이 아닌 1 한자리로 출력된다. 그대로 디지털 시계에 적용하기엔 부적절하므로 값이 한자리일 경우 앞에 "0" 을 붙여서 출력하도록 하였다.

시간은 setInterval 을 통해 100ms 간격으로 업데이트 된다.
프로젝트 초기에 ms도 표기하기 위해 간격을 100ms로 설정 했었다. 현재는 수정하여 가장 작은 표기 단위가 1s지만 최소한의 오차로 초를 업데이트 하기 위해 100ms를 유지하였다.


알람 기능 구현

위에서 설명한 시계 기능이 100ms 간격으로 시간을 업데이트할 때 알람은 같은 간격으로 현재 시간과 알람 시간을 비교한다.

비교가 일치하면 시계가 좌우로 진동하며 알람음이 울린다.
또한 "STOP" 버튼이 위로 올라오는데, 이를 클릭하면 알람이 종료된다.

알람 사운드의 출처는 여기


버튼 기능 구현

"DATE" 버튼과 "ALARM" 버튼은 시계의 각 기능탭으로 이동하는 버튼이다. 현재 활성화 된 탭의 버튼은 밑으로 들어가고 비활성화 된 탭의 버튼은 위로 튀어나온다.

"PREV","SELECT", "NEXT" 버튼은 알람을 제어하기 위한 버튼이다. 이들을 통해 ON/시/분/초 항목을 지정하고 제어할 수 있다.

최초 로드 시 알람은 비활성화 상태이며 알람탭에서 "SELECT" 버튼으로 ON을 작동시켜 알람을 활성화할 수 있다. 활성화시 ON 텍스트에 초록불이 들어온다.

이후 "PREV", "NEXT", "SELECT" 버튼을 클릭하여 시/분/초를 지정하고 입력하여 알람 시간을 지정할 수 있다.

시/분/초 부분을 직접 마우스로 클릭하여 값을 입력할 수 없도록 하였다. 진짜 디지털 시계를 다루는 느낌을 주기 위해 오직 버튼으로만 조작이 가능하도록 만들었다. 다만 조금의 편의성을 위해 시간 입력은 키보드를 통해 이뤄질 수 있도록 하였다.

"STOP" 버튼은 알람이 울리면 위로 튀어나오며 클릭 시 알람이 종료된다.


favicon & logo

일러스트레이터로 대충 제작하였다.
날짜와 시간에 딱히 의미는 없다. 로고를 만들기 위해 시계를 캡쳐한 당시의 날짜와 시간일 뿐이다.

favicon

logo (512x512)


기타

스톱워치 기능도 제작했었으나 결국 삭제하였다.

스톱워치는 ms 표기도 지원하는 것이 일반적이다. 여기서 문제가 발생했는데 setInterval 간격마다 ms를 더하여 계산할 경우 과부하가 걸리는지 실제 시간보다 느리게 흘렀고,
ms를 Date 객체에서 불러와서 동기화할 경우 이 ms는 현재 시간을 나타내는 것이기 때문에 스톱워치가 0ms 에서 시작하지 않는다는 문제가 발생했다.

이 외에도 여러 방법들을 시도해봤지만 아직 배울게 많은 탓에 전부 문제가 발생했고 결국 스톱워치는 빼는 쪽으로 방향을 수정하였다.


그 외 딱히 문제가 발생한 부분은 없었지만 스타일이나 버튼 기능 등도 더 좋은 방법이 생각나 여러 차례 개선하면서 크고 작은 곳에서 여러차례 변화가 있었고, 그에 맞춰 코드의 수정도 존재했다.

수정을 거듭할수록 코드가 난잡해졌다. 애초에 블로그 글 작성이나 배포 목적으로 시작한 프로젝트도 아니었고 test 폴더에 생성해 시작한 심심풀이용 프로젝트였기 때문에 계획 단계부터 체계적으로 코딩을 시작하지 않았었다. React App 주제에 모듈화 안되어 있는 것도 이 이유에서다.

따라서 빌드 버전은 난독화를 적용했다. 사실 난독화 안거쳐도 이미 난독이긴 하지만 아닌 척 하고 싶었다. 공개하기 부끄럽지만 난독화 안된 코드는 github에 업로드 하였다. 다음 프로젝트 때는 꼭 클린 코드를 실천해 봐야지.

profile
https://www.rarebeef.co.kr/

1개의 댓글

comment-user-thumbnail
2022년 1월 25일

아침에 이거듣고 일어나볼게요,,(?) 넘멋집니당

답글 달기