Comment savoir quand une règle @ font-face est appliquée
-
08-07-2019 - |
Question
Existe-t-il un moyen de savoir quand une règle @ font-face est appliquée? Je crée des règles @ font-face qui utilisent des données: les URI à partir d'un fichier de police demandé avec un XMLHttpRequest synchrone en JavaScript, puis j'écris du texte dans un élément de structure en utilisant immédiatement la police. Le fait est qu’elle n’utilise pas réellement la police pour dessiner le texte pendant les premières millisecondes. Ma solution actuelle consiste à bloquer l'exécution pendant quelques millisecondes en envoyant un XMLHttpRequest synchrone, ce qui est une solution terrible.
Je ne parviens pas à rendre cette opération asynchrone, car elle implémente le traitement du code <> loadFont () . > fonction synchrone dans Processing.js .
Je préférerais que la solution ne vérifie pas les dimensions du caractère, car rien ne garantit que la police a un certain caractère et que ses dimensions sont différentes du même caractère de la police actuelle.
La solution
Réponse courte: les navigateurs ne sont pas encore assez bons pour nous permettre de tester le mode "chargé et prêt à être utilisé". sans utiliser réellement la police et la vérifier.
Réponse longue: Pjs est livré avec un validateur de polices intégré pour les précharges de polices (lié à https: // github .com / pomax / font.js ), mais comme vous l’indiquez, cela ne fonctionnera pas avec les règles @ font-face qui utilisent un data-uri. Une solution de contournement que je suggérerais (même si je n’ai pas encore essayé cela. Je suppose que cela fonctionnera en fonction de mon travail sur Processing.js et du chargement de polices dans les navigateurs) consiste à utiliser deux tampons hors écran PGraphic. Faites-les deux fond blanc avec un texte de remplissage noir, faites un texte ("X", 0,0) sur le premier tampon, puis après le chargement de votre police, utilisez le deuxième tampon pour exécuter le même texte ("X", 0,0 "). Saisissez le pixel [] pour chaque tampon et effectuez une comparaison côte à côte:
boolean verifyFontLoad() {
buffer1.loadPixels();
buffer2.loadPixels();
for (int i=0; i<buffer1.pixels.length; i++) {
if (buffer1.pixels[i] != buffer2.pixels[i]) {
return false; }}
return true;
}
lorsque vous chargez votre police, placez un booléen de suivi indiquant l'état de chargement de la police, dénommé "faux", et après le chargement de la police, au début de l'appel de draw ()
.void draw() {
// code that does not rely on your font
[...]
// check state
if(!fontLoaded) { fontLoaded = verifyFontLoaded(); }
// not ready? "stop" drawing.
if(!fontLoaded) { return; }
// font ready. run code that relies on the font being ready
else {
// code that depends on your font being available goes here.
}
}
Maintenant, vous pouvez au moins éviter les premières images pour lesquelles le navigateur a fini de décompresser votre police data-uri et de la charger en tant que ressource @ font-face, sans avoir eu le temps de la transférer au système de rendu Canvas2D. encore.
(le fait de styler un élément DOM à ce stade avec la police fonctionnerait bien, mais en fait le transférer à Canvas2D, ce qui l'empêche d'utiliser un ou plusieurs cadres)
Autres conseils
Bien que vous ne préfériez pas une vérification de dimension, voici comment Modernizr @ font-face < La détection de fonctionnalité fonctionne et peut être le meilleur moyen:
Modernizr incorpore un glyphe de police minuscule en utilisant une donnée: URI. En cela, le single ". " le personnage est créé; c'est alors appliqué à un élément temporaire dont innerHTML est défini sur '........' et dont la largeur est mesurée, d'abord avec un empattement de base, puis avec le police personnalisée appliquée. Si la largeur est différent, nous connaissons le navigateur rendu les nouvelles données de police nous fourni.