Menggunakan animasi pada komponen React dengan Framer Motion memudahkan kita untuk menambahkan gerakan dan transisi pada berbagai elemen UI. Pada bagian ini, kita akan fokus pada cara mengintegrasikan animasi dalam komponen React dengan lebih baik, serta bagaimana membuat animasi berdasarkan kondisi atau state.
### 1. Membuat Komponen React Animatif dengan `motion`
Setiap elemen `motion` dapat digunakan layaknya komponen HTML biasa seperti `<motion.div>`, `<motion.button>`, atau `<motion.img>`. Berikut ini contoh sederhana di mana kita menambahkan animasi pada komponen React yang menampilkan kotak bergerak saat ditekan tombol.
```jsx
import React, { useState } from "react";
import { motion } from "framer-motion";
function MovingBox() {
const [isMoving, setIsMoving] = useState(false);
return (
<div>
<button onClick={() => setIsMoving(!isMoving)}>Toggle Move</button>
<motion.div
animate={{ x: isMoving ? 100 : 0 }}
transition={{ type: "spring", stiffness: 200 }}
style={{ width: 100, height: 100, backgroundColor: "coral", marginTop: 20 }}
/>
</div>
);
}
export default MovingBox;
Pada kode ini:
- `isMoving` adalah state yang menentukan posisi kotak.
- `animate={{ x: isMoving ? 100 : 0 }}` mengatur kotak bergerak 100px ke kanan jika `isMoving` bernilai `true`, dan kembali ke posisi semula jika `isMoving` bernilai `false`.
### 2. Menggunakan Animasi Berdasarkan Props
Anda juga dapat membuat komponen animatif yang menyesuaikan animasinya berdasarkan *props*. Ini berguna untuk komponen yang digunakan di berbagai bagian aplikasi dengan perilaku animasi yang berbeda.
```jsx
import React from "react";
import { motion } from "framer-motion";
function AnimatedBox({ shouldRotate }) {
return (
<motion.div
animate={{ rotate: shouldRotate ? 180 : 0 }}
transition={{ duration: 0.5 }}
style={{ width: 100, height: 100, backgroundColor: "teal" }}
/>
);
}
export default AnimatedBox;
Kemudian, Anda bisa memanggil `AnimatedBox` dengan prop `shouldRotate`:
```jsx
<AnimatedBox shouldRotate={true} />
### 3. Mengelola Animasi berdasarkan State (Conditionally Rendered Animations)
Terkadang, kita ingin menampilkan animasi hanya ketika elemen tersebut dimunculkan atau dihapus. Framer Motion menyediakan komponen `AnimatePresence` untuk mengelola animasi masuk dan keluar saat komponen muncul atau hilang dari DOM.
#### Contoh Animasi Muncul dan Hilang
```jsx
import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
function ToggleBox() {
const [isVisible, setIsVisible] = useState(true);
return (
<div>
<button onClick={() => setIsVisible(!isVisible)}>Toggle Box</button>
<AnimatePresence>
{isVisible && (
<motion.div
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 50 }}
transition={{ duration: 0.5 }}
style={{ width: 100, height: 100, backgroundColor: "skyblue", marginTop: 20 }}
/>
)}
</AnimatePresence>
</div>
);
}
export default ToggleBox;
Pada contoh di atas:
- `initial`, `animate`, dan `exit` menentukan kondisi elemen saat masuk dan keluar.
- Elemen muncul dengan menggeser ke bawah dari atas dan hilang dengan menggeser ke bawah lagi.
### 4. Contoh Komponen Carousel dengan Framer Motion
Framer Motion juga dapat digunakan untuk membuat komponen yang lebih kompleks, seperti carousel atau slider. Di sini, kita akan menggunakan animasi `x` dan `drag` untuk menggeser gambar dalam slider.
```jsx
import React from "react";
import { motion } from "framer-motion";
const images = ["image1.jpg", "image2.jpg", "image3.jpg"]; // Ubah ini ke URL gambar Anda
function Carousel() {
return (
<div style={{ overflow: "hidden", width: "100%", maxWidth: 600, margin: "0 auto" }}>
<motion.div
drag="x"
dragConstraints={{ left: -600, right: 0 }}
style={{ display: "flex", cursor: "grab" }}
>
{images.map((src, index) => (
<motion.img
key={index}
src={src}
alt={`Slide ${index}`}
style={{ width: "100%", height: "auto", pointerEvents: "none" }}
whileTap={{ cursor: "grabbing" }}
/>
))}
</motion.div>
</div>
);
}
export default Carousel;
Penjelasan:
- `drag="x"` memungkinkan elemen bergerak di sumbu X.
- `dragConstraints` mengatur batas seberapa jauh elemen bisa digeser, misalnya -600px ke kiri dan 0 ke kanan.
- `whileTap` mengganti kursor saat gambar di-drag, menambah kesan interaktif.
### 5. Penggunaan `useAnimation` untuk Kontrol Animasi Manual
Framer Motion menyediakan `useAnimation`, sebuah *hook* untuk mengontrol animasi secara manual. Ini berguna jika Anda perlu memicu animasi berdasarkan kondisi yang kompleks.
```jsx
import React from "react";
import { motion, useAnimation } from "framer-motion";
function ControlledAnimation() {
const controls = useAnimation();
const startAnimation = () => {
controls.start({
x: 100,
opacity: 1,
transition: { duration: 1 },
});
};
return (
<div>
<button onClick={startAnimation}>Start Animation</button>
<motion.div
initial={{ x: 0, opacity: 0 }}
animate={controls}
style={{ width: 100, height: 100, backgroundColor: "plum", marginTop: 20 }}
/>
</div>
);
}
export default ControlledAnimation;
Dalam contoh ini:
- `controls.start()` digunakan untuk memulai animasi saat tombol ditekan.
- *Hook* ini memberi fleksibilitas lebih besar dalam memicu animasi, misalnya berdasarkan kondisi atau event tertentu.
### Kesimpulan
Dengan Framer Motion, Anda dapat mengubah komponen statis menjadi elemen interaktif dan dinamis dengan berbagai metode:
- Mengintegrasikan animasi dengan *props* dan *state*.
- Mengelola elemen yang muncul atau menghilang dengan `AnimatePresence`.
- Membangun komponen interaktif seperti carousel dan slider.
- Menggunakan `useAnimation` untuk kontrol animasi manual.
Dengan fitur ini, Framer Motion memungkinkan Anda menciptakan UI yang kaya, interaktif, dan sangat responsif di proyek React Anda.