마치 텍스트 에디터에서처럼 커서가 깜빡이고 글자가 타이핑하여 입력하는 것처럼 보이도록 애니메이션을 만들어 보고자 했다. 개인적인 편의를 위해서 styled-components를 이용했으나 기본적인 CSS를 이해하고 있다면 쉽게 구현할 수 있다.
커서가 깜빡이는 것은 CSS를 이용하면 간단하다.
우선 keyframes을 선언하고, 이를 blink라는 id를 가진 태그에 적용해준다. 1초에 한번씩 무한히 순환되도록 하면 된다.
const blinkAnimation = keyframes`
0% { opacity: 1; }
50% { opacity: 0; }
100% { opacity: 1; }
`;
// 투명도를 세단계로 나눠서 순환시키는 것으로 깜빡이는 듯한 애니메이션을 연출할 수 있다.
const StName = styled.div`
font-size: 94px;
font-weight: 700;
display: inline-block;
text-decoration-color: #fff;
#blink {
animation: ${blinkAnimation} 1s infinite;
}
`;
HTML (JSX)
<StName className='name'>
no <StStrike id='strike'>{currentGreeting}</StStrike><span id='blink'>|</span>
</StName>
이제 커서 애니메이션은 완성했으니, 텍스트를 타이핑하는 애니메이션을 만들어주면된다. 마운트된 시점부터 반복시키고 싶으므로 useEffect와 useState를 활용하면 될 것 같다.
우선 반복할 텍스트가 필요한데, 이번에는 배열을 이용해서 인사말들을 넣어 순환하도록 하고자 한다.
// 인삿말 배열은 리랜더링시 다시 선언될 필요가 없기에 컴포넌트 외부에서 선언해도 된다.
const sayHi = [
"Hi.",
"Hello!",
"hey!",
"bonjour!",
"greetings!",
"Yoooooo!",
"ping.",
"안녕하세요!",
];
function Hero() {
// 상태관리를 위한 state를 선언한다.
const [greetingIndex, setGreetingIndex] = useState(0);
const [currentGreeting, setCurrentGreeting] = useState('');
useEffect(() => {
const typeAnimation = () => {
const greeting = sayHi[greetingIndex];
let typedGreeting = '';
let currentIndex = 0;
// 인터벌 생성
const typingInterval = setInterval(() => {
typedGreeting += greeting[currentIndex];
setCurrentGreeting(typedGreeting);
currentIndex++;
if (currentIndex === greeting.length) {
clearInterval(typingInterval);
setTimeout(() => {
setGreetingIndex((prevIndex) => (prevIndex + 1) % sayHi.length);
}, 2000);
}
}, 100);
};
typeAnimation();
return () => {
clearTimeout(typingTimeout);
clearInterval(typingInterval);
};
}, [greetingIndex]);
함수 내에서 빈 문자열을 생성하고 sayHi안의 요소를 하나씩 반복하며 문자열의 index를 하나씩 올리며 문자열을 더한다. 인사말의 길이와 같아지면 인터벌을 종료하고 2초 뒤 다음 인사말을 세팅한다. greetingIndex가 변화하였으므로 다시 useEffect가 실행되며 반복한다. greetingIndex를 세팅할 때 기존 값에 1을 더한 값을 sayHi의 길이로 나눈 나머지를 반환하므로 sayHi의 마지막 문자열까지 동작한 뒤에는 다시 0번 index로 돌아가 반복하게 된다.
이 코드를 이용해서 currentGreeting 의 값을 계속 변화시켜주는 것으로 마치 타이핑하는 것과 같은 애니메이션 효과를 줄 수 있다.
'Develop > Web Front End' 카테고리의 다른 글
케스케이딩 원칙 이해하기 (0) | 2024.01.20 |
---|---|
MobX - 간단하고 확장 가능한 상태 관리 (0) | 2023.12.03 |
[React] 이미지 압축해서 업로드 하기 (0) | 2023.08.01 |
[React] 전역 상태 관리가 필요한 이유 (0) | 2023.08.01 |
[React] Local Storage 이용해서 브라우저에 데이터 저장하기 (0) | 2023.04.24 |