Градиенты

SVG-градиенты формируются через систему описания цветовых переходов, встроенную в спецификацию SVG, и представляют собой отдельные узлы <linearGradient> и <radialGradient>, которые затем применяются к атрибутам fill или stroke элементов. В анимации SVG-путей, управляемых библиотекой Vivus, градиенты часто становятся дополнительным визуальным слоем, усиливающим эффект «рисования» и создающим ощущение динамического освещения линии.

Линейный градиент задаёт переход цвета вдоль прямой линии между двумя точками. Базовая структура определяется координатами x1, y1, x2, y2, а также набором цветовых остановок <stop>.

<svg width="400" height="200">
  <defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="#00c6ff"/>
      <stop offset="100%" stop-color="#0072ff"/>
    </linearGradient>
  </defs>

  <path d="M10 100 L390 100"
        stroke="url(#grad1)"
        stroke-width="8"
        fill="none"/>
</svg>

В контексте Vivus такой путь может анимироваться, создавая эффект «прорисовки» линии с уже заданным цветовым переходом. Однако важно учитывать, что градиент не следует за прогрессом анимации, а остаётся статичным относительно координат SVG.

Радиальные градиенты и визуальная глубина

Радиальные градиенты формируют переход от центра к периферии и применяются для создания эффекта свечения, объёма или подсветки вдоль линии.

<radialGradient id="rad1" cx="50%" cy="50%" r="50%">
  <stop offset="0%" stop-color="#ffffff"/>
  <stop offset="100%" stop-color="#ff4d4d"/>
</radialGradient>

При использовании в анимируемых путях Vivus радиальные градиенты часто комбинируются с увеличением толщины штриха или изменением прозрачности, создавая иллюзию энергетического импульса.

Особенности применения градиентов к stroke

Векторные анимации Vivus чаще всего работают именно с stroke, поскольку библиотека управляет свойствами stroke-dasharray и stroke-dashoffset. При применении градиента к обводке возникает важный визуальный нюанс: градиент рассчитывается по всей геометрии пути сразу, а не по текущему прогрессу рисования.

path {
  stroke: url(#grad1);
  stroke-width: 6;
}

В результате при анимации путь «проявляется» из уже существующего цветового перехода, что иногда создаёт эффект преждевременного появления цвета в невидимых сегментах.

Взаимодействие Vivus с SVG-градиентами

Vivus управляет только геометрическим раскрытием пути, изменяя параметры обводки, но не затрагивает визуальные атрибуты заливки или stroke-стиля. Это означает, что градиенты существуют параллельно анимации и не синхронизируются с её прогрессом напрямую.

Типичный запуск анимации:

new Vivus('my-svg', {
  type: 'delayed',
  duration: 200
});

При этом градиент остаётся статической сущностью, определённой в <defs>, и не пересчитывается на каждом шаге анимации.

Имитирование «движущегося» градиента вдоль пути

Для создания эффекта перемещающегося градиента используется комбинация stroke-dashoffset (управляемого Vivus) и анимации координат градиента через JavaScript или SMIL.

const gradient = document.getElementById('grad1');

let offset = 0;

function animateGradient() {
  offset += 1;
  gradient.setAttribute('x1', offset + '%');
  gradient.setAttribute('x2', (offset + 100) + '%');
  requestAnimationFrame(animateGradient);
}

animateGradient();

Такой подход создаёт иллюзию «скольжения» цвета вдоль линии, хотя фактически меняется направление градиента.

userSpaceOnUse и objectBoundingBox

Ключевым параметром, определяющим поведение градиента, является gradientUnits. Он может принимать два значения:

  • objectBoundingBox — координаты нормализованы относительно элемента
  • userSpaceOnUse — координаты соответствуют общей системе SVG
<linearGradient id="grad2" gradientUnits="userSpaceOnUse"
                x1="0" y1="0" x2="400" y2="0">

При использовании Vivus различие становится критичным: в режиме objectBoundingBox градиент масштабируется вместе с каждым сегментом пути, что может давать неожиданные визуальные артефакты при сложных кривых.

Градиенты и сложные контуры путей

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

<path d="M50 150 C150 0, 250 300, 350 150"
      stroke="url(#grad1)"
      stroke-width="5"
      fill="none"/>

При анимации Vivus такой путь будет «раскрываться» постепенно, но градиент останется глобальным.

Динамическое изменение градиента в процессе анимации

Vivus предоставляет колбэки, позволяющие синхронизировать внешние эффекты с прогрессом прорисовки. Это используется для изменения градиента в зависимости от стадии анимации.

new Vivus('my-svg', {
  duration: 150,
  type: 'oneByOne',
  onProgress: function (obj) {
    const progress = obj.currentFrame / obj.totalFrames;

    const stop1 = document.querySelector('#grad1 stop:first-child');
    const stop2 = document.querySelector('#grad1 stop:last-child');

    stop1.setAttribute('stop-color', `rgba(0, 198, 255, ${1 - progress})`);
    stop2.setAttribute('stop-color', `rgba(0, 114, 255, ${progress})`);
  }
});

Такой подход позволяет связать визуальную динамику цвета с прогрессом отрисовки пути, создавая эффект «раскалённого следа».

Множественные градиенты на одном пути

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

<path d="M10 80 L390 80"
      stroke="url(#grad1)"
      stroke-width="10"
      opacity="0.6"/>

<path d="M10 80 L390 80"
      stroke="url(#grad2)"
      stroke-width="4"
      opacity="1"/>

В сочетании с Vivus такая техника создаёт эффект свечения вокруг основной линии, особенно заметный при медленной анимации.

Трансформация градиентов

SVG позволяет применять gradientTransform, который изменяет координатную систему градиента независимо от геометрии пути.

<linearGradient id="grad3" gradientTransform="rotate(45)">

При анимации Vivus это может использоваться для создания ощущения вращающегося света вдоль линии, хотя сама геометрия остаётся неизменной.

Производительность при сочетании Vivus и градиентов

Градиенты в SVG не являются вычислительно дорогими сами по себе, однако их динамическая модификация через JavaScript в каждом кадре анимации может создавать нагрузку на DOM. Особенно это заметно при большом количестве <stop> элементов или при одновременной анимации множества SVG-путей.

Оптимизация обычно достигается за счёт:

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

Комбинирование stroke-dasharray и градиентов

Основной механизм Vivus основан на изменении stroke-dasharray, что позволяет скрывать и постепенно раскрывать контур. Градиент при этом накладывается поверх уже существующей логики отрисовки.

path {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  stroke: url(#grad1);
}

Такое сочетание приводит к эффекту постепенного «проявления» цветового перехода без необходимости изменять сам градиент.

Сложные визуальные эффекты на основе градиентов

При расширенных техниках используются комбинации нескольких SVG-механизмов:

  • маски (mask)
  • фильтры (filter)
  • градиенты (linearGradient, radialGradient)
  • анимация пути через Vivus

Это позволяет создавать эффекты неоновых линий, энергетических разрядов или следов движения, где градиент играет роль основного источника визуальной глубины, а Vivus обеспечивает временную динамику появления формы.