Spec-Zone.ru › SVG

Градиенты в SVG

Возможно, ещё интереснее, чем просто заливки и обводки, то, что вы также можете создавать градиенты и применять их как заливки или обводки.

В SVG есть два типа градиентов: линейные и радиальные. Их определяют отдельно от места использования, что позволяет повторно использовать их. Вы должны задать каждому градиенту атрибут id, чтобы другие элементы могли на него ссылаться. Определения градиентов можно поместить в элемент <defs> или <svg>.

Линейный градиент

Линейные градиенты изменяются вдоль прямой линии. Чтобы добавить такой градиент, создайте узел <linearGradient> внутри раздела <defs> файла SVG.

Простой пример

<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="Gradient1">
      <stop class="stop1" offset="0%" />
      <stop class="stop2" offset="50%" />
      <stop class="stop3" offset="100%" />
    </linearGradient>
    <linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1">
      <stop offset="0%" stop-color="red" />
      <stop offset="50%" stop-color="black" stop-opacity="0" />
      <stop offset="100%" stop-color="blue" />
    </linearGradient>
  </defs>
  <style>
    #rect1 {
      fill: url("#Gradient1");
    }
    .stop1 {
      stop-color: red;
    }
    .stop2 {
      stop-color: black;
      stop-opacity: 0;
    }
    .stop3 {
      stop-color: blue;
    }
  </style>

  <rect id="rect1" x="10" y="10" rx="15" ry="15" width="100" height="100" />
  <rect
    x="10"
    y="120"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#Gradient2)" />
</svg>

Выше показан пример применения линейного градиента к элементу <rect>. Внутри линейного градиента находятся несколько узлов <stop>. Эти узлы задают цвет градиента в определённых позициях, указывая атрибут offset для позиции и атрибут stop-color. Его можно задать напрямую или с помощью CSS. В этом примере для наглядности используются оба способа. Например, этот градиент начинается красным цветом, в середине становится прозрачным чёрным, а заканчивается синим. Вы можете добавить сколько угодно промежуточных цветов, чтобы создать градиент настолько красивый или ужасный, насколько вам нужно, однако значения смещений всегда должны увеличиваться от 0% (или от 0, если опустить знак %) до 100% (или 1). При одинаковых значениях используется остановка, расположенная ниже в дереве XML. Кроме того, как и для заливки и обводки, можно указать атрибут stop-opacity, чтобы задать прозрачность в этой позиции (в FF3 для этого также можно использовать значения rgba).

<stop offset="100%" stop-color="yellow" stop-opacity="0.5"/>

Чтобы использовать градиент, нужно указать на него в атрибуте fill или stroke объекта. Это делается так же, как ссылка на элементы в CSS, с помощью url. В данном случае url — это просто ссылка на наш градиент с креативным идентификатором «Gradient1». Чтобы применить его, задайте fill значение url("#Gradient1") — и готово! Теперь наш объект разноцветный. То же самое можно сделать с stroke.

<style>
  #rect1 {
    fill: url("#Gradient1");
  }
</style>

У элемента <linearGradient> также есть несколько других атрибутов, задающих размер и вид градиента. Ориентацию градиента определяют две точки, обозначенные атрибутами x1, x2, y1 и y2. Эти атрибуты задают линию, вдоль которой проходит градиент. По умолчанию градиент горизонтальный, но его можно повернуть, изменив эти значения. Gradient2 в примере выше создаёт вертикальный градиент.

<linearGradient id="Gradient2" x1="0" x2="0" y1="0" y2="1"></linearGradient>

Примечание: Для градиентов также можно использовать атрибут href. С его помощью атрибуты и остановки одного градиента можно включить в другой. В примере выше не пришлось бы заново создавать все остановки для Gradient2.

<linearGradient id="Gradient1">
  <stop id="stop1" offset="0%" />
  <stop id="stop2" offset="50%" />
  <stop id="stop3" offset="100%" />
</linearGradient>
<linearGradient
  id="Gradient2"
  x1="0"
  x2="0"
  y1="0"
  y2="1"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  href="#Gradient1" />

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

Радиальный градиент

Радиальные градиенты похожи на линейные, но расходятся из одной точки. Чтобы создать такой градиент, добавьте элемент <radialGradient> в раздел <defs> документа.

Простой пример

<?xml version="1.0" standalone="no"?>
<svg width="120" height="240" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="RadialGradient1">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
    <radialGradient id="RadialGradient2" cx="0.25" cy="0.25" r="0.25">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
  </defs>

  <rect
    x="10"
    y="10"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#RadialGradient1)" />
  <rect
    x="10"
    y="120"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#RadialGradient2)" />
</svg>

