Skip to content

[DONE] Pattern Lab 텍스트 레이어에 노브로 움직이는 흐르기 · 반짝임 · 색 램프 효과가 생긴다 - #187

Merged
patternflow-bot merged 6 commits into
devfrom
claude/pf-round64-kn61hs
Oct 23, 2026
Merged

patternflow-bot merged 6 commits into
devfrom
claude/pf-round64-kn61hs

Conversation

@patternflow-bot

@patternflow-bot patternflow-bot commented Oct 23, 2026 •

Copy link
Copy Markdown

dev / https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ

Pattern Lab 의 텍스트 레이어에 Effect 칸이 생겼어요. 흐르기 · 반짝임 · 색 램프 따라 바뀌기 가운데 하나를 고르면, 고른 노브가 그 빠르기를 정하고 끝까지 내리면 멈춰요. 흐르기는 판보다 긴 문장도 통째로 지나가요. 머지하면 내보낸 JS 와 To hardware 헤더도 미리보기와 같은 LED 를 같은 걸음으로 켜서, 협업 문구를 움직이는 채로 기기에 올릴 수 있어요.

좋아지는 것: 글자가 노브 빠르기로 흐르고 반짝이고 색이 바뀐다 — 협업 문구를 움직이는 채로 기기에 올린다

폰 390 · 흐르기
데스크톱 1440 · 흐르기
데스크톱 1440 · 반짝임
데스크톱 1440 · 램프 따라 바뀌기

체크리스트

한 일

  • web/src/lib/lab/textEffects.ts (새 파일): 효과 셋의 셈이에요. 위상(phase)은 매 프레임 dt × (노브 몫 × 빠르기) 를 더하고 주기로 나눈 나머지만 남겨요. 픽셀마다는 정수 셈뿐이라 미리보기 · JS · C++ 가 같은 LED 를 켜요.
    • 흐르기(Scroll): 글자가 왼쪽으로 나가고 오른쪽에서 다시 들어와요. 노브 끝까지면 1초에 128칸(판 폭 하나)이에요. 위상 0 은 Text 패널이 둔 자리예요.
    • 반짝임(Twinkle): 켜진 LED 마다 제 박자로 밝기가 1/4 까지 내려갔다 돌아와요. 박자는 32비트 곱셈 해시라 기기에서도 같은 LED 가 같은 때 반짝여요. 알파로 어두워져서 다른 레이어 위에선 그 레이어 쪽으로 희미해져요.
    • 램프 따라 바뀌기(Run the ramp): 픽셀마다 램프 위 자리가 앞으로 갔다가 돌아와요. 끝에서 처음으로 튀지 않아요. 한 색 채우기면 글자 전체가 같이 램프를 따라 바뀌어요.
  • types.ts: TextSpec 에 effect · effectKnob, TextLayer 에 source. 흐르기와 램프는 판 밖까지 줄 전체를 source 로 그려 둬요(가장 큰 판 한 장 분량, 128×64 판에서 4096칸까지).
  • text.ts, textRaster.ts: 줄이 닿는 칸을 재고(textReach) 그 폭의 캔버스에 같은 정수 자리로 그려요. 판과 겹치는 칸은 판에 그린 것과 바이트까지 같아요(아래 증거).
  • engine.ts: 효과가 있는 텍스트 레이어마다 위상과 프레임을 들고, 마스크로 쓰여도 같이 움직여요. Graphic Export 가 다른 격자로 그릴 땐 그 프레임을 늘려요(stretch.ts 로 옮긴 stretchNearest).
  • flatten.ts, hExport.ts: 효과 레이어는 움직일 것(source 나 비트맵, RLE)과 위상, 램프면 LUT 를 싣고 textEffects.ts 와 같은 걸음을 JS · C++ 로 적어요. 효과가 없는 스택의 출력은 전과 한 글자도 같아요. 헤더의 rleDecode 는 칸 수를 받는 인자가 기본값과 함께 생겼어요.
  • serialize.ts, store/shared.ts: source 를 저장하고 열어요(맞지 않으면 버리고 그 레이어는 멈춘 글자로 보여요). 판 크기를 바꾸면 source 도 글자와 같이 옮겨요. 램프를 따르는 한 색 텍스트는 램프를 고치면 다시 그려요.
  • TextPanel.tsx: Effect 칸(None · Scroll · Twinkle · Run the ramp)과 Speed knob 칸(Knobs 패널의 이름 그대로). 그 노브가 지금 몇 % 인지, 0% 면 「아직 안 움직이니 Knobs 에서 올리라」고 말해요. 램프를 따를 땐 Color 칸을 감춰요.
  • RampPanel.tsx: 램프를 따르는 한 색 텍스트를 「This text is one colour」라 하지 않아요.
  • HardwareModal.tsx: 움직이는 텍스트가 있으면 「Text that moves moves there too, on the same knob.」을 더해요.
  • pixelToCode.ts: 흐르는 텍스트의 Copy as code 는 판 밖까지 줄 전체를 실어요. 효과는 싣지 않고 멈춘 글자예요(Text 패널이 그렇다고 말해요).
  • web/ARCHITECTURE.md 의 Text 줄에 효과와 source 를 적었어요.
  • 시험: textEffects.test.ts (새 파일, 22개), textExport.test.ts 에 움직이는 스택 19개 × 여러 프레임, TextPanel.test.tsx 5개, HardwareModal.test.tsx 1개.

