Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> HTML

Vẽ text lên HTML5 Canvas với @font-face: Lỗi không hiển thị lần đầu và cách khắc phục

Khi vẽ text lên canvas sử dụng font tải qua CSS @font-face, văn bản thường không hiển thị đúng font ở lần đầu tiên. Nguyên nhân: Trình duyệt chưa kịp tải xong font từ mạng trước khi code vẽ canvas chạy, nên nó dùng font fallback (thường là sans-serif mặc định).

Giải pháp 1: Preload font bằng thẻ <div> ẩn (Đơn giản, cũ)

Thêm một thẻ div ẩn sử dụng font đó để buộc trình duyệt tải font sớm:

<div style="font-family: 'PressStart'; position: absolute; left: -9999px; visibility: hidden;">&nbsp;</div>

Đặt div này ở đầu <body>. Ký tự &nbsp; buộc trình duyệt render font.

Giải pháp 2: Font Loading API (Hiện đại, khuyên dùng)

Sử dụng FontFace và document.fonts để tải font và chờ sẵn sàng trước khi vẽ:

// Tạo FontFace object
var newFont = new FontFace('MyCustomFont', 'url(https://example.com/font.woff2)');

// Tải font
newFont.load().then(function(font) {
  // Thêm font vào document
  document.fonts.add(font);
  console.log('Font tải xong, có thể vẽ canvas!');
  
  // Bây giờ an toàn để vẽ text lên canvas
  drawCanvasText();
}).catch(function(err) {
  console.error('Lỗi tải font:', err);
});

// Hàm vẽ canvas
function drawCanvasText() {
  var ctx = canvas.getContext('2d');
  ctx.font = '24px MyCustomFont';
  ctx.fillText('Hello Canvas!', 50, 50);
}

Giải pháp 3: document.fonts.ready (Đơn giản cho nhiều font)

// Chờ TẤT CẢ font trong document sẵn sàng
document.fonts.ready.then(function() {
  console.log('Tất cả font đã sẵn sàng');
  drawCanvasText();
});

Best Practice

  1. Sử dụng định dạng WOFF2 (nén tốt nhất, hỗ trợ rộng rãi).
  2. Khai báo font-display: swap trong @font-face để hiển thị font fallback ngay, swap khi font chính tải xong.
  3. Preload font quan trọng trong <head>:
    <link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
  4. Luôn có font fallback trong CSS: font-family: 'MyFont', Arial, sans-serif;