데이터

막대 레이스

연도가 흐르면 막대가 자라 서로 추월하고, 1위가 바뀔 때마다 새 1위의 색이 막대 끝에서 물결처럼 번져 방 전체를 다시 칠한다.

막대 레이스 실행 화면
새 탭에서 보기

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

프롬프트 설정

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

막대 그래프 레이스 영상을 HTML 파일 하나로 만들어 줘. 미리보기에서 바로 재생되게. 길게 설명할 테니 숫자는 그대로 지켜 줘.

핵심 아이디어: 연도가 흐르며 가로 막대 여덟 개가 값만큼 자라고, 값이 앞지르는 순간 막대가 위아래로 미끄러져 서로 자리를 바꾼다. 값은 연도 사이를 부드럽게 잇고, 막대의 세로 자리는 값과 따로 노는 스프링이 따라가서 추월이 「미끄러짐」으로 보인다. 화면 전체는 밝은 방이고, 그 방은 언제나 그 순간 1위 항목의 색으로 옅게 물들어 있다. 1위가 바뀌면 새 1위 막대 끝에서 색 물결이 0.9초 만에 화면 전체로 번져 방과 커다란 연도 숫자를 새 1위의 색으로 다시 칠한다. 첫 화면부터 막대가 화면을 꽉 채우고, 0.8초에 첫 물결이 번진다. 마지막 해에 멈추면 막대마다 첫 해의 몫이 옅어져 「얼마나 자랐나」가 두 톤으로 드러나고, 값이 거꾸로 흐르는 되감기로 막대가 그 몫으로 돌아가 첫 해의 꽉 찬 화면에서 반복한다.

[바꿀 곳]
- 제목: 도시 여덟 곳, 한 해 방문객
- 작은 글씨(제목 줄 오른쪽): 가상 데이터 · 값은 모두 지어낸 예시 · 단위 명
- 데이터 — 지어낸 값이다(실제 통계가 아니다). 연도 2019~2025, 단위 만 명, 순서대로 2019·2020·…·2025:
  바람시 6200, 6900, 7600, 8200, 8700, 9100, 9400
  노을시 5900, 7300, 8600, 9300, 9800, 10200, 10500
  구름시 4800, 6200, 8100, 10100, 11200, 11900, 12400
  은하시 2600, 3400, 5000, 7600, 10900, 13300, 14800
  물결시 4300, 4900, 5600, 6800, 8300, 10400, 12900
  솔빛시 3600, 4200, 4800, 5300, 5900, 6500, 7100
  모래시 2400, 2700, 3000, 3400, 3800, 4300, 4600
  등대시 2200, 2600, 3200, 3500, 3900, 4200, 4500
- 막대 색(항목 순서대로): #007F84 · #E2283C · #1A7D34 · #9E44F0 · #A65300 · #857600 · #B8367A · #2A68BC
  (밝은 방 위에서 막대가 바탕과 3:1 이상, 막대끼리도 서로 갈리게 고른 값이다. 바꾸면 시작할 때 대조표 ⑧⑨가 다시 잰다.)
  1위를 차례로 거치는 바람시 → 노을시 → 구름시 → 은하시에 청록 → 빨강 → 초록 → 보라를 줘서, 이어지는 두 방이 늘 다른 색 가족이다(민트 → 분홍 → 세이지 → 라벤더).
  갈색·올리브는 1위가 되지 않는 물결시·솔빛시에 준다 — 갈색·올리브를 섞은 방은 종이와 구별되지 않는 베이지가 되어 물결이 안 보인다.
- 방(배경): 바탕 #FAFAF7 에 그 순간 1위 항목의 막대 색을 섞는다 — 오른쪽 위 모서리 18%, 왼쪽 아래 모서리 7%.
- 글자 색: 제목·항목 이름 #17161C(잉크) · 값 글자 #2B2A31 · 작은 글씨·눈금 값 #4A4850. 연도 숫자 = 1위 항목의 막대 색에 잉크 #17161C 를 30% 섞은 색.
- 한 해 길이: 1.6초 (전진 구간 = 1.6초 × (연도 수 − 1) = 9.6초)
- 화면비: 16:9 (캔버스 1920×1080)
- 표에 연도나 항목을 더하면 시간표와 막대 간격이 아래 공식대로 따라 바뀌게 한다.

[크기] — 화면 폭 W, 높이 H 기준
- 제목: 글꼴 크기 0.042H, 굵기 800, 잉크, 왼쪽 끝 0.035W, 기준선 0.075H.
  작은 글씨: 글꼴 크기 0.026H, 굵기 500, #4A4850, 오른쪽 끝 0.965W, 기준선 0.075H.
