한글

메신저 대화 타이포

두 사람의 대화가 박자에 맞춰 말풍선으로 튀어 오르고, 마지막 낱말이 화면을 덮는다.

메신저 대화 타이포 실행 화면
새 탭에서 보기

실제 코드로 재생되는 미리보기입니다

프롬프트 설정

Claude 가 읽는 제작 지시문입니다. 직접 읽지 않아도 됩니다.

두 사람의 메신저 대화가 박자에 맞춰 말풍선으로 튀어 오르는 세로 영상을 HTML 파일 하나로 만들어 줘. 미리보기에서 바로 재생되게. 길게 설명할 테니 숫자는 그대로 지켜 줘.

핵심 아이디어: 대화가 음악처럼 박자 위에 떨어진다. 첫 프레임부터 화면에는 지난 대화가 위아래로 꽉 차 있고, 입력 중 점 세 개가 박자에 맞춰 통통 뛰다가, 정확히 박 위에서 새 말풍선이 「통」 하고 태어나며 위의 말풍선 더미 전체를 한 덩어리로 밀어 올린다. 마지막 말의 핵심 낱말은 말풍선에서 뽑혀 나와 화면을 가득 채우는 크기로 쾅 내려앉는다. 실제 메신저 앱처럼 보이게 하는 장식은 하나도 없고, 말풍선 문법(왼쪽 = 상대, 오른쪽 = 나)만 쓴다.

[바꿀 곳]
- 앞 대화(0초에 이미 화면에 쌓여 있는 말, 위에서부터 — 점도 탄생도 없이 처음부터 그대로 있다. L = 왼쪽 사람 · R = 오른쪽 사람):
  L 「몇 시에 끝나?」 · R 「방금 퇴근했어」 · R 「배고파 죽겠다」 · L 「나도 배고팠어」 · L 「저녁 같이 먹자」
- 대화(박자에 맞춰 하나씩 태어나는 말, 괄호 = 그 말 앞에 점 세 개가 뛰는 박 수):
  1. L 「뭐 먹고 싶어?」 (1박)
  2. R 「나는 아무거나」 (1박)
  3. L 「떡볶이 어때?」 (1박)
  4. R 「음… 그건 좀」 (2박)
  5. L 「아무거나라며!!」 (1박)
  6. R 「그럼 치킨!」 (3박)
  (한 말은 말풍선 3줄 — 한글 약 20자 — 안으로 쓴다. 한 줄에 한글 약 7자가 들어간다. 7자 안팎의 말이 화면을 가장 잘 채운다.)
- 핵심 낱말(마지막 말 안에 그대로 들어 있어야 한다): 치킨
- 박자: 120 BPM (한 박 = 0.5초). 기본 대화로 20박 = 10초, 끝나면 처음으로 이어서 반복
- 색: 배경 #EAE6DF · 왼쪽 말풍선 #FFFFFF(글자 #17171A, 점 #9C9CA4) · 오른쪽 말풍선 #2D5BFF(글자 #FFFFFF, 점 #FFFFFF 75%) · 펀치라인 바탕 = 마지막 말을 한 사람의 말풍선 색, 펀치라인 글자 = 그 사람의 글자 색(기본 대화는 오른쪽 사람이라 #2D5BFF 바탕에 #FFFFFF 글자)
- 화면비: 9:16 (캔버스 1080×1920)

