Тайминговая функция в анимации определяет, как изменяется прогресс
отрисовки SVG-пути во времени. В контексте Vivus это механизм, который
преобразует линейный прогресс анимации t ∈ [0, 1] в
нелинейную кривую f(t), задающую реальную скорость
прорисовки обводки.
Базовая модель анимации Vivus строится вокруг нормализованного времени:
t = currentFrame / totalFrames
Линейная интерпретация предполагает равномерное изменение состояния:
progress = t
Тайминговая функция вводит преобразование:
progress = f(t)
где f(t) — функция, определяющая ускорение или
замедление анимации.
Ключевое свойство такой функции:
f(0) = 0
f(1) = 1
Это гарантирует корректное начало и завершение анимации без скачков.
Vivus управляет анимацией через манипуляцию свойствами
stroke-dasharray и stroke-dashoffset.
Тайминговая функция влияет не на геометрию SVG, а на распределение
кадров, в которых изменяется смещение штриха.
При линейной функции каждый сегмент пути отрисовывается равномерно. При нелинейной функции изменяется плотность “видимого” прогресса:
f(t) = t
Самая простая модель. Используется, когда требуется равномерная прорисовка без акцентов на фазах анимации.
f(t) = t²
Создаёт эффект плавного старта с ускорением ближе к завершению. В SVG-анимации визуально усиливает “дорисовку” последних сегментов.
f(t) = 1 - (1 - t)²
Обеспечивает быстрый старт и плавное завершение. Часто используется для эффектов появления логотипов.
f(t) = 3t² - 2t³
Балансирует ускорение и замедление, создавая естественное восприятие движения.
Vivus позволяет передавать собственную функцию тайминга через
параметр animTimingFunction. Функция получает значение
прогресса t и возвращает преобразованное значение.
const easeInOutCubic = function (t) {
return t < 0.5
? 4 * t * t * t
: 1 - Math.pow(-2 * t + 2, 3) / 2;
};
const svgAnimation = new Vivus('my-svg', {
type: 'delayed',
duration: 200,
animTimingFunction: easeInOutCubic
});
Функция должна быть детерминированной и возвращать значения строго в
диапазоне [0, 1], иначе поведение анимации становится
непредсказуемым.
Vivus поддерживает несколько режимов отрисовки путей:
delayedoneByOnesyncТайминговая функция применяется поверх всех режимов, но эффект проявляется по-разному:
Каждый путь получает задержку, а тайминговая функция влияет на форму каждой индивидуальной задержки, создавая каскадное ускорение или замедление.
Эффект наиболее выражен, так как каждый сегмент обводки получает отдельное временное распределение.
Все пути анимируются одновременно, поэтому функция влияет на общую “кривую видимости” всей композиции SVG.
Vivus работает не с непрерывной математической кривой, а с дискретными кадрами. Тайминговая функция применяется на каждом шаге цикла:
for each frame:
t = frame / totalFrames
adjusted = f(t)
applyStrokeOffset(adjusted)
Чем больше значение duration, тем выше плотность
дискретизации и тем точнее соответствует визуальный результат заданной
функции.
При проектировании кастомных функций учитываются следующие ограничения:
[0, 1] приводит к визуальным
артефактамПример некорректной функции:
f(t) = sin(t * 20)
Такое поведение приводит к многократным возвратам и повторной прорисовке сегментов.
Вместо функции может использоваться предрасчитанная кривая (lookup table). В таком случае прогресс интерполируется между значениями массива.
curve = [0, 0.02, 0.05, 0.1, 0.18, ... , 1]
Vivus линейно интерполирует значения между ближайшими точками, создавая сложные нелинейные эффекты без вычислений на каждом кадре.
Кастомные функции добавляют вычислительную нагрузку на каждый кадр анимации. При большом количестве SVG-путей оптимизация становится критичной.
Оптимизационные подходы:
f(t) для фиксированных
durationТайминговая функция напрямую влияет на визуальное восприятие структуры SVG. При изменении кривой:
Особенно заметен эффект на сложных иконках с множеством пересекающихся путей, где нелинейная функция позволяет выделить ключевые контуры.
В сложных сценариях используется композиция функций:
f(t) = easeOut(easeIn(t))
Или через масштабирование времени:
f(t) = ease(t * k)
где k изменяет скорость “внутри” анимации, создавая
эффект ускоренного или замедленного сегмента.
При перезапуске Vivus функция применяется заново к полному диапазону
[0, 1]. Это означает отсутствие накопления состояния между
циклами, если не используется внешний контроллер прогресса.
При ручном управлении прогрессом:
vivus.setFrame(progress)
тайминговая функция может быть применена отдельно до передачи значения в движок отрисовки.
Разные типы функций формируют разные визуальные сценарии:
Каждый вариант влияет на характер движения линии, несмотря на идентичную геометрию SVG-пути.