본문 바로가기
Projects

[앱인토스]모두의 응원단 (cheerboard)

by miracle-tech 2026. 2. 22.
728x90
반응형

모두의 응원단 (cheerboard)

콘서트, 팬미팅에서 스마트폰을 네온 응원 보드로 바꿔주는 웹앱

 

스크린샷 / 데모

https://toss-cheerboard.vercel.app/

 

모두의 응원단

콘서트, 팬미팅에서 빛나는 네온 응원 보드

toss-cheerboard.vercel.app

 

 

기술 스택

  • React 18 + TypeScript
  • Vite 5 (SWC)
  • Tailwind CSS 3.4
  • shadcn/ui (Radix UI)
  • React Router 6
  • @apps-in-toss/web-framework (토스 앱인토스 SDK, 광고)
  • @sentry/react (에러 트래킹)
  • Noto Sans KR (한글 디스플레이 폰트)

왜 만들었나

콘서트나 팬미팅에 가면 LED 응원봉 말고 직접 만든 응원 보드를 들고 오는 팬들이 꽤 있어요.

근데 실물 보드는 만들기도 번거롭고, 매번 다른 문구를 쓰기도 어렵죠.

그래서 스마트폰 화면 자체를 네온 응원 보드로 쓸 수 있으면 좋겠다고 생각했어요.

공연장 어두운 곳에서 빛나는 네온 느낌을 살리고, 한국어·일본어 응원 문구를 바로 골라 쓸 수 있게 만들었어요.

주요 기능

  • 20가지 네온 컬러 — CSS 커스텀 속성(HSL)과 다중 text-shadow로 실제 네온사인처럼 빛나는 효과 구현
  • 8가지 텍스트 이펙트 — 고정, 흐르기, 깜빡, 반짝, 통통, 흔들기, 확대축소, 무지개. CSS keyframe 애니메이션으로 구현하고, 무지개는 gradient + background-clip 조합
  • 빠른 응원 메시지 — 사랑/애정, 응원/격려, 감사, 개그/어그로, 감성/서사 5개 카테고리에 총 80여 개 한국어·일본어 문구를 JSON으로 관리
  • 아티스트 이름 조합 — 이름을 입력하면 "BTS, 사랑해" 같은 문구를 자동 생성. 일본어는 쉼표(、)로 구분
  • 이모지 팔레트 — 20종 이모지를 메시지 뒤에 추가, 정규식으로 이모지만 일괄 제거 기능
  • 전체화면 모드 — Fullscreen API로 전환하고, 탭하면 컨트롤 토글 (4초 후 자동 숨김)
  • 드래그 스크롤 — 컬러/이모지 팔레트에 포인터 이벤트 기반 가로 드래그 스크롤 구현 (터치 + 마우스 모두 지원)
  • 리워드 광고 — 전체화면 전환 시 @apps-in-toss/web-framework의 GoogleAdMob 리워드 광고 표시, 로컬 환경에서는 Mock 광고로 대체

배운 점

  • CSS 커스텀 속성과 HSL 색공간을 활용한 다중 text-shadow 네온 글로우 효과 설계. 하나의 색상 변수로 3단계 발광(10px, 40px, 80px)을 투명도만 바꿔서 표현하는 패턴
  • CSS background-clip: text과 gradient animation을 조합한 무지개 텍스트 효과. background-size를 200%로 잡고 position을 이동시키는 방식
  • Pointer Events API로 터치와 마우스를 통합 처리하는 드래그 스크롤 훅 구현. setPointerCapture로 드래그 중 포인터 이탈 방지
  • 토스 앱인토스 GoogleAdMob SDK의 load → show 2단계 광고 흐름과, 로컬 개발용 Mock 광고 fallback 패턴
  • Fullscreen API의 fullscreenchange 이벤트 기반 상태 동기화와, 컨트롤 자동 숨김을 위한 타이머 관리

어려웠던 점

  • 네온 글로우 성능 — 20가지 색상 각각에 text-shadow 3겹을 거는데, 큰 폰트 사이즈(최대 200px)에서 렌더링이 무거워질 수 있었어요. CSS 변수를 활용해서 색상별 클래스를 만들지 않고 인라인 스타일로 동적 적용하는 방식으로 처리했어요
  • 드래그 스크롤과 클릭 충돌 — 컬러/이모지 팔레트에서 가로 드래그하다가 손을 떼면 클릭 이벤트가 발생해서 색상이 바뀌는 문제가 있었어요. moved 플래그를 두고 3px 이상 이동했으면 onClickCapture에서 이벤트를 막는 방식으로 해결했어요
  • 전체화면에서 컨트롤 토글 — 전체화면 진입 후 보드 영역을 탭하면 컨트롤이 나타나야 하는데, 컨트롤 내부 버튼 클릭도 보드 탭으로 인식되는 문제. controlsRef.contains(e.target) 체크로 컨트롤 영역 클릭은 토글에서 제외했어요

링크

다음 계획

  • 인앱결제 기능 추가 (심사 통과 후)
  • 광고 테스트 ID를 실제 ID로 교체
  • 응원 문구 카테고리 확장 (스포츠, 생일 등)
728x90