[Vue.js] Vue 애니메이션(Animate) #2 - Javascript Hooks, Velocity
하수도키
·2021. 4. 19. 00:01
- 이번 포스팅은 Vue 애니메이션에 대해 알아보자.
- 애니메이션을 이용해 사용자 경험을 향상할 수 있다.
- 버튼 같은 곳에 마우스 호버 상태 일 때 클릭률을 높이거나
- 강조해야 되는 문구, 영역 등에 애니메이션을 적용해 집중력을 높일 수 있다.
목차
- Transition
- Page Transition
- Transition Group
- Javascript Hooks + Velocity(이번 포스팅)
- GSAP
2021.04.11 - [개발일기/Vue.js] - [Vue.js] Vue 애니메이션(Animate) #1 - Transition
개요
이전 포스팅에서 transition, transtions-group을 사용하는 법을 알아봤다.
enter, leave할때 클래스명으로 제어할 수 있었다. 이번 포스팅에서는 Javascript hooks를 사용해 좀 더 특수한 상황이나, 복잡한 상황일 때 클래스를 부여해 제어해보자.
Velocity.js라는 라이브러리를 사용할 예정이다.
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
결론
CSS, Javascript 둘 다 사용해서 transition 하는 법을 모두 배웠다.
상황에 따라 맞는 방법을 사용해 프로젝트 최적화에 신경을 쓰면 좋을 것 같다.
Velocity라는 라이브러리를 살펴봤고 다음 포스팅에서는 gsap을 살펴볼 예정이다.
'개발일기 > Vue.js' 카테고리의 다른 글
[Vue.js] 이벤트 전파(버블링, 캡쳐링) 살펴보기 (0) | 2021.08.25 |
---|---|
[Vue.js] Vue 애니메이션(Animate) #3 - GSAP 3 (0) | 2021.05.01 |
[Vue.js] Vue 애니메이션(Animate) #1 - Transition (1) | 2021.04.11 |
[Vue.js] Portal-Vue 라이브러리 사용하기 (0) | 2021.03.26 |
[Vue.js] Vue3 + TypeScript #6 마지막 커스텀 타입 정의하기(Type Assertion, data, props, computed, methods) (0) | 2021.03.14 |