Здесь используются те же остановки, что и раньше, но теперь объект будет красным в центре и постепенно станет синим у края во всех направлениях. Как и линейные градиенты, узел <radialGradient> может принимать несколько атрибутов, задающих его положение и ориентацию. Однако здесь всё немного сложнее. Радиальный градиент также определяется двумя точками, которые задают его границы. Первая из них определяет окружность, на которой заканчивается градиент. Для неё нужны центральная точка, заданная атрибутами cx и cy, и радиус r. Задав эти три атрибута, вы сможете перемещать градиент и менять его размер, как показано во втором rect выше.

Вторая точка называется фокусной и задаётся атрибутами fx и fy. Первая точка указывает, где находятся границы градиента, а фокусная — где находится его середина. Это проще понять на примере.

Центр и фокусная точка

<?xml version="1.0" standalone="no"?>

<svg width="120" height="120" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient id="Gradient" cx="0.5" cy="0.5" r="0.5" fx="0.25" fy="0.25">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
  </defs>

  <rect
    x="10"
    y="10"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#Gradient)"
    stroke="black"
    stroke-width="2" />

  <circle
    cx="60"
    cy="60"
    r="50"
    fill="transparent"
    stroke="white"
    stroke-width="2" />
  <circle cx="35" cy="35" r="2" fill="white" stroke="white" />
  <circle cx="60" cy="60" r="2" fill="white" stroke="white" />
  <text x="38" y="40" fill="white" font-family="sans-serif" font-size="10pt">
    (fx,fy)
  </text>
  <text x="63" y="63" fill="white" font-family="sans-serif" font-size="10pt">
    (cx,cy)
  </text>
</svg>

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

Для линейных и радиальных градиентов также предусмотрено несколько других атрибутов, задающих возможные преобразования. Здесь я хочу упомянуть только атрибут spreadMethod. Он определяет, что происходит, когда градиент заканчивается, а объект ещё не заполнен. У него может быть одно из трёх значений: "pad", "reflect" или "repeat". Значение "pad" уже встречалось вам ранее. Когда градиент заканчивается, оставшаяся часть объекта заполняется цветом последнего смещения. Значение "reflect" заставляет градиент продолжаться в обратном направлении: начиная с цвета смещения 100%, он движется к смещению 0%, а затем снова вперёд. Значение "repeat" также продолжает градиент, но вместо движения назад он просто возвращается к началу и повторяется.

spreadMethod

<?xml version="1.0" standalone="no"?>

<svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <radialGradient
      id="GradientPad"
      cx="0.5"
      cy="0.5"
      r="0.4"
      fx="0.75"
      fy="0.75"
      spreadMethod="pad">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
    <radialGradient
      id="GradientRepeat"
      cx="0.5"
      cy="0.5"
      r="0.4"
      fx="0.75"
      fy="0.75"
      spreadMethod="repeat">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
    <radialGradient
      id="GradientReflect"
      cx="0.5"
      cy="0.5"
      r="0.4"
      fx="0.75"
      fy="0.75"
      spreadMethod="reflect">
      <stop offset="0%" stop-color="red" />
      <stop offset="100%" stop-color="blue" />
    </radialGradient>
  </defs>

  <rect
    x="10"
    y="10"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#GradientPad)" />
  <rect
    x="10"
    y="120"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#GradientRepeat)" />
  <rect
    x="120"
    y="120"
    rx="15"
    ry="15"
    width="100"
    height="100"
    fill="url(#GradientReflect)" />

  <text x="15" y="30" fill="white" font-family="sans-serif" font-size="12pt">
    Pad
  </text>
  <text x="15" y="140" fill="white" font-family="sans-serif" font-size="12pt">
    Repeat
  </text>
  <text x="125" y="140" fill="white" font-family="sans-serif" font-size="12pt">
    Reflect
  </text>
</svg>

У обоих градиентов также есть атрибут gradientUnits, который задаёт систему единиц для описания размера или ориентации градиента. Здесь можно использовать одно из двух значений: "userSpaceOnUse" или "objectBoundingBox". По умолчанию используется "objectBoundingBox" — именно это значение применялось во всех примерах выше. Оно масштабирует градиент в соответствии с размером объекта, поэтому достаточно указать координаты в диапазоне от нуля до единицы: они автоматически масштабируются под размер объекта. userSpaceOnUse использует абсолютные единицы. Поэтому нужно знать, где находится объект, и разместить градиент в том же месте. Элемент radialGradient выше можно переписать так:

<radialGradient
  id="Gradient"
  cx="60"
  cy="60"
  r="50"
  fx="35"
  fy="35"
  gradientUnits="userSpaceOnUse"></radialGradient>

Затем можно применить к градиенту дополнительное преобразование с помощью атрибута gradientTransform, но, поскольку мы ещё не рассматривали преобразования, оставим это на потом.

При работе с gradientUnits="objectBoundingBox" есть и другие нюансы, когда ограничивающая рамка объекта не квадратная, но они довольно сложны — лучше дождаться, пока их объяснит кто-нибудь, кто разбирается в теме лучше.

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorials/SVG_from_scratch/Gradients

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API