[Javascript 30] 2. Js-Clock

tino-kim·2022년 3월 6일
0
post-thumbnail

💗 [Javascript 30] 2. Js-Clock

✔ 레이아웃 짜기.

또 flex-box를 이용해서 가운데로 옮기고, 시계 모양을 만들어줄 예정이다. 구조 짤 때에는 flex-box가 진짜 좋은 것 같다. 위치 지정하기도 굉장히 편리하고, 여러모로 마음에 든다.

✔ HTML 코드 작성하기.

HTML 코드는 간단하다.

  • clock : clock의 모양을 만들어줘야 하기 때문이다.
  • clock-face: 얼굴에 시, 분, 초를 표기해야 하기 때문이다.
  • hand: 시, 분, 초를 나타내준다. 여기서 이제 시간이 흐르면 움직이도록 이벤트를 설정해줘야 할 것이다.
<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>[Javascript30] Js-Clock</title>
    <link rel="stylesheet" href="style jsClock.css" />
  </head>
  <body>
    <div class="clock">
      <div class="clock-face">
        <div class="hand hour-hand"></div>
        <div class="hand min-hand"></div>
        <div class="hand second-hand"></div>
      </div>
    </div>
    <script src="app jsClock.js"></script>
  </body>
</html>

✔ CSS 스타일 지정하기.

  1. 시계 모양을 만들어야한다.
  2. 시계 얼굴에 시침, 분침, 초침을 모두 만들어야 한다.
  3. 그것들을 돌려봤을 때, 시계가 돌아가는 모양처럼 만들어야 한다.
    (transform-origin 이용하기.)
  4. 시침, 분침, 초침이 12시부터 시작하도록 만들어야 한다. 그것을 기준으로 각도를 생각하기 때문이다. 우리의 시계 모양을 생각하면 된다.

🤚 꼭 집고 넘어가야 하는 부분

  • position: relative VS absolute
    시침, 분침, 초침은 absolute로 지정하고, 나머지 부분은 relative로 지정하였다. 기존의 문서의 css흐름이 달라지면 absolute를 사용하는 것은 알고 있는데, "정확하게" 이유는 잘 모르겠다.

  • transform: translateY(-3px)
    이거는 진짜 왜 지정하는지 모르겠다. 3차원에서 y축 왼쪽으로 3px만큼 이동한다는 의미인데, 강의를 들으면서 확인해야겠다.

💙 신기하다고 느낀 부분

  1. class가 hand 부분을 background를 이용해서 선으로 만들어주었다.
    width와 height를 원하는 만큼 지정해서 선의 길이와 굵기를 지정해주었다.

  2. clock-face 부분을 width와 height를 100%로 지정하여 모든 영역을 사용하도록 만들어주었다.

  3. transition을 이용해서 시계가 틱톡틱톡 움직이는 느낌을 만들어준 것이 신기하다.

  • transform: 단순하게 변형을 주고 싶은 경우에 이용한다.
  • transition: 시간에 따라 스타일을 변형해주고 싶은 경우에 이용한다.

그래서 12시 방향으로 맞춰줄 때에는 transform: rotate(deg)를 이용했고, 빠르게 움직이게 만들어서 시계가 틱톡거리는 부분을 생성하기 위해 transition + transition-timing-function을 이용해서 cubic-bezier를 넣어주었다.

🤚 좀 아쉬운 부분...
transform-origin을 잘 이해하지 못해서, 시침 분침 초침의 길이를 줄이지 못하였다. 그래서 그냥 색깔만 다르게 지정하였다.

@import "reset.css";

html {
  background: no-repeat url("ocean.jpg");
  background-size: cover;
}

body {
  display: flex;
  flex-direction: row;
  justify-content: center;
  height: 100vh;
  align-items: center;
}

.clock {
  /* clock에서 시계 모양을 만들어준다. */
  width: 400px;
  height: 400px;
  border: 20px solid white;
  border-radius: 50%;
  position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
    inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}

/*  0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
    inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2); 그럴 듯하게 시계에 입체감을 줄 수 있다. */

.clock-face {
  /* 시침, 분침, 초침을 이 영역에서 움직일 수 있도록 조정시켜준다. */
  width: 100%;
  height: 100%;
  position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
  transform: translateY(-3px); /* account for the height of the clock hands */
}

.hand {
  width: 50%;
  height: 6px;
  background: rgb(252, 117, 252);
  position: absolute; /* 기존의 문서 흐름대로 가지 않기 때문이다. 계속 시침, 분침, 초침은 움직여야 하기 때문이다. */
  top: 50%;
}

✔ Javascript 코드 작성하기.

(목표) 현재 시각을 구해서 시, 분, 초로 나누어준다. 그렇게 한 다음 1초에 한번씩 함수가 돌아가도록 제작하고, css style을 주기 위해서(시침, 분침, 초침이 돌아가야 하기 때문이다.) degree를 계산한다.
그 각도에 맞게 html에서 시침, 분침, 초침을 가르키는 객체를 불러와서 돌아가도록 제작하면 된다.

(각도 구하는 팁)

  • 초침
    1초마다 바뀐다. 1초 ~ 60초까지 있기 때문에, "(초/60)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
    "(초/60)*360+90"으로 해줘야한다.

  • 분침
    1분 ~ 60분까지 있기 때문에, "(분/60)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
    "(분/60)*360+90"으로 해줘야한다.

  • 시침
    1시 ~ 12시까지 있기 때문에, "(시/12)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
    "(시/12)*360+90"으로 해줘야한다.

(문제점)
처음 새로고침을 하면, 원래 css가 1초정도 보여진다. 그래서 init() 함수로 setDate() 함수를 감싸고, init() 함수를 불러오자. 그러면 바로 date를 구해주기 때문에 바로 지금 시간을 시계에 보여줄 수 있다.

