Прежде чем вы начнете читать эту статью, пожалуйста, уделите 15 секунд и посетите раздел Что такое Лотти? страница. Это отличная отправная точка для знакомства с Лотти.

Почему нам нужно понимать, что скрывается под капотом?

Лотти повсюду.

В настоящее время доступно множество статей на тему «Лотти». Вы можете изучить их на различных платформах:

* статьи на dev.to
* статьи на Medium
* темы на Reddit
* статьи на hackernoon

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

Многие высоко ценят Лотти по следующим причинам:

* Он имеет небольшой размер файла.
* Он предлагает бесконечную масштабируемость.
* Он поддерживается на различных платформах.
* Анимации, созданные с помощью Lottie, могут быть интерактивными.

Первоначально Lottie был разработан как инструмент для преобразования анимации Adobe After Effects в формат, совместимый с конкретными платформами. Однако он превратился в независимую спецификацию и больше не связан терминологией Adobe After Effects. Вы можете найти спецификацию Лотти.

Недавно LottieFiles представила плагин для Figma, что еще больше расширило популярность и потенциальный рост Lottie. Такое развитие событий означает, что Лотти постепенно становится отраслевым стандартом, что является фантастической новостью для сообщества.

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

Мой личный опыт работы с «Лотти» относится конкретно к веб-разработке, поэтому эти наблюдения могут не иметь отношения к другим средам.

Если вы собираетесь включить анимацию Lottie в веб-проект, официальная документация направит вас на lottie-web.

Сообщество

Давайте посмотрим на список ведущих участников:

