Pengenalan
Animasi SVG dapat meningkatkan daya tarik visual website Anda secara signifikan. Dengan menggunakan Framer Motion, library animasi yang powerful untuk React, kita dapat membuat animasi SVG yang smooth dan interaktif dengan mudah.
Mengapa SVG dan Framer Motion?
Keuntungan SVG
- Scalable: Tidak kehilangan kualitas di berbagai ukuran layar
- Lightweight: Ukuran file yang kecil dibanding gambar raster
- Manipulable: Mudah dianimasi dan dimanipulasi dengan CSS/JavaScript
Keuntungan Framer Motion
- Declarative: API yang intuitif dan mudah dipahami
- Performant: Menggunakan GPU acceleration untuk animasi yang smooth
- Feature-rich: Mendukung berbagai jenis animasi dan gesture
Setup Project
Pertama, install Framer Motion:
npm install framer-motionContoh Implementasi
1. Animasi Path Drawing
import { motion } from 'framer-motion';
export function AnimatedLogo() {
return (
<svg width="200" height="200" viewBox="0 0 200 200">
<motion.path
d="M10 80 Q 95 10 180 80"
stroke="#3b82f6"
strokeWidth="4"
fill="none"
initial={{ pathLength: 0 }}
animate={{ pathLength: 1 }}
transition={{ duration: 2, ease: "easeInOut" }}
/>
</svg>
);
}2. Animasi dengan Hover Effect
export function InteractiveSVG() {
return (
<motion.svg
width="100"
height="100"
viewBox="0 0 100 100"
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
>
<motion.circle
cx="50"
cy="50"
r="40"
fill="#3b82f6"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.5 }}
/>
</motion.svg>
);
}3. Animasi Scroll-triggered
import { useScroll, useTransform } from 'framer-motion';
export function ScrollAnimatedSVG() {
const { scrollYProgress } = useScroll();
const pathLength = useTransform(scrollYProgress, [0, 1], [0, 1]);
return (
<svg width="100%" height="400" viewBox="0 0 100 400">
<motion.path
d="M50 0 L50 400"
stroke="#3b82f6"
strokeWidth="2"
fill="none"
style={{ pathLength }}
/>
</svg>
);
}Best Practices
1. Optimasi Performance
- Gunakan
will-changeuntuk animasi yang kompleks - Batasi jumlah elemen yang dianimasi secara bersamaan
- Gunakan
useReducedMotionuntuk aksesibilitas
import { useReducedMotion } from 'framer-motion';
export function AccessibleAnimation() {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
animate={shouldReduceMotion ? {} : { rotate: 360 }}
transition={{ duration: 2 }}
>
Content
</motion.div>
);
}2. Responsive Design
export function ResponsiveSVG() {
return (
<svg
width="100%"
height="auto"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid meet"
>
{/* SVG content */}
</svg>
);
}3. Reusable Components
interface AnimatedIconProps {
size?: number;
color?: string;
animationDuration?: number;
}
export function AnimatedIcon({
size = 24,
color = "currentColor",
animationDuration = 1
}: AnimatedIconProps) {
return (
<motion.svg
width={size}
height={size}
viewBox="0 0 24 24"
initial={{ opacity: 0, rotate: -180 }}
animate={{ opacity: 1, rotate: 0 }}
transition={{ duration: animationDuration }}
>
<path
fill={color}
d="M12 2L2 7l10 5 10-5-10-5z"
/>
</motion.svg>
);
}Advanced Techniques
1. Sequenced Animations
export function SequencedSVG() {
return (
<svg width="200" height="200" viewBox="0 0 200 200">
<motion.circle
cx="50"
cy="100"
r="20"
fill="#3b82f6"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0 }}
/>
<motion.circle
cx="100"
cy="100"
r="20"
fill="#3b82f6"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.2 }}
/>
<motion.circle
cx="150"
cy="100"
r="20"
fill="#3b82f6"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.4 }}
/>
</svg>
);
}2. Morphing Shapes
export function MorphingSVG() {
const [isCircle, setIsCircle] = useState(true);
return (
<motion.svg
width="200"
height="200"
viewBox="0 0 200 200"
onClick={() => setIsCircle(!isCircle)}
>
<motion.path
d={isCircle
? "M100,50 a50,50 0 1,1 0,100 a50,50 0 1,1 0,-100"
: "M50,50 L150,50 L150,150 L50,150 Z"
}
fill="#3b82f6"
transition={{ duration: 0.5 }}
/>
</motion.svg>
);
}Tips untuk Production
- Compress SVG: Gunakan tools seperti SVGO untuk mengoptimasi file SVG
- Lazy Loading: Load animasi hanya ketika diperlukan
- Testing: Test animasi di berbagai device dan browser
- Fallback: Sediakan fallback untuk browser yang tidak support animasi
Kesimpulan
Animasi SVG dengan Framer Motion memberikan cara yang powerful dan flexible untuk meningkatkan user experience website Anda. Dengan mengikuti best practices dan mengoptimasi performance, Anda dapat membuat animasi yang indah tanpa mengorbankan kecepatan loading.