- 막대 칸: 칸 간격 P = 0.76H ÷ 항목 수(8개면 0.095H), 막대 두께 = 0.8P(8개면 0.076H).
  자리 p(0 = 1위, 소수 가능)의 막대 윗변 y = 0.155H + p·P. 8개면 1위 윗변 0.155H, 8위 아랫변 0.896H.
- 막대 왼쪽 끝 x0 = 0.16W. 막대 길이 = 0.65W × (값 ÷ 그 순간 1위의 값). 1위 막대 오른쪽 끝은 늘 0.81W 다.
  오른쪽 끝 두 모서리만 반지름 0.010H 로 둥글린다. 납작한 단색(머묾·되감기의 「출발 몫」 두 톤만 예외 — [장면]).
- 항목 이름: 글꼴 크기 0.040H, 굵기 700, 잉크, 오른쪽 정렬해 x0 − 0.012W 에, 막대 세로 가운데에.
- 값 글자: 글꼴 크기 0.038H, 굵기 600, #2B2A31, 막대 오른쪽 끝 + 0.012W 에서 왼쪽 정렬, 막대 세로 가운데.
  가장 긴 값 「1억 4,800만」은 약 0.12W 이고, 1위 교체 때 1.17배로 튀어도(약 0.14W) 오른쪽 끝이 약 0.96W 라 0.965W 안에 든다.
- 세로 기준선: x0 에 굵기 2px, 잉크 40%, y 0.145H ~ 0.905H.
- 연도 숫자: 굵기 800, 숫자 높이(measureText('0').actualBoundingBoxAscent) = 0.20H 가 되게 글꼴 크기를 역산한다.
  오른쪽 끝 0.965W, 기준선 0.93H, 색은 위 「연도 숫자」 색(불투명). 네 자리는 각자 칸에 그리고 칸 폭 = '0'~'9' advance 폭 중 최댓값(숫자 폭이 달라도 흔들리지 않게).
  연도 숫자는 가로 약 0.58W~0.965W, 세로는 멈춰 있을 때 0.73H~0.93H 이고 굴러갈 때도 잘림 띠 윗선 0.726H(= 0.93H − 1.02 × 0.20H)까지다 — 7·8위 막대의 오른쪽 빈 곳이다.
  이 표로 계산하면 7위 값은 언제나 1위의 0.39배 이하라 7·8위 막대와 값 글자가 약 0.51W 안에서 끝난다. 6위 줄(아랫변 0.706H)은 잘림 띠보다 위에 있고, 자리를 바꾸며 띠 높이로 미끄러지는 막대·값 글자도 연도 왼쪽 끝보다 약 0.05W 왼쪽에서 끝난다.

