Dandy Now!
  • [Vue.js] 카운트다운 서클 타이머 버튼 만들기
    2024년 10월 04일 11시 39분 09초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    1. 네이버 지도의 카운트다운 서클 타이머 버튼

    모니터링 서비스에 사용자가 새로고침 버튼을 클릭하지 않아도 일정 시간이 지나면 자동으로 최신의 정보를 서버에서 받아와 리렌더링 하는 기능이 필요했고, [그림 1]과 같은 네이버 지도앱의 카운트다운 서클 타이머 버튼이 적당해 보였다.

     

    [그림 1] 네이버 지도앱의 카운트다운 서클 타이머 버튼

     

    2. Vue.js용 컴포넌트 제작 및 적용

    [그림 2]는 Vue.js용으로 만든 카운트다운 서클 타이머 버튼 컴포넌트를 적용한 사례이다. 시간은 15초부터 시작하고 0초가 되면 refresh 아이콘이 시계방향으로 회전한 후 초기화된다.

    [그림 2] 완성하여 적용한 사례

     

    0초가 되거나 버튼을 클릭하면 $emmit에 의해 부모 컴포넌트의 함수를 호출한다. 부모 컴포넌트의 함수에는 서버에 get 요청하는 코드를 적용할 수 있다. 아래 코드는 부모 코드에서 사용한 사례이다.

    <CountDownTimmerButton @count-button-event="getAlarmList" />

     

    컴포넌트 전체 코드(CountDownTimmerButton.vue)는 아래와 같다.

    <template>
      <button @click="rotateIcon" class="icon-button">
        <div
          class="icon-container"
          :style="{ transform: `rotate(${rotateDeg}deg)` }"
        >
          <span class="counter-number" v-show="clickedCounterNumber">{{
            number
          }}</span>
        </div>
      </button>
    </template>
    <script>
    export default {
      data() {
        return {
          number: 15, // 카운트다운 15초로 설정
          rotateDeg: 0,
          clickedCounterNumber: true
        }
      },
      watch: {
        number() {
          if (this.number === 0) {
            this.rotateIcon()
            this.number = 16 // transform 1s 감안하였음
            this.$emit('count-button-event')
          }
        }
      },
      mounted() {
        setInterval(() => {
          this.number -= 1
        }, 1000)
      },
      methods: {
        rotateIcon() {
          this.clickedCounterNumber = false
          this.rotateDeg += 360
          setTimeout(() => (this.clickedCounterNumber = true), 1000)
          this.number = 16
          this.$emit('count-button-event')
        }
      }
    }
    </script>
    <style scoped lang="scss">
    button:hover {
      background-color: transparent !important;
    }
    
    .icon-button {
      background: none;
      border: none;
      padding: 0;
      cursor: pointer;
      background-color: none;
    }
    
    .icon-container {
      width: 32px;
      height: 32px;
      background-image: url('@/assets/svg/refresh.svg');
      background-size: cover;
      background-position: center;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      transition: transform 1s cubic-bezier(0.5, 0, 0.1, 1);
    }
    
    .counter-number {
      position: absolute;
      font-size: 8px;
      font-weight: bold;
      color: #fff;
    }
    </style>

     


    NPM에 React.js용 서클 타이머가 있었다.

    참고: https://www.npmjs.com/package/react-countdown-circle-timer


    2024-10-07 추가

    rotateDeg 값이 회전할 때마다 360이라는 값이 무한히 누적되어 성능에 영향을 주지 않을까하는 생각이 들었다. 결론적으로 "브라우저는 이 정도의 transform 계산을 성능에 문제없이 처리할 수 있으니, 성능 걱정 없이 진행해도 된다"고 한다.

    728x90
    반응형
    댓글