Lorsque je dessine un texte dans un canevas avec une police qui est chargée via @ font-face, le texte ne s'affiche pas correctement. Il ne s'affiche pas du tout (dans Chrome 13 et Firefox 5), ou la police est incorrecte (Opera 11). Ce type de comportement inattendu se produit uniquement lors du premier dessin avec la police. Ensuite, tout fonctionne bien.
Est-ce le comportement standard ou quelque chose?
Je vous remercie.
PS: voici le code source du cas de test
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>@font-face and <canvas></title>
<style id="css">
@font-face {
font-family: 'Press Start 2P';
src: url('fonts/PressStart2P.ttf');
}
</style>
<style>
canvas, pre {
border: 1px solid black;
padding: 0 1em;
}
</style>
</head>
<body>
<h1>@font-face and <canvas></h1>
<p>
Description: click the button several times, and you will see the problem.
The first line won't show at all, or with a wrong typeface even if it does.
<strong>If you have visited this page before, you may have to refresh (or reload) it.</strong>
</p>
<p>
<button id="draw">#draw</button>
</p>
<p>
<canvas width="250" height="250">
Your browser does not support the CANVAS element.
Try the latest Firefox, Google Chrome, Safari or Opera.
</canvas>
</p>
<h2>@font-face</h2>
<pre id="view-css"></pre>
<h2>Script</h2>
<pre id="view-script"></pre>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script id="script">
var x = 30,
y = 10;
$('#draw').click(function () {
var canvas = $('canvas')[0],
ctx = canvas.getContext('2d');
ctx.font = '12px "Press Start 2P"';
ctx.fillStyle = '#000';
ctx.fillText('Hello, world!', x, y += 20);
ctx.fillRect(x - 20, y - 10, 10, 10);
});
</script>
<script>
$('#view-css').text($('#css').text());
$('#view-script').text($('#script').text());
</script>
</body>
</html>
Réponses:
Le dessin sur toile doit se produire et revenir immédiatement lorsque vous appelez la
fillText
méthode. Cependant, le navigateur n'a pas encore chargé la police depuis le réseau, ce qui est une tâche d'arrière-plan. Il doit donc revenir à la police dont il dispose .Si vous voulez vous assurer que la police est disponible, faites précharger un autre élément sur la page, par exemple:
la source
display: none
, mais cela pourrait empêcher les navigateurs de charger la police. Il vaut mieux utiliser un espace au lieu d'un.
.Utilisez cette astuce et liez un
onerror
événement à unImage
élément.Démo ici : fonctionne sur la dernière version de Chrome.
la source
src
attribut est défini, le chargement commencera dans le bloc d'exécution suivant.Le nœud du problème est que vous essayez d'utiliser la police mais que le navigateur ne l'a pas encore chargée et ne l'a peut-être même pas demandée. Ce dont vous avez besoin, c'est de quelque chose qui chargera la police et vous rappellera une fois qu'elle sera chargée; une fois que vous obtenez le rappel, vous savez que vous pouvez utiliser la police.
Regardez le WebFont Loader de Google ; il semble qu'un fournisseur "personnalisé" et un
active
rappel après le chargement le feraient fonctionner.Je ne l'ai jamais utilisé auparavant, mais à partir d'une analyse rapide de la documentation, vous devez créer un fichier css
fonts/pressstart2p.css
, comme celui-ci:Ajoutez ensuite le JS suivant:
la source
Vous pouvez charger des polices avec l' API FontFace avant de l'utiliser dans le canevas:
La ressource de police
myfont.woff2
est d'abord téléchargée. Une fois le téléchargement terminé, la police est ajoutée au FontFaceSet du document .La spécification de l'API FontFace est un projet de travail au moment de la rédaction de cet article. Voir le tableau de compatibilité du navigateur ici.
la source
document.fonts.add
. Voir la réponse de Bruno.Qu'en est-il d'utiliser un CSS simple pour masquer un div en utilisant la police comme celle-ci:
CSS:
HTML:
la source
https://drafts.csswg.org/css-font-loading/
la source
J'ai récemment rencontré le problème en jouant avec http://people.opera.com/patrickl/experiments/canvas/scroller/
contourné en ajoutant la famille de polices au canevas directement dans le CSS, vous pouvez donc simplement ajouter
canvas {font-family: PressStart; }
la source
Je ne sais pas si cela vous aidera, mais pour résoudre le problème avec mon code, j'ai simplement créé une boucle for en haut de mon Javascript qui parcourait toutes les polices que je voulais charger. J'ai ensuite exécuté une fonction pour effacer la toile et précharger les éléments que je voulais sur la toile. Jusqu'à présent, cela a parfaitement fonctionné. C'était ma logique, j'ai posté mon code ci-dessous:
la source
J'ai écrit un jsfiddle incorporant la plupart des correctifs suggérés ici, mais aucun n'a résolu le problème. Cependant, je suis un programmeur novice, donc je n'ai peut-être pas codé correctement les correctifs suggérés:
http://jsfiddle.net/HatHead/GcxQ9/23/
HTML:
CSS:
JS:
Solution de contournement J'ai finalement cédé et, lors du premier chargement, j'ai utilisé une image du texte tout en positionnant le texte avec les polices de caractères en dehors de la zone d'affichage du canevas. Tous les affichages suivants des polices de caractères dans la zone d'affichage du canevas ont fonctionné sans problème. Ce n'est en aucun cas une solution de contournement élégante.
La solution est intégrée à mon site Web, mais si quelqu'un en a besoin, j'essaierai de créer un jsfiddle pour le démontrer.
la source
Certains navigateurs prennent en charge la spécification CSS Font Loading . Il vous permet d'enregistrer un rappel lorsque toutes les polices ont été chargées. Vous pouvez retarder le dessin de votre canevas (ou au moins dessiner du texte dans votre canevas) jusque-là, et déclencher un redessiner une fois que la police est disponible.
la source
Tout d'abord, utilisez le chargeur de polices Web de Google comme indiqué dans l'autre réponse et ajoutez votre code de dessin au rappel qu'il fournit pour indiquer que les polices ont été chargées. Cependant, ce n'est pas la fin de l'histoire. À partir de là, il dépend beaucoup du navigateur. La plupart du temps, cela fonctionnera bien, mais il peut parfois être nécessaire d'attendre quelques centaines de millisecondes ou d'utiliser les polices ailleurs sur la page. J'ai essayé différentes options et la seule méthode qu'afaik fonctionne toujours est de dessiner rapidement des messages de test dans le canevas avec la famille de polices et les combinaisons de taille de police que vous allez utiliser. Vous pouvez le faire avec la même couleur que l'arrière-plan, de sorte qu'ils ne seront même pas visibles et cela se produira très rapidement. Après cela, les polices ont toujours fonctionné pour moi et dans tous les navigateurs.
la source
Ma réponse concerne les polices Google Web plutôt que @ font-face. J'ai cherché partout une solution au problème de la police n'apparaissant pas dans la toile. J'ai essayé des minuteries, setInterval, des bibliothèques de délai de police et toutes sortes d'astuces. Rien n'a fonctionné. (Y compris mettre la famille de polices dans le CSS pour le canevas ou l'ID de l'élément canevas.)
Cependant, j'ai trouvé que le texte d' animation rendu dans une police Google fonctionnait facilement. Quelle est la différence? Dans l'animation de canevas, nous redessinons les éléments animés encore et encore. J'ai donc eu l'idée de rendre le texte deux fois.
Cela n'a pas fonctionné non plus - jusqu'à ce que j'aie également ajouté un court délai (100 ms). Je n'ai testé que sur un Mac jusqu'à présent. Chrome a bien fonctionné à 100 ms. Safari nécessitait un rechargement de page, j'ai donc augmenté la minuterie à 1000, puis tout allait bien. Firefox 18.0.2 et 20.0 ne chargeraient rien sur le canevas si j'utilisais des polices Google (y compris la version d'animation).
Code complet: http://www.macloo.com/examples/canvas/canvas10.html
http://www.macloo.com/examples/canvas/scripts/canvas10.js
la source
Fait face au même problème. Après avoir lu "bobince" et d'autres commentaires, j'utilise le javascript suivant pour contourner le problème:
la source
Si vous souhaitez redessiner à chaque fois qu'une nouvelle police est chargée (et probablement modifier le rendu), l'API de chargement de la police a également un événement intéressant pour cela. J'ai eu des problèmes avec le Promise dans un environnement dynamique complet.
la source
Le canevas est dessiné indépendamment du chargement du DOM. La technique de précharge ne fonctionnera que si le canevas est dessiné après le préchargement.
Ma solution, même si ce n'est pas la meilleure:
CSS:
HTML:
JavaScript:
la source
J'essaye d'utiliser FontFaceSet.load pour résoudre le problème: https://jsfiddle.net/wengshenshun/gr1zkvtq/30
Vous pouvez trouver la compatibilité du navigateur sur https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/load
la source
Cet article a réglé mes problèmes avec les polices chargées paresseusement qui ne sont pas affichées.
Comment charger des polices Web pour éviter les problèmes de performances et accélérer le chargement des pages
Cela m'a aidé ...
la source
Ajoutez un délai comme ci-dessous
la source