Vivus запускает анимацию SVG как последовательное прорисовывание путей, и контроль момента старта анимации становится важной частью интеграции с интерфейсом, аналитикой и синхронизацией с другими эффектами. Внутри библиотеки нет отдельного «официального» события начала анимации в виде стандартного EventEmitter API, поэтому отслеживание старта реализуется через комбинацию встроенных хуков, обёрток методов и внешних механизмов наблюдения.
Анимация в Vivus инициируется тремя основными способами:
autostart: true — запуск сразу после инициализацииstart: 'inViewport' — запуск при попадании SVG в
область видимостиinstance.play() или
instance.reset().play()Ключевой момент: фактический старт анимации происходит не в момент создания объекта, а в момент вызова внутреннего метода проигрывания. Это создаёт точку контроля, которую можно перехватить.
Самый надёжный способ фиксировать начало — переопределение метода
play у экземпляра Vivus.
const instance = new Vivus('my-svg', {
type: 'delayed',
duration: 120
});
const originalPlay = instance.play;
instance.play = function () {
console.log('Анимация начала');
if (typeof this.__onStart === 'function') {
this.__onStart();
}
return originalPlay.apply(this, arguments);
};
instance.__onStart = () => {
console.log('Хук старта выполнен');
};
Такой подход гарантирует фиксацию момента запуска вне зависимости от
причины вызова play.
При работе с множеством SVG удобнее централизовать контроль:
function createVivusWithStartHook(id, options, onStart) {
const instance = new Vivus(id, options);
const originalPlay = instance.play;
instance.play = function () {
onStart?.(instance);
return originalPlay.apply(this, arguments);
};
return instance;
}
const svgAnim = createVivusWithStartHook(
'logo',
{ type: 'sync', duration: 80 },
() => console.log('SVG стартовал')
);
Такой подход позволяет внедрять логику аналитики, например отправку событий в систему трекинга или синхронизацию с UI.
Внутри Vivus есть внутренние флаги состояния, которые можно использовать косвенно. Хотя они не являются частью стабильного публичного API, в реальных проектах часто применяются для контроля жизненного цикла.
Идея заключается в отслеживании перехода из состояния «ожидание» в «анимация»:
const instance = new Vivus('icon', { duration: 100 });
let started = false;
instance.play = (function (original) {
return function () {
if (!started) {
started = true;
console.log('Первый запуск анимации');
}
return original.apply(this, arguments);
};
})(instance.play);
Этот метод полезен, когда важно отследить именно первый старт, а не последующие перезапуски.
При autostart: true вызов play() может
происходить внутри конструктора, поэтому простое переопределение после
создания экземпляра иногда оказывается поздним. В таких случаях
используется задержка и контроль через onReady.
const instance = new Vivus('logo', {
type: 'delayed',
duration: 100,
onReady: function () {
console.log('SVG готов, вот-вот начнётся анимация');
}
});
onReady сигнализирует о завершении подготовки DOM и
вычисления путей, но не гарантирует старт анимации. Поэтому его
используют как подготовительный этап перед фактическим запуском.
Для точного контроля применяется связка двух механизмов:
const instance = new Vivus('logo', {
duration: 120,
onReady: function () {
console.log('Готово к запуску');
}
});
const originalPlay = instance.play;
instance.play = function () {
console.log('Фактический старт анимации SVG');
return originalPlay.apply(this, arguments);
};
Такая комбинация разделяет подготовку и реальный старт, что особенно важно при синхронизации с интерфейсными переходами.
Если доступ к экземпляру ограничен, можно наблюдать за изменениями
атрибутов SVG. Vivus изменяет stroke-dashoffset для
имитации прорисовки, что можно отследить:
const svg = document.getElementById('logo');
const observer = new MutationObserver(() => {
console.log('Обнаружено изменение SVG — возможный старт анимации');
});
observer.observe(svg, {
attributes: true,
subtree: true,
attributeFilter: ['style', 'stroke-dashoffset']
});
Этот метод менее точный, но полезен при интеграции с чужим кодом.
Часто старт анимации используется как триггер для интерфейсных действий: затемнение фона, запуск загрузочного индикатора, переключение секций.
instance.play = function () {
document.body.classList.add('svg-animation-running');
requestAnimationFrame(() => {
console.log('UI синхронизирован со стартом анимации');
});
return originalPlay.apply(this, arguments);
};
Использование requestAnimationFrame позволяет
синхронизировать визуальные изменения с первым кадром анимации.
При работе с множеством экземпляров важно унифицировать механизм:
const vivusRegistry = [];
function registerVivus(id, options) {
const instance = new Vivus(id, options);
const originalPlay = instance.play;
instance.play = function () {
console.log(`Старт анимации для #${id}`);
return originalPlay.apply(this, arguments);
};
vivusRegistry.push(instance);
return instance;
}
Такой реестр позволяет контролировать все SVG-анимации на странице и строить глобальную систему событий.
Для превращения Vivus в событийно-ориентированную систему можно внедрить простой эмиттер:
function makeEventedVivus(id, options) {
const events = {};
const instance = new Vivus(id, options);
instance.on = function (event, cb) {
events[event] = cb;
};
const originalPlay = instance.play;
instance.play = function () {
events['start']?.();
return originalPlay.apply(this, arguments);
};
return instance;
}
const v = makeEventedVivus('icon', { duration: 90 });
v.on('start', () => {
console.log('SVG animation started');
});
Такой слой абстракции превращает библиотеку в управляемый анимационный движок с контролируемыми состояниями.