Quando desenho um texto em uma tela com uma fonte carregada por meio de @ font-face, o texto não é exibido corretamente. Ele não é mostrado (no Chrome 13 e Firefox 5) ou a fonte está errada (Opera 11). Esse tipo de comportamento inesperado ocorre apenas no primeiro desenho com a fonte. Depois disso, tudo funciona bem.
É o comportamento padrão ou algo assim?
Obrigado.
PS: A seguir está o código-fonte do caso de teste
<!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>
Respostas:
O desenho na tela deve acontecer e retornar imediatamente quando você chamar o
fillText
método. No entanto, o navegador ainda não carregou a fonte da rede, o que é uma tarefa em segundo plano. Portanto, ele precisa voltar à fonte que está disponível.Se você quiser ter certeza de que a fonte está disponível, faça com que algum outro elemento na página pré-carregue-a, por exemplo:
fonte
display: none
, mas isso pode fazer com que os navegadores ignorem o carregamento da fonte. É melhor usar um espaço em vez de um.
.Use este truque e vincule um
onerror
evento a umImage
elemento.Demonstração aqui : funciona no Chrome mais recente.
fonte
src
atributo seja definido, o carregamento começará no próximo bloco de execução.O cerne do problema é que você está tentando usar a fonte, mas o navegador ainda não a carregou e possivelmente nem a solicitou. O que você precisa é de algo que carregue a fonte e forneça um retorno de chamada quando ela for carregada; depois de obter o retorno de chamada, você sabe que pode usar a fonte.
Veja o WebFont Loader do Google ; parece um provedor "personalizado" e um
active
retorno de chamada após o carregamento faria com que funcionasse.Eu nunca usei antes, mas a partir de uma rápida verificação dos documentos você precisa fazer um arquivo css
fonts/pressstart2p.css
, assim:Em seguida, adicione o seguinte JS:
fonte
Você pode carregar fontes com a API FontFace antes de usá-la na tela:
O recurso de fonte
myfont.woff2
é baixado primeiro. Após a conclusão do download, a fonte é adicionada ao FontFaceSet do documento .A especificação da API FontFace é um rascunho de trabalho no momento da redação deste artigo. Veja a tabela de compatibilidade do navegador aqui.
fonte
document.fonts.add
. Veja a resposta de bruno.Que tal usar CSS simples para ocultar um div usando a fonte como esta:
CSS:
HTML:
fonte
https://drafts.csswg.org/css-font-loading/
fonte
Encontrei o problema ao brincar com ele recentemente http://people.opera.com/patrickl/experiments/canvas/scroller/
contornamos isso adicionando a família de fontes ao canvas diretamente no CSS, para que você possa apenas adicionar
canvas {font-family: PressStart; }
fonte
Não tenho certeza se isso vai te ajudar, mas para resolver o problema com meu código, simplesmente criei um loop for no topo do meu Javascript que percorreu todas as fontes que eu queria carregar. Em seguida, executei uma função para limpar a tela e pré-carregar os itens que queria na tela. Até agora, funcionou perfeitamente. Essa foi a minha lógica. Postei meu código abaixo:
fonte
Escrevi um jsfiddle incorporando a maioria das correções sugeridas aqui, mas nenhuma resolveu o problema. No entanto, sou um programador novato, então talvez não tenha codificado as correções sugeridas corretamente:
http://jsfiddle.net/HatHead/GcxQ9/23/
HTML:
CSS:
JS:
Gambiarra Acabei cedendo e, no primeiro carregamento, usei uma imagem do texto enquanto também posicionava o texto com as fontes fora da área de exibição da tela. Todas as exibições subsequentes das faces da fonte na área de exibição da tela funcionaram sem problemas. Esta não é uma solução alternativa elegante de forma alguma.
A solução está embutida no meu site, mas se alguém precisar, tentarei criar um jsfiddle para demonstrar.
fonte
Alguns navegadores suportam a especificação CSS Font Loading . Ele permite que você registre um retorno de chamada para quando todas as fontes forem carregadas. Você pode atrasar o desenho da sua tela (ou pelo menos desenhar o texto na sua tela) até então e acionar um redesenho assim que a fonte estiver disponível.
fonte
Em primeiro lugar, use o carregador de fontes da Web do Google, conforme aconselhado na outra resposta, e adicione seu código de desenho ao retorno de chamada fornecido para indicar que as fontes foram carregadas. No entanto, este não é o fim da história. A partir deste ponto, é muito dependente do navegador. Na maioria das vezes funcionará bem, mas às vezes pode ser necessário esperar algumas centenas de milissegundos ou usar as fontes em outro lugar da página. Tentei várias opções e o método que o afaik sempre funciona é desenhar rapidamente algumas mensagens de teste na tela com a família de fontes e as combinações de tamanho de fonte que você vai usar. Você pode fazer isso com a mesma cor do fundo, então eles nem ficarão visíveis e vai acontecer muito rápido. Depois disso, as fontes sempre funcionaram para mim e em todos os navegadores.
fonte
Minha resposta aborda fontes do Google Web em vez de @ font-face. Procurei em todos os lugares por uma solução para o problema da fonte não aparecer na tela. Tentei timers, setInterval, bibliotecas de atraso de fonte e todos os tipos de truques. Nada funcionou. (Incluindo colocar a família da fonte no CSS para canvas ou o ID do elemento canvas.)
No entanto, descobri que a animação de texto renderizado em uma fonte do Google funcionou facilmente. Qual é a diferença? Na animação da tela, nós redesenhamos os itens animados novamente e novamente. Então, tive a ideia de renderizar o texto duas vezes.
Isso também não funcionou - até que eu também adicionei um pequeno atraso de temporizador (100 ms). Eu só testei em um Mac até agora. O Chrome funcionou bem a 100 ms. O Safari exigiu um recarregamento da página, então aumentei o cronômetro para 1000 e ficou bom. O Firefox 18.0.2 e 20.0 não carregaria nada na tela se eu estivesse usando fontes do Google (incluindo a versão de animação).
Código completo: http://www.macloo.com/examples/canvas/canvas10.html
http://www.macloo.com/examples/canvas/scripts/canvas10.js
fonte
Enfrenta o mesmo problema. Depois de ler "bobince" e outros comentários, uso o seguinte javascript para contornar isso:
fonte
Se você quiser redesenhar toda vez que uma nova fonte for carregada (e provavelmente alterar a renderização), a API de carregamento de fontes também tem um bom evento para isso. Tive problemas com o Promise em um ambiente totalmente dinâmico.
fonte
A tela é desenhada independentemente do carregamento do DOM. A técnica de pré-carregamento só funcionará se a tela for desenhada após o pré-carregamento.
Minha solução, mesmo que não seja a melhor:
CSS:
HTML:
JavaScript:
fonte
Tento usar FontFaceSet.load para corrigir o problema: https://jsfiddle.net/wengshenshun/gr1zkvtq/30
Você pode encontrar a compatibilidade do navegador em https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet/load
fonte
Este artigo resolveu meus problemas com fontes carregadas lentamente não sendo exibidas.
Como carregar fontes da web para evitar problemas de desempenho e acelerar o carregamento da página
Isso me ajudou ...
fonte
Adicione um atraso conforme abaixo
fonte