리μ‘νΈ μ λλ©μ΄μ μ»΄ν¬λνΈλ‘ μλκ° μλ μΈν°λμ λ§λ€κΈ°(Framer Motion, React Transition Group)
νλ μΉ μ ν리μΌμ΄μ μμλ λ¨μν μ μ UIλ₯Ό λμ΄, μ¬μ©μμμ λμ μΈ μνΈμμ©μ΄ λ§€μ° μ€μν©λλ€. νΉν 리μ‘νΈ κΈ°λ° μ λλ©μ΄μ μ»΄ν¬λνΈλ₯Ό νμ©νλ©΄, μ¬μ©μ κ²½ν(UX)μ κ·Ήλννκ³ μΈν°νμ΄μ€μ μλκ°μ λΆμ΄λ£μ μ μμ΅λλ€. μ΄λ² ν¬μ€ν μμλ CSS μ λλ©μ΄μ , React Transition Group, Framer Motion λ± λ€μν μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬λ₯Ό νμ©νμ¬ λμ μΈ UIλ₯Ό ꡬννλ λ°©λ²κ³Ό ν¨κ», μ λλ©μ΄μ μ μ±λ₯ μ΅μ ν λ° μ¬μ©μ κ²½ν κ°μ λ°©μμ μ¬λ μκ² λ€λ£¨μ΄ λ³΄κ² μ΅λλ€.
μ λλ©μ΄μ μ νμμ±κ³Ό 리μ‘νΈμ κ°μ
μ λλ©μ΄μ μ μ¬μ©μκ° μΉ νμ΄μ§λ μ ν리μΌμ΄μ μμ μ 보λ₯Ό λ³΄λ€ μ½κ² μΈμ§νκ³ , μΈν°λμ μ κ²°κ³Όλ₯Ό μ§κ΄μ μΌλ‘ μ΄ν΄ν μ μλλ‘ λλ μ€μν μμμ λλ€. μλ₯Ό λ€μ΄, λ²νΌ ν΄λ¦ μ λΆλλ¬μ΄ μ ν ν¨κ³Όλ νμ΄μ§ μ΄λ μ νμ΄λ μΈ/μμ ν¨κ³Όλ₯Ό μ μ©νλ©΄, μ¬μ©μμκ² λ³΄λ€ μμ°μ€λ¬μ΄ κ²½νμ μ 곡ν μ μμ΅λλ€. 리μ‘νΈλ μ»΄ν¬λνΈ κΈ°λ° κ΅¬μ‘°μ κ°μ DOM(Virtual DOM) λλΆμ μ λλ©μ΄μ μ²λ¦¬μλ λ°μ΄λ μ±λ₯μ λ°νν©λλ€. μ»΄ν¬λνΈ λ¨μλ‘ μ λλ©μ΄μ λ‘μ§μ λΆλ¦¬ν μ μμ΄ μ μ§λ³΄μμ νμ₯μ± λ©΄μμλ ν° μ₯μ μ μ§λκ³ μμ΅λλ€.
λ€μν μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬ μκ°
1. CSS μ λλ©μ΄μ
μ ν΅μ μΈ CSS μ λλ©μ΄μ μ keyframesμ transition μμ±μ νμ©νμ¬ κ°λ¨νκ³ μ§κ΄μ μΈ μ λλ©μ΄μ ν¨κ³Όλ₯Ό ꡬνν μ μμ΅λλ€. CSS μ λλ©μ΄μ μ λΈλΌμ°μ λ΄μ₯ κΈ°λ₯μ μ¬μ©νλ―λ‘ λ³λμ λΌμ΄λΈλ¬λ¦¬ μ€μΉ μμ΄λ μ¬μ©ν μ μμΌλ©°, μ λλ©μ΄μ μ μ±λ₯ λν λΈλΌμ°μ μ΅μ νμ μν΄ λ³΄μ₯λ©λλ€.
μμ μ½λ:
import React from 'react';
import styled, { keyframes } from 'styled-components';
const fadeIn = keyframes`
from {
opacity: 0;
}
to {
opacity: 1;
}
`;
const AnimatedDiv = styled.div`
width: 200px;
height: 200px;
background-color: #4caf50;
animation: ${fadeIn} 1s ease-in-out forwards;
`;
const CSSAnimationComponent = () => {
return <AnimatedDiv>CSS μ λλ©μ΄μ
</AnimatedDiv>;
};
export default CSSAnimationComponent;
μ μ½λλ styled-componentsλ₯Ό μ¬μ©νμ¬ κ°λ¨ν νμ΄λ μΈ μ λλ©μ΄μ μ ꡬνν μμ λ‘, μ»΄ν¬λνΈκ° λ λλ§λλ©΄μ μμν λνλλ ν¨κ³Όλ₯Ό 보μ¬μ€λλ€.
2. React Transition Group
React Transition Groupμ 리μ‘νΈ μ»΄ν¬λνΈμ μν λ³νμ λ°λ₯Έ μ λλ©μ΄μ μ μμ½κ² μ μ©ν μ μλ λΌμ΄λΈλ¬λ¦¬μ λλ€. μ΄ λΌμ΄λΈλ¬λ¦¬λ μ»΄ν¬λνΈμ λ§μ΄νΈ, μ λ°μ΄νΈ, μΈλ§μ΄νΈμ κ°μ μλͺ μ£ΌκΈ° μ΄λ²€νΈμ κΈ°λ°νμ¬ μ λλ©μ΄μ μ μ μ©ν μ μμΌλ©°, CSS ν΄λμ€ κΈ°λ° μ λλ©μ΄μ κ³Ό μ°λνκΈ° μ’μ΅λλ€.
μμ μ½λ:
import React, { useState } from 'react';
import { CSSTransition } from 'react-transition-group';
import './transition.css'; // λ³λμ CSS νμΌμ μ λλ©μ΄μ
ν΄λμ€ μ μ
const TransitionComponent = () => {
const [show, setShow] = useState(false);
return (
<div>
<button onClick={() => setShow(!show)}>ν κΈ μ λλ©μ΄μ
</button>
<CSSTransition
in={show}
timeout={300}
classNames="fade"
unmountOnExit
>
<div className="animated-box">React Transition Group</div>
</CSSTransition>
</div>
);
};
export default TransitionComponent;
μ μμ μμλ λ²νΌ ν΄λ¦μ λ°λΌ μ»΄ν¬λνΈκ° λ±μ₯νκ±°λ μ¬λΌμ§λ©°, CSS ν΄λμ€λ₯Ό ν΅ν νμ΄λ ν¨κ³Όλ₯Ό μ μ©ν©λλ€. transition.css νμΌμλ μ λλ©μ΄μ ν¨κ³Όλ₯Ό μν ν΄λμ€λ€μ΄ μ μλμ΄ μμ΄μΌ ν©λλ€.
3. Framer Motion
Framer Motionμ μ΅μ 리μ‘νΈ μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬λ‘, μμ°μ€λ¬μ΄ 물리 κΈ°λ° μ λλ©μ΄μ κ³Ό μ μ€μ² μΈμ κΈ°λ₯μ μ 곡ν©λλ€. 볡μ‘ν μ λλ©μ΄μ μ΄λ μΈν°λν°λΈν λͺ¨μ ν¨κ³Όλ₯Ό ꡬνν λ λ§€μ° μ μ©νλ©°, APIκ° μ§κ΄μ μ΄μ΄μ λΉ λ₯Έ κ°λ°μ΄ κ°λ₯ν©λλ€.
μμ μ½λ:
import React from 'react';
import { motion } from 'framer-motion';
const FramerMotionComponent = () => {
return (
<motion.div
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5, ease: "easeOut" }}
style={{
width: '200px',
height: '200px',
backgroundColor: '#ff5722',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '10px'
}}
>
Framer Motion μ λλ©μ΄μ
</motion.div>
);
};
export default FramerMotionComponent;
Framer Motionμ νμ©ν μ΄ μμ λ μ»΄ν¬λνΈκ° λνλ λ, μμν νλλκ³ ν¬λͺ λμμ λ³ννλ λͺ¨μ ν¨κ³Όλ₯Ό 보μ¬μ€λλ€. κ°λ°μκ° μ μ΄ν μ μλ λ€μν μμ±κ³Ό νΈλμ§μ μ΅μ μ ν΅ν΄ λ§€μ° μ κ΅ν μ λλ©μ΄μ μ ꡬνν μ μμ΅λλ€.
μ λλ©μ΄μ μ±λ₯ μ΅μ ν λ°©μ
μ λλ©μ΄μ μ UIμ μλκ°μ λΆμ΄λ£μ΄ μ£Όμ§λ§, κ³Όλνκ² μ¬μ©νκ±°λ λΆμ μ νκ² κ΅¬νν κ²½μ° μ±λ₯ μ νμ μ¬μ©μ κ²½νμ μ νλ₯Ό μ΄λν μ μμ΅λλ€. λ€μμ 리μ‘νΈ κΈ°λ° μ λλ©μ΄μ μ»΄ν¬λνΈλ₯Ό ꡬνν λ κ³ λ €ν΄μΌ ν μ±λ₯ μ΅μ ν λ°©μμ λλ€.
1. νλμ¨μ΄ κ°μ νμ©
CSS μ λλ©μ΄μ μ κ²½μ°, transformκ³Ό opacity μμ±μ νλμ¨μ΄ κ°μμ μ¬μ©ν μ μμ΄ μ±λ₯μ μ 리ν©λλ€. λ°λΌμ μ λλ©μ΄μ μ ꡬνν λλ λ μ΄μμμ μν₯μ μ£Όλ μμ± λμ , νλμ¨μ΄ κ°μμ΄ κ°λ₯ν μμ±μ νμ©νλ κ²μ΄ μ’μ΅λλ€.
2. μ λλ©μ΄μ νλ μ μ μ΄
리μ‘νΈμμλ μν λ³νκ° λΉλ²νκ² λ°μνλ©΄ μ λλ©μ΄μ μ΄ μ€λ¨λκ±°λ λκΈΈ μ μμ΅λλ€. μ΄λ₯Ό λ°©μ§νκΈ° μν΄ requestAnimationFrameμ νμ©νκ±°λ, νλ μ λ¨μλ‘ μ λλ©μ΄μ μ μ μ΄νλ λ°©λ²μ κ³ λ €ν μ μμ΅λλ€.
3. μ»΄ν¬λνΈ λ¦¬λ λλ§ μ΅μν
λΆνμν 리λ λλ§μ μ λλ©μ΄μ μ±λ₯μ μ§μ μ μΈ μν₯μ λ―ΈμΉ©λλ€. React.memoμ κ°μ μ΅μ ν κΈ°λ²μ μ¬μ©νμ¬, μ λλ©μ΄μ μ΄ μ μ©λλ μ»΄ν¬λνΈμ 리λ λλ§ νμλ₯Ό μ΅μννλ κ²μ΄ μ€μν©λλ€.
4. λΌμ΄λΈλ¬λ¦¬ μ ν μ κ°λ²Όμ΄ μ΅μ νμ©
Framer Motionμ΄λ React Transition Groupκ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ λ€μν κΈ°λ₯μ μ 곡νμ§λ§, νλ‘μ νΈμ μꡬμ¬νμ λ§μΆμ΄ κ°λ²Όμ΄ μ λλ©μ΄μ μ΅μ λ§ μ ννλ κ²λ μ±λ₯ ν₯μμ λμμ΄ λ©λλ€.
μ¬μ©μ κ²½ν κ°μ μ μν μ λλ©μ΄μ μ λ΅
μ λλ©μ΄μ μ λ¨μν μκ°μ ν¨κ³Όλ₯Ό λμ΄μ μ¬μ©μ κ²½νμ κ°μ νλ μ€μν λꡬμ λλ€. λ€μμ μ λλ©μ΄μ μ νμ©νμ¬ μ¬μ©μ κ²½νμ κ·Ήλνν μ μλ λͺ κ°μ§ μ λ΅μ λλ€.
1. μΈν°λμ νΌλλ°± μ 곡
μ¬μ©μκ° λ²νΌ ν΄λ¦, λ§μ°μ€ μ€λ² λ±μ νλμ ν λ μ λλ©μ΄μ μ ν΅ν΄ νΌλλ°±μ μ 곡νλ©΄, ν΄λΉ μΈν°λμ μ΄ μ μμ μΌλ‘ μ²λ¦¬λκ³ μμμ μ§κ΄μ μΌλ‘ μΈμ§ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λ²νΌ ν΄λ¦ μ μ΄μ§ λ리λ ν¨κ³Όλ λ‘λ© μνλ₯Ό μ λλ©μ΄μ μΌλ‘ νννλ©΄ μ¬μ©μ λ§μ‘±λκ° λμμ§λλ€.
2. μ ν μ λλ©μ΄μ μΌλ‘ νμ΄μ§ νλ¦ κ°μ
νμ΄μ§ κ° μ νμ΄λ λͺ¨λ¬ μ°½μ λ±μ₯, μ¬λΌμ§μ μ λλ©μ΄μ ν¨κ³Όλ₯Ό μ μ©νλ©΄, μ¬μ©μκ° νμ¬ μμΉλ₯Ό μ½κ² μΈμν μ μμ΅λλ€. μ΄λ¬ν μ ν μ λλ©μ΄μ μ μ¬μ©μμκ² μμ°μ€λ¬μ΄ νλ¦μ μ 곡νλ©°, UIμ μΌκ΄μ±μ μ μ§νλ λ° λμμ μ€λλ€.
3. μ λλ©μ΄μ κ³Ό λ°μ΄ν° μκ°ν κ²°ν©
μ€μκ° λ°μ΄ν°λ μ°¨νΈμ κ°μ μκ°μ μμμ μ λλ©μ΄μ μ μ μ©νλ©΄, λ°μ΄ν°μ λ³νκ° λ³΄λ€ μ§κ΄μ μΌλ‘ μ λ¬λ©λλ€. μλ₯Ό λ€μ΄, κ·Έλνμ λ°κ° μ¦κ°νκ±°λ κ°μν λ μ λλ©μ΄μ ν¨κ³Όλ₯Ό μ μ©νλ©΄, λ³νμ νλ¦μ μ¬μ©μμκ² λͺ ννκ² λ³΄μ¬μ€ μ μμ΅λλ€.
4. μ¬μ©μ μ€μ μ΅μ μ 곡
μ λλ©μ΄μ μ΄ κ³Όλνλ©΄ μΌλΆ μ¬μ©μμκ² λΆνΈμ μ€ μ μμΌλ―λ‘, μ λλ©μ΄μ ν¨κ³Όλ₯Ό μΌκ³ λ μ μλ μ΅μ μ μ 곡νλ κ²λ μ’μ λ°©λ²μ λλ€. μ΄λ₯Ό ν΅ν΄ μ κ·Όμ±μ κ³ λ €νκ³ , μ¬μ©μ λ§μΆ€ν κ²½νμ μ 곡ν μ μμ΅λλ€.
μ€λ¬΄ μ μ© λ° κ²°λ‘
리μ‘νΈ κΈ°λ° μ λλ©μ΄μ μ»΄ν¬λνΈλ μΉ μ ν리μΌμ΄μ μ μλκ°κ³Ό μΈν°λν°λΈν κ²½νμ λν΄μ£Όλ κ°λ ₯ν λꡬμ λλ€. CSS μ λλ©μ΄μ , React Transition Group, Framer Motionκ³Ό κ°μ λ€μν λΌμ΄λΈλ¬λ¦¬λ₯Ό μ μ ν νμ©νλ©΄, κ°λ¨ν ν¨κ³ΌλΆν° 볡μ‘ν λͺ¨μ κΉμ§ λ€μν μ λλ©μ΄μ μ μμ½κ² ꡬνν μ μμ΅λλ€. λν, μ±λ₯ μ΅μ νμ μ¬μ©μ κ²½ν κ°μ μ μν μ λ΅μ ν¨κ» κ³ λ €νλ©΄, μ€μ νλ‘μ νΈμμ μμ μ μ΄κ³ ν¨κ³Όμ μΈ μ λλ©μ΄μ ꡬνμ΄ κ°λ₯ν©λλ€.
μ€λ¬΄μμ μ λλ©μ΄μ μ λμ ν λλ λ€μκ³Ό κ°μ μ λ€μ μ λ νμκΈΈ λ°λλλ€.
- κΈ°λ₯κ³Ό μ±λ₯μ κ· ν: μ λλ©μ΄μ ν¨κ³Όκ° κ³Όλνμ§ μλλ‘, μ€μ μ¬μ©μ μΈν°λμ μ νμν μ΅μνμ ν¨κ³Όλ§ μ μ©ν©λλ€.
- μ½λμ μ μ§λ³΄μμ±: μ»΄ν¬λνΈ λ¨μλ‘ μ λλ©μ΄μ λ‘μ§μ λΆλ¦¬νκ³ , μ¬μ¬μ© κ°λ₯ν λͺ¨λλ‘ κ΅¬μ±νμ¬ μ μ§λ³΄μμ νμ₯μ±μ κ³ λ €ν©λλ€.
- ν μ€νΈμ νΌλλ°±: μ λλ©μ΄μ μ μ© ν μ¬μ©μ νΌλλ°±μ μ κ·Ή μλ ΄νκ³ , νμν κ²½μ° κ°μ μμ μ μ§νν©λλ€.
- μ κ·Όμ±κ³Ό νΈνμ±: λ€μν λλ°μ΄μ€μ λΈλΌμ°μ νκ²½μμ μ λλ©μ΄μ μ΄ μννκ² λμνλλ‘, νλμ¨μ΄ κ°μ λ° CSS μ΅μ ν κΈ°λ²μ νμ©ν©λλ€.
μ΄λ² ν¬μ€ν μμ μκ°ν λ€μν μ λλ©μ΄μ λΌμ΄λΈλ¬λ¦¬μ ꡬν μμ λ 리μ‘νΈ μ ν리μΌμ΄μ μ λμ μΈ μΈν°λμ μ λμ νλ λ° ν° λμμ΄ λ κ²μ λλ€. μ¬λ¬λΆμ νλ‘μ νΈμ λ§λ μ λλ©μ΄μ μ λ΅μ μ ννκ³ , μ§μμ μΈ μ±λ₯ μ΅μ νμ μ¬μ©μ νΌλλ°± λ°μμ ν΅ν΄ λμ± νλΆν UI/UXλ₯Ό ꡬννμκΈΈ λ°λλλ€.
리μ‘νΈμ μ»΄ν¬λνΈ κΈ°λ° κ΅¬μ‘°μ λ€μν μ λλ©μ΄μ λꡬλ₯Ό μ μ ν νμ©νλ©΄, μ¬μ©μμκ² μ§κ΄μ μ΄κ³ λͺ°μ κ° μλ κ²½νμ μ 곡ν μ μμ΅λλ€. μμΌλ‘λ μ΅μ κΈ°μ λν₯κ³Ό μ¬μ©μ λμ¦μ λ§μΆμ΄ μ λλ©μ΄μ ν¨κ³Όλ₯Ό μ§μμ μΌλ‘ κ°μ νκ³ λ°μ μμΌ λκ°μκΈΈ κΈ°μν©λλ€.
λκΈ