THREE.TextTexture
THREE.TextTexture copied to clipboard
Trying to use custom font on startup, often shows the browser's default font
I am loading the Roboto
font in index.html
:
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet" />
Then trying to use it in a TextSprite
:
const instance = new TextSprite({
alignment: "left",
color: "#24ff00",
fontFamily: "Roboto",
fontSize: 1,
text: text,
});
Sometimes, the TextSprite
renders the browser's default font instead of Roboto
. Any idea to safely wait for Roboto
?
document.fonts.load (used in THREE.TextTexture): https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/load https://stackoverflow.com/a/32292880
Libs to wait for font loading: https://github.com/bramstein/fontfaceobserver and https://fontfaceobserver.com/ (6 KB) https://github.com/typekit/webfontloader (old, 13 KB)
Libs to get font metrics: https://github.com/foliojs/fontkit https://github.com/opentypejs/opentype.js and https://opentype.js.org/ (170 KB) https://github.com/Pomax/lib-font (not so popular, 80 KB) https://github.com/rsms/fontkit (with WASM) https://github.com/soulwire/FontMetrics (old, 2 KB)
Metrics explanation: https://freetype.org/freetype2/docs/glyphs/glyphs-3.html https://soulwire.github.io/FontMetrics/
TextMetrics: https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics https://stackoverflow.com/a/67698040
Another way: https://threejs.org/docs/#examples/en/loaders/FontLoader https://github.com/gero3/facetype.js
Possible solution from https://stackoverflow.com/a/64192936:
export async function waitForFontLoad(
font: string,
timeout = 1000,
interval = 10
) {
return new Promise((resolve, reject) => {
// repeatedly poll check
const poller = setInterval(async () => {
try {
await document.fonts.load(font);
} catch (err) {
reject(err);
}
if (document.fonts.check(font)) {
clearInterval(poller);
resolve(true);
}
}, interval);
setTimeout(() => clearInterval(poller), timeout);
});
}
Recommendation to use document.fonts.onloadingdone instead.