23 điểm bởi princox 23 ngày trước | 3 bình luận | Chia sẻ qua WhatsApp

Việc xác định văn bản sẽ chiếm bao nhiêu dòng trong trình duyệt khó hơn tưởng tượng. Thông thường người ta dùng getBoundingClientRect hoặc offsetHeight, nhưng các cách này buộc trình duyệt phải tính lại layout. Đây chính là hiện tượng reflow layout. Với trình duyệt, đó là một tác vụ khá nặng.
Pretext giải quyết vấn đề này theo cách khác. Nó dùng measureText() của Canvas để lấy trực tiếp độ rộng ký tự từ font engine, sau đó việc tính dòng chỉ còn là các phép toán số học thuần túy dựa trên các giá trị độ rộng đã được cache. Hoàn toàn không truy cập DOM.

const prepared = prepare('AGI 春天到了. بدأت الرحلة 🚀', '16px Inter')
const { height, lineCount } = layout(prepared, textWidth, 20)

Hiệu năng cũng rất ấn tượng. Với mốc 500 lần bố trí văn bản, prepare() mất khoảng 19ms, còn layout() sau đó ở mức 0.09ms.
Hai cách sử dụng
Nếu chỉ cần chiều cao, tổ hợp prepare() + layout() là đủ. Có thể dùng cho việc triển khai danh sách ảo hóa, giữ nguyên vị trí cuộn, hoặc kiểm tra xem văn bản do AI tạo ra có bị tràn ra ngoài nút hay không.
Nếu muốn tự điều khiển layout theo từng dòng, có thể tận dụng các API như layoutWithLines(), walkLineRanges(), layoutNextLine(). Có thể gắn vào Canvas, SVG, WebGL, render phía máy chủ, và cũng xử lý được các layout có độ rộng thay đổi theo từng dòng, chẳng hạn kiểu văn bản chảy quanh ảnh.
Nó còn hỗ trợ emoji, CJK và cả văn bản hai chiều như tiếng Ả Rập. Đây là dự án của chenglou, người tạo ra React và Relay. ⭐ 7.1k
https://github.com/chenglou/pretext​​​​​​​​​​​​​​​​

3 bình luận

 

Ngay sau liên kết github ở cuối cùng có rất nhiều %E2%80%8B (zero-width space) được gắn vào.
js .replace(/\u200b/g, '')

 

Có vẻ trang https://chenglou.me/pretext/editorial-engine/ trong phần demo là nơi thể hiện rõ nhất.

 

Không phải là mình đã hiểu rõ rồi mới dùng đâu, mong mọi người thông cảm trước.

Nghe nói nó tính toán lại dựa trên measureText của canvas...
Mình không tin lắm API đó.
Chính xác hơn thì không phải là mình không tin bản thân API,
mà là khi render cùng một DOM, chỉ khi các giá trị điều kiện khớp hoàn toàn thì
chiều cao hay hình dạng nhìn thấy trong trình duyệt mới giống hệt với khi lấy ra dưới dạng API,
và mình từng có một cơn ác mộng rợn người vì không nhận ra điều đó, cứ tự hỏi sao giá trị lại khác và phát sinh bug...