概要
Pretext は、マルチラインテキストの測定とレイアウトを行う 純粋なJavaScript/TypeScriptライブラリ。 高速かつ正確 で、多言語対応および絵文字・双方向テキストもサポート。 DOMへのアクセス不要 で、レイアウト再計算によるパフォーマンス低下を回避。 Canvas, SVG, WebGL, サーバーサイド描画 にも対応予定。 npm install @chenglou/pretext で簡単インストール。
Pretextの特徴
-
DOM測定不要
- getBoundingClientRectやoffsetHeightなどの 高コストなDOM再計算を回避
- 独自のテキスト測定ロジックを実装し、 ブラウザのフォントエンジンを基準 に利用
- AIフレンドリーなイテレーション方式 採用
-
多様な描画先対応
- DOM, Canvas, SVG, WebGL, サーバーサイド 描画サポート
- 多言語・絵文字・混在双方向テキスト も正確に測定
-
高速なパフォーマンス
- 500テキストのバッチ処理で prepare()は約19ms、layout()は約0.09ms
- キャッシュ利用による効率化
-
柔軟なレイアウト制御
- Masonryや仮想スクロールなど 高度なUIレイアウト にも最適
- ユーザー独自のレイアウト実装 も容易
-
開発・検証用途
- AI生成UIの検証 や ラベルのオーバーフロー防止 に活用
- レイアウトシフトの防止 や スクロール位置の再アンカー にも有効
インストール・デモ
- インストール方法
npm install @chenglou/pretext
- デモ閲覧
- リポジトリをクローン後、
bun install→bun start→/demosパスをブラウザで開く - オンラインデモ:
- リポジトリをクローン後、
主要APIと使い方
-
段落の高さ測定(DOM非依存)
-
import { prepare, layout } from '@chenglou/pretext' const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter') const { height, lineCount } = layout(prepared, textWidth, 20) - prepare(): テキストの正規化・分割・測定を一度だけ実行、結果をハンドルとして返却
- layout(): キャッシュ済み幅を使った純粋な算術処理で高速計算
-
-
textarea風の表示
-
const prepared = prepare(textareaValue, '16px Inter', { whiteSpace: 'pre-wrap' }) const { height } = layout(prepared, textareaWidth, 20) - whiteSpace: 'pre-wrap' でスペース・タブ・改行をそのまま表示
-
-
段落の手動レイアウト
-
import { prepareWithSegments, layoutWithLines } from '@chenglou/pretext' const prepared = prepareWithSegments('AGI 春天到了. بدأت الرحلة 🚀', '18px "Helvetica Neue"') const { lines } = layoutWithLines(prepared, 320, 26) for (let i = 0; i < lines.length; i++) ctx.fillText(lines[i].text, 0, i * 26) - walkLineRanges で各行の幅やカーソル情報のみ取得可能
- layoutNextLine で幅が変化する場合に一行ずつレイアウト可能
-
APIリファレンス
-
prepare(text, font, options?)
- テキスト解析・測定、
layout()用ハンドルを返却 - fontは
16px InterなどCanvas互換指定
- テキスト解析・測定、
-
layout(prepared, maxWidth, lineHeight)
- 指定幅・行高に対する 高さ・行数 を返却
-
prepareWithSegments(text, font, options?)
- 手動レイアウト用 の詳細なセグメント情報を返却
-
layoutWithLines(prepared, maxWidth, lineHeight)
- 各行情報(text, width, start/end cursor) を含む結果を返却
-
walkLineRanges(prepared, maxWidth, onLine)
- 各行の幅・カーソル範囲のみコールバックで取得
-
layoutNextLine(prepared, start, maxWidth)
- カーソルから次の行を一行ずつ取得、段組や画像回り込みに最適
-
clearCache()
- 内部キャッシュの消去
-
setLocale(locale?)
- ロケール指定&キャッシュクリア
注意点・制限
- 完全なフォントレンダリングエンジンではない
- 現状は
white-space: normal,word-break: normal,overflow-wrap: break-word,line-break: autoが対象 whiteSpace: 'pre-wrap'指定時はスペース・タブ・改行を保持
- 現状は
- system-uiはmacOSで精度保証外
- 必ず明示的なフォント名を指定
開発・クレジット
- 開発手順 は
DEVELOPMENT.md参照 - 着想元: Sebastian Markbage氏のtext-layout
- Canvas measureText + pdf.jsのbidi + ストリーミング改行 方式を踏襲