# Introduction
Ketika kita sudah membuat sebuah website dan lagi mikir untuk kasih user experience yang lebih keren dengan memberikan sebuah animasi di website kita. Di artikel kali ini, saya akan memberikan tutorial cara membuat scroll animation menggunakan Intersection Observer. Untuk contoh studi kasus, kita akan membuat galeri, yang mana isi dari galeri tersebut kita fetch API dari Unsplash API.
# Apa itu Intersection Observer?
Intersection Observer adalah sebuah interface dari Intersection Observer API yang memberikan kita cara untuk mengamati suatu perubahan secara asynchronous pada element target terhadap viewport atau elemen ancestor.
Gampangnya, dengan Intersection Observer kita akan memantau suatu element apakah element tersebut sudah muncul di viewport browser atau belum. Berikut ini adalah contoh ilustrasinya
Biasanya, Intersection Observer di gunakan untuk lazy loading, infinite scrolling, dan masih banyak lagi. Kali ini kita akan memanfaatkan Intersection Observer untuk membuat scroll animation pada project website kita.
1. Membuat Aplikasi di Unsplash Developers
Seperti yang sudah saya sampai di awal, kita akan membuat galeri foto dengan memanfaatkan API dari Unsplash. Pertama, silahkan masuk ke Unsplash Developers. Kemudian buat akun Unsplash Developers agar kita mendapatkan hak akses API. Jika sudah, kita akan diarahkan ke menu dashboard.
Buat aplikasi dan centang semua terms yang ada. Kemudian isi semua informasi aplikasi, jika sudah kita akan diarahkan ke halaman aplikasi yang sudah kita buat. Scroll kebawah sampai kita menemukan Keys yang akan kita gunakan, dan copy Access Key.
2. Testing API menggunakan Postman
Untuk testing API, kita akan menggunakan aplikasi Postman. Jika kalian belum menginstall aplikasi Postman, silahkan download di sini.
Buka aplikasi Postman, dan paste link dibawah ini
https://api.unsplash.com/photos/?client_id=YOUR_ACCESS_KEY
Jika hasilnya sudah seperti ini, maka kita sudah dapat menggunakan API dari Unsplash.
3. Install Vue
Di project kali ini kita akan menggunakan Vue 3 dengan Vite. Silahkan jalankan perintah dibawah ini pada terminal untuk memulai project Vue.
#npm
npm create vite@latest nama-project -- --template vue
# yarn
yarn create vite nama-project --template vue
Perintah tersebut akan memunculkan opsi pilihan framework apa yang akan kita gunakan, pilih framework vue.
vanilla
> vue
react
preact
lit-element
svelte
Jika sudah, akan muncul opsi pilihan lagi. Yaitu apakah kita akan menggunakan pure js atau typescript. Pilih saja sesuai dengan selera kalian, kali ini saya akan menggunakan pure js.
❯ vue
vue-ts
Setelah selesai nanti akan dibuatkan folder sesuai nama project yang kita ketik sebelumnya. Masuk ke dalam folder project lalu install dependecies.
cd nama-project
npm install
or
yarn install
Buka project di text editor kemudian jalankan perintah npm run dev
atau yarn dev
di terminal. Maka tampilannya akan seperti ini.
4. Desain Layout & Fetch API
Kita akan mendesain layout dengan masonry grid. Hapus semua component yang ada di folder component
, kemudian salin code ini ke dalam file App.vue
<template>
<div class="container">
<h1>My Gallery</h1>
<div class="container-photo">
<figure v-for="image in galleries" :key="image.id">
<img :src="image.urls.regular" :alt="image.alt_description" />
</figure>
</div>
</div>
</template>
CSS
.container {
max-width: 48rem;
margin: 0 auto;
}
.container-photo {
column-count: 2;
}
@media (min-width: 768px) {
.container-photo {
column-count: 3;
column-gap: 10px;
}
}
figure {
margin: 0;
display: grid;
grid-template-rows: 1fr auto;
margin-bottom: 10px;
break-inside: avoid;
}
img {
width: 100%;
height: auto;
border-radius: 1rem;
object-fit: cover;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}
figure > img {
grid-row: 1 / -1;
grid-column: 1;
}
Jika kita lihat hasilnya memang belum ada, itu karena kita belum melakukan fetch ke Unsplash API yang sudah kita punya tadi. Sekarang kita buat fungsi fetch API di file App.vue dalam tag script
<script>
import { ref } from "vue"
export default {
setup() {
const galleries = ref([])
const fetchImage = () => {
fetch(`https://api.unsplash.com/photos/?client_id=${import.meta.env.VITE_ACCESS_KEY}&per_page=30`)
.then(res => res.json())
.then(response => galleries.value = response)
.catch(error => console.log(error))
}
fetchImage()
return { galleries }
}
}
</script>
Buat file .env
di root folder project kalian, kemudian isikan dengan access key yang sudah kalian punya.
VITE_ACCESS_KEY=ACCESS_KEY
Maka hasilnya akan menjadi seperti ini
Nice! Kita sudah membuat desain layout dengan masonry grid dan sudah terhubung ke API, selanjutnya kita buat animasi ketika di scroll.
5. Membuat Custome Directive
Buat folder directives
di dalam folder src, dan beri nama scrollAnimation.js
. Salin kode ini ke dalam file scrollAnimation.js
const options = { threshold: 0.5 }
const observer = new IntersectionObserver((entries, observer) => {
let delay = 0
entries.forEach((entry) => {
if (entry.isIntersecting) {
setTimeout(() => {
entry.target.classList.add('enter')
entry.target.classList.remove('before-enter')
}, delay)
delay += 150
observer.unobserve(entry.target)
}
})
}, options)
export default {
mounted(el) {
el.classList.add('before-enter')
observer.observe(el)
},
}
Coba kita bedah kode di atas satu persatu
- Baris pertama kita membuat variabel options berisi objek threshold untuk menentukan pada saat berapa persen element muncul di viewport. Pada kode di atas kita memberikan threshold 0.5 yang artinya sebersar 50%. Variabel ini kita gunakan pada parameter IntersectionObserver.
- Kemudian kita membuat variabel observer yang berisikan IntersectionObserver. Pada IntersectionObserver terdapat dua parameter yaitu callback dan options. Nah pada parameter callback kita membuat fungsi dengan variabel entries dan observer, kemudian untuk paramter options kita masukkan variabel yang sudah kita buat pertama dengan nama variabel options juga.
- Didalam fungsi callback kita membuat variabel delay yang nantinya akan digunakan untuk memberi delay pada setiap element yang sudah masuk ke viewport.
- Kita memberikan kondisi, jika element sudah ter-intersecting dengan property
isIntersecting
dan menambah fungsisetTimeout
untuk memberi delay setiap element yang sudah masuk viewport. - Kemduian terdapat variabel observer dengan method unboserve yang berfungsi jika element sudah muncul di viewport, maka element tersebut tidak perlu di observe lagi jika keluar dari viewport.
- Kita export kemudian berikan method mounted yang ada di VueJS. Mounted berfungsi jika semua component sudah selesai dirender, maka jalankan semua fungsi yang ada didalam method mounted.
Untuk lebih jelasnya lagi tentang IntersectionObserver, bisa lihat di sini.
Masuk ke file main.js kemudian import directive yang sudah kita buat tadi.
import { createApp } from 'vue'
import App from './App.vue'
import ScrollAnimation from './directives/scrollAnimation'
createApp(App).directive('scrollanimation', ScrollAnimation).mount('#app')
Pada kode di atas, method directive terdapat dua parameter. Parameter pertama adalah custome directive yang akan kita gunakan file .vue dan parameter kedua merupakan fungsi dari directive tersebut. Untuk lebih jelasnya tentang custome directive, bisa lihat di sini
Kembali ke file App.vue, kemudian tambahkan directive yang baru kita buat ke tag html img
...
<img v-scrollanimation :src="image.urls.regular" :alt="image.alt_description" />
...
Tambahkan sedikit css
.before-enter {
transform: translateY(50px);
opacity: 0;
}
.enter {
transform: translateX(0);
opacity: 1;
transition: 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
Berikut ini adalah hasilnya.
Wow! Sekarang kita sudah berhasil membuat scroll animation menggunakan IntersectionObserver dengan custome directive. Sekarang terlihat keren bukan?
# Closing
Jika punya pendekatan yang lebih baik, boleh sekali untuk memberikan saran agar penulisan kode menjadi lebih baik lagi. Semoga artikel ini bermanfaat. Goodluck!
Referensi