[방 — 배경과 연도 숫자의 색]
- 섞기 mix(a, b, k) 는 0~255 sRGB 채널마다 a + (b − a)·k 를 반올림한다(캔버스 그라디언트도 같은 공간에서 섞는다).
- 항목 i 의 방 = 캔버스 전체를 채우는 직선 그라디언트 createLinearGradient(W, 0, 0, H): 0 지점 mix(#FAFAF7, 색 i, 0.18), 1 지점 mix(#FAFAF7, 색 i, 0.07).
  방 그라디언트 8개와 연도 색 8개는 시작할 때 한 번 만들어 둔다. 예: 바람시 방 #CDE4E2 → #E8F1EF(연도 #076065) · 노을시 방 #F6D4D5 → #F8EBEA · 구름시 방 #D2E4D4 → #EAF1E9 · 은하시 방 #E9D9F6 → #F4EDF7.
- 방 주인은 그 순간의 1위다. 0초의 방 = 바람시 방(민트).
- 전진 구간의 1위 교체 = 색 물결. 교체 시각 tc, τ = t − tc, 0 ≤ τ < 0.9 동안:
  · 원점 O = 교체 순간(tc 칸) 새 1위 막대의 오른쪽 끝, 막대 세로 가운데. 이 표면 세 번 모두 (0.810W, 0.288H) — 아직 2위 줄에 있는 막대의 끝이다.
  · 반지름 R = Rmax·easeOutCubic(τ ÷ 0.9), Rmax = O 에서 가장 먼 화면 모서리까지의 거리(이 표면 왼쪽 아래까지 1735px = 0.904W).
  · 그리기: 이전 1위의 방을 전체에 칠하고 → 중심 O·반지름 R 원으로 자른 안쪽에 새 1위의 방을 칠하고 → 그 원 둘레에 테두리 선(굵기 0.006H, 새 1위 막대 색, 불투명도 0.7·(1 − τ ÷ 0.9)²)을 긋는다.
  · τ = 0.9 부터는 새 1위의 방 한 겹이다. 바로 다음 교체가 0.9초 안에 오면 새 교체가 이긴다(앞 물결은 끝난 것으로 친다). 이 표의 전진 교체 간격은 2.7초 이상이라 겹치지 않는다.
  · 이어지는 두 방(진한 끝)의 OKLab 거리 × 100 은 바람→노을 6.3 · 노을→구름 6.1 · 구름→은하 7.1 이라 세 물결이 모두 방에서 보인다. 꼭대기는 6.49초 은하시 — 초록 방이 0.9초 만에 보라 방이 된다.
- 되감기 구간의 1위 교체 = 물결 없이 0.3초 겹쳐 바꾸기: 이전 방을 칠하고, 불투명도 smoothstep(τ ÷ 0.3) 로 새 방을 그 위에 칠한다. 이 표면 11.85 · 12.08 · 12.48초, 마지막이 12.78초에 끝나 13.00초 = 0초 = 바람시 방.
- 연도 숫자도 같은 규칙의 두 겹이다: 물결 중에는 이전 1위의 연도 색으로 그리고, 같은 원으로 자른 안쪽에 새 1위의 연도 색으로 한 번 더 그린다(자리마다의 잘림 띠와 원 자르기는 save/restore 로 겹쳐 쓴다). 되감기 겹쳐 바꾸기도 같은 불투명도로.
- 비용 상한: 프레임마다 방 전면 칠하기 최대 2번 + 원 자르기 1번 + 테두리 선 1번. 종이 결·잡음·흐림 같은 화면 전체 효과는 쓰지 않는다.

[눈금선]
- 1천만, 2천만, 3천만 … (1천만 간격) 중 그 순간 1위 값 이하인 것마다 x = x0 + 0.65W × (눈금 ÷ 1위 값)에 세로선을 긋는다.
  선 굵기 2px, 잉크 14%, y 0.145H ~ 0.905H. 선 위에 눈금 값(값 글자와 같은 표기법)을 글꼴 크기 0.024H, #4A4850, 가운데 정렬, 기준선 0.135H 로.
- 눈금마다 단계 = [1천만, 2천만, 1억, 2억, 10억] 중 그 눈금을 나누어떨어지게 하는 가장 큰 값(3천만 → 1천만, 4천만 → 2천만, 5천만 → 1천만, 1억 → 1억).
  목록의 각 단계는 바로 앞 단계의 배수다(2천만 = 1천만 × 2, 1억 = 2천만 × 5, 2억 = 1억 × 2, 10억 = 2억 × 5). 이래야 잔 눈금이 사라진 뒤 남는 눈금들이 늘 고른 간격이다.
  그 단계 하나가 화면에서 차지하는 폭 s = 0.65W × (단계 ÷ 1위 값)으로 a = clamp((s − 0.06W) ÷ 0.06W, 0, 1) 을 구한다.
  선에는 a 를 그대로 불투명도로 곱하고, 눈금 값 글자에는 따로 a_글자 = smoothstep((a − 0.3) ÷ 0.1) 을 곱한다 — 글자는 a 가 0.3~0.4 를 지나는 짧은 순간에만 켜지고 꺼지며, 그 밖에는 완전히 보이거나 아예 없다.
  반투명한 글자는 바탕과 섞여 대비가 a 만큼 깎이므로(a 0.46 이면 2.2:1) 오래 머무는 글자를 반투명으로 두지 않는다.
  1위 값이 커질수록 잔 눈금 선이 저절로 옅어져 사라진다.
  2019년(1위 6,200만): 1천만 단계 a = 0.75 — 1천만·3천만·5천만, 2천만 단계 a = 1 — 2천만·4천만·6천만.
  2025년(1위 1억 4,800만): 1천만 단계 a = 0(선·글자 없음) · 2천만 단계 a = 0.46 — 2천만·4천만·6천만·8천만·1억 2,000만·1억 4,000만(선은 0.46, 글자는 완전히 보임) · 1억 단계 a = 1 — 1억. 머묾 동안 보이는 눈금 글자 7개가 전부 불투명이다.
  이 표로 0~13초를 훑으면 반투명 글자가 있는 프레임은 약 4%(켜지고 꺼지는 순간뿐)이고, 보이는(a_글자 > 0.05) 이웃 눈금 글자 사이 최소 간격은 약 30px 이다(9.6초, 「1억 2,000만」과 「1억 4,000만」).
  (a_글자 문턱을 0.5 로 올리지 않는다 — 2025년에 「1억」 하나만 남아 프레임의 21% 가 눈금 글자 하나 이하가 된다.)

[값 표기 — 한국식]
- 만 단위로 반올림한 n = round(값 ÷ 10000).
  n ≥ 10000 이면 「억 = floor(n ÷ 10000)」과 「만 = n mod 10000」으로 「1억 2,346만」. 만이 0 이면 「1억」.
  n < 10000 이면 「6,200만」. 값이 1만 미만이면 쉼표 넣은 정수 그대로(「9,800」).
- 쉼표는 직접 넣는다: 정수 문자열에 /\B(?=(\d{3})+(?!\d))/g 로 「,」를 끼운다.
- 예: 62,000,000 → 6,200만 · 99,995,000 → 1억 · 123,456,789 → 1억 2,346만 · 148,000,000 → 1억 4,800만.

[장면] (연 수 = 연도 수 − 1 = 6. Y(t) = 그 순간의 연도(소수). FW = 9.6초. 전체 T = FW + 1.4 + 2.0 = 13.0초)
1. 0.00–9.60 전진. 처음 0.3초는 속도가 0에서 일정 속도 v 로 오르고(가속), 마지막 0.6초는 v 에서 0으로 내린다(감속), 그 사이는 일정 속도.
   v = 연 수 ÷ (FW − 0.45) = 6 ÷ 9.15 ≈ 0.6557년/초(한 해 약 1.525초).
   t < 0.3: Y = 2019 + v·t² ÷ 0.6
   0.3 ≤ t < FW − 0.6: Y = 2019 + v·(t − 0.15)
   FW − 0.6 ≤ t < FW: Y = 2025 − v·(FW − t)² ÷ 1.2
   (세 식은 경계에서 값과 속도가 이어진다.)
2. 9.60–11.00 머묾. Y = 2025. 값·연도는 멈추고, 막대 자리는 스프링이 남은 흔들림을 가라앉힌다. 이때 「출발 몫」이 켜진다(아래).
3. 11.00–13.00 되감기(2.0초). u = (t − 11.00) ÷ 2.00, Y = 2025 − 6·easeInOutCubic(u). 값·눈금·연도가 거꾸로 흐르고, 막대는 스프링으로 거꾸로 추월한다.
   되감기 동안만 스프링 ω = 24(ζ 그대로 0.6). 거꾸로 추월 13번이 11.43~12.48초에 몰리므로 ω 12 로는 막대가 3칸까지 뒤처져 순서가 뒤섞인다.
   ω 24 면 가장 크게 뒤처질 때도 1.4칸이고, 13.00초에 모든 막대가 제자리 ±0.001칸 안으로 돌아온다(검산 최대 0.0005칸).
   되감기에서도 이름과 값 글자는 감추지 않는다. 값 글자는 자기 막대 바로 위 층에 그려서 남의 막대 위에 뜨지 않는다. 두 이름이 포개지는 것은 ω 24에서 추월마다 약 0.03초라 보이지 않는다.
   13.00초 = 0.00초 프레임 = 고르게 정렬된 2019년의 꽉 찬 화면, 바람시 방, 한 톤 막대.

- 값 보간(모든 구간 공통): 항목마다 연도별 값 v0…v6 를 Catmull-Rom 꼴 3차 에르미트로 잇는다.
  x = Y − 2019, k = min(floor(x), 5), s = x − k.
  기울기 m_i = (v_{i+1} − v_{i−1}) ÷ 2, 양 끝은 m_0 = v1 − v0, m_6 = v6 − v5.
  값 = h00·v_k + h10·m_k + h01·v_{k+1} + h11·m_{k+1}, h00 = 2s³ − 3s² + 1, h10 = s³ − 2s² + s, h01 = −2s³ + 3s², h11 = s³ − s².
  이 표로는 어느 항목도 중간에 값이 줄지 않는다.
- 목표 순위: 그 순간의 값으로 내림차순 정렬한 순서(0 = 1위). 값이 같으면 표에서 위에 있는 항목이 앞.
- 막대 자리 p(스프링): 항목마다 p'' = ω²·(목표 순위 − p) − 2ζω·p'.
  전진·머묾 구간 ω = 12, 되감기 구간 ω = 24, ζ = 0.6 은 공통.
  ω 12 에서 한 칸 계단을 주면 0.11초에 반을 가고, 약 9% (8개면 약 9px) 넘쳤다가 0.48초 안에 2% 안으로 든다.
  그래서 추월하는 두 막대는 1위 교체 뒤 τ ≈ 0.08~0.15초에 같은 줄을 지나며 이름·값 글자가 잠깐 포개진다.
- 이 표로 계산한 전진 구간의 사건(시시각각 맞는지 대조용):
  추월 13번. 1위가 바뀌는 순간 = 0.80초(바람시 → 노을시, 2019.43년) · 3.81초(노을시 → 구름시) · 6.49초(구름시 → 은하시, 둘 다 약 1억 1,300만).
  0.80초의 첫 1위 교체와 첫 물결이 첫 1초 안에 일어나는 것이 이 작품의 출발 신호다.
- 1위 교체 강조(시그니처) — 전진 구간(0 < t ≤ FW)에서 1위가 바뀐 시각 tc 부터, τ = t − tc:
  · 색 물결은 τ = 0 에서 시작한다([방] 절). 아직 2위 줄에 있는 새 1위 막대의 끝에서 번지므로 「곧 올라간다」는 예고가 되고, 물결은 방 층에서만 번져 추월을 가리지 않는다.
  · 값 글자 튐은 두 막대가 서로 지나간 뒤에 시작한다: τ₂ = τ − 0.15, 0 ≤ τ₂ < 0.9 동안 새 1위의 값 글자를 왼쪽 가운데 점을 기준으로 1 + 0.30·e^(−6τ₂)·sin(14τ₂) 배 한다.
    τ₂ = 0 에서 정확히 1, τ₂ = 0.083초(1위 교체 0.233초 뒤 — 1.03 · 4.04 · 6.73초)에 약 1.17배, τ₂ = 0.31초에 약 0.96배, 0.9초에 사실상 1. 튐은 자리를 잡은 뒤의 확인이다.
  · 막대 색은 바꾸지 않는다.
  되감기 구간의 1위 교체에는 물결과 튐을 주지 않는다(방은 0.3초 겹쳐 바꾸기만).
- 출발 몫(마무리): 항목마다 첫 해 값 v_first 의 자리 xs = x0 + 0.65W × (v_first ÷ 그 순간 1위의 값) 를 구하고,
  막대 중 x0 ~ min(xs, 막대 오른쪽 끝 − 0.010H) 부분을 「막대 색에 흰색 #FFFFFF 를 0.45·g 섞은 색」으로 덧칠한다(네모 그대로, 둥근 끝은 건드리지 않는다). 나머지(자란 몫)는 막대 색 그대로.
  g(t) = smoothstep((t − FW − 0.06·r) ÷ 0.3) × (1 − smoothstep((t − 12.5) ÷ 0.4)), r = 그 항목의 목표 순위. FW 전에는 g = 0.
  → 9.60초부터 1위 줄이 먼저, 한 줄 아래마다 0.06초 늦게 켜져 10.32초에 다 켜지고, 12.5초부터 꺼져 12.9초에 g = 0(한 톤)이다.
  2025년에 은하시는 막대의 18%만 출발 몫이고 82%가 자란 몫, 바람시는 66%가 출발 몫이다 — 한눈에 「누가 가장 자랐나」.
  되감기 동안 xs 는 1위 값을 따라 막대 끝과 함께 움직이고, 자란 몫이 줄어들어 막대가 출발 몫으로 돌아간다. g > 0 인 줄은 이 표로 언제나 xs ≤ 막대 끝이다.
- 연도 숫자(오도미터): n = floor(Y), f = Y − n. f < 0.8 이면 r = 0, 아니면 r = smoothstep((f − 0.8) ÷ 0.2).
  네 자리마다 n 의 숫자 a 와 n+1 의 숫자 b 를 비교해, 같으면 a 만 그리고, 다르면 a 를 −r·1.15·숫자 높이만큼 위로, b 를 (1 − r)·1.15·숫자 높이만큼 아래에 그린다.
  각 자리는 [기준선 − 1.02·숫자 높이, 기준선 + 0.02·숫자 높이] 띠로 잘라 보이게 한다(굴림 거리 1.15 는 그대로) — 띠를 숫자 윗선·기준선에 붙여야 굴러가는 숫자가 다른 숫자의 윗선·아랫선에서 들어가고 나와 「창으로 보이는 회전판」이 된다.
  띠가 위아래로 0.15 씩 남으면 잘린 숫자 조각이 다른 숫자보다 크게 삐져나와 깨진 글자로 보인다. 2019 → 2020 은 두 자리가 함께 굴러간다. 되감기에서는 같은 식이 저절로 아래로 굴린다.

[구현]
- 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)은 스크립트 맨 끝에서 한 번만 호출한다. 정의되기 전에 쓰면 첫 화면에서 멈춘다.