[크기]
W = 화면 폭, H = 화면 높이.
- 말풍선 글자 크기 F = 0.10W(1080 폭에서 108px), 굵기 500. 핵심 낱말은 말풍선 안에서도 굵기 800.
- 줄 높이 1.32F, 말풍선 안쪽 여백 위아래 0.55F · 좌우 0.85F. 한 줄 말풍선 높이 H1 = 2.42F(≈ 0.136H).
- 말풍선 최대 폭 0.90W(글자 영역 0.90W − 1.70F = 0.73W ≈ 한글 7~8자). 넘으면 띄어쓰기에서 줄을 바꾸고, 띄어쓰기 없는 낱말이 혼자 넘치면 글자 단위로 자른다. 핵심 낱말은 줄 사이에서 자르지 않는다.
- 최대 3줄. 넘치면 3줄째 끝을 「…」로 줄이고(「…」까지 글자 영역 안에 들어가게) console.warn 으로 알린다. 마지막 말이 넘쳐 핵심 낱말이 3줄 안에 못 들어가면, 핵심 낱말이 든 줄이 3줄째가 되도록 앞쪽 줄들을 버리고 남은 첫 줄 맨 앞에 「…」를 붙인다.
- 말풍선 폭 = 가장 긴 줄의 measureText 폭 + 1.70F, 최소 H1(한 글자 말도 둥근 알약이 되게).
- 왼쪽 말풍선의 왼쪽 끝 = 0.05W, 오른쪽 말풍선의 오른쪽 끝 = 0.95W.
- 말풍선 사이 간격 g = 0.30F(누가 말하든 같다). 태어날 때 1.115배로 넘치는 높이 0.115 × 2.42F = 0.278F 보다 커서 넘쳐도 위 말풍선에 닿지 않는다.
- 바닥선 yBase = 0.78H: 가장 최근 말풍선의 아래 끝이 여기에 놓인다. 0초 화면에서는 앞 대화의 마지막 말풍선 아래 끝이 yBase 에 있고, 앞 대화 5줄이 그 위로 0.03H 까지 쌓여 화면 위쪽을 채운다. 대화 구간(0~8초) 내내 말풍선이 화면 면적의 약 절반(글꼴에 따라 0.48~0.59)을 차지한다. 화면 위로 밀려 나간 말풍선은 그냥 잘린다.
- 입력 중 말풍선: 말하는 사람 쪽 끝(0.05W 또는 0.95W)에 붙고, 폭 2.6F, 높이 H1, 점 지름 0.24F, 점 중심 간격 0.50F, 점이 뛰는 높이 0.22F. 자리 = 바닥선 바로 아래, 위 끝 yBase + g(≈0.797H), 아래 끝 ≈0.933H.
- 펀치라인 낱말: 굵기 800, 잉크 폭(actualBoundingBoxLeft + actualBoundingBoxRight)이 0.86W 가 되는 글자 크기. 다만 잉크 높이가 0.32H 를 넘으면 0.32H 에 맞춘다. 잉크 상자 중심 = (0.5W, 0.46H). 기본 낱말 「치킨」이면 대략 0.86W × 0.26H 를 차지한다(0.32H 상한에는 걸리지 않는다).

[말풍선 모양]
- 둥근 사각형, 모서리 반지름 0.95F. 단 말하는 사람 쪽 아래 모서리(왼쪽 사람 = 왼쪽 아래, 오른쪽 사람 = 오른쪽 아래)만 반지름 0.22F. 이 모서리가 꼬리 역할이다. 따로 꼬리 모양을 붙이지 않는다.
- 이 각진 모서리가 그 말풍선의 「축」이다: 태어날 때 커지는 중심, 사라질 때 줄어드는 중심.
- 글자 세로 위치: 시작할 때 '한' 의 actualBoundingBoxAscent(a)·Descent(d)를 재 두고, 각 줄의 기준선 = 그 줄 가운데 + (a − d) / 2 (textBaseline 'alphabetic'). 글자는 말풍선 안에서 왼쪽 정렬(오른쪽 말풍선도 글자는 왼쪽 정렬).
- 입력 중 말풍선은 같은 모양·같은 색에 글자 대신 점 셋.
- 앞 대화 말풍선도 대화 말풍선과 똑같은 모양·크기·색이다(흐리게 하거나 작게 하지 않는다).

[장면]
박자표.
기호: 박 = 60 / BPM 초. 대화의 말 i(1부터)의 점 시작 박 D_i, 탄생 박 P_i. D_1 = 1, P_i = D_i + (그 말의 점 박 수), D_(i+1) = P_i + 1. 펀치 박 K = P_마지막 + 1, 전체 길이 = K + 4 박.
기본 대화로 계산하면 이렇다(검산한 값):
- 0.0–0.5초 앞 대화만 쌓여 있는 화면(첫 박은 점 없이 쉰다).
- 점 시작 / 탄생: 1번 0.5 / 1.0초 · 2번 1.5 / 2.0초 · 3번 2.5 / 3.0초 · 4번 3.5 / 4.5초 · 5번 5.0 / 5.5초 · 6번 6.0 / 7.5초.
- 펀치 K = 16박 = 8.0초 · 전체 20박 = 10.0초.