- На первом месте с 1602 публикациями находится bodymovin, создатель bodymovin/lottie. Неудивительно, что наибольший вклад внес создатель библиотеки.
- На втором месте с 250 вкладами находится Hernan-dev. Скорее всего, это один и тот же человек.
- На третьем месте с 15 вкладами knekne
который создал полезное вводное [видео об использовании лоттии в Интернете](https://www.youtube.com/watch?v=OSUH81OGuSg)

Из остальных участников было сделано только 80 коммитов, что составляет менее 5% от общего числа коммитов. Большинство этих коммитов могут не иметь прямого отношения к воспроизведению анимации, поиску, применению преобразований или оптимизации отрисовки. Хотя эти коммиты, несомненно, важны, похоже, что основная часть кода в основном поддерживается bodymovin.

Проблемы

С одной стороны, сопровождающие «Лотти» отлично справляются с решением многочисленных проблем. Однако стоит отметить, что наличие 600 открытых вопросов действительно указывает на наличие текущих проблем и областей, требующих внимания. Это говорит о том, что еще предстоит проделать работу для решения этих нерешенных проблем.

Тесты

На момент прекращения моих знаний в мае 2023 года в репозитории GitHub Lottie-web не было доступных тестов. Вполне возможно, что тесты были реализованы во внутренней кодовой базе Airbnb и не были общедоступными. Однако важно отметить, что с тех пор, как вы начали писать эту статью, разработчики добавили [некоторые тесты](https://github.com/airbnb/lottie-web/blob/master/test), что является удачей. совпадение. Это подчеркивает тот факт, что в прошлом участие во внутренних компонентах Лотти было затруднено из-за отсутствия механизмов проверки. Отрадно видеть, что были предприняты шаги для решения этой проблемы путем включения тестов.

Функции

Lottie-web не поддерживает все функции, описанные в формате lottie.

Разные рендереры с разными проблемами

Lottie-web предлагает поддержку рендеринга анимации в контексте холста 2D, SVG и HTML.

Каждый из этих рендереров представляет свой собственный набор проблем. Например, при использовании средства рендеринга холста можно оптимизировать воспроизведение анимации, переместив ее в веб-воркер с помощью [transferControlToOffscreen](https://developer.mozilla.org/en-US/docs/Web/ API/OffscreenCanvas). Это может значительно повысить производительность логики анимации. Однако средство рендеринга SVG не поддерживает эту возможность, поскольку невозможно получить доступ к DOM изнутри веб-работника.

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

Вы можете найти разные статьи об этом [например](https://jaredstanley.medium.com/improving-site- Performance-by-optimizing-lottie-animations-9f032972d338)

Или даже [сервис, который оптимизирует вашу лотерею](https://lottiefixer.com/),.
[и это](https://lottiefiles.com/features/optimize-lottie), лол

Действительно, заметно, что многие статьи посвящены оптимизации файлов «Lottie» и их структуры с использованием различных методов. В некоторых случаях такая оптимизация может потребовать внесения изменений в исходный файл After Effects.

Readme говорит

› В ближайшее время будут проводиться дополнительные оптимизации, но старайтесь не использовать огромные формы в `AE` только для того, чтобы замаскировать небольшую их часть.
› Слишком большое количество узлов также повлияет на производительность.

Но почему воспроизведение анимации в сети может стать проблемой?…

Для `webgl`, `webgpu` нет средств рендеринга.

Представьте, что вы создаете 2D-игру с использованием WebGL. Было бы здорово включить в вашу игру анимацию, созданную в After Effects. Хотя вы можете рисовать анимацию с помощью элемента холста, ему не хватает некоторых функций. Другой вариант — отображать анимацию в формате SVG, но для ее использования в контексте WebGL вам необходимо сериализовать SVG, преобразовать его в изображение, а затем загрузить это изображение в WebGL. К сожалению, в настоящее время идеального решения для этой проблемы не существует.

На самом деле это не совсем точно. Сама библиотека `lottie-web`
не поддерживает рендеринг в `WebGL`. Однако существует пакет под названием [canvaskit-wasm](https://www.npmjs.com/package/canvaskit-wasm), который обертывает [Skia](https://skia.org) (графический движок) с помощью WebAssembly (wasm). Этот пакет включает модуль под названием [skottie](https://skia.org/docs/user/modules/skottie/), который поддерживает рендеринг анимации в поверхность `WebGL`. Однако у этого подхода есть недостаток: использование wasm требует загрузки относительно большого пакета, и нет уверенности в том, что все функции поддерживаются правильно, как указано в [официальной таблице совместимости](https://github.com/airbnb/ lottie/blob/master/supported-features.md), который отслеживает поддержку lottie на разных платформах, не включает skottie.

История

Я часто задаюсь вопросом, почему эта технология была представлена ​​только в 2015 году. Концепция кажется довольно простой, не правда ли? Ну, возможно, нет. Я предполагаю, что было не так много разработчиков с опытом работы с этим конкретным типом программного обеспечения. Все, что связано с графикой, часто может показаться загадочным царством, почти черной магией, особенно для таких, как я.

Что нам следует делать как сообществу?

Очевидно, что проект «lottie-web» нуждается в помощи.

Как мы можем помочь?

* Пожертвовать Финансовая помощь – один из способов поддержать проект. Даже небольшое ежемесячное пожертвование может изменить ситуацию. Лично я вношу 5 долларов каждый месяц и надеюсь, что [bodymovin](https://github.com/bodymovin) рассмотрит проблемы, которые я открыл, наслаждаясь чашкой кофе, финансируемой моим пожертвованием.
* [contribute](https://github.com/airbnb/lottie-web)
Если у вас есть знания и навыки, прямое участие в проекте — еще один ценный способ помочь. Однако имейте в виду, что внести свой вклад может быть непросто, если вы не знакомы с основами анимации и форматом лотереи. Именно этому и посвящена данная статья!

Демистифицируем «лотти»

Я провел [мастер-класс](https://holyjs.ru/en/talks/8b9ab68b933844869272de89633d0817/?referer=/archive/2023%20Spring/), где попробовал построить лотоплеер с нуля.
[ Еще одно](https://www.youtube.com/watch?v=QAOaBpYLA58&t=1333s) видео может быть вам интересно, речь идет о генерации видео, но в то же время оно пересекается с информацией, которой я собираюсь поделиться .

Наш план:
* Создать простую анимацию в After Effects
* Экспортировать анимацию в json с помощью `bodymovin`
* Изучить содержимое json-файла и его структуру
* Создать демо-версию, в которой мы используем `lottie-web` для рендеринга видео
* Замените `lottie-web` нашим пользовательским рендерером на `webgl`
* Сравните дизайн нашего рендерера с дизайном лоттие-web

Проект в After Effects

Давайте создадим простую анимацию в After Effects.

* Создать проект в After Effects

* Настройка композиции

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

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iwrgoj1vgimjyusqn5as.png)

* Создать сплошной слой

[Здесь](https://helpx.adobe.com/ca/after-effects/using/creating-layers.html) вы можете найти обзор различных слоев, которые вы можете создавать с помощью эффектов After Effects.

Давайте создадим простой слой со сплошным цветом.

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x27s4yt0afywfkdybj6x.png)

Здесь мы можем указать его цвет, ширину и высоту.
![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9z76m92rp3n6pthr9vq.png)

Хорошо, это наша анимация:

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z2jp0dz45mvyqdi13cu2.gif)

Но анимации нет!!!

Является ли анимация процессом преобразования чего-либо на экране?
Какие возможности изменения у нас есть?
Когда вы щелкаете по сплошному слою, вы можете заметить, что у него доступна функция «трансформировать».

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e5ntmq1kmbsof3xi4ai.png)

Вы можете изменить «положение», «поворот», «непрозрачность», «масштаб», «точку привязки» слоя. Давайте кое-что изменим:

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9nkton0kv9t4lniq66u.gif)

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

Теперь пришло время ввести «ключевые кадры»:
Давайте переместим наш прямоугольник в правое нижнее положение.

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4f12be2cko4ow5lhc8gn.gif)

Что это влечет за собой?
Для начального ключевого кадра в момент времени (0) мы указали, что слой должен располагаться в точке (0, 0).
Для второго ключевого кадра в момент времени (2 с) мы заявили свою позицию как (1920, 1080). В течение интервала времени от 0 до 2 секунд положение будет интерполировано с использованием линейной функции.

Теперь, как мы можем создать нелинейную анимацию?
Чтобы добиться этого, мы можем использовать кривые Безье. Эти кривые, названные в честь Пьера Безье, позволяют создавать более сложные и настраиваемые анимации. Вы можете узнать о них больше [здесь](https://en.wikipedia.org/wiki/B%C3%A9zier_curve).

В этом скринкасте мы открыли редактор кривых и выделили кривую для позиции (подробнее мы углубимся в эту тему позже).

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sxdxrnofxcrfxgzs1r2e.gif)

Следовательно, у нас есть возможность управлять изменениями координат «x» и «y» с течением времени, используя «кубическую кривую Безье».

Что такое кубический Безье? Подробное объяснение вы можете найти в Википедии, которая предоставляет ценный ресурс по этой теме. Вот [ссылка](https://en.wikipedia.org/wiki/B%C3%A9zier_curve):

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dk25t4f8xrjwupjvwyh9.gif)

Чтобы определить такую ​​кривую, нам нужно указать только две точки, обычно называемые контрольными точками «вход» и «выход».

Например, взгляните на [эту кривую](https://cubic-bezier.com/#0,1,1,0). Она состоит из двух контрольных точек:
* Первая контрольная точка имеет координаты x=0, y=1.
* Вторая контрольная точка имеет координаты x=1, y=0.
![Описание изображения](https://dev-to-uploads. s3.amazonaws.com/uploads/articles/0tqwos2iq33ui6pc8erq.png)

Стоит отметить, что мы можем даже создать линейную анимацию, используя кубическую кривую Безье. Просто установите [контрольные точки по диагонали](https://cubic-bezier.com/#.14,.14,.86,.86)

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dulal7og4lv3avihajn9.png)

Чтобы упростить нашу первую анимацию, давайте вернемся к линейной анимации.

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uyxovsq44q8vdzq2obuh.gif)

Хорошо, давайте сохраним нашу анимацию в формате json, для этого мы используем [bodymovin](https://aescripts.com/bodymovin/)
Следуйте [этапам установки плагина](https://github.com/ airbnb/lottie-web#plugin-installation)

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/st1f9qbhe8k6wj14a1yg.gif)

Структура Лотти

Давайте посмотрим на сохраненный файл:

```json
{
«v»: «5.10.2»,
«fr»: 29.9700012207031,
«ip»: 0,
«op» : 900.000036657751,
«w»: 1920,
«h»: 1080,
«нм»: «Подвижный квадрат»,
«ddd»: 0,
«активы»: [],
«слои»: [
{
«ddd»: 0,
«ind»: 1,
«ty»: 1 ,
«нм»: «Красное сплошное 1»,
«ср»: 1,
«кс»: {
«о»: {
«а» : 0,
«к»: 100,
«ix»: 11
},
«r»: {
«а»: 0,
«к»: 0,
«ix»: 10
},
«р»: {
«а»: 1,
«к»: [
{
«i»: {
«x»: 0,833,
«y»: 0,833
},
«o»: {
«x»: 0,167,
«y»: 0,167
},
«t»: 0,
«s»: [
0,
0,
0
],
«к»: [
0,
0,
0
],
«ти»: [
0,
0,
0
]
},
{
«t»: 15.0000006109625,< br /> «s»: [
1920,
1080,
0
]

],
«ix»: 2 ,
«л»: 2
},
«а»: {
«а»: 0,
«к»: [
150,
150,
0
],
«ix»: 1,
«л»: 2
},
«s»: {
«a»: 0,
«k»: [
100,
100,
100
],
«ix» : 6,
«л»: 2

},
«ао»: 0,
«ш»: 300,
«ш» : 300,
«sc»: «#ef0c0c»,
«ip»: 0,
«op»: 900.000036657751,
«st»: 0,
«bm»: 0

],
«маркеры»: []

```

Он содержит множество полей с одним-двумя символьными именами. Оно уже застегнуто 😃!

Чтобы понять значение всех полей, мы можем использовать эту [схему лотереи](https://lottiefiles.github.io/lottie-docs/schema/lottie.schema.json)
Еще одна вещь, которую можно удобно [редактор json](https://lottiefiles.github.io/lottie-docs/playground/json_editor/)
На самом деле, у `lottie` очень хорошая [документация](https://lottiefiles .github.io/lottie-docs/concepts/#general-concepts), можете прочитать и пропустить эту статью 😄

Корневой уровень файла «lottie», который в спецификации называется «анимация».

› Объект верхнего уровня, описывающий анимацию

Давайте сосредоточимся на этом

```json
{
«v»: «5.10.2»,
«fr»: 29.9700012207031,
«ip»: 0,
«op» : 900.000036657751,
«w»: 1920,
«h»: 1080,
«нм»: «Подвижный квадрат»,
«ddd»: 0,
«активы»: […],
«слои»: […],
«маркеры»: […]

```

* `v` — версия. Он используется для версионирования данных в соответствии с semver
* `fr` — Частота кадров в секунду
* `ip` — «In Point», с какого кадра начинается анимация (обычно 0)
* `op` — «Точка выхода», в которой кадр анимации останавливается/зацикливается, что определяет продолжительность в кадрах, когда `ip` равен 0
* `w` — Ширина анимации
* `h` — Высота анимации
* `nm` — Имя, как видно из редакторов и т.п.
* `ddd` — Имеет ли анимация 3D-слои
* `layers` — Слои

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

Некоторые схемы поддержки IDE
например, в vscode можно добавить [vscode/settings.json](https://code.visualstudio.com/docs/languages/json)

```json
{
“json.schemas”: [

{
fileMatch: [
src/animations/*.json
],
url: «https://lottiefiles.github.io/lottie -docs/schema/lottie.schema.json'

]

```

И вы получите описание каждого свойства вашего json прямо внутри `IDE`.
![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zq7k1u9j8dyv3ckphgi3 .png)

С объектом верхнего уровня все ясно.

Что находится внутри [слоев](https://lottiefiles.github.io/lottie-docs/layers/)?
Всего один сплошной слой:

```json
{
«ddd»: 0,
«ind»: 1,
«ty»: 1,
«nm»: «Red Solid 1»,
«ср»: 1,
«ао»: 0,
«ш»: 300,
«ш»: 300,
«сб» : «#ef0c0c»,
«ip»: 0,
«op»: 900.000036657751,
«st»: 0,
«bm»: 0,
«ks»: {
«o»: {
«a»: 0,
«k»: 100,
«ix»: 11
},< br /> «r»: {
«a»: 0,
«k»: 0,
«ix»: 10
},
«p» : {
«a»: 1,
«k»: [
{
«i»: {
«x»: 0,833,
« у»: 0,833
},
«о»: {
«х»: 0,167,
«у»: 0,167
},
«t ”: 0,
«с»: [
0,
0,
0
],
«к»: [
0 ,
0,
0
],
«ти»: [
0,
0,
0
] },
{
«т»: 15.0000006109625,
«с»: [
1920,
1080,
0
]

],
«ix»: 2,
«l»: 2
},
«a»: {
«a»: 0,
«k»: [
150,
150,
0
],
«ix»: 1,
«l»: 2
},
«s»: {
«a»: 0,
«k»: [
100,
100,
100
],
«ix»: 6,
«l»: 2



/> ```

* `ty` — Тип слоя, в нашем случае это 1, что означает сплошной слой по схеме
* `sw` — With
* `sh` — Heigh
* `sc` — цвет, в нашем случае это `#ef0c0c`, который не совсем красный! Хорошо, после эффектов я тебя понял.

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbtkv9hjgjubrvkvyf9w.png)

Давайте пока пропустим другие свойства и сосредоточимся на важном — `ks`

`ks` — объект Transform, который отвечает за анимацию этого `слоя`.

```json
{
«o»: {
«a»: 0,
«k»: 100,
«ix»: 11
},
«r»: {
«a»: 0,
«k»: 0,
«ix»: 10
},
«р»: {
«а»: 1,
«к»: [
{
«i»: {
«х»: 0,833, «у»: 0,833
},
«о»: {
«х»: 0,167,
«у»: 0,167
},
«т»: 0,
«с»: [
0,
0,
0
],
«до»: [ 0,
0,
0
],
«ти»: [
0,
0,
0
]
},
{
«t»: 15.0000006109625,
«s»: [
1920,
1080,
0
]

],
«ix»: 2,
«l»: 2
},
«a»: {
«а»: 0,
«к»: [
150,
150,
0
],
«ix»: 1,
«л»: 2
},
«с»: {
«а»: 0,
«к»: [
100 ,
100,
100
],
«ix»: 6,
«l»: 2


```

* `o` — непрозрачность
* `r` — поворот
* `p` — положение
* `a` — точка привязки
* `s` — масштаб

Все свойства, которые мы видели в объекте `after Effects`, `transform`.

Каждый из них содержит

Свойство `a`, которое указывает, является ли это свойство анимированным или нет.
Если это не анимированное свойство, это означает, что для него нет `ключевых кадров`, значение статическое.

В нашем примере анимированным свойством является только позиция.
Если свойство не анимировано, `k` содержит статическое значение.

итак, в нашем примере

* `opacity` = 100
* `rotation` = 0
* `anchor point` = [150, 150, 0]
* `scale` = [100, 100, 100]

«position» анимируется, поэтому «k» содержит «ключевые кадры».

```json
[
{
«i»: {
«x»: 0,833,
«y»: 0,833
},
«о»: {
«х»: 0,167,
«у»: 0,167
},
«т»: 0,
«с»: [
0,
0,
0
],
«к»: [
0,
0,
0
],
«ти»: [
0,
0,
0
]
},
{
«t»: 15.0000006109625,
«s»: [
1920,
1080,
0
]

] ```

он описывает 2 ключевых кадра.

для `t` (время) = 0, `s` (состояние/значение) равно [0,0] означает, что наш слой находится в верхнем левом углу сцены
для `t` (время) = 15.000000610962, (состояние /value) равно [1920,1080] означает, что наш слой находится в правом нижнем углу сцены.

Довольно легко, правда?

Это сложнее, чем вы думаете

Первый ключевой кадр содержит другие свойства: `i`, `o`, `to`, `ti`

Что это значит?

Как я упоминал ранее, After Effects поддерживает два разных режима положения.

«разделенный» и «комбинированный» (это не термин «последействия»).

в режиме «разделения» координаты x, y имеют отдельные определения ключевых кадров.

в этом случае у нас будет объект `p` (позиция) следующим образом:

```json
{
«s»: true,
«x»: {
«a»: 1,
«k»: [
],
«ix»: 3
},
«y»: {
«a»: 1,
«k»: [
],
«ix»: 4


```

`s` означает раскол.

давайте рассмотрим `p.x` (position.x)

```json
[
{
«i»: {
«x»: [
0,833
],
«y» : [
0,833
]
},
«о»: {
«х»: [
0,167
],
«у»: [
0,167
]
},
«т»: 0,
«с»: [
0
]
},
{
«t»: 15.0000006109625,
«s»: [
1920
]

]
```

Здесь все просто
для `t` = 0 значение = 0
для `t` = 15.0000006109625, значение = 1920

```json
{
«i»: {
«x»: [
0,833
],
«y»: [
0,833
]
},
«о»: {
«х»: [
0,167
],
«у»: [
0,167
]


```

`i` — означает вход в контрольную точку кубической Безье
`o` — означает выход из контрольной точки кубической Безье

Ранее мы обсуждали значение этих терминов.

Когда используются эти значения, анимация становится линейной.

Теперь давайте вычислим значение FrameNumber = 7. Вот как это можно сделать.

```js
const bezier = new cubicBezier({in: [0.83, 0.83], out = [0.167, 0.167]});

// прогресс между двумя кадрами — это значение от 0 до 1;
const Progress = FrameNumber / (15.0000006109625–0);

const x = bezier.get(progress) * (1920–0);
```

То же самое для `y`.
Обратите внимание, что та же логика интерполяции применима к непрозрачности, повороту, масштабу и т. д.

давайте вернемся к нашему первоначальному случаю с «комбинированной» позицией

Что такое «я», «о», «то», «ти»?

В этом режиме «After Effects» отображает кривую Безье, которая описывает кривую для положения, и это не то же самое, что интерполяционная «кубическая кривая Безье».

В настройках интерполяции `transform.position` мы можем выбрать желаемый тип интерполяции.
![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cibeaw68gkxnn977bjl5. png)

Это не меняет способ экспорта в «lottie», потому что, как я упоминал ранее, линия также может быть представлена ​​с помощью кривой Безье.

Давайте рассмотрим этот пример:
![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nwf2dl8f1wi4cqlevht.gif)

В экспортированном `json`

вы можете видеть, что `ti` и `to` описывают входные и выходные контрольные точки двумерного пути Безье.

```json
{
«to»: [
0,
1080,
0
],
«ti»: [
0,
-540, // обратите внимание, что оно относительно значения второго ключевого кадра
0
]
}
```

В этом режиме `ti`, `to` описывают только путь, но как анимационному игроку понять, насколько быстро мы должны перемещать `слой` по этому `пути`?

«Lottie» хранит эту информацию внутри свойств «i» и «o».

В After Effects это можно изменить в настройках скорости ключевого кадра.

![Описание изображения](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utricl44g6c0li76n3zw.png)

Мы рассмотрим интерполяцию положения в этом сценарии позже.

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

Я считаю, что мы готовы создать наш собственный рендерер Lottie с нуля.

Давайте продолжим это в следующей статье.