개인 포트폴리오 사이트를 만드는중 간단한 코드로 애니메이션을 사용하려고 정보를 찾아보던중 Framer motion이 가장 적합해 보여 Framer motion을 적용해보았다.
우선 내가 원했던 방식으로는 글자들이 동시에 나타나는것이 아닌 차례대로 하나씩 나타나는 방식을 원했다.
가장 적절한 방식이 Orchestration 이다.
애니메이션을 딜레이를 주거나 반복 횟수를 설정할 때 Orchestration
을 사용한다.
// useShowFramer.ts
const useShowFramer = () => {
const parent: {
hidden: {
opacity: number;
};
visible: {
opacity: number;
transition: {
when: string;
staggerChildren: number;
};
};
} = {
hidden: {
opacity: 0,
},
visible: {
opacity: 1,
transition: {
when: 'beforeChildren',
staggerChildren: 0.2,
},
},
};
const item: {
hidden: {
opacity: number;
y: number;
};
visible: {
opacity: number;
y: number;
};
} = {
hidden: { opacity: 0, y: 50 },
visible: { opacity: 1, y: 0 },
};
return { parent, item };
};
export default useShowFramer;
Custom Hook
으로 Orchestration
에 대한 객체를 만들어주었다.
transition
에 when
을 beforeChildren
혹은 afterChildren
을 적용하면 언제 나타날 지 정할 수 있다.
'use client';
import useShowFramer from '@/app/hooks/useShowFramer';
import { motion } from 'framer-motion';
import styles from '../styles/Intro.module.css';
import Image from 'next/image';
const Intro = () => {
const { parent, item } = useShowFramer();
return (
<section id='intro' className={styles['intro-section']}>
<motion.div
variants={parent}
className={styles['intro-inner']}
initial='hidden'
whileInView='visible'
>
<motion.div variants={item}>
<motion.img
animate={{ scale: [1, 1.1, 1] }}
transition={{
repeat: Infinity,
duration: 3,
ease: 'linear',
}}
src='/img/main_1.png'
width={250}
height={250}
alt='main'
/>
</motion.div>
<motion.h1 className={styles['intro-title']} variants={item}>
안녕하세요
</motion.h1>
<motion.h1 className={styles['intro-title']} variants={item}>
Hello
</motion.h1>
<motion.div variants={item}>
<p className={styles['tag1']}>
<a href='#about'><Image src='/img/down-arrow.png' alt='arrow' width={50} height={50}/></a>
</p>
</motion.div>
</motion.div>
</section>
);
};
export default Intro;
Framer-motion에 있는 모션을 사용하기위해서는 motion 컴포넌트를 이용해야한다.
variants
로 미리 정의 된 애니메이션을 props
로 내려준다.
initial
과 whileInView
도 마찬가지로 props로 애니메이션을 내려준다.