일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- useEffect
- REACT
- web
- db
- HTML
- Fetch
- this
- IntersectionObserver
- CSS
- firestoredatabase
- Github Pages
- JavaScript
- jQuery
- API
- Database
- data
- Protocol
- nosql
- til
- TMDB
- SQL
- W
- Boostrap
- url
- github
- bootstrap
- Cloud
- supabase
- 배포
- http
- Today
- Total
072DATA
레벨링 시스템 구현하기 본문
최근 작업하는 프로젝트에서 레벨링 시스템을 구현했는데
유저의 포인트를 기반으로 레벨을 계산하고 현재 레벨과 다음 레벨까지 남은 포인트를
시각적으로 표현하여 경험치바도 만들어 보았다
1. 레벨과 경험치 설정
우선, 레벨과 필요한 경험치를 정의한 LEVEL_CONFIG 라는 상수를 만들었다
각 레벨마다 이름, 최소/최대 포인트, 이미지 등을 포함해
사용자가 어떤 레벨에 속하는지 쉽게 파악할 수 있게 했다.
export const LEVEL_CONFIG = {
1: { name: "씨앗", min: 0, max: 1000, image: "/seed.png" },
2: { name: "새싹", min: 1100, max: 5000, image: "/sesac.png" },
3: { name: "트리", min: 5100, max: 10000, image: "/tree.png" },
4: { name: "클로버", min: 10100, max: 20000, image: "/clover.png" }
} as const;
2. 현재 레벨 계산 함수
calculateLevelInfo 함수를 통해 누적된 totalPoints가 각 레벨의 범위에 속하는지 계산하고,
현재 레벨 정보와 경험치바의 진행 상태를 반환하도록 했다.
이 함수는 totalPoints를 기준으로 현재 레벨을 찾아주고,
현재 포인트와 다음 레벨까지 남은 포인트를 계산하여 반환해준다.
export const calculateLevelInfo = (totalPoints: number): LevelInfo => {
for (const [level, config] of Object.entries(LEVEL_CONFIG)) {
if (totalPoints >= config.min && totalPoints <= config.max) {
return {
level: Number(level),
name: config.name,
currentPoints: totalPoints - config.min,
maxPoints: config.max - config.min,
pointsToNextLevel: config.max - totalPoints,
image: config.image
};
}
}
// 최대 레벨 초과 시
return { ...LEVEL_CONFIG[4], currentPoints: 20000, maxPoints: 20000, pointsToNextLevel: 0 };
};
LEVEL_CONFIG 객체는 각 레벨에 대한 정보를 담고 있고
Object.entries()를 사용하면 각 키-값 쌍이 [level, config] 형태의 배열로 변환되어,
[레벨 번호, 설정 정보] 쌍을 순회할 수 있게 된다
if (totalPoints >= config.min && totalPoints <= config.max) 조건을 사용해
현재 totalPoints가 해당 레벨의 최소(min)와 최대(max) 포인트 사이에 있는지 확인하고
조건에 맞는 레벨을 찾으면, 해당 레벨의 정보를 반환해줌
만약 totalPoints가 최고 레벨의 최대치보다 높으면
루프를 돌고 나서 LEVEL_CONFIG[4]에 해당하는 정보를 반환해 최종 레벨을 반환해줌!
3. 경험치바 UI 구현
레벨 이미지, 레벨 이름, 경험치 바 등의 UI를
LevelSection 컴포넌트에 넣어 사용자 경험을 직관적으로 만들었다.
CSS width에 현재 포인트와 최대 포인트를 비율로 계산하여
경험치바가 동적으로 변하도록 했다.
export const LevelSection = ({ levelInfo }: LevelSectionProps) => (
<section>
<figure className="w-[300px] h-[300px] border">
<Image src={levelInfo.image} alt={levelInfo.name} width={300} height={300} />
</figure>
<div className="space-y-2">
<p className="text-lg font-bold">LV.{levelInfo.level} {levelInfo.name}</p>
<p className="text-sm text-gray-600">레벨업까지 {levelInfo.pointsToNextLevel}P 남았어요</p>
<div className="w-full bg-gray-200 rounded-full h-4">
<div
className="bg-black rounded-full h-4 transition-all duration-300"
style={{ width: `${(levelInfo.currentPoints / levelInfo.maxPoints) * 100}%` }}
/>
</div>
<p className="text-sm text-right">{levelInfo.currentPoints}/{levelInfo.maxPoints}</p>
</div>
</section>
);
느낀 점
이 작업을 통해 사용자 경험을 직관적으로 제공하는 UI의 중요성을 다시 한 번 느꼈다.
레벨과 경험치를 단계별로 보여주면서 사용자에게 성장의 동기를 줄 수 있는 요소를 더 고민하게 됐다.
transition 속성을 통해 경험치바가 자연스럽게 차오르는 효과도 꽤 만족스러웠다.
'FrontEnd > HTML, CSS, JavaScript' 카테고리의 다른 글
캘린더에 데이터 시각화하기 - 특정 기간 조회 및 데이터 정리 (0) | 2024.11.01 |
---|---|
Skeleton UI 적용하기 🦴 (0) | 2024.10.30 |
렉시컬 환경과 클로저 (0) | 2024.10.24 |
Throttling 알아보기 ( 성능 최적화 기법 ) (1) | 2024.10.24 |
토스트(react-toastify) 사용하기 (0) | 2024.09.20 |