Динамический текст в Lottie Web строится вокруг работы с текстовыми
слоями, которые в экспортированном JSON из After Effects представляют
собой структуру данных, описывающую содержимое, стили и параметры
рендеринга. Каждый текстовый элемент хранится внутри слоя типа
"t" и содержит вложенную иерархию, где ключевым является
поле t внутри массива k, отвечающее за сам
текстовый контент.
Текстовый слой в Lottie представляется следующим образом:
{
"ty": 5,
"t": {
"d": {
"k": [
{
"s": {
"t": "Hello World"
}
}
]
}
}
}
Ключевые элементы:
ty: 5 — обозначение текстового слояt.d.k[] — массив ключей анимации текстаs.t — строка текста, отображаемая в анимацииДаже при отсутствии анимации текста структура сохраняется, поскольку Lottie рассматривает текст как анимируемый параметр.
После инициализации анимации доступ к данным возможен через объект экземпляра:
const anim = lottie.loadAnimation({
container: document.getElementById('container'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'animation.json'
});
Экземпляр содержит внутренние структуры:
anim.rendereranim.renderer.elementsanim.data.layersНаиболее устойчивый способ модификации текста — работа через данные слоя и метод обновления документа.
Одним из поддерживаемых механизмов является обновление текстовых
данных через updateDocumentData, доступный в части сборок
Lottie Web.
anim.updateDocumentData({
text: 'Новый текст'
});
Однако в реальных проектах поведение зависит от версии сборки и типа рендера (SVG, Canvas, HTML).
Чаще применяется точечное обновление слоя:
anim.addEventListener('DOMLoaded', () => {
const layers = anim.renderer.elements;
layers.forEach(layer => {
if (layer.data && layer.data.ty === 5) {
layer.updateDocumentData({
t: 'Новый текст'
});
}
});
});
Внутреннее представление позволяет напрямую модифицировать значение:
anim.addEventListener('DOMLoaded', () => {
const layers = anim.renderer.elements;
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
if (layer.data && layer.data.ty === 5) {
const textProperty = layer.data.t.d.k[0].s;
textProperty.t = 'Обновлённый текст';
}
}
anim.renderer.renderFrame(true);
});
Важные аспекты:
k[0] соответствует первому ключу анимации
текстаЕсли текст анимирован во времени, структура содержит несколько ключей:
"k": [
{ "t": 0, "s": { "t": "Первый текст" } },
{ "t": 50, "s": { "t": "Второй текст" } }
]
Модификация всех ключей:
layers.forEach(layer => {
if (layer.data.ty === 5) {
const keys = layer.data.t.d.k;
for (let i = 0; i < keys.length; i++) {
keys[i].s.t = 'Единый текст для всех ключей';
}
}
});
Такой подход выравнивает текстовую анимацию, заменяя все состояния одним значением.
После изменения данных требуется обновление кадра:
anim.setSubframe(false);
anim.goToAndStop(anim.currentFrame, true);
или принудительная отрисовка:
anim.renderer.renderFrame(true);
Эти методы влияют на синхронизацию визуального состояния с изменёнными данными.
При использовании SVG-рендера текст часто представлен DOM-элементами
<text>:
const svgTextElements = document.querySelectorAll('svg text');
svgTextElements.forEach(el => {
el.textContent = 'Изменённый текст';
});
Однако такой подход:
Поэтому он применяется только как временная визуальная подмена.
Распространённый подход основан на изменении исходных данных перед загрузкой:
const animationData = fetch('animation.json')
.then(res => res.json())
.then(data => {
data.layers.forEach(layer => {
if (layer.ty === 5) {
layer.t.d.k.forEach(k => {
k.s.t = 'Динамический текст';
});
}
});
return lottie.loadAnimation({
container: document.getElementById('container'),
renderer: 'svg',
loop: true,
autoplay: true,
animationData: data
});
});
Такой метод обеспечивает:
При интеграции с логикой интерфейса изменение текста обычно привязывается к внешнему состоянию:
function updateLottieText(anim, value) {
const layers = anim.renderer.elements;
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
if (layer.data.ty === 5) {
const keys = layer.data.t.d.k;
for (let j = 0; j < keys.length; j++) {
keys[j].s.t = value;
}
}
}
anim.renderer.renderFrame(true);
}
Особенности поведения:
При работе с текстовыми слоями Lottie Web проявляются системные ограничения:
Lottie оптимизирует рендеринг, кэшируя элементы:
data не всегда приводит к немедленному
обновлениюanim.renderer.destroyed = false;
anim.renderer.renderFrame(true);
В композициях с несколькими сценами текстовые слои могут быть вложены в прекомпозиции:
function traverseLayers(layers) {
for (let i = 0; i < layers.length; i++) {
const layer = layers[i];
if (layer.ty === 5) {
layer.t.d.k.forEach(k => {
k.s.t = 'Обновлённый контент';
});
}
if (layer.layers) {
traverseLayers(layer.layers);
}
}
}
Такой обход необходим при сложной структуре экспортов из After Effects с nested compositions.
Изменение текста без повторной инициализации анимации достигается через прямую модификацию data-структуры:
function setText(anim, newText) {
const layers = anim.renderer.elements;
layers.forEach(layer => {
if (layer.data && layer.data.ty === 5) {
layer.data.t.d.k[0].s.t = newText;
}
});
anim.renderer.renderFrame(true);
}
Это позволяет сохранять текущее состояние анимации, изменяя только текстовую часть.
При архитектуре с внешним источником данных текст часто связывается с API:
fetch('/api/title')
.then(res => res.json())
.then(data => {
updateLottieText(anim, data.title);
});
Такой подход сохраняет разделение логики: