๐ 7์ฃผ์ฐจ ๊ณผ์ : ๋ ธ๋ง๋์ฝ๋ React JS ๋ง์คํฐํด๋์ค 8.animation ์๊ฐ
import { motion } from "framer-motion";
ํ์)div๋ฅผ framer motion์ ํตํด ์ง์ ์ ์ผ๋ก animateํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅ
๋์ <motion.div>
ํ์์ผ๋ก ์์ฑ
motion.
์ ์์ฑํด๋ณด๋ฉด ์์ ๊ฐ์ด ์ฐ๋ฆฌ๊ฐ animate ์ํฌ ์ ์๋ ๋ชจ๋ HTML๋ค์ ํ์ธํ ์ ์๋ค.
์ฆ, ์ฐ๋ฆฌ๊ฐ ๋ฌด์ธ๊ฐ๋ฅผ animateํ๊ฒ ๋ง๋๋ ค๋ฉด ํญ์ motion์ผ๋ก๋ถํฐ HTML element๋ฅผ ๋ถ๋ฌ์์ผ๋ง ํจ!
Box๋ผ๋ styled components๊ฐ ์๋๋ฐ ์ด๊ฑธ animate์ํค๊ณ ์ถ๋ค๊ณ ํ์.
์ผ๋จ์, motion.Box
๋ ๋ถ๊ฐ๋ฅํ๋ค.. ์ด๋ ๊ฒ ํ ์ X
โญโญโญ ๋์ , styled components๋ฅผ ์ ์ธํ๋ ๊ณณ์ ๊ฐ์ styled.div
๋ฅผ styled(motion.div)
๋ก ๋ฐ๊ฟ์ฃผ์!!!!!!
์ ์ ์ธ๋์ง ํ์ธํ๊ธฐ ์ํด props๋ฅผ ๋๊ฒจ์ฃผ์
props์๋ animate, transition ๋ฑ์ด ์๋ค.
prop๋ค์ ์์ฑํ๋ฉด ์๋์ ๊ฐ์ด ์๋์์ฑ์ผ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ์ ์๋ ๊ฒ๋ค์ด ๋ฌ๋ค.
function App() {
return (
<Wrapper>
<Box transition={{ delay:3 }} animate={{ borderRadius: "100px" }}/>
</Wrapper>
);
}
์ด๋ ๊ฒ ํด์ฃผ๊ณ ํ์ธํด๋ณด๋ฉด
์ด๋ ๊ฒ ์๋ก๊ณ ์นจ ํ 3์ด ํ์ borderRadius 100px๋ฅผ ๊ฐ์ง ์์ผ๋ก ๋ฐ๋๋ค!
๊ทธ ์ด๋ค css ์ฝ๋๋ ์์ฑํ์ง ์๊ณ ๋ง๋ค์ด ๋ธ ๊ฒ์ด๋ค. ๋งค์ฐ ๊ฐ๋จ
+) props๋ค ์์๋ ๋ชจ๋ css ์ฌ์ฉ ๊ฐ๋ฅ
๊ฑ ์ฐ๋ฆฌ๊ฐ ์๋ css๋ค์ ๋ฃ์ด์ ์ฌ์ฉํ๋ฉด ๋จ
๋ฉ์ถ ๋ ์ด์ง ํ๊ธฐ๋๊ฒ ์๋๋ฐ ์ด๋ transition type์ ๊ธฐ๋ณธ ์ค์ ์ด spring์ด๋ผ์ ๊ทธ๋ฐ๊ฑฐ๊ณ tween์ผ๋ก ์ง์ ํด์ฃผ๋ฉด ํด๊ฒฐ.
(๊ทผ๋ฐ ๋ณดํต spring ์ด๋ค๊ณ ํจใ
)
animation์ด ์์๋๋ ์ง์ ์์์ ์ํ๋ฅผ ์ง์ ํด์ฃผ๋ prop. ์ฆ, element์ ์ด๊ธฐ ์ํ
function App() {
return (
<Wrapper>
<Box
initial={{ scale:0 }}/>
</Wrapper>
);
}
๋ฌผ๋ฆฌ ํ์ ์๋ฎฌ๋ ์ดํธ ํจ๊ณผ๋ฅผ ์ค
โ ๋ปฃ๋ปฃํ๊ฒ ๋ง๋ค์ด์ค
function App() {
return (
<Wrapper>
<Box
transition={{type:"spring", stiffness:10 }}
initial={{ scale:0 }}
animate={{scale:1, rotateZ:360 }}/>
</Wrapper>
);
}
๋ฌผ๋ฆฌํ์ ์๋ฎฌ๋ ์ดํธ ํจ๊ณผ๋ฅผ ์ค
โ ๋ฐ๋๋ ฅ
function App() {
return (
<Wrapper>
<Box
transition={{type:"spring", damping:1}}
initial={{ scale:0 }}
animate={{scale:1, rotateZ:360 }}/>
</Wrapper>
);
}
๋ฌด๊ฑฐ์ด ์ ๋๋ฅผ ์กฐ์ ๊ฐ๋ฅ
- ๊ธฐ๋ณธ์ค์ ๊ฐ = 1
function App() {
return (
<Wrapper>
<Box
transition={{type:"spring", mass: 5}}
initial={{ scale:0 }}
animate={{scale:1, rotateZ:360 }}/>
</Wrapper>
);
}
ํ๊ธฐ๋ ์ ๋ ์กฐ์ (0๊ณผ 1 ์ฌ์ด์ฌ์ผ ํจ)
- 0์ ํ๊ธฐ์ง X, 1์ ์์ฒญ ํ๊น
- stiffness, damping, mass๊ฐ ์ค์ ๋์๋ค๋ฉด bounce๋ ๋ฎ์ด์์์ง
- ๊ธฐ๋ณธ๊ฐ 0.25
function App() {
return (
<Wrapper>
<Box
transition={{type:"spring", bounce:0.8}}
initial={{ scale:0 }}
animate={{scale:1, rotateZ:360 }}/>
</Wrapper>
);
}
๊ณต์ํ์ด์ง์ ๊ฐ๋ณด๋ฉด ์ด ์ธ์๋ ๋ง์ ํจ๊ณผ ์ฌ์ฉ ๊ฐ๋ฅ
์ ๋๋ฉ์ด์ ์ stage ์ญํ .
์ปดํฌ๋ํธ๊ฐ ๊ฐ์ง ์ ์๋ ๋ฏธ๋ฆฌ ์ ์๋ ์๊ฐ์ state
- ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ํด์ค
- ๋ถ๋ชจ์ปดํฌ๋ํธ์์ ๋ฐ์ํ๋ animation์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์์์ปดํฌ๋ํธ์๋ ๋ฐ์์ํด
- ๋ง์ ์ ๋๋ฉ์ด์ ๋ค์ ํ๋๋ก ์ฐ๊ฒฐ์์ผ์ค
const myVars = {
start: { scale: 0 },
end: { scale: 1, rotateZ: 360, transition: {type: "spring", delay: 0.5} }
};
function App() {
return (
<Wrapper>
<Box variants={myVars} initial="start" animate="end" />
</Wrapper>
);
}
์ด๋ฐ ์์ผ๋ก ๋ฐ๊ฟ์ค ์ ์์
initial="~~ animate="~~"
๋ถ๋ถ์ ๋ณต์ฌํด์ ์์์๊ฒ ์ ๋ฌํ๋ค.delayChildren: ๋ชจ๋ ์์๋ค์๊ฒ ์ค์ ํด์ค๋งํผ์ ์๊ฐ์ ์ง์ฐ์์ผ์ค
staggerChildren: ๋ชจ๋ ์์๋ค์๊ฒ ์ค์ ํด์ค๋งํผ์ ์๊ฐ์ ์์ฐจ์ ์ผ๋ก ์ง์ฐ์์ผ์ค
const boxVariants = {
start:{
opacity:0,
scale:0.5,
},
end:{
scale:1,
opacity:1,
transition:{
type:"spring",
duration:0.5,
bounce: 0.5,
delayChildren: 0.5,
staggerChildren: 0.2,
}
}
}
const circleVariants = {
start:{
opacity:0,
y: 10 //y์ขํ ์์ ํ๊ณ ์ถ์ ๋ ์ฌ์ฉ
},
end:{
opacity:1,
y: 0
},
}
function App() {
return (
<Wrapper>
<Box variants={boxVariants} initial="start" animate="end">
<Circle variants={circleVariants}/>
<Circle variants={circleVariants}/>
<Circle variants={circleVariants}/>
<Circle variants={circleVariants}/>
</Box>
</Wrapper>
);
}
ํธ๋ฒ ์ ์ค์ฒ๊ฐ ์ธ์๋๋ ๋์ ์ ๋๋ฉ์ด์ ํ ์์ฑ ๋๋ ๋ณํ ๋ ์ด๋ธ
function App() {
return (
<Wrapper>
<Box whileHover={{scale:2}}/>
</Wrapper>
);
}
์ปดํฌ๋ํธ๋ฅผ ๋๋ฅด๊ณ ์๋ ๋์ ์ ๋๋ฉ์ด์ ํ ์์ฑ ๋๋ ๋ณํ ๋ ์ด๋ธ
function App() {
return (
<Wrapper>
<Box
whileHover={{scale:1.5, rotateZ:90 }}
whileTap={{scale:1, borderRadius: "100px"}}
/>
</Wrapper>
);
}
๋ฌผ๋ก variants๋ก ์ ๋ฆฌ ๊ฐ๋ฅํ๋ค.
const boxVariants = {
hover:{scale:1.5, rotateZ:90 },
click:{scale:1, borderRadius: "100px"},
}
function App() {
return (
<Wrapper>
<Box
variants={boxVariants}
whileHover="hover"
whileTap="click"
/>
</Wrapper>
);
}
์กฐ๊ฑด๋ฌธ์ด ํ์ํ ๋๊ฐ ์๊ฒ ์ง? ๊ทธ๋ฌ๋ฉด
function App() {
return (
<Wrapper>
<Box
variants={boxVariants}
whileHover={condition ? "hover" : "other"}
//condition์๋ ํด๋น ์กฐ๊ฑด ๋ฃ๊ณ "other"์๋ ๋ค๋ฅธ ์์ฑ ์ด๋ฆ ๋ฃ๊ธฐ
whileTap="click"
/>
</Wrapper>
);
}
์ด๋ฐ ์์ผ๋ก ํด์ฃผ๋ฉด ๋๋ค.
๋๋๊ทธ ์ ์ค์ฒ๊ฐ ์ธ์๋๋ ๋์ ์ ๋๋ฉ์ด์ ํ ์์ฑ ๋๋ ๋ณํ ๋ ์ด๋ธ
์ผ๋จ drag๋ฅผ ํ์ฑ์์ผ์ค์ผ๊ฒ ์ง?
๋๋๊ฒ๋ ๊ทธ๋ฅ drag ๋จ์ด๋ง ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
drag๋ฅผ ์ถ๊ฐํ๋ฉด ์ด๋๋ ์ง ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ณณ์ผ๋ก ๋๋๊ทธํ ์ ์๋ค.
function App() {
return (
<Wrapper>
<Box
drag //์ด๊ฒ๋ง ํด์ฃผ๋ฉด ๋จ!
variants={boxVariants}
whileHover="hover"
whileTap="click"
/>
</Wrapper>
);
}
์์นซํ๋ฉด ํ๋ฉด ๋ฐ์ผ๋ก ๋ ์๊ฐ๋ฒ๋ฆผใ
์ด์ whileDrag๋ฅผ ์ฌ์ฉํด๋ณด์. ์์์ ๋ฐ๊พผ๋ค๊ณ ํ๋ฉด,
whileDrag={{backgroundColor:"blue"}}
์ด๋ฐ์์ผ๋ก ๋ฃ์ผ๋ฉด ์๋๊ณ rgba ๊ฐ์ผ๋ก ๋ณํํด์ ๊ทธ ๊ฐ์ ๋ฃ์ด์ค์ผํ๋ค.
(์ฐธ๊ณ : https://flatuicolors.com/palette/defo)
๊ทธ๋์ผ ์ ๋๋ฉ์ด์ ์ด ์ ์ ์ฉ๋จโ๏ธโ๏ธ
function App() {
return (
<Wrapper>
<Box
drag
variants={boxVariants}
whileDrag={{backgroundColor:"rgb(46,204,113)"}} //์๋ฉ๋๋์
whileHover="hover"
whileTap="click"
/>
</Wrapper>
);
}
์ค์ ๋ก ์ฝ์์ฐฝ์ ์ด์ด์ ํ์ธํด๋ณด๋ฉด
์์ง์ผ ๋๋ง๋ค ๊ฐ์ด ์
๋ฐ์ดํธ ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
+) ์ถ๊ฐ๋ก drag="x"
๋ฅผ ํ๋ฉด x์ถ ๋ด์์๋ง ๋๋๊ทธํ ์ ์๊ณ ,
drag="y"
๋ฅผ ํ๋ฉด y์ถ ๋ด์์๋ง ๋๋๊ทธํ ์ ์๋ค.
๋๋๊น ์ด ํ์ฉ๋ ์ ์๋ ์์ญ์ผ๋ก ํ์ฉ๋ ๋๋๊ทธ ๊ฐ๋ฅ ์์ญ์ ์ ์ฝ ์กฐ๊ฑด์ ์ ์ฉ.
๋๋๊ทธ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ์ ๊ฐ์ฅ์๋ฆฌ ๊ฑฐ๋ฆฌ๋ฅผ ์ ์. (๋๋๊ทธ ๊ฐ๋ฅํ ์์ญ์ ๊ฐ์ฅ์๋ฆฌ์์ ์ผ๋ง๋งํผ๊น์ง ํ์ฉํ ๊ฒ์ธ์ง ์ง์ )
function App() {
return (
<Wrapper>
<Box
drag
dragConstraints={{top:-50, bottom:50, left:-50, right: 50}}
variants={boxVariants}
whileDrag="drag"
whileHover="hover"
whileTap="click"
/>
</Wrapper>
);
}
๋ณด๋ค์ํผ dragConstraints
์ ์ํด ๋๋๊ทธ์์ญ์ด ์ ํ๋๋ค.
function App() {
const biggerBoxRef = useRef<HTMLDivElement>(null); //typescript์๊ฒ HTML ์์์์ ์๋ฆผ
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragConstraints={biggerBoxRef}
variants={boxVariants}
whileDrag="drag"
whileHover="hover"
whileTap="click"
/>
</BiggerBox>
</Wrapper>
);
}
๋ณด๋ค์ํผ ref ์ค์ ํ ๋ถ๋ถ์ ์ ์ฝ์ด ๊ฑธ๋ฆฐ๋ค.
๋๋๊ทธ ๊ฐ๋ฅํ ์์๋ ๋๋๊ทธ๋ฅผ ๋์ ๋, ์์ ์ผ๋ก ๋๋์๊ฐ
function App() {
const biggerBoxRef = useRef<HTMLDivElement>(null);
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragSnapToOrigin //์ฌ๊ธฐ๋ง ์ถ๊ฐํด์ฃผ๋ฉด๋จ
dragConstraints={biggerBoxRef}
variants={boxVariants}
whileDrag="drag"
whileHover="hover"
whileTap="click"
/>
</BiggerBox>
</Wrapper>
);
}
์ธ๋ถ ์ ์ฝ ์กฐ๊ฑด์์ ํ์ฉ๋๋ ์ด๋ ์ ๋
0 = ์์ง์ ์์, 1 = ์ ์ฒด ์์ง์. ๊ธฐ๋ณธ๊ฐ 0.5
function App() {
const biggerBoxRef = useRef<HTMLDivElement>(null);
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragSnapToOrigin
dragElastic={0.5} //๋์ BiggerBox์ overflow:hidden์ ์ง์์ฃผ์
dragConstraints={biggerBoxRef}
variants={boxVariants}
whileDrag="drag"
whileHover="hover"
whileTap="click"
/>
</BiggerBox>
</Wrapper>
);
}