[Vue.js] Vue 애니메이션(Animate) #2 - Javascript Hooks, Velocity

하수도키

·

2021. 4. 19. 00:01

728x90
반응형
SMALL
  • 이번 포스팅은 Vue 애니메이션에 대해 알아보자.
  • 애니메이션을 이용해 사용자 경험을 향상할 수 있다.
    • 버튼 같은 곳에 마우스 호버 상태 일 때 클릭률을 높이거나
    • 강조해야 되는 문구, 영역 등에 애니메이션을 적용해 집중력을 높일 수 있다.

목차

  1. Transition
    1. Page Transition
    2. Transition Group
  2. Javascript Hooks + Velocity(이번 포스팅)
  3. GSAP

2021.04.11 - [개발일기/Vue.js] - [Vue.js] Vue 애니메이션(Animate) #1 - Transition

 

[Vue.js] Vue 애니메이션(Animate) #1 - Transition

이번 포스팅은 Vue 애니메이션에 대해 알아보자. 애니메이션을 이용해 사용자 경험을 향상할 수 있다. 버튼 같은 곳에 마우스 호버상태 일 때 클릭률을 높이거나 강조해야 되는 문구, 영역 등에

hasudoki.tistory.com

 

개요

이전 포스팅에서 transition, transtions-group을 사용하는 법을 알아봤다.

enter, leave할때 클래스명으로 제어할 수 있었다. 이번 포스팅에서는 Javascript hooks를 사용해 좀 더 특수한 상황이나, 복잡한 상황일 때 클래스를 부여해 제어해보자.

Velocity.js라는 라이브러리를 사용할 예정이다.

velocityjs.org/

 

Velocity.js

Overview At only 3Kb zipped, the UI pack is a must-have for improving your animation workflow. It exposes two functions: $.Velocity.RegisterEffect() and $.Velocity.RunSequence(). The former allows you to combine multiple Velocity calls into a a single effe

velocityjs.org

 

 

Javascript Hooks

Javascript Hooks는 transition, transition-group보다 더 구체적이고 Vue lifecycle hooks하고 비슷하다.

아래는 Javascript Hooks 목록이다.

  • before-enter
  • enter
  • after-enter
  • before-leave
  • enter-cancelled
  • leave
  • after-leave
  • leave-cancelled

위에 hooks을 보면 enter와 leave사이 전환될때 호출된다.

hooks을  호출하면 method를 실행할 수 있다. 이 method에서 javascript를 사용해 css만으로 할 수 없던 다양한 로직들을 실행할 수 있다.

<transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @enter-cancelled="enterCancelled"

    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
    @leave-cancelled="leaveCancelled"
  >
	<!-- ... -->
</transition>

 

A Drawer Transition

웹앱에서 자주 사용되는 Drawer 컴포넌트에 왼쪽에서 오른쪽으로 전환될 때 애니메이션 효과를 넣어보자.

Drawer 컴포넌트는 User profile, navigation menu, dashboard 등을 보여줄 때 자주 사용된다.

 

Drawer.vue

    <template>
      <div>
        <button @click="isOpen = !isOpen">
          My Profile
        </button>
    
        <div v-if="isOpen" class="drawer">
          <img src="../assets/avatar.png" alt="avatar" />
          <div></div>
          <div></div>
          <div></div>
          <div></div>
        </div>
    
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          isOpen: false
        }
      }
    }
    </script>
    
        <style scoped>
    img {
      height: 2.5em;
      width: 2.5em;
      border-radius: 50%;
    }
    
    .drawer {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 12em;
      height: 20em;
      border-radius: 1%;
      background-color: #e0e0e0;
      box-shadow: 0.08em 0.03em 0.4em #ababab;
      padding-top: 0.7em;
    }
    .drawer div {
      height: 3.5em;
      width: 95%;
      margin-top: 0.6em;
      background-color: #f0f0f0;
      border: 0.02em solid #ababab;
      border-radius: 1%;
    }
    </style>

 

위에 코드는 transition 컴포넌트를 적용하기 전이다.

이제 transition 컴포넌트를 사용하고 javascript hooks로 사용해보자.\