이 작품에만 해당하는 구현:
- 캔버스 밖 남는 곳의 색은 #FAFAF7 이다.
- 내부 해상도 배율(devicePixelRatio 를 반영한 배율)은 1.5 를 넘기지 않는다 — 방 그라디언트를 프레임마다 화면 전체에 칠하므로(물결 중 두 번), 4K 내부 해상도에서는 물결 프레임이 그래픽 가속 없는 캔버스에서 한 프레임 예산(16.7ms)을 넘는다(1080p 6.7ms · 4K 25~28ms).
- 스프링은 시작할 때 표로 한 번 미리 계산한다. dt = 1/240초, 한 바퀴 칸 수 N = T × 240 = 3120. 칸마다 그 칸 시각의 ω(되감기면 24, 아니면 12)를 쓴다.
  p = 0초의 목표 순위, p' = 0 에서 출발해 두 바퀴(2N 칸)를 반암시 오일러(p' += p''·dt, 그다음 p += p'·dt)로 진행하고, 둘째 바퀴의 p 를 표[칸][항목]에 적는다.
  머묾 구간에서 흔들림이 다 가라앉으므로 둘째 바퀴는 정확히 주기적이다 — 표의 끝과 처음이 이어진다(검산: 둘째·셋째 바퀴 차이 0).
  render(t) 는 t mod T 를 칸 번호 t·240 으로 바꿔 이웃 두 칸을 선형 보간해 읽는다. 0초 칸의 모든 막대는 제자리 ±0.001칸 안이다.
