experiment
code
import { prepareWithSegments, layoutWithLines } from "@chenglou/pretext";
// 1. pretext で行折り返し位置を計算(DOM 計測なし)
const prepared = prepareWithSegments(text, font);
const { lines } = layoutWithLines(prepared, containerWidth, lineHeight);
// 2. 各文字の静止座標を確定
const chars = [];
for (const [i, line] of lines.entries()) {
let x = 0;
for (const ch of line.text) {
const w = ctx.measureText(ch).width;
chars.push({ ch, restX: x, restY: i * lineHeight, x, y, vx: 0, vy: 0 });
x += w;
}
}
// 3. フレームごとにスプリング + マウス反発
function tick() {
for (const c of chars) {
const dx = c.x - mouse.x, dy = c.y - mouse.y;
const dist = Math.hypot(dx, dy);
if (dist < RADIUS) {
const force = (RADIUS - dist) / RADIUS * STRENGTH;
c.vx += (dx / dist) * force;
c.vy += (dy / dist) * force;
}
c.vx += (c.restX - c.x) * STIFFNESS;
c.vy += (c.restY - c.y) * STIFFNESS;
c.vx *= DAMPING; c.vy *= DAMPING;
c.x += c.vx; c.y += c.vy;
}
} chenglou/pretext で行折り返し位置を事前計算し、 文字ごとの静止座標を確定。あとは Canvas 上でスプリング物理だけで動かしている。 テキストエリアに入力すると文字が更新される。