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.
<?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>
<?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.
<?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 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.
<?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.
<?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ść.<?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>