const secondHand = document.querySelector(".second-hand");
// console.log(secondHand);
const minuteHand = document.querySelector(".min-hand");
const hourHand = document.querySelector(".hour-hand");

function setDate() {
  const date = new Date();
  // console.log(date);
  const second = date.getSeconds();
  // console.log(second);
  const secondDegree = (second / 60) * 360 + 90; // 여기 살짝 주의하기. 아까 12시 방향으로 맞추기 위해서 90도 돌려놓았기 때문에 + 90deg을 해줘야한다.
  // console.log(secondDegree);
  secondHand.style.transform = `rotate(${secondDegree}deg)`;
  // console.log(second);

  const minute = date.getMinutes();
  // console.log(minute);
  const minuteDegree = (minute / 60) * 360 + 90;
  minuteHand.style.transform = `rotate(${minuteDegree}deg)`;

  const hour = date.getHours();
  // console.log(hour);
  const hourDegree = (hour / 12) * 360 + 90;
  hourHand.style.transform = `rotate(${hourDegree}deg)`;
}

setInterval(setDate, 1000); // 1초에 setDate 1번씩 갱신시키기.

function init() {
  setDate();
}

setDate();

😡 아쉬운 점...

시침, 분침, 초침의 길이를 조정하고 싶은데 잘 안되었다. 조정하는 순간, 원점에 놓이질 않게 되어서 할 수가 없었다. 나중에 꼭 해결하고 싶다.

✔ 최종 코드

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>[Javascript30] Js-Clock</title>
    <link rel="stylesheet" href="style jsClock.css" />
  </head>
  <body>
    <div class="clock">
      <div class="clock-face">
        <div class="hand hour-hand"></div>
        <div class="hand min-hand"></div>
        <div class="hand second-hand"></div>
      </div>
    </div>
    <script src="app jsClock.js"></script>
  </body>
</html>
@import "reset.css";

html {
  background: no-repeat url("ocean.jpg");
  background-size: cover;
}

body {
  display: flex;
  flex-direction: row;
  justify-content: center;
  height: 100vh;
  align-items: center;
}

.clock {
  /* clock에서 시계 모양을 만들어준다. */
  width: 400px;
  height: 400px;
  border: 20px solid white;
  border-radius: 50%;
  position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
    inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}

/*  0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
    inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2); 그럴 듯하게 시계에 입체감을 줄 수 있다. */

.clock-face {
  /* 시침, 분침, 초침을 이 영역에서 움직일 수 있도록 조정시켜준다. */
  width: 100%;
  height: 100%;
  position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
  transform: translateY(-3px); /* account for the height of the clock hands */
  /* 이 부분은 왜 있는지 잘 모르겠다. */
}

.hand {
  width: 50%;
  height: 6px;
  background: rgb(252, 117, 252);
  position: absolute; /* 기존의 문서 흐름대로 가지 않기 때문이다. 계속 시침, 분침, 초침은 움직여야 하기 때문이다. */
  top: 50%;
  transform-origin: 100%;
  transform: rotate(90deg);
  /* 시간이 흐름에 따라서 효과를 주고 싶은 경우에 transition 이용하기. */
  /* 시계가 틱톡틱톡 움직이는 효과를 줄 수 있다. - cubic-bezier 이용함으로서 */
  transition: all 0.05s;
  transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
}

.second-hand {
  background-color: yellowgreen;
}

.min-hand {
  background-color: rgb(64, 64, 255);
}
const secondHand = document.querySelector(".second-hand");
// console.log(secondHand);
const minuteHand = document.querySelector(".min-hand");
const hourHand = document.querySelector(".hour-hand");

function setDate() {
  const date = new Date();
  // console.log(date);
  const second = date.getSeconds();
  // console.log(second);
  const secondDegree = (second / 60) * 360 + 90; // 여기 살짝 주의하기. 아까 12시 방향으로 맞추기 위해서 90도 돌려놓았기 때문에 + 90deg을 해줘야한다.
  // console.log(secondDegree);
  secondHand.style.transform = `rotate(${secondDegree}deg)`;
  // console.log(second);

  const minute = date.getMinutes();
  // console.log(minute);
  const minuteDegree = (minute / 60) * 360 + 90;
  minuteHand.style.transform = `rotate(${minuteDegree}deg)`;

  const hour = date.getHours();
  // console.log(hour);
  const hourDegree = (hour / 12) * 360 + 90;
  hourHand.style.transform = `rotate(${hourDegree}deg)`;
}

setInterval(setDate, 1000); // 1초에 setDate 1번씩 갱신시키기.

function init() {
  setDate();
}

init();

📢 Digital Clock VS Analog Clock

일단 작동 원리는 비슷하다. 그리고 쓰는 메소드와 함수는 동일하다.
조금은 다른 점은 있었지만, 그래도 어느 정도 비슷한 결로 제작되었다.

  • (Digital Clock) 하지만, 디지털 시계에서는 각도를 고려해서 바늘이 돌아갈 수 있도록 만들어야 했다. 바늘이 돌아가게 만들기 위해서 style.transform = rotate(deg) 를 이용했다. 단순한 변형은 transform이 좋다. 그리고 바늘의 위치를 가운데 맞추기 위해서 transfrom-origin 또한 이용하였다.

  • (Analog Clock) 아날로그 시계에서는 10보다 작은 수 앞에 0을 붙여서 깔끔하게 돌아가도록 만들어야 한다. 텍스트 내용을 바꿔야 하기 때문에 innerText를 이용해주었다.

profile
알고리즘과 웹 개발을 공부하는 대학생

0개의 댓글