SVG od podstaw - gradienty i wzorki

Oprócz wypełnienia figury jednym kolorem w SVG można używać również gradientów czyli płynnych przejść jednej barwy w drugą. Gradient musi być zdefiniowany wewnątrz znacznika <defs>. Podajemy tam identyfikator, do którego odwołujemy się później we właściwości fill wybranej figury za pomocą adresu złożonego ze znaku # i nazwy gradientu. W SVG wyróżniamy dwa rodzaje gradientów liniowy i promienisty.

Gradient liniowy

Do zdefiniowania gradientu liniowego służy znacznik <linearGradient>. Wstawiamy go oczywiście wewnątrz <defs>.
<defs><linearGradient id="gradient1">
...
</linearGradient></defs>
<rect fill="url(#gradient1)"
...
Wewnątrz znacznika <linearGradient> należy umieścić element <stop> lub większą ich liczbę. Określają one poszczególne kolory składające się na gradient. Każdy z nich ma atrybut offset oraz stop-color. Offset wskazuje miejsce zakończenia koloru i przyjmuje wartości od 0 do 1 lub procentowo od 0 do 100. Stop-color to definicja koloru. Kolor zdefiniowany w pierwszym znaczniku <stop> gradientu to pierwsza barwa, kolejne znaczniki <stop> opisują następne.
<linearGradient id=”gradient1”>
<stop offset=”5%” stop-color=”red”/>
<stop offset=”40%” stop-color=”green”/>
<stop offset=”100%” stop-color=”blue”/>
Ważniejsze atrybuty elementu <linearGradient>
gradientUnits="userSpaceOnUse | objectBoundingBox" – definiuje układ współrzędnych dla atrybutów x1, y1, x2, y2. Jeśli wybrano gradientUnits="userSpaceOnUse" to x1, y1, x2, y2 reprezentują współrzędne w aktualnym układzie użytkownika w czasie, gdy następuje odwołanie do gradientu. Jeśli wybrano gradientUnits=”objectBoundingBox” układ dla x1, y1, x2, y2 jest ustawiony przy użyciu ramy obiektu, w który wstawiany jest gradient. Jeśli nie podano wartości to domyślna wartość gradientUnits to objectBoundingBox. x1, y1, x2, y2 – definiują wektor gradientu. Umożliwia on podanie początkowych i końcowych punktów, w które będą wstawione przejścia kolorów (gradient stops). Wartości mogą być liczbami bądź procentami. Jeśli atrybut nie jest podany przyjmuje wartość 0%. spreadMethod="pad | reflect | repeat" – określa, co ma się stać, gdy gradient zaczyna się lub kończy wewnątrz ramki obiektu, do którego będzie wstawiony. Możliwe wartości to: pad, która mówi, że będą użyte końcowe kolory do wypełnienia prostokąta, reflect, gradient będzie odbity (start-to-end, end-to-start, start-to-end, etc), repeat - gradient będzie powtórzony. Wartością domyślną jest "pad".
xlink:href="uri" – odnośnik URI do innego gradientu. Gradient w SVG
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  
  <g>
    <defs>
      <linearGradient id="MyGradient">
        <stop offset="5%" stop-color="#F60" />
        <stop offset="95%" stop-color="#FF6" />
      </linearGradient>
    </defs>

    <!-- The rectangle is filled using a linear gradient paint server -->
    <rect fill="url(#MyGradient)" stroke="black" stroke-width="5"  
          x="100" y="100" width="200" height="140"/>
  </g>
</svg>
Gradient pionowy w SVG
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<defs>
<linearGradient id="grad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:rgb(250,0,0);stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,255,0);stop-opacity:1"/>
</linearGradient>
</defs>

<ellipse cx="200" cy="190" rx="85" ry="55"
style="fill:url(#grad)"/>

</svg>
Analizując poniższy kod można zorientować się jakie parametry są potrzebne by okreslić różne kierunki gradient liniowego. Najpierw definiujemy trzykolorowy gradient liniowy o identyfikatorze three_stops. Domyślnie kierunek gradientu to od lewej do prawej. Aby zdefiniować inny kierunek musimy określić współrzędne punktu początkowego (x1, y1) oraz punktu końcowego (x2, y2). Aby nie używać ciągle znaczników <stop> odnosimy się do pierwszego gradientu za pomocą atrybutu xlink:href. Gradient w SVG
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">

