Dikarenakan banyaknya fitur yang harus dikerjakan, kadang kita lupa untuk memberikan efek animasi pada komponen yang kita buat. Meskipun tidak memberikan dampak yang besar pada pengalaman pengguna, namun efek animasi bisa membuat aplikasi kita terlihat lebih menarik dan interaktif. Selain itu, efek animasi juga bisa membantu pengguna dalam memahami perubahan yang terjadi pada aplikasi. Vue.js menyediakan fitur transition menggunakan komponen Transition
yang memudahkan kita dalam memberikan efek animasi pada komponen.
Pada artikel ini saya menggunakan tailwindcss sebagai utility class untuk membuat animasi.
Animasi Komponen Muncul / Hilang
Komponen Transition pada Vue.js sebenarnya sudah cukup untuk memberikan efek animasi pada komponen, namun karena ada banyak props
yang harus dituliskan maka kita akan membuat komponen sendiri yang lebih sederhana. Komponen ini saya beri nama ToggleTransition.vue
yang akan memiliki tiga props
, yaitu duration
, type
dan timingFunction
. Anda bisa meletakkannya di dalam folder src/components
pada proyek Vue.js Anda.
<script setup lang="ts">
import { computed } from 'vue';
const props = withDefaults(defineProps<{
duration: 'fast' | 'normal' | 'slow';
type: 'fade' | 'slideX' | 'slideY' | 'zoomIn' | 'zoomOut';
timingFunction: 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
}>(), {
duration: 'normal',
type: 'fade',
timingFunction: 'ease-in'
});
const transitionClassesMap = {
slideY: {
enterFromClass: 'opacity-0 translate-y-20',
enterToClass: 'opacity-100 translate-y-0',
leaveFromClass: 'opacity-100 translate-y-0',
leaveToClass: 'opacity-0 translate-y-20',
},
slideX: {
enterFromClass: 'opacity-0 translate-x-20',
enterToClass: 'opacity-100 translate-x-0',
leaveFromClass: 'opacity-100 translate-x-0',
leaveToClass: 'opacity-0 translate-x-20'
},
zoomIn: {
enterFromClass: 'opacity-0 scale-50',
enterToClass: 'opacity-100 scale-100',
leaveFromClass: 'opacity-100 scale-100',
leaveToClass: 'opacity-0 scale-50'
},
zoomOut: {
enterFromClass: 'opacity-0 scale-150',
enterToClass: 'opacity-100 scale-100',
leaveFromClass: 'opacity-100 scale-100',
leaveToClass: 'opacity-0 scale-150'
},
fade: {
enterFromClass: 'opacity-0',
enterToClass: 'opacity-100',
leaveFromClass: 'opacity-100',
leaveToClass: 'opacity-0'
},
};
const transitionClasses = computed(() => transitionClassesMap[props.type]);
const durationMap = {
fast: 'duration-300',
normal: 'duration-700',
slow: 'duration-1000'
};
</script>
<template>
<Transition appear
:enter-active-class="`transition ${props.timingFunction} ${durationMap[props.duration]}`"
:enter-from-class="transitionClasses.enterFromClass"
:enter-to-class="transitionClasses.enterToClass"
:leave-active-class="`transition ${props.timingFunction} ${durationMap[props.duration]}`"
:leave-from-class="transitionClasses.leaveFromClass"
:leave-to-class="transitionClasses.leaveToClass">
<slot></slot>
</Transition>
</template>
Komponen ToggleTransition
di atas menerima tiga props
, yaitu duration
, type
dan timing-function
. duration
digunakan untuk menentukan durasi animasi, sedangkan type
digunakan untuk menentukan jenis animasi yang akan digunakan (fade
, slideY
, slideX
, zoomIn
, zoomOut
). timingFunction
digunakan untuk menentukan jenis fungsi waktu yang digunakan dalam animasi.
Contoh penggunaan komponen ToggleTransition
:
<script setup lang="ts">
import { ref } from 'vue';
import ToggleTransition from './components/ToggleTransition.vue';
const state = ref(true);
</script>
<template>
<button @click="state = !state" class="bg-yellow-700 rounded m-5 text-white p-4">Toggle State</button>
<ToggleTransition type="slideY" duration="slow">
<div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Slide Y</div>
</ToggleTransition>
<ToggleTransition type="fade" timing-function="ease-in">
<div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Fade</div>
</ToggleTransition>
</template>
Tombol Toggle State
digunakan untuk mengubah nilai variabel state
yang akan menampilkan atau menyembunyikan elemen yang berada di dalam komponen ToggleTransition
. Pada contoh di atas, kita menggunakan dua jenis animasi, yaitu slideY
dan fade
.
Animasi Antara Komponen
Selain animasi muncul dan hilang, kita juga bisa memberikan efek animasi ketika komponen berubah. Misalnya, ketika kita mengganti sebuah blok pada aplikasi, kita bisa memberikan efek animasi ketika komponen lama digantikan dengan komponen baru. Kita juga akan membuat komponen sendiri yang bernama SwitchTransition.vue
yang juga akan memiliki tiga props
, yaitu duration
, type
dan timingFunction
.
<script setup lang="ts">
import { computed } from 'vue';
const props = withDefaults(defineProps<{
duration: 'fast' | 'normal' | 'slow';
type: 'fade' | 'slideX' | 'slideY' | 'zoom';
timingFunction: 'ease-in' | 'ease-out' | 'ease-in-out' | 'linear';
}>(), {
duration: 'normal',
type: 'fade',
timingFunction: 'ease-in'
});
const transitionClassesMap = {
slideY: {
enterFromClass: 'opacity-0 translate-y-20',
enterToClass: 'opacity-100 translate-y-0',
leaveFromClass: 'opacity-100 translate-y-0',
leaveToClass: 'opacity-0 translate-y-20',
},
slideX: {
enterFromClass: 'opacity-0 translate-x-20',
enterToClass: 'opacity-100 translate-x-0',
leaveFromClass: 'opacity-100 translate-x-0',
leaveToClass: 'opacity-0 translate-x-20'
},
zoom: {
enterFromClass: 'opacity-0 scale-50',
enterToClass: 'opacity-100 scale-100',
leaveFromClass: 'opacity-100 scale-100',
leaveToClass: 'opacity-0 scale-50'
},
fade: {
enterFromClass: 'opacity-0',
enterToClass: 'opacity-100',
leaveFromClass: 'opacity-100',
leaveToClass: 'opacity-0'
}
};
const transitionClasses = computed(() => transitionClassesMap[props.type]);
const durationMap = {
fast: 'duration-300',
normal: 'duration-700',
slow: 'duration-1000'
};
const enterLeaveActiveClass = computed(() => `transition ${props.timingFunction} ${durationMap[props.duration]}`);
</script>
<template>
<Transition
:enter-active-class="enterLeaveActiveClass"
:enter-from-class="transitionClasses.enterFromClass"
:enter-to-class="transitionClasses.enterToClass"
:leave-active-class="enterLeaveActiveClass"
:leave-from-class="transitionClasses.leaveFromClass"
:leave-to-class="transitionClasses.leaveToClass"
mode="out-in">
<slot></slot>
</Transition>
</template>
Komponen SwitchTransition
di atas hampir sama dengan komponen ToggleTransition
, namun kita menggunakan properti mode="out-in"
pada komponen Transition
. Properti ini digunakan untuk memberikan efek animasi pada komponen lama sebelum digantikan dengan komponen baru. Untuk menggunakan komponen ini harus dipastikan bahwa hanya ada 1 komponen yang ditampilkan pada satu waktu.
Contoh penggunaan komponen SwitchTransition
:
<script setup lang="ts">
import { ref } from 'vue';
import SwitchTransition from './components/SwitchTransition.vue';
const state = ref(true);
</script>
<template>
<button @click="state = !state" class="bg-yellow-700 rounded m-5 text-white p-4">Toggle State</button>
<SwitchTransition type="slideY" duration="slow">
<div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Slide Y</div>
<div v-else class="bg-red-500 text-white p-4 mb-2">Slide Y</div>
</SwitchTransition>
<SwitchTransition type="fade" timing-function="ease-in">
<div v-if="state" class="bg-blue-500 text-white p-4 mb-2">Fade</div>
<div v-else class="bg-red-500 text-white p-4 mb-2">Fade</div>
</SwitchTransition>
</template>
Pada contoh di atas, kita menggunakan dua jenis animasi, yaitu slideY
dan fade
. Ketika tombol Toggle State
ditekan, maka komponen yang ditampilkan akan berubah dengan efek animasi yang kita tentukan.
Kesimpulan
Semoga artikel ini bisa membantu Anda dalam memberikan efek animasi pada komponen Vue.js yang Anda buat. Dengan menggunakan komponen Transition
pada Vue.js, kita bisa memberikan efek animasi pada komponen dengan mudah. Dengan memberikan efek animasi pada komponen, kita bisa membuat aplikasi kita terlihat lebih menarik dan interaktif.