Drawer.vue

    <template>
    	<div>
    	  <button @click="isOpen = !isOpen">
    	    My Profile
    	  </button>
      
        <transition
          @before-enter="beforeEnter"
          @enter="enter"
          @leave="leave"
          :css="false"
        >
          <div v-if="isOpen" class="drawer">
            <img src="../assets/avatar.png" alt="avatar" />
            <div></div>
            <div></div>
            <div></div>
            <div></div>
          </div>
        </transition>
      </div>
    </template>

beforeEnter, enter, leave 메서드 정의가 필요하다.

  • beforeEnter는 초기 스타일 설정하는 로직을 넣으면 된다. 인터페이스에 보여지기 전 상태를 정의한다.
  • enter는 보여졌을 때 스타일을 정의하면 된다.
  • leave는 인터페이스에서 사라질 때 스타일을 정의하면 된다.
  • css:false는 이전 포스팅에서 이야기했던 css transition 클래스를 사용하지 않기로 정의하는 속성이다.

이제 위에서 처음 이야기한 Velocity를 설치하고 불러오자.

// 아래 커맨드로 package.json에 추가하고 설치하자.
npm i velocity-animate 
or
yarn add velocity-animate

  <script>
    import Velocity from 'velocity-animate'
    
    export default {
      data() {
        return {
          isOpen: false
        }
      },
      methods: {
        beforeEnter(el) {
          // we'll place our starting style here
        },
        enter(el, done) {
    			// style to transition to on enter
        },
        leave(el, done) {
    	   // style to transition away to on leave
        }
      }
    }
    </script>

methods를 보면 el 파라미터가 있다. el은 class="drawer"를 가진 div를 나타낸다.

처음에 이 div는 숨겨져 있는 상태이므로 opacity, width를 안 보이게 0으로 세팅한다.

 

Starting Style(스타일 정의)

beforeEnter(el) {
  el.style.opacity = 0
  el.style.width = '0em'
},
enter(el, done) {
  Velocity(
    el, // 애니메이션이 적용될 element
    { opacity: 1, width: '12em' }, // 스타일 정의
    { duration: 1000, easing: 'easeOutCubic', complete: done } // transion 속성 정의 및 complete 정의
  )
},
leave(el, done) {
  Velocity(
    el,
    { opacity: 0, width: '0em' },
    { duration: 500, easing: 'easeInCubic', complete: done }
  )
}

 

beforeEnter 메서드는 Velocity 라이브러리를 사용하지 않은 순수한 자바스크립트이다.

enter메서드에서 Velocity 라이브러리를 사용했다.

  • 첫 번째 파라미터에는 애니메이션이 적용될 엘리먼트 정의
  • 두 번째 파라미터에는 CSS style을 정의
  • 마지막 파라미터에는 complete라는 속성을 true로 정의해 이 hook가 끝났다는 걸 Vue에게 알려준다.

이렇게만 작성하면 Velocity 사용하는 큰 이유가 없을 것 같으니 Velocity에 기능 하나 소개하면서 이 포스팅을 마무리하겠다.

    enter(el, done) {
      Velocity(
        el,
        { opacity: 1, width: '12em' }, 
        { duration: 1000, easing: [60, 10], complete: done } // now with spring physics
      )
    }

easing에 배열을 사용해 다양한 효과를 낼 수 있다.(springy/snappy/bouncy)

60은 tension이고 10은 friction이다. 장력과 마찰이란 뜻이다.

위와 같이 하면 스프링 효과를 낼 수 있다.

 

예제 코드 : codesandbox.io/s/affectionate-sound-o6sf6?file=/src/components/Drawer.vue

 

affectionate-sound-o6sf6 - CodeSandbox

affectionate-sound-o6sf6 by shldhee using @vue/cli-plugin-babel, velocity-animate, vue

codesandbox.io

 

결론

CSS, Javascript 둘 다 사용해서 transition 하는 법을 모두 배웠다.

상황에 따라 맞는 방법을 사용해 프로젝트 최적화에 신경을 쓰면 좋을 것 같다.

Velocity라는 라이브러리를 살펴봤고 다음 포스팅에서는 gsap을 살펴볼 예정이다.

728x90
반응형
LIST