Отображение шрифтов Google на canvas

149
08 января 2022, 23:30

Имеется приложение, на главной странице канвас с текстом. В приложении есть функционал смены языка (русский, английский). На канвасе текст имеет шрифт Roboto Mono. У меня была проблема с тем, что шрифт Roboto Mono отображался на канвасе не сразу, а только после какого либо взаимодействия с канвасом. Эта проблема не проявляется, если добавить в html как либо фиктивный элемент со шрифтом Roboto Mono. То есть, как я понял, браузер начинает подгружать шрифты, только когда они появляются на странице. Если подгружать шрифт таким образом

  <link rel='prefetch' href="https://fonts.googleapis.com/css?family=Roboto+Mono:500" as="style"
onload="this.rel='stylesheet'">

Example jsFiddle То мы можем видеть, что шрифт не применился (он применится, при перерисовке канваса), но в консоле разработчика во вкладке network мы видим, что шрифты загрузились.

После этого я подумал, что было бы логично подгружать шрифты заранее, перед отрисовкой текста на канвасе. С помощью этого вопроса я реализовал нечто подобное Example jsFiddle

Теперь мы видим, что шрифт подгрузился и отобразился корректно. Так же теперь в network мы видим, что появился запрос непосредственно к файлу шрифта

Но обратите внимание на пример, мы начинаем загружать шрифты в методе onload объекта window, то есть, когда загрузилась вся страница, включая стили, картинки и другие ресурсы и только после этого мы начали рисовать на канвасе текст. Если мы вынесем загрузку шрифтов из onload, а отрисовку текста оставим там, то шрифт загрузится, но не отобразится на канвасе. Example jsFiddle К сожалению это почему то не воспроизводится в jsFiddle, даже если очистить кэш. Но можете создать html файл и проверить на нем, проблема воспроизведется. В network мы увидим, что шрифт загрузился! Но опять же, отобразится он только при переотрисовке канваса То есть все корректно работает, если начать загрузку шрифтов в onload, а потом, после того, как все шрифты загружены начинать отрисовку на канвасе. Может кто нибудь объяснить, почему так происходит? Почему если начать предварительно грузить шрифты, не в onload, то они на канвасе не отображаются.

Напомню, что в приложении имеется два языка, русский и английский. Вернемся к рабочему примеру с загрузкой шрифта в onload. Загрузим два шрифта на латинице и кириллице, напишем на канвасе текст на английском и на русском языке. ExampleJsFiddle Что мы видим? Что подрузился только английский шрифт! Обратите внимание на эту строчку, первым мы указали latin:

      google: { families: ['Roboto Mono:500:latin,cyrillic'] },

Если поставить на первое место cyrillic, то на успешно подгрузится только русский шрифт! В network мы видим, что загрузку одного шрифта начал объект webfont, а другого сам canvas!

Кто нибудь может объяснить как и почему это так работает? Как можно исправить этот баг?

Answer 1

Я вот так подгружал на canvas в своих проектах:

const font  = new FontFace('Alternity', 'url(Alternity.otf)');
font.load().then(function() {
  document.fonts.add(font);
  context.font = "48px Alternity";
  context.fillText("merrymaker14", width / 2 - 75, height - 25);
})```
READ ALSO
Spring. Rest API. Java

Spring. Rest API. Java

Работа с телефонной книгойПишу серверную часть, хочу созданного пользователя изменить его данные(имя и номер), добавить, удалить, редактировать...

128
как сопоставить атрибуты метода

как сопоставить атрибуты метода

Есть задача, я её приложил к вопросу, суть в том что есть заказы

184
Алгоритм набора слов на аналоговой клавиатуре телефона

Алгоритм набора слов на аналоговой клавиатуре телефона

На собеседовании задали задачу: имеется клавиатура аналогового телефона от 0 до 9, где каждой цифре соответствуют три буквы, 1 - абв, 2 - где и тд

289
hibernate + маппинг без сущностей?

hibernate + маппинг без сущностей?

Я разбираю старый проект и нашел интересную вещь, которую не понимаю

133