- 1위 교체 목록도 같은 1/240초 격자로 시작할 때 한 번 만든다: 칸마다 목표 순위 0 인 항목이 앞 칸과 다르면 { t, from, to, rewind(t > FW), 원점 O } 를 적는다.
  이 표면 전진 3개(0.80·3.81·6.49초) · 되감기 3개(11.85·12.08·12.48초). render(t) 는 t 이하의 마지막 교체를 찾아(없으면 0초의 1위) 방과 연도 색을 [방] 절대로 정한다.
- 그리는 순서: 방(이전 방 → 물결 원 안의 새 방 → 물결 테두리 선) → 제목·작은 글씨 → 눈금선·눈금 값 → 세로 기준선 → 연도 숫자(방과 같은 두 겹) → 항목마다 [막대(출발 몫 덧칠 포함) → 그 막대의 값 글자](목표 순위가 나쁜 것부터) → 항목 이름 전부.
  값 글자는 자기 막대 바로 위 층에 그린다 — 다음 막대가 겹쳐 지나가면 앞 막대의 값 글자는 그 막대 밑에 가려진다(값 글자가 남의 막대 위에 떠 있지 않다).
  추월하는 막대는 목표 순위가 앞이라 나중에 그려져, 겹치는 순간 위로 지나가고 새 1위의 값 글자 튐이 가려지지 않는다.
