이 실험에 대해
layoutWithLines()로 각 라인의 텍스트와 너비를 계산한 뒤, Canvas의 fillText()로 사인 곡선 오프셋을 적용해 렌더링한다. DOM을 건드리지 않기 때문에 레이아웃 스래싱 없이 60fps를 유지한다.
핵심 코드
const prepared = prepareWithSegments(text, '15px monospace')
// 매 프레임마다 호출 — 매우 빠름 (~0.09ms)
const { lines } = layoutWithLines(prepared, width, 28)
lines.forEach((line, i) => {
const waveY = Math.sin(t + i * 0.4) * 6
ctx.fillText(line.text, x, baseY + i * 28 + waveY)
})