본문 바로가기
DEV/JS30

[JS30] day 2 - CSS Clock

by newjp 2021. 12. 6.

HTML / CSS

<div class="digit-clock"></div>

<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>
@font-face {
    font-family: 'LAB디지털';
    src: url('<https://cdn.jsdelivr.net/gh/projectnoonnu/noonfonts_20-07@1.0/LAB디지털.woff>') format('woff');
    font-weight: normal;
    font-style: normal;
    }
    html {
      background: #121212 url(<https://img1.daumcdn.net/thumb/R1280x0.fjpg/?fname=http://t1.daumcdn.net/brunch/service/guest/image/lAkK4-zh0l5z2fJtJUMizoReHk0.JPG>);
      background-size: cover;
      font-family: 'helvetica neue';
      text-align: center;
      font-size: 10px;
    }

    body {
      margin: 0;
      font-size: 2rem;
      display: flex;
      flex: 1;
      min-height: 100vh;
      align-items: center;
    }

    .clock {
      width: 30rem;
      height: 30rem;
      border: 1px solid rgba(255, 255, 255, 0.125);
      /* border: 20px solid white; */
      backdrop-filter: blur(25px);
      background-color: rgba(255, 255, 255, .13);
      border-radius: 50%;
      margin: 50px auto;
      position: relative;
      padding: 3rem;
    }

    .clock-face {
      position: relative;
      width: 100%;
      height: 100%;
      transform: translateY(-3px); /* account for the height of the clock hands */
      border-radius: 50%;
    }

    .hand {
      width: 50%;
      height: 6px;
      background: black;
      position: absolute;
      top: 50%;
      transform-origin: 100%;
      transform: rotate(90deg);
      transition: all 0.05s;
      transition-timing-function: cubic-bezier(0, 1.11, 0.51, 1.13);
    }
    .hour-hand {
      width: 45%;
      left: 5%;
    }

    .second-hand {
      height: 2px;
      background: grey;
      z-index: -1;
    }

    .digit-clock {
      font-family: 'LAB디지털';
      position: absolute;
      top: 12rem;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 300px;
      height: 100px;
      border: 1px solid rgba(255, 255, 255, 0.125);
      border-radius: 20px;
      backdrop-filter: blur(25px);
      background-color: rgba(255, 255, 255, .13);
      line-height: 100px;
      font-size: 2.6em;
    }
  • transition-timing-function 기본으로 ease-in, ease-out, ease-in-out 등이 있지만 더 섬세하게 동작을 정할수 있는 cubic-bezier를 사용해 초침의 움직임을 흉내냄
  • cubic-bezier transition, transition-fiming-function에 사용하는 그래프, 효과의 시작과 끝 시간을 달리하여 다양한 효과를 만들 게 해줌 bezier 그래프는 👉 https://matthewlein.com/tools/ceaser 에서 만들어보거나 개발자 도구에서 설정 해 볼 수 있다
  • backdrop-filter filter가 나 자체에 filter를 주는 효과라면 backdrop-filter는 배경에 filter를 주는 것
  • transform-origin transform의 중심축을 바꿔 줌, 설정하지 않으면 보통 모든 요소의 중심축은 정 가운데 이기 때문 아날로그 시계를 구현하기 위해서는 시침, 분침 등이 원의 중심부터 돌게 구현해야 하는데 만약 transform-origin을 주지 않았다면 제자리에서 뱅글뱅글 돌아버린다..!
    👇 기본 위치는 원의 왼 편 이었으니 오른쪽 끝으로 중심축을 옮겨주면 된다

<script>
    const digitClock = document.querySelector('.digit-clock')

    const secondHand = document.querySelector('.second-hand')
    const minsHand = document.querySelector('.min-hand')
    const hourHand = document.querySelector('.hour-hand')
    
    function setDate() {
      const now = new Date();
      const seconds = now.getSeconds();
      const secondsDegrees = ((seconds /60) *360 + 90);

      const mins = now.getMinutes();
      const minsDegrees = ((mins /60) *360 + 90);

      const hours = now.getHours();
      const hoursDegrees = ((hours /60) *360 + 90);
      
      secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
      minsHand.style.transform = `rotate(${minsDegrees}deg)`;
      hourHand.style.transform = `rotate(${hoursDegrees}deg)`;
      // console.log(seconds)
      digitClock.innerText = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`
    }
    
    setInterval(setDate, 1000);
  </script>
  • setInterval() 일정한 간격으로 작업을 수행하기 위해서 사용 ****n초마다 실행할 함수와, n초가 들어간다. 초는 밀리 초 단위로 1000 == 1 이번 과제에서는 1초마다 시계를 갱신해 주어야 하므로 사용한다

[ 문제점 ]

시간이 0초가 되면, CSS에서 0→90도로 바꿔주는 기본 값 설정 때문에 이마저도 transition이 되어 침이 주춤거리게 보이는 효과가 발생한다 이를 고치기 위해서는

  1. deg count를 계속 올리거나
  2. JS에게 60초가 되면 잠깐 transition을 멈추라고 해줘야 함 HTML / CSS

'DEV > JS30' 카테고리의 다른 글

[JS30] day 5 - Flex panels image gallery  (0) 2021.12.09
[JS30] day 4 - Array cadio day 1  (0) 2021.12.09
[JS30] day 3 - playing with CSS variables and JS  (0) 2021.12.07
[JS30] day 1 - drumkit  (0) 2021.12.05
Javascript 30-course 끝!  (0) 2021.12.04