CSS animation መፃፍ ሳያስፈልግ፣ ከ React ውጭ ሳንወጣ — motion.div ብቻ!
Spring physics፣ Variants፣ AnimatePresence፣ Gestures — ሁሉንም በአንድ ላይ! 🎬
The most popular production-ready motion library for React.
Framer Motion — React ውስጥ animation ለመስራት የሚያገለግል production-ready library ነው! CSS keyframes መፃፍ ሳያስፈልግ፣ በ Spring physics እጅግ ማራኪ አኒሜሽኖችን መስራት ይቻላል። motion.divን በመጠቀም ብቻ አኒሜሽኑ ይጀምራል!
Declarative animations — describe what you want, Framer figures out how.
npm install framer-motion
import { motion, AnimatePresence } from 'framer-motion'
/* CSS */ @keyframes slideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .card { animation: slideIn 0.5s ease; } // ❌ Exit animation? የለም! // ❌ Spring physics? በራስ መስራት ያሻል! // ❌ Gesture? addEventListener ያስፈልጋል! // ❌ Stagger? ሌላ logic ይጠይቃል!
import { motion } from 'framer-motion'; // ✅ motion. + ማንኛውም HTML element <motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} exit={{ opacity: 0, y: -20 }} transition={{ type: 'spring', stiffness: 300 }} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} /> // ✅ Enter · Exit · Spring · Gesture — ሁሉም ተካተዋል!
initial — Component ሲጫን (mount ሲሆን) የሚጀምርበት ሁኔታ! animate — ደርሶ ማለቅ ያለበት ሁኔታ! React state ሲቀየር animate አብሮ ይቀየራል!
import { motion } from 'framer-motion'; // 🔵 Fade + Slide In <motion.div initial={{ opacity: 0, y: 30 }} animate={{ opacity: 1, y: 0 }} /> // 🔵 Scale In (Pop effect) <motion.div initial={{ scale: 0, opacity: 0 }} animate={{ scale: 1, opacity: 1 }} /> // 🔵 Rotate In <motion.div initial={{ rotate: -180, opacity: 0 }} animate={{ rotate: 0, opacity: 1 }} /> // 🔵 State ሲቀየር animate አብሮ ይቀየራል! <motion.div animate={{ x: isOpen ? 0 : -200 }} />
exit — Component ከ DOM ላይ ሲወገድ (Unmount ሲሆን) የሚታይ animation! ከ AnimatePresence ጋር ብቻ ነው የሚሰራው — ያለ CSS!
import { motion, AnimatePresence } from 'framer-motion'; // ⚠️ ከ AnimatePresence ጋር ብቻ ነው exit የሚሰራው! function Modal({ isOpen }) { return ( <AnimatePresence> {isOpen && ( <motion.div key="modal" initial={{ opacity: 0, scale: 0.85 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.85 }} ← exit! transition={{ duration: 0.25 }} > Modal Content </motion.div> )} </AnimatePresence> ); } // exit animation → ከ DOM ላይ ሲወገድ ሳይሆን አኒሜሽኑ ሲያልቅ ነው የሚወገደው!
transition — አኒሜሽኑ እንዴት እንደሚጓዝ ይወስናል! spring (ፊዚክስን የተከተለ) ወይም tween (የተለመደው easing) — ሁለቱ ዋና አይነቶች ናቸው!
// 🌿 Spring — ተፈጥሯዊ Physics ይኖረዋል <motion.div transition={{ type: 'spring', stiffness: 300, // ጠንካራነቱ? (100–1000) damping: 30, // መቆሚያው? (0–100) mass: 1, // ክብደቱ }} /> // 📐 Tween — linear/ease/easeIn... <motion.div transition={{ type: 'tween', duration: 0.5, // ሰኮንድ ease: 'easeOut',// easeIn · easeOut · backOut delay: 0.2, // ዘግይቶ ይጀምር }} /> // ⚡ Stagger — children አንድ በአንድ <motion.ul variants={containerVariants} initial="hidden" animate="show" /> // containerVariants.show.transition.staggerChildren: 0.1
Keyframes — Animation ውስጥ ብዙ values በ array መልክ መስጠት! CSS @keyframes ያለ ቀላሉ መንገድ!
// ✨ Values array = keyframes! <motion.div animate={{ x: [0, 100, 50, 200], // 0 → 100 → 50 → 200 }} /> // 🔵 Bounce effect <motion.div animate={{ y: [0, -30, 0], scale: [1, 1.1, 1], }} transition={{ duration: 0.6, ease: 'easeInOut', times: [0, 0.5, 1], // % of animation repeat: Infinity, repeatDelay: 1, }} /> // 🎨 Color keyframes <motion.div animate={{ backgroundColor: ['#e879f9', '#a3e635', '#e879f9'] }} transition={{ duration: 2, repeat: Infinity }} />
AnimatePresence — Component ከ DOM ከመወገዱ በፊት exit animation ሰርቶ እንዲጨርስ ያደርጋል! ያለ AnimatePresence የ exit prop አይሰራም!
import { motion, AnimatePresence } from 'framer-motion'; // 🔔 Notification Stack function NotifStack() { const [notifs, setNotifs] = useState([]); const add = (type) => setNotifs(n => [...n, { id: Date.now(), type }]); const remove = (id) => setNotifs(n => n.filter(x => x.id !== id)); return ( <AnimatePresence> {notifs.map(n => ( <motion.div key={n.id} initial={{ opacity: 0, x: 50, scale: 0.9 }} animate={{ opacity: 1, x: 0, scale: 1 }} exit={{ opacity: 0, x: 50, scale: 0.9 }} onClick={() => remove(n.id)} > {n.type === 'success' ? '✅' : '❌'} </motion.div> ))} </AnimatePresence> ); }
// 🎭 Stagger — List items አንድ በአንድ const containerV = { hidden: {}, show: { transition: { staggerChildren: 0.1, // 100ms ልዩነት delayChildren: 0.2, // ሁሉም ሲጀምሩ delay } } }; const itemV = { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0, transition: { type: 'spring', stiffness: 300 } } }; <motion.ul variants={containerV} initial="hidden" animate="show" > {items.map(item => ( <motion.li key={item.id} variants={itemV} // ← parent trigger ያደርገዋል exit={{ opacity: 0, x: -30 }} > {item.name} </motion.li> ))} </motion.ul>
Framer Motion ውስጥ Gesture animations — whileHover (ማውስ ሲጠጋ)፣ whileTap (ሲጫን)፣ drag (ሲጎትት) — CSS ሳይጻፍ! ↓ ሞክሩ!
whileHover={{ scale: 1.15 }}whileTap={{ scale: 0.88 }}drag dragConstraints={...}whileFocus={{ scale: 1.1 }}whileInView={{ opacity: 1 }}useTransform(x, in, out)import { motion, AnimatePresence } from 'framer-motion'; // 1️⃣ Variants ፍጠር (Reusable!) const cardV = { hidden: { opacity: 0, y: 30, scale: 0.95 }, show: { opacity: 1, y: 0, scale: 1, transition: { type: 'spring', stiffness: 260, damping: 20 } }, exit: { opacity: 0, y: -20, scale: 0.95 } }; const listV = { hidden: {}, show: { transition: { staggerChildren: 0.1 } } }; // 2️⃣ Component export function ProductList({ products, isOpen }) { return ( <AnimatePresence mode="popLayout"> {isOpen && ( <motion.ul variants={listV} initial="hidden" animate="show" exit="exit" > {products.map(p => ( <motion.li key={p.id} variants={cardV} layout // ✅ List ሲቀየር smooth! whileHover={{ x: 6, backgroundColor: 'rgba(232,121,249,.08)' }} whileTap={{ scale: 0.98 }} > {p.name} — {p.price} </motion.li> ))} </motion.ul> )} </AnimatePresence> ); } // 3️⃣ Page transition (Next.js App Router) export default function Page() { return ( <motion.main initial={{ opacity: 0, x: -20 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 20 }} transition={{ duration: 0.4, ease: 'easeOut' }} > {/* Page content */} </motion.main> ); }
ማንኛውም HTML element motion. ጨምሮ መፃፍ! initial, animate, exit props በመስጠት አኒሜሽኑን ሙሉ በሙሉ ትቆጣጠራላችሁ!
Animation config object ውጭ ፍጠር → variants prop ሰጥ! Parent-child stagger ለ list animations ምርጡ!
Component ከ DOM ሲወጣ exit animation እንዲሰራ ያደርጋል! key prop ያስፈልገዋል! mode="wait" ወይም "popLayout" መጠቀም ይቻላል!
type:'spring' + stiffness + damping = ተፈጥሯዊ እንቅስቃሴ ይኖረዋል! type:'tween' + duration + ease = ጊዜውን በትክክል ለመቆጣጠር! Default = spring ነው!
whileHover · whileTap · whileDrag · whileInView · whileFocus — props ብቻ በመስጠት! ምንም አይነት Event listener አያስፈልግም!