Interactive Message
전시회 방문 인터렉티브 방명록
개요
- 하루 동안만 유지되는 익명 감사 메시지 보드로, 사용자가 입력한 한 줄 메시지가 화면에 물리적으로 떨어져 서로 충돌하며 떠다니는 형태로 표현
- KST 자정 기준으로 모든 메시지는 자동 삭제되고 새로운 하루가 빈 상태로 시작
주요 기능
- 메시지 입력 페이지
/message폼에서 한 줄 입력 후 POST 시 D1에 id, 텍스트, 타임스탬프, 랜덤 좌표, 색상 저장 - 물리 디스플레이 Matter.js 기반으로 중력 0.1g, 벽 반사 0.85, 박스 반사 0.5 설정, 박스 간 충돌 시 추가 임펄스로 자연스러운 움직임 구현
- 2초 폴링 동기화
/api/messages/new?since=…호출로 신규 메시지만 수신하여 실시간으로 박스 생성 - 3번 탭 삭제 동일 박스를 연속 3회 탭하면 DELETE 요청 후 사라짐 애니메이션 실행, 다른 박스 탭 시 카운트 초기화
- 자정 자동 만료 1분 단위로 KST 날짜를 비교하여 전일 메시지 페이드 아웃 및 제거
- 랜덤 등장 처리 메시지마다 위치와 색상을 랜덤 부여하여 시각적 다양성 확보
- 반응형 경계 처리 resize 이벤트 시 물리 경계를 재생성하여 화면 밖 이탈 방지
- PWA 풀스크린 설치 시 portrait 풀스크린 모드로 동작하며 다크 테마 기반 단독 앱 형태로 실행
기술 스택
- Cloudflare Worker가 입력 페이지, 디스플레이 페이지, API, PWA manifest를 단일 코드베이스로 서빙
- 데이터는 D1에 저장되며, 정적 리소스 및 아이콘은 R2에서 제공
- 프론트엔드는 Vanilla JS 기반이며 Matter.js를 CDN으로 로드하여 물리 엔진을 구성
- 실시간 동기화는 WebSocket 없이 2초 폴링 구조로 처리
설계 노트
- WebSocket 없이 짧은 폴링 구조를 사용하여 단일 일자성 서비스에 최적화
- KST 기준 자정 만료 로직을 클라이언트와 서버가 동일하게 공유
- Matter.js 안정화를 위해 충돌 계수 및 마찰값을 지속적으로 재적용
- 화면 이탈 방지를 위해 물리 좌표를 프레임 단위로 클램프 처리
- 3탭 삭제 구조를 단일 활성 타겟 모델로 제한하여 오탭 누적 방지