Progress bar 만들기
완성 이미지
tailwind animaton 추가하기
- 사용자 지정 animation을 추가하려면, tailwind.config 파일을 수정해야한다.
extend: {
keyframes: {
progress: {
'0%': { width: '0%' },
'100%': { width: '100%' }
}
},
animation: {
progress3: 'progress 3s ease-in',
progress5: 'progress 5s ease-in',
progress7: 'progress 7s ease-in'
}
}
- 원하는 이름으로 keyframe을 추가한다. (progress bar를 만들 것이라서 progress로 만들었다!)
- 0%, 100% 만 설정하는 경우에는 from / to로 작성해도 된다.
- animation에도 원하는 이름으로 값을 작성해주면 된다.
- progress 뒤의 3, 5, 7은 초를 의미하는데, 총 3종류의 animation이 필요해서 3가지를 만들었다.
- 원하는 이름 : 'keyframe이름 몇초 (ease-in/ease-in-out/등)'
- animation 효과가 일어나고 마지막 상태를 유지하게 하고 싶을때
- progress3: 'progress 3s ease-in forwards'
- animation 뒤에 forward를 적어주면 해결된다.
ProgressBar.tsx 전체코드
import { useEffect, useState } from 'react';
type animateType = {
[key: number]: string;
};
const ProgressBar = ({ time }: { time: number }) => {
const [sec, setSec] = useState(time);
const [color, setColor] = useState('bg-green');
const animateTime: animateType = {
3000: 'animate-progress3',
5000: 'animate-progress5',
7000: 'animate-progress7'
};
useEffect(() => {
const interval_id = setInterval(() => {
setSec(sec => sec - 1000);
}, 1000);
setTimeout(() => {
setColor('bg-red');
}, time * 0.8);
setTimeout(() => {
clearInterval(interval_id);
}, time);
}, []);
return (
<>
<div className="w-[1000px] overflow-hidden h-7 rounded-xl bg-gray1">
<div className={`h-7 w-full ${animateTime[time]} ${color}`}></div>
</div>
</>
);
};
export default ProgressBar;
//사용방법
{
/* <ProgressBar time={3000} /> */
/* <ProgressBar time={5000} /> */
/* <ProgressBar time={7000} /> */
}
- tailwind를 동적으로 스타일링 하려면, 전체 코드를 전달해주어야 한다.
- Bad : className={`felx felx-col bg-${colorProp}`} / colorProp = 'green'
- Good : className={`felx felx-col ${colorProp}`} / colorProp = 'bg-green'
- 그래서 해당 코드에서는 animateTime 이라는 객체에 동적으로 스타일링 해야하는 부분의 tailwind 코드를 키값마다 작성했다.
- 타입스크립트에서 오브젝트의 키값에는 원래 string이나 number가 올 수 없다.
- 해결방법
type animateType = {
[key: number]: string;
};
key 값으로 사용할 타입을 적어서 명시해주면 string이나 number로 key를 사용할 수 있다.
그래서 props로 받아온 string이나 number 자체를 key로 사용하는 ${animateTime[time]}과 같은 표현이 가능해진다.
시간이 20%만 남았을 때 bar의 색상 바꿔주기
setTimeout(() => {
setColor('bg-red');
}, time * 0.8);
setTimeout 함수를 이용해서 color state를 변경해주면 bar 색상이 바뀐다!
state의 변경이 일어나서 렌더링 되는 것이다!
만약 color가 state가 아닌 변수였다면, 바뀌지 않을 것이다.