1. 점 세 개(입력 중). D_i 에 입력 중 말풍선이 축 모서리에서 팝 스프링 B 로 커지며 나타난다. 점 k(0, 1, 2)는 x = frac((t − D_i 시각) / 박 − 0.18·k) 로, x < 0.45 일 때만 위로 0.22F·sin(π·x / 0.45) 뛰고 나머지는 바닥에 있다. 한 박에 한 번씩, 왼쪽 점부터 0.18박 간격으로 물결친다. 뛸 때 불투명도 = 0.5 + 0.5·(그 순간 높이 / 0.22F).
2. 탄생(박 위의 「통」). P_i 시각에 입력 중 말풍선은 0.08초 동안 축 모서리로 줄어 사라지고(easeInCubic, 크기 1 → 0), 그 자리에서 말풍선이 태어난다.
   팝 스프링: B(τ) = 1 − e^(−14τ)·cos(18τ), τ = 탄생 뒤 초. 0 에서 출발해 τ≈0.138초에 1.115 로 넘쳤다가 τ≈0.31초에 0.990, 0.25초 뒤로는 ±1% 안에 든다. 말풍선 크기 = B(τ), 커지는 중심 = 축 모서리.
3. 밀어 올리기(한 덩어리). 앞 대화와 대화를 한 목록으로 이어(앞 대화가 먼저) 「내용 좌표」로 위에서부터 쌓는다: 목록 n번째 말의 위 끝 Y_n = (앞 말들의 높이 합) + (2번째부터 n번째까지의 간격 합), 첫 말 위에는 간격이 없다.
   S0 = 앞 대화 전체의 (높이 + 간격) 합 = 앞 대화 마지막 말의 Y + H.
   스크롤 S(t) = S0 + Σ_대화 j (g + H_j)·B(t − P_j 시각) (아직 안 태어난 말은 0). 모든 말풍선의 화면 아래 끝 = yBase + Y_n + H_n − S(t).
   이 식 하나로: 0초에는 앞 대화의 마지막 말이 바닥선에 앉아 있고, 새 말풍선은 입력 중 말풍선 자리에서 바닥선까지 솟아오르며, 앞 대화까지 포함한 위의 말풍선 전부가 같은 양만큼 함께 밀려 올라가 약 0.115·(g + H) 만큼(기본 크기로 약 34px) 넘쳤다가 자리를 잡는다. 말풍선끼리의 간격은 언제나 그대로다.
   입력 중 말풍선도 내용 좌표에 있다: 그 화면 위 끝 = yBase + Y_n − S(t)(탄생 전에는 S = Y_n − g 이므로 yBase + g). 새 말풍선의 τ=0 자리는 정확히 이 입력 중 말풍선 자리다.
