Come sapere quando viene applicata una regola @ font-face
-
08-07-2019 - |
Domanda
Esiste un modo per sapere quando viene applicata una regola @ font-face? Sto creando le regole @ font-face che utilizzano i dati: URI da un file di font richiesto con un XMLHttpRequest sincrono in JavaScript e quindi scrivere testo su un elemento canvas usando subito il font. Il fatto è che in realtà non utilizza il carattere quando si disegna il testo per i primi millisecondi. La mia attuale soluzione è bloccare l'esecuzione per alcuni millisecondi inviando un XMLHttpRequest sincrono, che è una soluzione terribile.
Non posso renderlo asincrono come per l'implementazione di Processing loadFont ()
funzione, che è sincrona, in Processing.js .
Preferirei che la soluzione non controllasse le dimensioni del carattere poiché non esiste alcuna garanzia che il carattere abbia un certo carattere e che le sue dimensioni siano diverse dallo stesso carattere del carattere corrente.
Soluzione
Risposta breve: i browser non sono ancora abbastanza buoni per permetterci di testare " caricati e pronti per l'uso " senza effettivamente utilizzare il carattere e verificarlo.
Risposta lunga: Pjs viene fornito con un validatore di caratteri integrato per i precarichi dei caratteri (relativo a https: // github .com / pomax / font.js ) ma come fai notare, questo non funzionerà con le regole di @ font-face che usano un data-uri. Una soluzione alternativa che suggerirei (anche se non l'ho ancora provato. Sto solo immaginando che funzionerà in base al mio lavoro su Processing.js e al caricamento dei font nei browser) è di utilizzare due buffer PGraphic offscreen. Rendi entrambi uno sfondo bianco con testo di riempimento nero, esegui un testo (" X ", 0,0) sul primo buffer, quindi dopo il caricamento del font, usa il secondo buffer per eseguire lo stesso testo (" X " ;, 0,0 "). Prendi il pixel [] per ogni buffer e fai un confronto fianco a fianco:
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;
}
quando carichi il tuo font, hai un tracciamento booleano da qualche parte che indica lo stato di caricamento del font, intagliato su " false " ;, e dopo aver caricato il font, all'inizio della chiamata 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.
}
}
Ora almeno puoi evitare i primi pochi frame in cui il browser ha finito di decomprimere il tuo font data-uri e caricarlo come risorsa @ font-face, ma non ha avuto il tempo di passarlo al sistema di rendering Canvas2D ancora.
(lo stile di un elemento DOM a questo punto con il carattere funzionerebbe davvero bene, in realtà lo sta consegnando a Canvas2D che lo rende non utilizzabile uno o più frame)
Altri suggerimenti
Anche se non preferisci un controllo dimensionale, è così che Modernizr @ font-face il rilevamento delle funzionalità funziona e potrebbe essere il modo migliore:
Modernizr incorpora un piccolo glifo di carattere utilizzando un dato: URI. In questo, il singolo & Quot;. & Quot; il personaggio è stato creato; lo è allora applicato a un elemento temporaneo di cui innerHTML è impostato su '........' e la cui larghezza è misurata, prima con a font serif di base e poi con il carattere personalizzato applicato. Se la larghezza è diverso, conosciamo il browser abbiamo reso i nuovi dati dei font noi in dotazione.