- 막대·이름·값 글자의 세로 위치는 모두 p 하나에서 나온다(셋이 함께 미끄러진다). 막대 색은 항목을 따라간다.
- CONFIG.timing = { yearSec 1.6, easeIn 0.3, easeOut 0.6, hold 1.4, rewind 2.0, wave 0.9, rewindFade 0.3, popDelay 0.15, popDur 0.9, baseStagger 0.06, baseIn 0.3, baseOutStart 12.5, baseOut 0.4 }, CONFIG.spring = { omega 12, omegaRewind 24, zeta 0.6, dt 1/240 },
  CONFIG.room = { paper '#FAFAF7', tintHi 0.18, tintLo 0.07, yearInk 0.30, ringWidth 0.006, ringAlpha 0.7, baseWhite 0.45 },
  CONFIG.layout 에 [크기]의 비율을 전부, CONFIG.data 에 표를 그대로 둔다. 시간표는 전부 이 값에서 계산한다(FW = yearSec × 연 수, T = FW + hold + rewind).
- 자체 대조: 시작할 때 한 번 아래를 계산해 console.table 로 내고, 줄마다 기준과 PASS/FAIL 을 적는다(화면에는 그리지 않는다). 어긋나면 console.warn 도 한 줄. 이 표로는 전부 PASS 여야 한다.
  ① 1위 교체 시각 — 전진 0.80·3.81·6.49초, 되감기 11.85·12.08·12.48초(±0.02) ② 전진 추월 수 — 13
  ③ 0초 칸 잔여 max|p − 목표 순위| ≤ 0.01칸(기대 0.0005) ④ 둘째·셋째 바퀴 표 차이 ≤ 1e-6
  ⑤ 7위 값 ÷ 1위 값 최댓값 ≤ 0.42(기대 0.389)
  ⑥ 눈금 글자 최소 간격 ≥ 12px — 0~T 를 1/60초 격자로 훑어, a_글자 > 0.05 인 이웃 눈금 글자의 measureText 상자 사이 간격의 최솟값(기대 약 30px)
  ⑦ 가장 긴 값 글자 × 1.17 의 오른쪽 끝 ≤ 0.965W
  ⑧ 대비(WCAG 상대 휘도 식, (밝은 쪽 + 0.05) ÷ (어두운 쪽 + 0.05)) — 방 8개 × 그라디언트 양 끝 = 16색 전부에 대해:
     막대 8색 최솟값 ≥ 3.0(기대 3.33, 노을시 막대 ↔ 노을시 방 진한 끝) · 잉크 ≥ 4.5(기대 13.1) · 값 글자 ≥ 4.5(기대 10.4) · 작은 글씨·눈금 글자(불투명일 때) ≥ 4.5(기대 6.56) · 연도 색 ↔ 자기 방 양 끝 ≥ 4.5(기대 5.31, 노을시)
     반투명 글자 — 0~T 를 1/60초 격자로 훑어 0.05 < a_글자 < 0.9 인 눈금 글자가 하나라도 있는 프레임 비율 ≤ 6%(기대 3.8%). 반투명 글자는 위 4.5 를 지키지 못하므로 이 비율이 대비의 나머지 절반이다.
  ⑨ 막대 색 쌍 구분 — OKLab 거리 × 100 의 최솟값 ≥ 9(기대 10.3, 물결시–솔빛시)
  ⑩ 물결 원점 — 전진 교체 세 번 모두 (0.810W, 0.288H) ±0.01, Rmax ≈ 0.904W(±0.01).

