Gradients

В процессе перевода.

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

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

Линейный градиент (Linear Gradient)

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

Basic example

<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>
      <style type="text/css"><![CDATA[
        #rect1 { fill: url(#Gradient1); }
        .stop1 { stop-color: red; }
        .stop2 { stop-color: black; stop-opacity: 0; }
        .stop3 { stop-color: blue; }
      ]]></style>
  </defs>
 
  <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>

ScreenshotLive sample

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

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

Чтобы использовать градиент, мы должны сослаться на него из атрибутов объекта fill/stroke. Это делается таким же образом, как вы ссылаетесь на элементы в CSS, используя url. В этом случае, url - это просто ссылка на наш градиент, которому задан уникальный ID, "Gradient". Чтобы добавить его, установим fill="url(#Gradient)". Наш объект теперь многоцветный. То же самое можно сделать с атрибутом stroke.

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

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

Замечание: Вы также можете использовать атрибут xlink: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" xlink:href="#Gradient1"/>

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

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

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

Basic example

<?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>

ScreenshotLive sample

Аттрибуты stop, используемые здесь - отвечают за то же, что и в линейных градиентах. Однако сейчас объект будет красным в центре и постепенно меняться к синему цвету, "двигаясь" к краям. Как и линейный градиент, элемент <radialGradient> может иметь несколько аттрибутов, описывающих его позицию и ориентацию (направленность?). Однако, в отличие от линейных градиентов, радиальные немного сложнее. Радиальные градиенты задаются двумя "точками", которые определят где будут границы. Первая "точка" определяет окружность, где градиент заканчивается. Для этого нам потребуется центр круга, который обозначается как cy и cy, и радиус - r. Изменяя эти аттрибуты, вы можете "двигать" внешнюю границу градиента и менять ее размер, как показано во втором прямоугольнике выше.

Вторая "точка" называется фокальной и задается аттрибутами fx и fy. В то время как первые "точки" указывают на внешнюю границу градиента, фокальная "точка" определяет где должна быть его середина. Это легко увидеть на примере.

Center and focal point

<?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>

ScreenshotLive sample

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

Линейный и радиальный градиенты также принимают несколько аттрибутов, описывающих как они могут изменяться. Единственный аттрибут, о котором я хотел бы рассказать более подробно - это spreadMethod. Этот аттрибут указывает что должно происходить когда градиент "достигает" внешней границы градиента, но объект еще не заполнен. Аттрибут может принимать одно и трех значений:"pad", "reflect", или"repeat". "Pad" - это то что вы пока что видели: когда градиент достигает "краев", финальный цвет используется для заполнения оставшейся области. "Reflect" - градиент продолжает "двигаться" в "зеркальном" отражении (стартовый цвет берется из 100%, а конечный из 0%). А затем снова "переворачивается". И так до тех пор пока не достигнет края.

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>

ScreenshotLive sample

У обоих типов градиентов также есть атрибут gradientUnits, который описывает систему измерений, которую Вы собираетесь использовать, когда описываете размеры или ориентацию или градиен. Данный атрибут принимает 2 возможных значения: userSpaceOnUse или objectBoundingBox (дефолтное, показывалось во всех примерах выше). objectBoundingBox автоматически адаптирует градиент к размеру объекта, так что Вы можете указать координаты в виде значений от 0 до 1, и браузер автоматически их отпозиционирует. userSpaceOnUse позиционирует градиент в абсолютных единицах измерения, так что Вам необходимо знать где находится целевой объект, что бы правильно применить к нему градиент. radialGradient  выше может быть переписан:

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

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

There are some other caveats for dealing with gradientUnits="objectBoundingBox" when the object bounding box isn't square, but they're fairly complex and will have to wait for someone more in-the-know to explain them.

Метки документа и участники

 Внесли вклад в эту страницу: valery-paschenkov, tavira
 Обновлялась последний раз: valery-paschenkov,