이 실험에 대해
layoutWithLines()로 라인을 구한 뒤, 각 글자의 x 위치는 ctx.measureText()로 누적 계산한다. 마우스가 반경 80px 안에 들어오면 반발력을 적용하고, 스프링 물리로 원래 자리로 되돌아온다.
핵심 코드
// 글자별 resting position 계산
lines.forEach((line, li) => {
let x = PADDING
for (const ch of line.text) {
const cw = ctx.measureText(ch).width
chars.push({ char: ch, restX: x, restY: baseY + li * 28, x, y, vx: 0, vy: 0 })
x += cw
}
})
// 매 프레임: 마우스 반발력 + 스프링
const force = (RADIUS - dist) / RADIUS
c.vx += Math.cos(angle) * force * 4
c.vx += (c.restX - c.x) * 0.12 // spring
c.vx *= 0.78 // damping