4. 펀치라인 (K = 8.0초부터). K 이후 대화는 K 시각의 모습 그대로 멈춘다(S 도 K 시각 값으로 고정).
   - 8.0–8.1초 예비 동작: 마지막 말풍선 안의 핵심 낱말만 제자리에서 1 → 0.85배로 움츠린다(easeOutCubic, 중심 = 낱말 잉크 중심). 8.0초부터 낱말은 말풍선과 따로 그리는 「큰 낱말」이 되고, 말풍선 안의 그 자리는 비운다. 8.0초의 큰 낱말은 말풍선 속 낱말과 같은 자리·같은 크기·같은 색이어서 바뀌는 순간이 보이지 않아야 한다.
   - 8.1–8.45초 덮기: 낱말의 처음 중심에서 마지막 말을 한 사람의 말풍선 색 원이 반지름 0 → (그 점에서 가장 먼 화면 모서리까지 거리 + 4px)로 커진다(easeInOutCubic). 8.45초부터 화면 전체가 그 색이고, 이후 대화 말풍선은 그리지 않는다.
   - 8.1–8.5초 뽑혀 나오기: u = (t − 8.1) / 0.4, e = easeInCubic(u). 글자 크기 = 0.85F·(F_big / 0.85F)^e(로그 공간 보간 — 처음엔 천천히, 끝에서 확 커진다), 잉크 중심 = 처음 중심에서 (0.5W, 0.46H)로 e 만큼 이동. 글자 색은 8.0초부터 끝까지 그 말풍선의 글자 색 하나다(기본 대화는 #FFFFFF). 같은 사람의 말풍선 색 위에 그 사람의 글자 색이므로 덮기 원 안팎 어디서도 낱말이 사라지지 않는다.
   - 8.5초 쾅(시그니처 순간): 가장 빠른 속도로 도착해 눌렸다 튄다. τ = t − 8.5, 크기 배율 1 − 0.10·e^(−9τ)·sin(22τ): τ≈0.054초에 0.943 으로 눌렸다가 τ≈0.197초에 1.016, 0.24초 뒤로는 ±1% 안. τ=0 에서 정확히 1 이다(cos 꼴 금지 — 한 프레임 튐).
   - 9.0초(K+2 박) 박자 맥박: τ = t − 9.0, 배율 1 + 0.08·e^(−8τ)·sin(18τ) → τ≈0.064초에 1.044, 0.26초 뒤 ±1% 안. 쾅 배율과 곱한다.
   - 9.5–10.0초 퇴장: 바탕과 큰 낱말이 한 장처럼 위로 1.05H 밀려 나가고(easeInCubic), 그 아래에서 0초 화면(앞 대화만 쌓인 화면)이 드러난다. 퇴장하는 판 아래에는 render(0) 과 같은 그림을 그린다. 대화가 위로 밀리던 것과 같은 방향이다. 10.0초 화면 = 0초 화면.
- 말이 늘거나 줄어도 같은 규칙으로 박을 다시 계산한다. 펀치 안의 세부 시각(0.1·0.35·0.4초)은 「K 뒤 0.2박 · 0.9박 · 1박」으로 저장해 BPM 을 따라 늘고 준다. 스프링 세 개는 초 단위로 고정이다.

[구현]
- HTML 파일 하나로 만든다. 외부 파일·글꼴·라이브러리·네트워크 요청을 쓰지 않는다(미리보기에서 막히거나 느려진다).
- 첫 <script> 맨 앞에 CONFIG 객체를 두고 [바꿀 곳]의 값과 이 글에 나온 숫자(시간표·크기·색·세기)를 이름 붙여 모은다. 나중에 숫자만 바꿔 다듬을 수 있게.
- 그림은 시간 t(초)만으로 계산하는 함수 render(t) 로 그린다. requestAnimationFrame 의 타임스탬프나 performance.now() 로 t 를 구한다. setTimeout·setInterval·CSS 애니메이션·transition 으로 움직이지 않는다(프레임마다 속도가 달라지고, 다시 재생할 때 어긋난다). 시뮬레이션처럼 상태가 쌓이는 작품은 고정 시간 간격으로 상태를 진행하되 그 진행도 타임스탬프로만 정한다.
- 난수는 시드 고정 난수(mulberry32 등)만 쓴다. Math.random 은 쓰지 않는다(매번 다른 화면이 나온다).
- 캔버스 내부 해상도는 화면비에 맞춘 기준 크기로 고정하고, 창 크기에 맞춰 화면비를 지키며 가운데에 꽉 차게 보이게 한다(남는 곳은 배경색). 스크롤이 생기지 않게 한다. devicePixelRatio 는 그리는 선명도에만 반영한다.
- 글자는 시스템 글꼴만 쓴다: 'Pretendard', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans KR', sans-serif. 붓글씨·손글씨 느낌은 글꼴이 아니라 획을 그려서 낸다.
- 길이가 정해진 작품은 끝나면 처음과 같은 화면으로 돌아가 이음매 없이 반복한다.
- 모든 함수·상수·셰이더 문자열을 먼저 정의하고, 시작(초기화와 첫 requestAnimationFrame)은 스크립트 맨 끝에서 한 번만 호출한다. 정의되기 전에 쓰면 첫 화면에서 멈춘다.
- CONFIG 예: bpm, before: [{ who: 'L', text: '몇 시에 끝나?' }, …], messages: [{ who: 'L', text: '뭐 먹고 싶어?', dots: 1 }, …], keyword, colors, size(F 비율·여백·간격·yBase 등), spring({ pop: [14, 18], slam: [0.10, 9, 22], pulse: [0.08, 8, 18] }), punch(박 단위 오프셋 0.2·0.9·1·2·3·4).
- 시작할 때 한 번만: 줄바꿈(3줄 넘침 처리 포함)·말풍선 폭과 높이·내용 좌표 Y_n·S0·핵심 낱말의 줄 안 위치(그 줄에서 낱말 앞부분의 measureText 폭으로 x 를 구한다)·F_big 을 계산해 표로 캐시한다. render(t) 는 그 표와 t 만 쓴다. 프레임 사이에 쌓이는 상태는 없다.
- 핵심 낱말이 마지막 말에 없으면 마지막 말의 마지막 띄어쓰기 덩어리에서 앞뒤 문장부호(! ? . , … ~)를 뗀 것을 대신 쓰고 console.warn 으로 알린다(「그럼 피자!」 → 「피자」).
- t = (경과 시간) mod (전체 길이). 전체 길이 = (K + 4) × 60 / BPM.

[하지 말 것]
각 줄의 「—」 뒤가 이유다.
- 0초 화면을 비워 두지 않는다(앞 대화를 빼거나 하나씩 늦게 들이지 않는다) — 영상의 첫 1초에 보는 사람이 넘길지 말지 정한다. 첫 프레임부터 대화가 화면을 채우고 있어야 한다.
- 앱 이름·로고·상단바·입력창·프로필 사진·이름표·시각 표시·「읽음」 숫자를 그리지 않는다 — 특정 메신저를 베낀 화면으로 읽히고, 그만큼 말풍선이 작아져 화면이 빈다.
- 말풍선에 뾰족한 삼각 꼬리나 휘어진 꼬리를 붙이지 않는다 — 특정 앱의 모양으로 읽힌다. 화자 표시는 반지름 0.22F 모서리 하나로 충분하다.
- 그림자·발광·그라디언트·테두리선을 쓰지 않는다 — 평면 색면이어야 「통」 하는 크기 변화가 또렷하고, 녹화하면 그라디언트에 띠가 생긴다.
- 말풍선이 알파 페이드로 나타나거나 글자가 한 자씩 찍히게(타자기) 하지 않는다 — 박 위에서 통째로 태어나야 박자가 들린다. 페이드와 타자기는 박을 흐린다.
- 앞 말풍선들을 하나씩 시차를 두고 밀지 않는다 — 시차를 두면 말풍선끼리 겹치는 프레임이 생기고 「한 덩어리로 밀린다」가 사라진다. S(t) 하나로 다 같이 움직인다.
- 넘치는 말을 표시 없이 잘라 버리지 않는다 — 말이 중간에서 사라지면 대화가 깨져 보인다. 3줄째 끝의 「…」로 줄였다는 것이 보여야 한다.
- 펀치라인에 폭죽·파티클·이모지·별 반짝이·방사선 줄무늬를 더하지 않는다 — 시그니처는 낱말 하나의 크기다. 장식이 끼면 낱말이 상대적으로 작아 보인다.
- 화면 흔들기·회전·3D 기울기를 쓰지 않는다 — 한글 판독이 떨어지고, 반복 이음매에서 튄다.
- 펀치라인 낱말을 화면 가운데에 작게 두지 않는다 — 폭 0.86W 가 이 작품의 「와」다. 잉크 상자로 재서 맞춘다(글자 크기 숫자로 짐작하면 글꼴마다 폭이 달라진다).
- 소리를 넣지 않는다 — 미리보기에서 자동 재생이 막히고, 박자는 화면만으로 보여야 한다.
- 화면에 BPM·박 번호·안내 글자 같은 설명 문구를 쓰지 않는다 — 대화 말고 다른 글자가 있으면 대화가 가짜처럼 보인다.

사용 방법

필요한 것: claude.ai 계정 — 무료 계정에서도 Claude Opus 5.5 를 고를 수 있습니다

  1. claude.ai 에서 새 대화를 엽니다.
  2. 모델 메뉴에서 Claude Opus 5.5 를 고르고, 같은 메뉴의 Effort(답변 깊이)를 High 로 둡니다.
  3. 복사한 프롬프트를 붙여 넣고 전송합니다. 결과로 나온 HTML 파일을 브라우저로 열면 재생됩니다.
권장 모델
Claude Opus 5.5 · Effort High
화면비
9:16 (세로)
재생 길이
10초
결과물
HTML 파일 하나 · 따로 설치할 것 없음
영상 파일
위 「MP4 저장 기능 포함」을 켜면 결과 화면에 녹화 단추가 생깁니다 1080 기준 · 12 Mbps · 브라우저에 따라 MP4 또는 WebM

추가 요청 예시

결과가 나온 뒤 같은 대화에서 이어서 요청하면 해당 부분만 수정됩니다.

  • 대화 전체를 「내일 몇 시에 볼까?」로 시작하는 약속 잡기 이야기로 바꾸고(말마다 7자 안팎), 마지막에 화면을 덮는 낱말은 「지금」으로 해 줘.
  • 배경을 #111114 로 어둡게, 왼쪽 말풍선은 #2A2A30 에 흰 글자로, 오른쪽 말풍선과 마지막 낱말 화면의 바탕은 #FF5A36 으로 바꿔 줘.
  • 전체 속도를 조금 늦추고(BPM 120 → 96), 마지막 말 앞의 입력 중 표시(점 세 개)를 약 2.5초 동안 띄워 뜸을 들이다 터지게 해 줘.

한글

같은 카테고리의 다른 프롬프트

한글 전체 보기

모든 모션 보기 블로그 글 목록 RSS 로 새 글 받기