[하지 말 것]
- 막대가 0에서 자라며 시작하지 않는다 — 첫 1초가 빈 차트면 그대로 넘겨진다. 0초부터 2019년 값으로 꽉 찬 막대가 있고, 반복은 되감기로 꽉 찬 화면끼리 잇는다.
- 페이드·흰 화면·컷으로 반복을 넘기지 않는다 — 이음매가 장면 전환으로 읽힌다. 되감기 2초가 이음매를 맡는다.
- 되감기를 1초로 줄이거나 되감기 동안 ω 를 12 로 두지 않는다 — 추월 13번이 한꺼번에 쏟아져 막대가 3칸까지 뒤처지고 순서가 뒤엉킨다. 그 잔여가 0초 프레임에 남아 막대 간격이 3~37px 로 들쭉날쭉하고, 파일을 열자마자 차트가 까닭 없이 꿈틀거린다.
- 되감기 중에 목표 순위와의 거리(|p − 목표 순위|)로 글자를 감추지 않는다 — 목표 순위는 정수로 바뀌어 그 거리가 추월 순간 0에서 1칸으로 한 프레임에 뛰므로, 글자가 페이드 없이 꺼졌다 켜지며 1초 남짓 동안 48번 깜빡이고 한때 막대 절반이 이름 없이 움직인다.
- 순위가 바뀔 때 막대를 새 자리로 순간이동시키거나 자리를 값에서 바로 계산하지 않는다(시그모이드로 부드럽게 만든 순위 포함) — 순간이동은 추월이 안 보이고, 값에서 바로 만든 부드러운 순위는 값이 비슷한 두 막대를 반쯤 겹친 채 오래 붙여 둔다. 목표 순위는 정수로 바뀌고 자리는 스프링이 따라간다.
- 스프링을 프레임마다 경과 시간으로 누적하지 않는다 — 탭을 다녀오면 큰 시간 간격 한 번에 막대가 튀어 나가고, 반복할 때마다 처음 자리가 달라진다. 시작할 때 만든 표만 읽는다.
- 연도와 연도 사이를 각각 easeInOut 으로 잇지 않는다 — 해마다 모든 막대가 한꺼번에 멈칫해 레이스가 계단으로 보인다. 연도는 전진 구간 내내 일정 속도로 흐르고, 값은 에르미트 곡선으로 잇는다.
- 축 범위를 고정하지 않는다 — 처음 해에는 1위 막대도 화면 폭의 3분의 1에 그쳐 화면이 빈다. 1위 막대는 늘 0.81W 까지 닿고, 커지는 값은 눈금선이 왼쪽으로 몰리는 것으로 보여 준다.
- 값 글자를 toLocaleString·Intl 로 만들지 않는다 — 기기 언어 설정에 따라 쉼표나 단위가 달라진다. 위 표기 함수를 직접 쓴다.
- 실제 도시·회사 이름이나 「출처: ○○」 같은 표기를 넣지 않는다 — 지어낸 값이 실제 통계로 읽힌다. 「가상 데이터」 문구는 지우지 않는다.
- 막대에 그라디언트·그림자·광택·3D 를 넣지 않는다 — 막대의 길이 차이만 읽혀야 추월이 보이고, 장식은 길이 판독을 흐린다. 두 톤은 머묾·되감기의 출발 몫 하나뿐이고, 그것도 데이터(첫 해 값)다.
- 깃발·아이콘·사진 원·이모지를 막대 끝에 붙이지 않는다 — 프롬프트에 없는 장식이고, 외부 이미지를 부를 수도 없다. 항목은 이름과 색으로만 구분한다.
- 1위 교체 강조에 왕관·폭죽·파티클·글로우·화면 흔들림을 쓰지 않는다 — 강조는 방 층의 색 물결과 값 튐 둘뿐이다. 더 큰 효과는 추월 자체(미끄러짐)를 가린다.
- 물결이나 방 색을 막대·글자 위 층에 칠하지 않는다(반투명 원을 맨 위에 덮는 것 포함) — 막대 색이 물결 색과 섞여 바뀌면 계열 구분이 무너지고 미끄러지는 막대의 경계가 흐려진다. 물결은 방과 연도 숫자에만 번진다.
- 새 1위 막대를 흰색 쪽으로 섞어 번쩍이지 않는다 — 밝은 방에서는 막대가 바탕에 녹아(흰색 55% 를 섞으면 방 대비 약 1.4) 1위가 사라지는 것처럼 보인다. 예고는 막대 끝에서 번지는 물결이 맡는다.
- 방을 18% 보다 진하게 물들이거나 막대 색 그대로 칠하지 않는다 — 1위 막대가 자기 색 방에 묻힌다(18% 에서 노을시 막대 대비 3.33, 더 진하면 그래픽 대비 3:1 아래). 방은 「누가 1위인가」를 옅게 말할 뿐이다.
- 1위가 되는 항목에 갈색·올리브·노랑을 주지 않는다 — 그 색을 18% 섞은 방은 종이색 베이지가 되어 물결 앞뒤 방 차이가 OKLab 2 아래로 떨어져 물결이 안 보인다.
- 눈금 값 글자를 반투명으로 오래 두지 않는다(선의 a 를 글자에 그대로 곱하는 것 포함) — 머묾 1.4초 내내 a 0.46 인 글자는 대비 2.2:1 로 흐린 글자가 된다. 글자는 a_글자 로 켜고 끈다.
- 방 색을 연도나 시간으로 바꾸지 않는다(무지개처럼 흐르는 배경 포함) — 방 색은 1위라는 데이터다. 데이터와 무관하게 바뀌면 색이 아무 뜻 없이 막대 색과 다툰다.
- 되감기의 1위 교체에 물결을 쓰지 않는다 — 되감기 교체는 0.22·0.41초 간격이라 0.9초 물결이 서로 잘려 번쩍임이 되고, 거꾸로 흐르는 시간에 새 사건처럼 읽힌다. 되감기는 0.3초 겹쳐 바꾸기만.
- 출발 몫을 12.9초 뒤까지 남기지 않는다 — 0초 프레임은 한 톤 막대라, 남아 있으면 이음매에서 막대 색이 한 프레임에 튄다.
- 배경을 검정·짙은 남색으로 되돌리거나, 종이 결·잡음·비네트·흐림을 깔지 않는다 — 막대 대비(⑧)를 위에서 잰 방 색으로 지켰고, 화면 전체 효과는 대비를 자리마다 흔들고 프레임 비용을 늘린다.
- 순위 번호·「1위」 배지·범례·축 제목을 더하지 않는다 — 순위는 위치가 말하고, 이름이 막대 옆에 있어 범례는 중복이다. 늘어난 글자는 막대 사이 틈을 메워 화면이 표처럼 보인다.
- 막대 색을 순위에 따라 칠하지 않는다 — 색이 자리를 따라가면 추월하는 순간 색이 바뀌어 누가 누구를 앞질렀는지 안 보인다. 색은 항목을 따라간다.
- 연도 숫자를 막대 위에 그리지 않는다 — 표를 바꿔 아래쪽 막대가 길어지면 숫자가 막대를 가린다. 연도는 막대 뒤에 그린다.
- 되감기에 줄무늬 노이즈·되감기 아이콘·흐림·색 반전을 넣지 않는다 — 값이 거꾸로 흐르는 것만으로 되감기로 읽히고, 효과가 붙으면 장면 전환처럼 보인다.
- 모션 블러·잔상을 넣지 않는다 — 막대 끝 값 글자가 번져 읽을 수 없게 되고, 미끄러짐의 경계가 흐려진다.

사용 방법

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

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

추가 요청 예시

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

  • 데이터 표를 동네 빵집 여덟 곳의 한 달 판매 개수(지어낸 값, 단위 개)로 바꾸고, 제목도 그에 맞게 바꿔 줘.
  • 방이 1위 색으로 물드는 세기를 절반으로 줄여(오른쪽 위 9%, 왼쪽 아래 3%) 거의 흰 종이처럼 차분하게 해 줘. 물결 테두리 선은 그대로 둬서 1위 교체는 보이게.
  • 한 해를 2.4초로 늘려서 추월이 더 천천히 보이게 하고, 마지막 해에 머무는 시간도 2초로 늘려 줘.

데이터

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

데이터 전체 보기

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