Формат Lottie представляет собой декларативное описание анимации в виде JSON-структуры, где каждая анимация строится из набора слоёв, фигур, трансформаций и ключевых кадров. В основе лежит принцип описания сцены как дерева объектов, где каждый элемент имеет собственные параметры и временные зависимости.
Базовые элементы JSON-анимации:
layers — список слоёв композицииshapes — геометрические примитивы и их группыks — ключевые свойства (position, scale, rotation,
opacity)ip / op — диапазон кадров (in point / out
point)fr — частота кадровw / h — размеры композицииКаждый слой представляет собой независимую сущность, внутри которой описывается логика поведения и визуальное содержимое.
Программная генерация Lottie-анимаций заключается в создании JSON-структуры динамически, без использования After Effects и Bodymovin как промежуточного инструмента. Такой подход позволяет строить анимации на основе данных, алгоритмов и пользовательских параметров.
Генерация JSON сводится к построению дерева объектов:
Основное преимущество подхода — возможность параметризации анимации в реальном времени.
Минимальная Lottie-композиция может быть описана следующим образом:
const animation = {
v: "5.7.4",
fr: 60,
ip: 0,
op: 120,
w: 500,
h: 500,
layers: []
};
v — версия спецификацииfr — частота кадровip / op — диапазон воспроизведенияw, h — размеры сценыНа этом уровне формируется пустая сцена, готовая к наполнению слоями.
Слой — ключевая единица структуры. Каждый слой описывает объект или группу объектов.
Пример слоя с базовой формой:
const circleLayer = {
d: 1,
ty: 4,
nm: "Circle",
sr: 1,
ks: {
o: { k: 100 },
r: { k: 0 },
p: { k: [250, 250, 0] },
s: { k: [100, 100, 100] }
},
shapes: []
};
Здесь:
ty: 4 обозначает shape layerks содержит трансформацииp, r, s, o
управляют позицией, вращением, масштабом и прозрачностьюФигуры описываются через массив shapes. Каждая форма —
объект с типом и параметрами.
const circleShape = {
ty: "el",
p: { k: [0, 0] },
s: { k: [200, 200] }
};
const rectShape = {
ty: "rc",
p: { k: [0, 0] },
s: { k: [300, 150] },
r: { k: 20 }
};
const stroke = {
ty: "st",
c: { k: [0, 0.5, 1, 1] },
w: { k: 4 }
};
Ключевые кадры в Lottie описываются через массив объектов с временными метками.
Базовая структура:
{
k: [
{ t: 0, s: [0, 0, 0] },
{ t: 60, s: [100, 100, 0] }
]
}
const positionAnimation = {
k: [
{ t: 0, s: [100, 100, 0] },
{ t: 30, s: [250, 100, 0] },
{ t: 60, s: [400, 300, 0] }
]
};
const opacityAnimation = {
k: [
{ t: 0, s: 0 },
{ t: 20, s: 100 },
{ t: 80, s: 100 },
{ t: 120, s: 0 }
]
};
Программная генерация позволяет создавать анимации на основе математических функций.
function lerp(a, b, t) {
return a + (b - a) * t;
}
Используется для построения промежуточных значений:
function generateKeyframes(start, end, frames) {
const result = [];
for (let i = 0; i <= frames; i++) {
const t = i / frames;
result.push({
t: i,
s: [
lerp(start[0], end[0], t),
lerp(start[1], end[1], t),
0
]
});
}
return result;
}
Использование тригонометрии позволяет создавать органичные движения.
function sineWaveAnimation(amplitude, frequency, frames) {
const result = [];
for (let i = 0; i <= frames; i++) {
const value = Math.sin(i * frequency) * amplitude;
result.push({
t: i,
s: [250 + value, 250, 0]
});
}
return result;
}
Такая генерация используется для:
Слои могут создаваться на основе массивов данных.
function createBars(count) {
const layers = [];
for (let i = 0; i < count; i++) {
layers.push({
ty: 4,
nm: `Bar_${i}`,
ks: {
p: { k: [i * 20, 250, 0] },
s: {
k: [
{ t: 0, s: [10, 10, 100] },
{ t: 60, s: [10, Math.random() * 200, 100] }
]
}
},
shapes: [
{
ty: "rc",
s: { k: [10, 100] }
},
{
ty: "fl",
c: { k: [0.2, 0.6, 1, 1] }
}
]
});
}
return layers;
}
Такой подход используется для:
Композиция Lottie может строиться как функция от входных параметров:
function createComposition(width, height, items) {
return {
v: "5.7.4",
fr: 60,
ip: 0,
op: 120,
w: width,
h: height,
layers: items
};
}
Это позволяет создавать масштабируемые анимационные системы.
Морфинг состояний достигается через интерполяцию наборов параметров.
function transition(from, to, frames) {
const result = [];
for (let i = 0; i <= frames; i++) {
const t = i / frames;
result.push({
t: i,
s: from.map((v, idx) => lerp(v, to[idx], t))
});
}
return result;
}
Используется для:
Сложные сцены строятся через композицию функций:
const scene = createComposition(800, 600, [
...createBars(10),
circleLayer
]);
При программной генерации важно учитывать размер и сложность итогового JSON.
Основные подходы оптимизации:
Чем меньше глубина и плотность структуры, тем выше производительность Lottie Web при рендеринге.
Сгенерированный JSON используется напрямую в библиотеке Lottie Web:
lottie.loadAnimation({
container: document.getElementById("anim"),
renderer: "svg",
loop: true,
autoplay: true,
animationData: animation
});
Генерация на стороне кода заменяет статический импорт JSON-файлов, позволяя создавать анимации на лету, без перезагрузки ресурсов.
Генераторы анимаций становятся универсальными, если вынести параметры:
function generateWaveScene({ width, height, density, amplitude }) {
return createComposition(width, height, sineWaveAnimation(amplitude, 0.1, density));
}
Такая структура превращает анимацию в вычислимую модель, а не статический ресурс.