증거

web/ 에서, 이 브랜치 마지막 코드 커밋(9044e80)으로:

$ npm ci
added 762 packages, and audited 763 packages in 37s
$ npm run lint -- --max-warnings=0
> eslint --max-warnings=0
(출력 없음, 통과)
$ npm run typecheck
> tsc --noEmit && tsc --noEmit -p ../tools/virtual-panel
(출력 없음, 통과)
$ npm run build
✓ Compiled successfully in 16.1s
✓ Generating static pages using 3 workers (145/145) in 17.9s
$ npm run check:ci
 Test Files  92 passed (92)
      Tests  1136 passed (1136)
passed   audio-vectors … passed   virtual-panel   (skipped: links-absolute, roadmap — gh 로그인 없음)
exit 0
$ npm run check:voice
check:voice: nothing found
$ npm run check:human-lock
check:human-lock: no locked words changed

같은 픽셀 시험(npx vitest run src/lib/lab/textExport.test.ts, 157개 통과). 움직이는 스택마다 미리보기, 내보낸 JS, g++ 로 컴파일한 헤더를 1 · 23 · 77 프레임처럼 여러 때에 비교해요. 흐르기가 한 바퀴 돌아 제자리에 오는 85 프레임, 램프가 끝에 닿는 128 프레임과 돌아오는 256 프레임, 반짝임 박자가 끝나는 64 프레임을 넣었어요. 헤더 쪽은 dt 를 1/64 초, 노브를 1/4 단위로 둬서 float 와 double 의 위상 합이 비트까지 같아요. JS 쪽은 노브 0.3 · 0.37 · 0.81 같은 값과 1/60 초로도 비교해요.

시험이 틀린 걸 잡는지 일부러 고장 내 봤어요(돌려 놓은 뒤 다시 초록).

C++ 반짝임을 1/3 까지만 어둡게        → TwinkleOverArt, TwinkleMaskOverCode, Moving43 … 빨강
C++ 흐르기를 한 칸 어긋나게           → ScrollAlone, ScrollSoftRampOverArt, StandingStill … 빨강
C++ 램프를 왕복 대신 되감기로          → RampAcross, RampSolidOverArt, Moving47 … 빨강
JS 위상이 노브 값을 1% 더 읽게         → ScrollSoftRampOverArt, TwinkleOverArt, RampAcross … 빨강
C++ 반짝임 해시의 자리 옮김 하나 바꿈 → TwinkleOverArt, Moving43, Moving46 … 빨강

실제 브라우저(빌드한 사이트, 컨테이너 Chromium, Silkscreen 실제 글꼴)에서 128×64 미리보기 캔버스를 읽었어요. 「PATTERNFLOW SEOUL 2026」은 판보다 길어요.

plain text steady: true font loaded: true
standing scroll is the plain text 0 columns on, to the byte   (Freq 노브 0% 에 둔 흐르기 = 효과 없는 글자, 바이트까지 같음)
scroll moving: lit columns now [12,13,14] then [0,1,2]
twinkle: bytes changed in 0.3 s 1255
ramp: bytes changed in 0.4 s 1044

다른 판에선 Freq 로 바꾸기 전 Speed 노브로 한 칸 흘러가 있었고, 그때도 「1 columns on, to the byte」였어요. 사진 맨 위 둘은 흐르기 중간이라 판 밖에 있던 「SEOUL 2026」이 들어와 있어요.

실행법

  1. Pattern Lab 에서 Layers 의 + Text 를 눌러요. Text 패널이 열려요.
  2. 판보다 긴 글을 넣고 Effect 를 Scroll 로 둬요. Speed knob 은 처음 프로젝트에서 「Speed」(39%)예요. Knobs 패널에서 그 노브를 돌리면 빨라지고 끝까지 내리면 멈춰요.
  3. Twinkle, Run the ramp 도 같아요. Run the ramp 는 Color Ramp 패널의 색을 따라가요.
  4. To hardware 의 Copy .h 헤더와 Export 의 JS 도 같은 노브로 같이 움직여요.

가정

  • 작업 글은 앞 바퀴 댓글 다음 「후보」 표를 말하지만, ROUND.md 고르는 차례 0 이 「창작자 지시」를 먼저 둬서 지시 4 를 맡았어요([DONE] Pattern Lab 에 텍스트 레이어가 생겨 내 기기의 글꼴로 글을 넣고 끌어 옮긴다 #184 · [DONE] Pattern Lab 에서 글자를 글꼴 없이 도는 코드로 복사하고, 기기 헤더가 미리보기와 같은 그림을 낸다 #186 과 같은 읽기). 맡을 댓글은 없었어요.
  • 「노브로 움직이는」은 노브가 빠르기를 정하는 것으로 읽었어요. 노브가 자리를 정하면 아무도 안 만지는 판에선 글자가 서 있어요. 흐르기는 혼자 흘러야 흐르기라서요. 끝까지 내리면 그 자리에 서요. Director 나 MQTT 가 노브를 움직이면 효과도 같이 따라가요.
  • 효과는 레이어마다 하나만 골라요. 셋을 겹치는 것은 「첫 셋」 다음 일로 뒀어요. 새 효과는 TEXT_EFFECTS 와 세 렌더러(textEffects.ts, flatten.ts, hExport.ts)에 한 갈래씩 더하면 돼요.
  • 처음 노브는 둘째 노브예요. 펌웨어 순서로 Speed 자리고, 처음 프로젝트에서 이름도 Speed 이며 바닥에 있지 않은 유일한 노브예요(나머지 셋은 0%). 첫째 노브로 두면 효과를 골라도 아무것도 안 움직여요.
  • 반짝임은 RGB 대신 알파를 낮춰요. 검은 판 위에선 같고, 다른 레이어 위에선 글자가 그 레이어 쪽으로 희미해져요. 마스크로 쓰면 반짝이는 칸이 마스크 문턱(0.5)을 오가며 깜빡여요.
  • 램프 따라 바뀌기는 왕복이에요. 되감기는 램프 끝 색에서 첫 색으로 튀어요. 위상 0 에선 램프 채우기(Ramp across · down)와 픽셀까지 같아요.
  • 흐르기는 왼쪽으로만 가요. 세운 패널에서 위로 흐르기는 하지 않았어요.
  • source 는 가장 큰 판 한 장(512×512×4 바이트)까지예요. 128×64 판에선 4096칸이라 Silkscreen 16px 로 200자 넘게 들어가요. 넘는 글자는 빠져요.
  • Copy as code 는 효과를 싣지 않아요. AI 에게 넘기는 틀(DISTORT · LIGHT 칸)에 효과 셋을 다 옮기면 크기가 이 바퀴를 넘어요. 흐르기면 판 밖 글자까지 실어서 챗에서 흐르게 할 수는 있어요.
  • .pfm 을 보드에서 돌려 보지는 못했어요. 이 컨테이너엔 보드가 없어요. 증거는 헤더를 호스트 g++ 로 돌린 데까지예요. 기기의 실제 dt 는 1/64 가 아니라서 위상이 미리보기와 아주 조금 다르게 쌓이지만, 같은 위상에선 같은 LED 를 켜요.
  • 반짝임 · 램프 효과를 쓰면 헤더에 fmodf 와 32비트 곱셈이 들어가요. 효과가 없는 스택의 헤더 · JS 는 전과 같아요.
  • 사진의 Playwright 는 페이지를 열 때 「PAGEERROR Event」를 한 번 냈어요. 컨테이너가 jsdelivr 의 Monaco loader.js 를 막아서 나는 것이고, 효과를 고르기 전 빈 페이지에서도 나요.
  • 앞 바퀴가 고친 것을 되돌린 곳은 없어요. stretchNearest 는 capture/core.ts 에서 stretch.ts 로 옮겼고, core.ts 가 다시 내보내서 부르는 곳은 그대로예요.

Changelog

Web

  • Pattern Lab's text layers scroll, twinkle or run their colour ramp, at the speed of a knob. The Text panel's Effect picks one, and the knob it names sets the speed; turned all the way down, the letters stop. A scroll carries the whole line, so words longer than the panel pass through it. The flattened JS and the To hardware header move the same LEDs the preview does, frame for frame, which a test checks by compiling the header on the host.

경험

언제: 바퀴에서 vitest 시험의 beforeEach 로 목(mock)을 비울 때
교훈: beforeEach(() => vi.mocked(fn).mockClear()) 처럼 화살표가 값을 돌려주게 쓰지 않고 중괄호로 감싼다. mockClear() 가 목 자신을 돌려주면 vitest 가 그것을 정리 함수로 알고 인자 없이 불러서, 목 안에서 엉뚱한 TypeError 가 난다
근거: #187 의 textEffects.test.ts 가 「Cannot read properties of undefined (reading 'align')」로 7개 빨갰고, 스택이 vitest 의 callCleanupHooks 에서 목을 부르고 있었어요. 중괄호로 감싸자 사라졌어요

바퀴

바퀴 64 · 지시 4 「텍스트 효과 첫 셋」

다음 바퀴

  • 지시 5 「Pattern Lab UI · UX 다듬기」: 처음 온 사람이 레이어 더하기 → 노브 → 기기로 보내기까지 막히는 곳을 폰 · 데스크톱으로 재서 「후보」 표를 Lab 위주로 다시 채워요. 이번에 본 것 하나: 텍스트 효과의 빠르기를 Text 패널 안에서 바로 못 돌려요(Knobs 패널로 가야 해요).
  • 「후보」 표 1위: WebGL 을 못 쓰는 브라우저에서 첫 화면과 Build · Pattern · Inside 탭이 오류 화면 대신 글과 단추를 보여 준다.
  • 「후보」 표 2위: 첫 화면 영상 밑 사진이 2.1 MB 원본 대신 화면 폭에 맞춘 20 KB 남짓으로 와요.

https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ


Generated by Claude Code

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ
@patternflow-bot patternflow-bot changed the title [WIP] pf 64바퀴 — 고를 일을 찾는 중 [WIP] Pattern Lab 텍스트 레이어에 노브로 움직이는 흐르기 · 반짝임 · 색 램프 효과가 생긴다 Oct 23, 2026
… in the Lab and both exports

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ
…ed JS and the compiled header

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ
…uns through it, and ARCHITECTURE names text effects

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PzCQEsRTRtmM7tcthcCUnQ
@patternflow-bot patternflow-bot changed the title [WIP] Pattern Lab 텍스트 레이어에 노브로 움직이는 흐르기 · 반짝임 · 색 램프 효과가 생긴다 [DONE] Pattern Lab 텍스트 레이어에 노브로 움직이는 흐르기 · 반짝임 · 색 램프 효과가 생긴다 Oct 23, 2026
@patternflow-bot
patternflow-bot marked this pull request as ready for review October 23, 2026 22:28
@patternflow-bot
patternflow-bot merged commit 1b9a04a into dev Oct 23, 2026
3 checks passed
@patternflow-bot
patternflow-bot deleted the claude/pf-round64-kn61hs branch October 23, 2026 22:36
engmung pushed a commit to engmung/Patternflow that referenced this pull request Oct 25, 2026
engmung pushed a commit that referenced this pull request Oct 25, 2026
지시 1~5 는 끝(#183 #184 #186 #187). 6 은 텍스트 레이어 고침 셋(빈 글의 옛 source · 판 바꾼 뒤 다시 열면 버려지는 source · 글꼴 기억 안내), 7 은 주석 속 포크 PR 번호 · 가이드 카드의 옛 노브 셈 · PatternLabClient 머리 주석. 상한을 102 로 올려 정리 바퀴 열은 그대로.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants