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

하수도키

·

2021. 4. 11. 17:32

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

목차

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

Transition(트랜지션)

  • Vue에서 Transition 래퍼(Wrapper) 컴포넌트를 기본으로 제공하고 있다. 이 Transition 컴포넌트를 이용해 다양한 애니메이션 효과를 낼 수 있다.
  • Transition은 번역하자면 전환이다. 말 그대로 from → to로 되는 것이 전환이다. 전활 될 때 애니메이션을 할 수 있게 도와준다.
    • on → off, off → on
    • open → closed, closed → open

Transition 스타일 클래스 알아보기

.v-enter { /* starting style */
    opacity: 0;
}

.v-enter-active { /* active entering style */
    transition: opacity 2s ease-in; 
}

.v-leave-active { /* active leaving style */
    transition: opacity 2s ease-out; 
}

.v-leave-to { /* ending style */
    opacity: 0;
}
  • 간단히 설명하겠다.
  • v-enter는 element가 dom에 추가되기 직전에 상태(from)
  • v-enter-active는 element가 dom에 보일 때까지 과정 상태(to)
  • v-leave-active는 element가 dom에서 없어질 때까지 과정 상태(from)
  • v-leave-to는 element가 dom에 없어진 상태(종료 to)
  • v-enter-to, v-leave도 있지만 기본 스타일이라 따로 지정하지 않는다. (ex. opacity 1, 항상 보인다. scale - 항상 1이다.)

Transition fade 예제

<template>
  <div>
    <button @click="toggleModal">Open</button>

    <transition name="fade">
      <div v-if="isOpen" class="modal">
        <p>
          <button @click="toggleModal">Close</button>
        </p>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false
    }
  },
  methods: {
    toggleModal() {
      this.isOpen = !this.isOpen
    }
  }
}
</script>

<style>
.fade-enter {
  opacity: 0;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease-out;
}

.fade-leave-to {
  opacity: 0;
}
</style>

Page Transtions(페이지 트랜지션)

  • vue-router를 사용해 페이지 이동시 애니메이션 효과를 넣는 법을 알아보자.
  • 기존과 똑같이 Transition 래퍼 컴포넌트를 감싸주면 된다.
<template>
  <div id="app">

    <div id="nav">
      <router-link to="/">Modal</router-link> |
      <router-link to="/about">About</router-link>
    </div>

    <transition name="fade">
      <router-view />
    </transition>

  </div>
</template>
  • 하지만, 이렇게만 작성하면 fade-in, fade-out 되는 페이지 컴포넌트들이 동시에 애니메이션이 작동되므로 보기 좋지 않다. 이걸 수정하기 위해서는 transition modes 를 살펴보자.

Transition Modes(트랜지션 모드)

  • in-out : 새로운(in) 트랜지션 엘리먼트가 먼저 작동되고, 기존(out) 트랜지션 엘리먼트가 그다음 동작한다.
  • out-in : 기존(in) 트랜지션 엘리먼트가 먼저 작동되고, 새로운(out) 트랜지션 엘리먼트가 그 다음 동작한다.
  • 기본 설정은 in-out이다. 아래처럼 mode를 추가하고 out-in으로 작성하면 매끄러운 페이지 이동이 된다.
<transition name="fade" mode="out-in">
    <router-view />
</transition>

slide transition

  • fade in, out으로 페이지가 이동되는 것보다 더 액티브하게 왼쪽으로 out 되고 오른쪽에서 in 되는 slide-fade 애니메이션을 적용해보자.
<transition name="slide-fade" mode="out-in">
    <router-view />
</transition>
.slide-fade-enter {
  transform: translateX(10px);
  opacity: 0;
}

.slide-fade-enter-active,
.slide-fade-leave-active {
  transition: all 0.2s ease;
}

.slide-fade-leave-to {
  transform: translateX(-10px);
  opacity: 0;
}

예제 코드 : https://codesandbox.io/s/wild-feather-jqx5v?file=/src/App.vue

Transition-group

  • 컴포넌트/엘리먼트 그룹에 대해 전체 트랜지션 효과를 넣는 방법을 살펴보자.
  • contacts 데이터로 ul > li 구조로 만들었고 여기 li 엘리먼트들에게 동일한 트랜지션 효과를 넣어보자.
    • contact를 추가할 수 있다.(addContact)
<template>
  <div>

    <input v-model="newContact" placeholder="Name" type="text" />
    <button @click="addContact">Add Contact</button>

        <ul>
      <li v-for="(contact, index) in contacts" :key="index">
        {{ contact }}
      </li>
        </ul>

  </div>
</template>

<script>
export default {
  data() {
    return {
      newContact: "",
      contacts: [
        "Beau Thabeast",
        "Cindy Rella",
        "Alice Wunderlind"
      ]
    }
  },
  methods: {
    addContact() {
      this.contacts.push(this.newContact)
      this.newContact = ""
    }
  }
}
</script>
  • transition 래퍼 컴포넌트를 사용하고 tag 속성을 이용해 대체할 태그를 입력한다.
  • 입력하지 않으면 기본 span 태그로 대체된다.
  • transition 컴포넌트와 똑같이 name 속성을 이용한다.
<transition-group tag="ul">
  <li v-for="contact in contacts" :key="contact" name="slide-up" apper>
    {{ contact }}
  </li>
</transition-group>

<style>
.slide-up-enter {
  transform: translateY(10px); /* start 10px down*/
  opacity: 0;
}

.slide-up-enter-active {
  transition: all 0.2s ease;
}
</style>
  • style을 보면 enter와 관련된 스타일만 작성했다. 현재는 addContact로 추가하는 기능만 있기 때문이다.
  • 새로고침 하면 page transition 효과가 그대로 transition-group을 덮어 씌운다.
  • appear 속성을 사용하면 쉽게 slide-up 효과로 보여질 수 있다.

move transition-group

  • sort 기능을 추가하고 li들이 sorting 될 때 트랜지션 효과를 추가해보자.
<template>
    ...
        <button @click="sortContacts">Sort</button>
    ...
</template>
<script>
methods: {
...
  sortContacts() {
    this.contacts = this.contacts.sort()
  }
}
</script>
  • sort 기능을 추가하고 실행해보면 트랜지션 효과가 되지 않는다.
  • v-move를 스타일에 추가해야 한다.
.slide-up-enter {
  transform: translateX(10px);
  opacity: 0;
}

.slide-up-enter-active {
  transition: all 0.2s ease;
}

.slide-up-move {
  transition: transform 0.5s ease-out;
}
728x90
반응형
LIST