SVG-прогресс-бары на основе SVG представляют собой один из наиболее гибких способов визуализации загрузки, выполнения операций и состояния процессов в интерфейсе. В отличие от растровых индикаторов, такие элементы сохраняют чёткость на любых разрешениях и позволяют точно управлять анимацией через JavaScript. Использование Vivus добавляет к этому контролируемую отрисовку SVG-пути, создавая эффект «рисования» прогресс-бара в реальном времени.
SVG-прогресс-бар строится вокруг базового принципа: линия или контур,
длина которого визуально отражает степень выполнения задачи. В основе
лежит элемент <path>, геометрия которого может быть
прямой линией, дугой или сложной фигурой.
Ключевое свойство SVG, используемое для анимации прогресса:
stroke-dasharray — задаёт длину штрихов и пробеловstroke-dashoffset — смещает начало отображаемой части
линииМанипулируя этими параметрами, можно «скрывать» часть линии и постепенно раскрывать её по мере увеличения прогресса.
Для вычисления полной длины пути используется метод:
path.getTotalLength()
Он возвращает точное значение длины кривой, что позволяет синхронизировать визуальный прогресс с реальными данными.
Vivus — библиотека, ориентированная на анимацию SVG-путей через
последовательное изменение stroke-dashoffset. Она позволяет
создавать эффект рисования элементов без ручного управления каждой
точкой пути.
Инициализация базируется на объекте:
new Vivus('svgElementId', {
type: 'delayed',
duration: 200,
start: 'autostart'
});
Основные параметры:
type — стратегия анимацииduration — длительность анимацииstart — способ запуска (авто или вручную)Vivus работает напрямую с DOM SVG, разбивая пути на сегменты и изменяя их состояние по кадрам.
Каждый SVG-путь анимируется с небольшой задержкой относительно предыдущего. В контексте прогресс-баров создаёт эффект последовательного заполнения сегментов.
new Vivus('progressSvg', {
type: 'delayed',
duration: 150
});
Использование этого режима оправдано для сложных индикаторов, состоящих из нескольких частей.
Все пути анимируются одновременно. Подходит для линейных прогресс-баров, где требуется равномерное заполнение.
new Vivus('progressSvg', {
type: 'sync',
duration: 100
});
Этот режим ближе всего к классическому пониманию прогресс-бара.
Элементы SVG отрисовываются последовательно, один за другим. При применении к индикаторам создаёт эффект «рисующейся линии прогресса».
new Vivus('progressSvg', {
type: 'oneByOne',
duration: 200
});
Используется для сложных визуальных сценариев, где прогресс представлен как маршрут или траектория.
Базовый вариант прогресс-бара представляет собой прямую линию
<line> или простой <path>.
Пример SVG:
<svg id="progressSvg" width="300" height="20">
<path d="M10 10 L290 10" stroke="#4caf50" stroke-width="6" fill="none"/>
</svg>
При подключении Vivus линия начинает «рисоваться» от начала к концу, создавая визуальный эффект заполнения.
Для точного управления прогрессом без автоматической анимации Vivus
можно комбинировать с ручным контролем
stroke-dashoffset.
Алгоритм:
stroke-dasharraystroke-dashoffset в зависимости от процентаconst path = document.querySelector('#progressSvg path');
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
Далее прогресс вычисляется:
function setProgress(percent) {
const offset = length - (percent / 100) * length;
path.style.strokeDashoffset = offset;
}
Vivus может использоваться параллельно, чтобы анимировать появление пути, а затем управление передаётся логике прогресса.
Vivus выполняет роль первичной анимации появления, после чего SVG становится интерактивным индикатором.
const vivus = new Vivus('progressSvg', {
type: 'sync',
duration: 120
}, () => {
enableProgressControl();
});
После завершения анимации активируется управление значением прогресса через JavaScript.
SVG позволяет строить не только линейные индикаторы, но и круговые,
основанные на окружности <circle>.
<svg id="circleProgress" width="120" height="120">
<circle cx="60" cy="60" r="50" stroke="#ddd" stroke-width="8" fill="none"/>
<circle cx="60" cy="60" r="50" stroke="#4caf50" stroke-width="8" fill="none"/>
</svg>
Длина окружности:
const circle = document.querySelector('#circleProgress circle:nth-child(2)');
const radius = 50;
const circumference = 2 * Math.PI * radius;
Настройка:
circle.style.strokeDasharray = `${circumference} ${circumference}`;
circle.style.strokeDashoffset = circumference;
Прогресс:
function setCircleProgress(percent) {
const offset = circumference - (percent / 100) * circumference;
circle.style.strokeDashoffset = offset;
}
Vivus в данном случае может анимировать начальную прорисовку окружности, после чего управление берёт логика состояния.
Vivus предоставляет набор методов для контроля процесса:
play() — запуск или продолжение анимацииstop() — остановкаreset() — сброс в исходное состояниеfinish() — мгновенное завершение анимацииconst v = new Vivus('progressSvg', {
duration: 150,
start: 'manual'
});
v.play();
v.stop();
v.reset();
v.finish();
Для прогресс-баров finish() часто используется для
мгновенного перехода к 100%.
SVG-прогресс-бары с Vivus часто используются в интерфейсах загрузки файлов и API-запросов. В таких сценариях визуальная часть отделяется от реального состояния процесса.
Пример логики:
function simulateLoading(vivusInstance) {
let progress = 0;
const interval = setInterval(() => {
progress += 2;
setProgress(progress);
if (progress >= 100) {
clearInterval(interval);
vivusInstance.finish();
}
}, 100);
}
Сложные интерфейсы используют несколько путей в одном SVG:
Vivus анимирует каждый путь отдельно, что позволяет создавать многослойные эффекты загрузки.
<svg id="multiProgress">
<path class="bg" d="..." />
<path class="progress" d="..." />
<path class="ticks" d="..." />
</svg>
new Vivus('multiProgress', {
type: 'oneByOne',
duration: 200
});
Для стабильной работы анимаций важны следующие аспекты:
<path>Сложные кривые увеличивают нагрузку на перерасчёт длины пути, что влияет на плавность анимации Vivus.
Прогресс-бары часто привязываются к событиям:
Пример:
fetch('/upload')
.then(res => res.json())
.then(() => setProgress(100));
Vivus при этом используется для начальной анимации появления индикатора, создавая визуальную подготовку интерфейса к отображению состояния процесса.