Маркерная система в Lottie представляет собой набор именованных точек или диапазонов на временной шкале анимации, которые позволяют связывать визуальные состояния с внешними событиями. В контексте Lottie Web маркеры становятся ключевым инструментом для синхронизации аудио, поскольку обеспечивают стабильные якоря внутри таймлайна, независимые от кадровой частоты и внутренних оптимизаций рендеринга.
В структуре JSON-файла Lottie маркеры располагаются в корневом объекте анимации:
"markers": [
{
"tm": 0,
"cm": "intro",
"dr": 60
},
{
"tm": 60,
"cm": "beat_drop",
"dr": 120
}
]
Параметры маркера:
tm — временная позиция в кадрахcm — имя маркераdr — длительность диапазона (в кадрах)Такая структура позволяет интерпретировать маркер не как одиночную точку, а как сегмент анимации, что критично при работе с аудиоритмическими событиями.
В Lottie Web маркеры доступны через объект анимации после загрузки JSON:
lottie.loadAnimation({
container: document.getElementById('anim'),
renderer: 'svg',
loop: false,
autoplay: false,
path: 'animation.json'
}).addEventListener('DOMLoaded', (anim) => {
console.log(anim.markers);
});
Каждый маркер становится частью внутреннего индекса анимации. Движок формирует карту соответствий:
frameRate)Эта карта используется при вызове переходов между сегментами и при синхронизации с внешними источниками времени, включая аудиодорожки.
Основной сценарий использования маркеров в аудиоориентированных анимациях — привязка звуковых событий к визуальным сегментам. Аудиоплеер и Lottie-анимация работают как два независимых таймера, синхронизируемых через общую шкалу времени.
Базовая схема:
requestAnimationFrameПример привязки аудиопозиции к маркерам:
const audio = document.querySelector('audio');
const animation = lottie.loadAnimation({
container: document.getElementById('anim'),
renderer: 'svg',
loop: false,
autoplay: false,
path: 'animation.json'
});
function sync() {
const currentTime = audio.currentTime;
const frameRate = animation.frameRate;
const currentFrame = currentTime * frameRate;
const markers = animation.markers;
for (let i = 0; i < markers.length; i++) {
const m = markers[i];
if (currentFrame >= m.time && currentFrame < (m.time + m.duration)) {
// логика попадания в сегмент маркера
}
}
requestAnimationFrame(sync);
}
audio.play();
sync();
Такой подход обеспечивает непрерывное сопоставление аудио-времени и визуального состояния без необходимости жесткой привязки к кадровому циклу анимации.
Lottie Web поддерживает переходы к маркерам через API:
animation.goToAndPlay('beat_drop', true);
или переход к сегменту:
animation.playSegments([60, 120], true);
Внутренняя логика преобразует имя маркера в числовой диапазон кадров, после чего активируется стандартный механизм проигрывания.
Маркеры становятся логическими блоками:
В аудиосценариях такие блоки соответствуют структуре трека. При достижении определённого таймкода аудио инициирует переход к соответствующему маркеру.
Аудиоанализ может работать как источник событий, инициирующих переходы по маркерам. При этом маркеры выступают как таблица маршрутизации.
Пример сопоставления:
const audioMap = {
0: 'intro',
15: 'verse',
30: 'chorus',
45: 'beat_drop'
};
audio.addEventListener('timeupdate', () => {
const t = Math.floor(audio.currentTime);
if (audioMap[t]) {
animation.goToAndPlay(audioMap[t], true);
}
});
Такая структура эффективна при линейных композициях, где аудио разбито на фиксированные интервалы.
Маркеры могут использоваться не только как статические метки, но и как основа для вычисления динамических переходов. В этом случае создаётся слой логики поверх Lottie-анимации.
Пример вычисления ближайшего маркера:
function getNextMarker(currentFrame, markers) {
return markers
.filter(m => m.time > currentFrame)
.sort((a, b) => a.time - b.time)[0];
}
Такой подход используется при аудио с переменным темпом или интерактивной генерацией ритма, когда точка синхронизации определяется в реальном времени.
Важная особенность Lottie — поддержка длительных маркеров. Это позволяет связывать аудио не только с моментом, но и с состоянием.
Пример:
intro — 0–60 кадровbuild_up — 60–120 кадровdrop — 120–180 кадровВ таком случае синхронизация строится на проверке попадания текущего времени в диапазон:
function isInMarker(frame, marker) {
return frame >= marker.time && frame < marker.time + marker.duration;
}
Это используется для удержания визуального состояния в рамках аудиосекции, а не для одноразового триггера.
При расширенной обработке аудио маркеры используются как конечные точки сегментации сигнала. Например, Web Audio API позволяет извлекать амплитуду и спектр, а маркеры задают интервалы анализа.
const context = new AudioContext();
const analyser = context.createAnalyser();
const source = context.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(context.destination);
const data = new Uint8Array(analyser.frequencyBinCount);
Далее маркеры используются как границы обработки:
function analyzeSegment(startFrame, endFrame) {
const startTime = startFrame / animation.frameRate;
const endTime = endFrame / animation.frameRate;
if (audio.currentTime >= startTime && audio.currentTime < endTime) {
analyser.getByteFrequencyData(data);
}
}
Таким образом, маркер становится не только визуальным указателем, но и параметром аудиокомпьютинга.
При сложных композициях маркеры формируют граф переходов. Каждый маркер может содержать ссылку на следующий логический сегмент.
Пример структуры:
const transitions = {
intro: 'verse',
verse: 'chorus',
chorus: 'beat_drop',
beat_drop: 'outro'
};
Логика перехода:
function nextSegment(current) {
return transitions[current];
}
animation.goToAndPlay(nextSegment('verse'), true);
В связке с аудио это позволяет строить нелинейные сценарии воспроизведения.
В многослойных проектах одна анимация может синхронизироваться с несколькими аудиотреками. Маркеры в этом случае выступают как глобальная временная шкала.
Каждая дорожка сопоставляется с набором маркеров:
Система синхронизации:
const layers = {
music: audio1,
fx: audio2,
voice: audio3
};
function syncAll(frame) {
if (frame === animation.markers.find(m => m.name === 'beat_drop').time) {
layers.fx.play();
}
}
Lottie пересчитывает временные значения маркеров при изменении
frameRate. Это означает, что синхронизация с аудио должна
опираться не на абсолютные кадры, а на секунды.
Корректная формула:
timeInSeconds = frame / frameRate
frame = timeInSeconds * frameRate
Использование секундной шкалы устраняет дрейф между аудио и анимацией при различных параметрах экспорта.
При построении интерактивных систем маркеры становятся событиями уровня движка. Они используются для:
Пример события:
animation.addEventListener('enterFrame', () => {
const frame = animation.currentFrame;
animation.markers.forEach(marker => {
if (frame === marker.time) {
handleAudioEvent(marker.name);
}
});
});
Такая архитектура превращает Lottie-анимацию в временную шину событий, где аудио и визуализация работают в едином тактовом режиме.