<defs>
<linearGradient id="three_stops">
<stop offset="0%" style="stop-color: #ffcc00;"/>
<stop offset="33.3%" style="stop-color: #cc6699"/>
<stop offset="100%" style="stop-color: #66cc99;"/>
</linearGradient>
<linearGradient id="right_to_left"
xlink:href="#three_stops"
x1="100%" y1="0%" x2="0%" y2="0%"/>
<linearGradient id="down"
xlink:href="#three_stops"
x1="0%" y1="0%" x2="0%" y2="100%"/>
<linearGradient id="up"
xlink:href="#three_stops"
x1="0%" y1="100%" x2="0%" y2="0%"/>
<linearGradient id="diagonal"
xlink:href="#three_stops"
x1="0%" y1="0%" x2="100%" y2="100%"/>
</defs>
<rect x="40" y="20" width="200" height="40"
style="fill: url(#three_stops); stroke: black;"/>
<rect x="40" y="70" width="200" height="40"
style="fill: url(#right_to_left); stroke: black;"/>
<rect x="250" y="20" width="40" height="200"
style="fill: url(#down); stroke: black;"/>
<rect x="300" y="20" width="40" height="200"
style="fill: url(#up); stroke: black;"/>
<rect x="40" y="120" width="200" height="100"
style="fill: url(#diagonal); stroke: black;"/>

</svg>
Poniższy rysunek ilustruje nam to zagadnienie. Gradient w SVG

Gradient promienisty

Do zdefiniowania gradientu promienistego (radialnego) używamy znacznika <radialGradient>. Znacznik ten musi być zdefiniowany wewnątrz <defs>. Podstawowe atrybuty elementu <radialGradient> to:
gradientUnits ="userSpaceOnUse | objectBoundingBox" – określa układ współrzędnych dla atrybutów x1, y1, x2, y2. Jeśli wybrano wartość gradientUnits="userSpaceOnUse", to x1, y1, x2, y2 reprezentują współrzędne w aktualnym układzie użytkownika w czasie, gdy następuje odwołanie do gradientu. Jeśli wybrano wartość gradientUnits="objectBoundingBox", układ dla x1, y1, x2, y2 jest ustawiony przy użyciu ramy obiektu, w który wstawiany jest gradient. Jeśli nie podano wartości, to domyślna wartość gradientUnits to objectBoundingBox.
cx, cy, r – definiują największe koło dla gradientu radialnego. Gradient będzie narysowany jakby przejście kolorów 100% (gradient stop) było ustawione na ten okrąg. Jeśli atrybut nie jest podany przyjmowana jest wartość "50%" dla cx, cy.
fx, fy – określają centralny (ogniskowy) punkt gradientu (ten gdzie gradient stop wynosi 0%). Jeśli nie podamy tego punktu, będzie on miał współrzędne cx, cy.
spreadMethod = "pad | reflect | repeat" – określa co ma się stać, gdy gradient zaczyna się lub kończy wewnątrz ramki obiektu, do którego będzie wstawiony. Możliwe wartości to: pad, która mówi, że będą użyte końcowe kolory do wypełnienia prostokąta, reflect, gradient będzie odbity (start-to-end, end-to-start, start-to-end, etc), repeat - gradient będzie powtórzony. Wartością domyślną jest "pad".
xlink:href = "uri" – określa odnośnik URI do innego gradientu. Gradient promienisty
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="radialgrad" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:white;"/>
<stop offset="100%" style="stop-color:orange;"/>
</radialGradient>
</defs>
<ellipse cx="230" cy="200" rx="100" ry="100"
style="fill:url(#radialgrad)"/>
</svg>
Inny przykład ze zmianą fx i fy. Gradient promienisty
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="radial2" cx="50%" cy="50%" r="50%" fx="25%" fy="25%">
<stop offset="0%" style="stop-color:green"/>
<stop offset="100%" style="stop-color:yellow"/>
</radialGradient>
</defs>
<ellipse cx="200" cy="150" rx="110" ry="100"
style="fill:url(#radial2)"/>
</svg>

Wzorki (patterns)

Obiekty graficzne i obrysy możemy również wypełniać wzorkami (deseniami). Do ich definiowania służy element <pattern>. Element ten, tak jak gradienty, ma atrybuty id oraz patternUnits, który po nadaniu wartości userSpaceOnUse definiuje obszar współrzędnych dla atrybutów x, y, width i height. Wartości x i y wyznaczają punkt, od którego jest rysowany deseń, a pozostałe dwa określają jego szerokość i wysokość. Wzorek w SVG
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
     xmlns="http://www.w3.org/2000/svg">
  <defs>
    <pattern id="TrianglePattern" patternUnits="userSpaceOnUse"
             x="0" y="0" width="20" height="20">
      <path d="M 0 0 L 3 0 L 3 5 z" fill="orange" stroke="blue" />
    </pattern> 
  </defs>
<ellipse fill="url(#TrianglePattern)" stroke="black" stroke-width="5"
           cx="400" cy="200" rx="350" ry="150" />
</svg>