Подключение внешних шрифтов

Анимации Lottie, экспортируемые через Bodymovin из After Effects, часто содержат текстовые слои. При рендеринге в браузере библиотекой Lottie Web текст не является «векторной формой», а зависит от доступности шрифтов в среде выполнения. Если нужный шрифт отсутствует, происходит подмена, которая может полностью изменить композицию: ломается выравнивание, переносы строк, размеры блоков и визуальная иерархия.

В отличие от статических SVG-экспортов, Lottie хранит метаданные о шрифтах и пытается восстановить текстовую структуру на стороне клиента. Это делает подключение внешних шрифтов критически важным этапом интеграции.


Как Lottie Web работает с текстовыми слоями

При экспорте через Bodymovin в JSON-файл попадает описание текстовых элементов:

  • имя шрифта
  • начертание (Regular, Bold, Light и т.д.)
  • размер
  • трекинг и кернинг
  • базовые метрики
  • иногда — ссылка на встроенный шрифт (если он был включён в экспорт)

В браузере Lottie Web пытается сопоставить эти данные с реальными шрифтами, доступными через:

  • системные шрифты
  • CSS @font-face
  • загруженные через WebFont Loader или аналогичные механизмы

Если совпадение не найдено, используется fallback, что почти всегда приводит к визуальным искажениям.


Структура описания шрифтов в JSON Lottie

Внутри файла анимации присутствует секция fonts:

"fonts": {
  "list": [
    {
      "fName": "Roboto-Bold",
      "fFamily": "Roboto",
      "fStyle": "Bold",
      "ascent": 75,
      "fPath": "",
      "fWeight": "700"
    }
  ]
}

Ключевые поля:

  • fName — внутреннее имя, используемое в текстовых слоях
  • fFamily — семейство шрифта
  • fStyle — начертание
  • fWeight — вес
  • fPath — путь к файлу шрифта (используется редко и зависит от экспорта)

Текстовые слои ссылаются именно на fName, а не на CSS-семейство, что создаёт необходимость явного маппинга.


Подключение шрифтов через CSS @font-face

Базовый способ подключения внешних шрифтов — использование стандартного CSS:

@font-face {
  font-family: "Roboto";
  src: url("/fonts/Roboto-Bold.woff2") format("woff2"),
       url("/fonts/Roboto-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
}

После этого браузер начинает загружать шрифт, и Lottie Web может использовать его при рендеринге текста.

Критически важно:

  • font-family должен совпадать с fFamily из JSON
  • font-weight и font-style должны соответствовать метаданным Lottie
  • шрифт должен быть загружен до старта анимации

Проблема тайминга загрузки шрифтов

Lottie Web не блокирует рендеринг до загрузки шрифтов. Это означает, что при запуске анимации до завершения загрузки:

  • текст сначала рендерится fallback-шрифтом
  • затем пересчитывается
  • возможны «прыжки» layout-а

Для предотвращения этого используются стратегии предварительной загрузки:

preload через HTML

<link
  rel="preload"
  href="/fonts/Roboto-Bold.woff2"
  as="font"
  type="font/woff2"
  crossorigin="anonymous"
/>

ожидание загрузки через Font Loading API

await document.fonts.load('700 16px Roboto');

Только после этого запускается Lottie-анимация:

lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: '/animation.json'
});

Маппинг шрифтов в Lottie Web

В реальных проектах имена шрифтов в JSON часто не совпадают с CSS-именами. Для этого используется ручное сопоставление.

Пример структуры маппинга

const fontMap = {
  "Roboto-Bold": "Roboto",
  "Roboto-Regular": "Roboto",
  "Inter-SemiBold": "Inter"
};

Далее подключается обработчик через document.fonts или глобальную замену:

Object.keys(fontMap).forEach((key) => {
  document.fonts.load(`16px ${fontMap[key]}`);
});

Использование fontManager в Lottie

Lottie Web предоставляет доступ к внутреннему менеджеру шрифтов:

lottie.setFonts({
  addFont: (font) => {
    console.log(font);
  }
});

Однако в стандартной практике чаще используется подход с предварительной загрузкой и CSS, так как внутренний API ограничен и зависит от версии библиотеки.


Google Fonts и динамическая загрузка

При использовании внешних сервисов шрифтов, например Google Fonts, важно учитывать задержку загрузки и CORS.

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap">

Проблема в том, что CSS может примениться быстрее, чем загрузятся реальные файлы шрифтов, поэтому визуально возможен FOUT (Flash of Unstyled Text).

Для снижения эффекта применяются:

  • font-display: swap
  • preload конкретных .woff2 файлов
  • блокировка старта анимации до загрузки document.fonts.ready

CORS и загрузка шрифтов

Если шрифты загружаются с CDN, обязательно корректно настроенный CORS:

Access-Control-Allow-Origin: *

Без этого браузер может загрузить файл, но не применить его к тексту Lottie, что приведёт к тихой подмене шрифта.


Частые проблемы несовпадения шрифтов

1. Разные названия семейства

After Effects:

Roboto-Bold

CSS:

Roboto

Результат — отсутствие точного совпадения и fallback.


2. Разные веса

Даже при совпадении family:

  • Lottie ожидает 700
  • подключён только 400

Итог — замена начертания.


3. Отсутствие кириллицы

Шрифт может поддерживать латиницу, но не содержать кириллицу. В Lottie это проявляется как:

  • пустые символы
  • квадраты (tofu)

4. Несинхронная загрузка

Анимация стартует до загрузки шрифтов, текст пересчитывается позже, что ломает композицию.


Практика стабильного подключения шрифтов

Стабильная схема обычно строится вокруг трёх этапов:

1. Предзагрузка

  • preload в HTML
  • document.fonts.load

2. Синхронизация с Lottie

await document.fonts.ready;

3. Инициализация анимации

lottie.loadAnimation({
  container: el,
  renderer: 'svg',
  path: '/anim.json'
});

Особенности SVG-рендерера Lottie

При использовании renderer: 'svg' текст остаётся текстом DOM:

  • можно инспектировать в DevTools
  • применяется CSS
  • шрифты влияют напрямую на layout

При canvas рендере текст растеризуется, и контроль над шрифтами становится ещё более критичным на этапе инициализации.


Встраивание шрифтов в сам JSON

Bodymovin позволяет включать шрифты в экспорт, но это редко используется из-за:

  • увеличения размера JSON
  • лицензионных ограничений
  • сложности управления обновлениями

Даже при наличии встроенных шрифтов браузер всё равно может требовать локальное соответствие для корректного рендеринга текста.


Контроль согласованности дизайна

Стабильность Lottie-анимаций с текстом зависит от строгого соответствия трёх уровней:

  • данные из After Effects
  • JSON описание шрифтов
  • реальные web-шрифты

Любое расхождение приводит к визуальному дрейфу композиции, особенно в интерфейсных анимациях, где текст участвует в сетке и выравнивании элементов.