[react] react Framer-motion 리μ‘νΈ νλ μ΄λ¨Έ νμ©νκΈ° (μ λλ©μ΄μ μ κ°νΈνκ²!)
νλ‘κ·Έλλ° μΈκ³λ₯Ό νꡬν©μλ€.
react Framer-motion 리μ‘νΈ νλ μ΄λ¨Έ λͺ¨μ νμ©νκΈ°
React Framer Motionμ μ£Όλ‘ λ€μκ³Ό κ°μ μν μ ν©λλ€:
μ λλ©μ΄μ
μ μ΄: μ¬μ©μκ° μ μν μ»΄ν¬λνΈλ DOM μμλ₯Ό μ λλ©μ΄μ
νν μ μμ΅λλ€. μμ§μ, ν¬κΈ° μ‘°μ , νμ λ± λ€μν μ λλ©μ΄μ
ν¨κ³Όλ₯Ό ꡬνν μ μμ΅λλ€.
μ μ€μ² μ²λ¦¬: ν°μΉ, ν΄λ¦ λ±μ μ μ€μ² μ΄λ²€νΈλ₯Ό κ°μ§νκ³ μ΄μ λ°λ₯Έ μ λλ©μ΄μ
μ μ½κ² μΆκ°ν μ μμ΅λλ€.
μ»΄ν¬λνΈ κ° ν΅μ : λ€μν μ»΄ν¬λνΈ κ°μ ν΅μ μ μ΄μ§νλ©°, μ λλ©μ΄μ
μ ν΅ν μ¬μ©μ κ²½ν ν₯μμ κΈ°μ¬ν©λλ€.
react Framer-motion 리μ‘νΈ νλ μ΄λ¨Έ λͺ¨μ ꡬν μμ
ꡬν μμ νλ©΄μ λλ€.
λ°μ€ ν¨κ³Ό, λ§μ°μ€ hover μ boxκ° μ»€μ§λ ν¨κ³Ό, λ²νΌμ΄ λνλλ ν¨κ³Όλ₯Ό μ¬μ©νμ΅λλ€.
react Framer-motion 리μ‘νΈ νλ μ΄λ¨Έ λͺ¨μ νμ© λ°©λ²
1. 곡μ μ¬μ΄νΈ
λ€μν ν¨κ³Όμ μ¬μ΄νΈλ μλ μ¬μ΄νΈ μ°Έκ³ λ°λλλ€.
https://www.framer.com/motion/
Documentation | Framer for Developers
An open source, production-ready motion library for React on the web.
www.framer.com
1. μ μ€μ² μ΄λ²€νΈμ νΈλμ§μ : whileHover, whileTap λ±μ μ μ€μ² κ΄λ ¨ μ΄λ²€νΈλ₯Ό ν΅ν΄ μ¬μ©μ μνΈ μμ©μ λ°μνλ©° λΆλλ¬μ΄ νΈλμ§μ μ μ 곡ν©λλ€.
2. νλ μ-λ³ μ λλ©μ΄μ : animate μμ±μ ν΅ν΄ νΉμ νλ μμμμ μμ±μ μ§μ νκ³ , λΆλλ½κ² μ νν μ μμ΅λλ€.
2. μ€μΉ
μλ λͺ λ Ήμ΄λ₯Ό μ λ ₯νλ©΄ μ€μΉν μ μμ΅λλ€.
npm install framer-motion
3. μ¬μ© λ°©λ²
motionμ μν¬νΈνκ³ motion.divλ₯Ό μμ±νμ¬ μ¬μ©ν μ μμ΅λλ€.
import { motion } from 'framer-motion'
<motion.div animate={{ scale: 0.7 }} />
4. μμ± μ½λ
μμ νλ©΄μ λν μμ± μ½λμ λλ€.
import style from './Main.module.css';
import { motion } from "framer-motion";
import { Link } from 'react-router-dom';
import { useState } from 'react';
function Main() {
// λ²νΌ μ΄λ―Έμ§μ μ λλ©μ΄μ
μνλ₯Ό μ μ΄νκΈ° μν state
const [isHovered, setIsHovered] = useState(false);
// λ²νΌ λ°μ€μ μ λλ©μ΄μ
μνλ₯Ό μ μν©λλ€.
const buttonBoxVariants = {
hover: { scale: 1.1 },
tap: { scale: 0.9 }
};
// λ²νΌ μ΄λ―Έμ§μ μ λλ©μ΄μ
μνλ₯Ό μ μν©λλ€.
const buttonIconVariants = {
hidden: { x: -30, opacity: 0 }, // μΌμͺ½μ μ¨κ²¨μ§ μν
visible: { x: 0, opacity: 1 } // μλ μμΉμ λνλ μν
};
return (
<div className={style.mainpage}>
<div className={style.main}>
<div className={style.main_text}>
<h1 className={style.main_text1}><span className={style.highlight1}>λ§</span>μ§,</h1>
<h1 className={style.main_text2}><span className={style.highlight2}>λ±μ°</span>λ‘,</h1>
<h1 className={style.main_text2}><span className={style.highlight1}>μ°μ
κΈ°μμ 보</span>λ₯Ό</h1>
<h1 className={style.main_text3}>
<span>ν λ²μ κ²μμΌλ‘ νμΈνμΈμ.</span>
<motion.span
className={style.underline}
initial={{ width: 0 }}
animate={{ width: "100%" }}
transition={{
repeat: Infinity,
repeatType: "reverse",
duration: 3
}}
/>
</h1>
</div>
<div className={style.main_box}>
<Link className={style.main_map} to="/map">
<motion.div
className={style.box}
variants={buttonBoxVariants}
whileHover="hover"
whileTap="tap"
onHoverStart={() => setIsHovered(true)}
onHoverEnd={() => setIsHovered(false)}
>
<div className={style.main_mapimg}>
<img src={`${process.env.PUBLIC_URL}/img/mapimg.png`} alt="mapimg" className={style.mapimg} />
</div>
{/* ν
μ€νΈ λΆλΆ */}
<div className={style.box_text1}>
λ±μ° μ 보 κ²μνλ¬ κ°κΈ°
</div>
{/* μ΄λ―Έμ§ λΆλΆ */}
<motion.img
src={`${process.env.PUBLIC_URL}/img/button.svg`}
alt="λ²νΌ"
className={style.buttonIcon}
variants={buttonIconVariants}
initial="hidden"
animate={isHovered ? "visible" : "hidden"}
transition={{ duration: 0.3 }}
/>
</motion.div>
</Link>
</div>
</div>
</div>
);
}
export default Main;
μμ κ°μ λ°©μμΌλ‘ reactμμ framer-motionμ μ¬μ©νμ¬ μ λλ©μ΄μ μ ν¨κ³Όμ μΌλ‘ ꡬνν μ μμ΅λλ€.