Таблица событий

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

Событийная модель в Vivus не является полноценной системой EventEmitter, как в DOM или Node.js. Вместо этого используется набор callback-функций, передаваемых через конфигурацию или вызываемых внутри экземпляра анимации. Несмотря на простоту, эта модель покрывает основные стадии жизненного цикла SVG-анимации и позволяет строить сложные сценарии управления визуальными эффектами.

Анимация SVG в Vivus проходит несколько логических этапов:

  • инициализация экземпляра и подготовка SVG-структуры
  • загрузка и парсинг путей (<path>, <line>, <polyline> и др.)
  • вычисление длины контуров
  • старт анимации
  • пошаговое изменение прогресса от 0 до 1
  • завершение анимации

Каждый этап может быть перехвачен через соответствующие события.

Таблица событий Vivus

Событие / Callback Момент вызова Описание Параметры
onReady После инициализации SVG и подготовки путей Срабатывает, когда SVG полностью загружен и готов к анимации, но до старта отрисовки vivusInstance
onStart В момент запуска анимации Вызывается один раз при начале анимационного цикла vivusInstance
onProgress На каждом шаге анимации Срабатывает при каждом изменении прогресса от 0 до 1 progress, vivusInstance
onEnd После завершения анимации Вызывается один раз после достижения конца анимации vivusInstance
onFrame (внутренний/пользовательский паттерн) На каждом кадре requestAnimationFrame Используется в кастомных сборках или расширениях поверх Vivus frameData

onReady: этап подготовки SVG

Событие подготовки играет ключевую роль в архитектуре Vivus. На этом этапе происходит разбор DOM-структуры SVG и подготовка всех путей к анимации.

Типичные операции внутри этого этапа:

  • вычисление длины каждого SVG-пути через getTotalLength()
  • установка stroke-dasharray и stroke-dashoffset
  • скрытие начального состояния линий
  • кэширование структуры DOM для ускорения анимации

Состояние onReady означает, что объект Vivus полностью готов к запуску, но визуально ещё не изменён.

Пример логики обработки:

new Vivus('svg-id', {
  type: 'delayed',
  duration: 200,
  onReady: function (instance) {
    instance.el.setAttribute('data-state', 'ready');
  }
});

На этом этапе можно безопасно изменять стили, не влияя на анимационный процесс.

onStart: запуск анимационного цикла

Событие старта фиксирует момент, когда начинается первый шаг изменения stroke-dashoffset. Оно вызывается единожды за жизненный цикл анимации.

Особенности:

  • вызывается после onReady
  • срабатывает перед первым кадром отрисовки
  • используется для синхронизации внешних эффектов (звуки, UI, переключатели состояния)

Пример применения:

new Vivus('svg-id', {
  duration: 150,
  onStart: function (instance) {
    document.body.classList.add('animation-running');
  }
});

Важный момент заключается в том, что onStart не зависит от текущего прогресса и всегда инициируется перед первым изменением состояния SVG.

onProgress: управление динамическим состоянием

Событие прогресса является наиболее часто используемым. Оно позволяет отслеживать текущее состояние анимации в диапазоне от 0 до 1.

Поведение прогресса

  • 0.0 — анимация не началась
  • 0.5 — половина путей прорисована
  • 1.0 — анимация завершена

В зависимости от режима (delayed, sync, oneByOne) прогресс может изменяться линейно или ступенчато.

Пример использования:

new Vivus('svg-id', {
  duration: 300,
  onProgress: function (progress, instance) {
    const percent = Math.floor(progress * 100);
    document.querySelector('#percent').textContent = percent + '%';
  }
});

Особенности onProgress

  • вызывается на каждом шаге обновления анимации
  • может быть связан с requestAnimationFrame
  • чувствителен к производительности SVG
  • не гарантирует равномерную частоту вызовов

Использование для синхронизации UI

Событие часто применяется для:

  • обновления прогресс-баров
  • управления цветом элементов в зависимости от прогресса
  • синхронизации текста и графики
  • управления параллельными анимациями

onEnd: завершение анимации

Событие завершения фиксирует момент, когда все SVG-пути полностью отрисованы.

Поведение:

  • вызывается один раз
  • происходит при достижении прогресса 1.0
  • зависит от режима анимации и задержек между сегментами

Пример:

new Vivus('svg-id', {
  duration: 200,
  onEnd: function (instance) {
    instance.el.classList.add('completed');
  }
});

Использование onEnd в сложных сценариях

Часто применяется для:

  • запуска следующей анимации
  • переключения экранов интерфейса
  • активации интерактивных элементов
  • освобождения ресурсов (если анимация одноразовая)

Взаимодействие событий между собой

Событийная последовательность строго определена:

  1. onReady
  2. onStart
  3. onProgress (многократно)
  4. onEnd

Эта цепочка формирует предсказуемый жизненный цикл, позволяющий строить сложные композиции анимаций.

Пример полной последовательности

new Vivus('svg-id', {
  duration: 250,

  onReady: function (instance) {
    instance.el.style.opacity = 1;
  },

  onStart: function () {
    console.log('start');
  },

  onProgress: function (p) {
    console.log('progress:', p);
  },

  onEnd: function () {
    console.log('end');
  }
});

Особенности реализации событийной модели

Система событий Vivus имеет несколько технических особенностей:

1. Отсутствие централизованного EventEmitter

Все события реализованы как callbacks в конфигурации, а не через подписку:

  • нет .on() или .emit()
  • события задаются при создании экземпляра
  • нельзя динамически добавлять слушатели после инициализации

2. Привязка к экземпляру

Каждый callback получает доступ к текущему экземпляру Vivus, что позволяет:

  • изменять SVG во время анимации
  • перезапускать анимацию
  • управлять параметрами в реальном времени

3. Зависимость от requestAnimationFrame

onProgress синхронизирован с циклом браузера:

  • частота зависит от FPS
  • при низкой производительности возможны пропуски кадров
  • точность прогресса сохраняется логически, но не всегда временно

Расширенные паттерны использования событий

Композиция нескольких SVG-анимаций

Событие onEnd часто используется для последовательного запуска анимаций:

const first = new Vivus('svg-1', {
  duration: 120,
  onEnd: function () {
    second.play();
  }
});

const second = new Vivus('svg-2', {
  duration: 120
});

Прогрессивное управление стилями

new Vivus('svg-id', {
  onProgress: function (p, instance) {
    instance.el.style.filter = `blur(${(1 - p) * 5}px)`;
  }
});

Синхронизация с интерфейсом

new Vivus('svg-id', {
  onStart: function () {
    loader.hidden = false;
  },
  onProgress: function (p) {
    loader.value = p;
  },
  onEnd: function () {
    loader.hidden = true;
  }
});

Ограничения событийной модели

Несмотря на удобство, модель имеет ограничения:

  • отсутствие отмены событий
  • невозможность добавления новых слушателей после создания экземпляра
  • ограниченная детализация промежуточных состояний
  • зависимость от режима анимации

Эти ограничения компенсируются простотой и предсказуемостью поведения, что важно для SVG-анимаций в браузере.