Когда вы делаете что-то 3D в Интернете, первая библиотека, которая приходит на ум разработчику, это Three.js. Three.js предоставляет абстракции высокого уровня для рисования 3D-графики с использованием WebGL в браузере. Недавно я немного поиграл с ним для рендеринга 3D-текста и понял, что использование пользовательских шрифтов — это боль, особенно когда вам нужен простой способ рендеринга пользовательских шрифтов из CDN, таких как Google Fonts, Fontsource. В Интернете очень мало документации по этой теме, и я надеюсь, что эта статья поможет заполнить этот пробел.

Элементы рендеринга 3D текста

Давайте взглянем на различные части, задействованные на высоком уровне для рендеринга текста в Three.js.

TextGeometry

Three.js предоставляет класс TextGeometry, который специализируется на создании базовой геометрии для текста. Думайте о геометрии как о наборе вершин, ребер, граней — в основном о структуре объекта. TextGeometry имеет различные параметры для настройки шрифта, размера, толщины, скоса и т. д. Пример использования этого класса в документации показывает следующий фрагмент кода.

const loader = new FontLoader();

loader.load('fonts/helvetiker_regular.typeface.json', function (font) {
  const geometry = new TextGeometry('Hello three.js!', {
    font: font,
    size: 80,
    height: 5,
    // other options...
  });
});

FontLoader

Обратите внимание на класс FontLoader в приведенном выше фрагменте? Он отвечает за создание экземпляра FontLoader, который отвечает за загрузку пользовательских шрифтов, которые TextGeometry может использовать для создания текста в этом шрифте.

Метод load() экземпляра FontLoader принимает путь к файлу/URL-адрес файла шрифта и функцию обратного вызова, которая вызывается с загруженными данными шрифта. Затем эти данные шрифта можно передать конструктору TextGeometry для создания геометрии текста в этом шрифте.

Mesh и Material

Текстовая геометрия не может быть визуализирована как есть, ее необходимо сначала преобразовать в объект Mesh. Mesh содержит определение геометрии и примененные к ней материалы, которые используются модулем визуализации для визуализации этого объекта. В примере здесь я назначаю MeshStandardMaterial объекту Text. Подробнее об опциях, которые можно установить в материале, вы можете прочитать в документации, связанной с ним.

Кажется простым, пока вы не заметите что-то странное в этом пути к файлу шрифта — 'fonts/helvetiker_regular.typeface.json'. Видите это расширение .json? Кажется странным, верно? Большинство из нас знакомы со стандартными форматами файлов шрифтов, такими как TTF, WOFF, WOFF2 и т. д., но FontLoader понимает только файлы шрифтов в >.json формат! Мой следующий вопрос: как преобразовать мои существующие файлы шрифтов в один из стандартных форматов файлов шрифтов, упомянутых выше, в формат JSON, поддерживаемый FontLoader?

Facetype.js

В документации класса FontLoader говорится об инструменте под названием facetype.js, который можно использовать для преобразования файлов шрифтов в формат JSON. Инструмент попросит вас выбрать файл шрифта и преобразует его в файл JSON или JS. Затем файл JSON можно включить в исходный код и загрузить в Three.js.

В репозитории GitHub проекта указано, что он не опубликован как библиотека, которую можно использовать в других проектах. Это оставляет нам два варианта, если мы хотим динамически загружать шрифты из чего-то вроде Google Fonts:

  1. Загрузите все исходные файлы шрифтов (в формате TTF) из Google Fonts, преобразуйте их в статический формат JSON с помощью инструмента facetype.js, затем включите их в исходный код проекта и загрузите в Three .js. Это не масштабируется, так как библиотека Google Fonts постоянно расширяется, и каждый шрифт имеет различную толщину шрифта (обычный, полужирный, полужирный и т. д.) и стили шрифта (обычный, курсив). Конвертировать каждый из них в формат JSON и обслуживать их с наших серверов — пустая трата ресурсов — времени, полосы пропускания и даже денег 💸!
  2. Используйте файлы JavaScript из исходного кода facetype.js. Файлы JS можно включить в исходный код проекта, а CDN и API Google Fonts можно использовать для получения необходимых файлов шрифтов TTF. После извлечения файла можно вызвать соответствующие функции (из JS-файлов, которые были включены из facetype.js) для преобразования данных TTF в формат JSON на лету. Наконец, эти данные JSON можно загрузить в Three.js. Этот подход намного лучше предыдущего, но его недостатком является то, что он включает внешние сценарии JS без менеджера пакетов. Мы не получим никаких будущих обновлений, если скрипты изменятся (если только изменения не будут вручную включены в наш проект), и может быть сложно использовать его с импортом ES6 и TypeScript.