Как узнать, когда применяется правило @ font-face
-
08-07-2019 - |
Вопрос
Есть ли способ узнать, когда применяется правило @ font-face? Я создаю правила @ font-face, которые используют data: URI из файла шрифта, запрошенного с синхронным запросом XMLHttpRequest в JavaScript, а затем сразу же пишем текст в элемент canvas, используя шрифт. Дело в том, что он фактически не использует шрифт при рисовании текста в течение первых нескольких миллисекунд. Мое текущее решение - заблокировать выполнение на несколько миллисекунд, отправив синхронный запрос XMLHttpRequest, что является ужасным решением.
Я не могу сделать это асинхронным, поскольку он предназначен для реализации обработки loadFont ()
Синхронная функция в Processing.js .
Я бы предпочел, чтобы решение не проверяло размеры символов, поскольку нет гарантии, что шрифт имеет определенный символ и что его размеры отличаются от того же символа текущего шрифта.
Решение
Краткий ответ: браузеры еще недостаточно хороши, чтобы позволить нам проверить наличие «загруженного и готового к использованию». без использования шрифта и его проверки.
Длинный ответ: Pjs поставляется со встроенным средством проверки шрифтов для предварительной загрузки шрифта (связано с https: // github .com / pomax / font.js ) но, как вы заметили, это не будет работать с правилами @ font-face, которые используют data-uri. Обходной путь, который я бы предложил (хотя я еще не пробовал это. Я просто предполагаю, что он будет работать, основываясь на моей работе над Processing.js и загрузкой шрифтов в браузерах), заключается в использовании двух буферов PGraphic вне экрана. Сделайте их обоими на белом фоне с черным текстом заливки, сделайте текст («X», 0,0) в первом буфере, а затем после загрузки шрифта используйте второй буфер для выполнения того же текста («X»); 0,0 & Quot;). Возьмите пиксель [] для каждого буфера и проведите параллельное сравнение:
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;
}
когда вы загружаете свой шрифт, где-то должно быть отслеживающее логическое значение, которое указывает состояние загрузки шрифта, вставляется в "false" и после загрузки вашего шрифта в начале вызова 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.
}
}
Теперь, по крайней мере, вы можете избежать первых нескольких кадров, когда браузер завершил распаковку шрифта data-uri и загрузил его как ресурс @ font-face, но у него не было времени передать его в систему рендеринга Canvas2D пока.
(стилизация элемента DOM на этом этапе с помощью шрифта на самом деле работает нормально, фактически его передача в Canvas2D приводит к тому, что он не может быть использован в одном или нескольких кадрах)
Другие советы
Даже если вы не предпочитаете проверку размера, именно так Modernizr @ font-face функция обнаружения работает и может быть лучшим способом:
Modernizr встраивает крошечный шрифт используя данные: URI. В этом единственном & Quot;. & Quot; персонаж создан; тогда применяется к временному элементу которого innerHTML имеет значение «........» и ширина которого измеряется, сначала с основной шрифт с засечками, а затем с пользовательский шрифт применяется. Если ширина разные, мы знаем браузер представили новые данные шрифта мы в комплект поставки. р>