Creating Gradients
Gradients create smooth blends between two distinct colors. One of the most over-used graphic effects since the origination of desktop publishing, gradients have been extensively and poorly used in attempts to mimic the shadings evident in shadows and dimensions in the natural world.
Gradients do have some beneficial uses, however. When used to create subtle shading within a non-realistic element, gradients can produce desirable effects.
Gradients come in two flavors: linear and radial. Linear gradients transition colors across a straight path, whereas radial gradients transition colors between an outer circle and an inner circle (see Figure 7.5). To create a gradient, you need two items: an element that defines the gradient and a style rule that applies the gradient to the object.
Figure 7.5 Two types of gradients: linear (left) and radial (right).
Linear Gradients
In the case of the linear blend, the linearGradient element defines a gradient according to the direction of a line. This element contains attributes similar to the line element. x1 and y1 define the start point of the line, and x2 and y2 define the end point of the line. Thus, the element uses the following syntax: <linearGradient x1="A" x2="B" y1="C" y2="D">...</linearGradient>, where A, B, C, and D represent values defining the coordinates of the gradient's directional line (known as the "gradient vector").
Inside of the linearGradient element is a series of stop child elements. Each stop element contains two important components: an offset attribute and a stop-color style rule. The offset attribute determines the point on the gradient line at which a color is defined. This value is in relation to the start and stop points defined previously. Often, you will see the offset attribute listed as a percentage, although pixel values are also accepted. Thus, if a percentage is used, it is in relation to the length of the line defined in the linearGradient element. The stop-color style rule defines the color value at that stop element's point.
To create a gradient then, you will need at least two stop elements within your linearGradient element. The syntax for your stop elements will then appear as follows, where E and F represent points along the directional line (usually noted in percentages) and color-name defines a color:
<linearGradient x1="A" y1="B" x2="C" y2="D"> <stop offset="E" style="stop-color:color-name"/> <stop offset="F" style="stop-color:color-name"/> </linearGradient>
Just as with the stroke and fill declarations, the stop-color declaration can accept any color notation that SVG allows (including the common hexadecimal notation and color keywords).
To apply a gradient to an object, you'll need to add a gradient style rule. The style rule used for applying gradients is fill:url(#BlendID), where BlendID is the value of the gradient's id attribute.
The gradient can take advantage of the gradientUnits attribute to interpret the line data from the x1, y1 and x2, y2 coordinates. The attribute has two possible values: objectBoundingBox and userSpaceOnUse.
The objectBoundingBox value tells the gradient to base the coordinates on the object's bounding box. In other words, the (x1,y2) coordinates are calculated against the top left-most corner of the object, rather than the top left-most corner of the SVG document.
The userSpaceOnUse value tells the gradient to consider the line coordinates relative to the user coordinate system (generally the document's coordinate system, unless a transformation has been applied to the gradient beforehand). Thus, the (x1,y2) coordinates are usually calculated against the document's (0,0) point.
To demonstrate the linear gradient in action, you'll create a simple box with a white-to-black gradient fill, as shown in Listing 7.4:
First, create the gradient on line 14, naming it BlendLinear and drawing the gradient's path from 50,0 to 150,0 according to the SVG document's coordinate system.
Then, set two stops (lines 16 and 17): white at 0% (the 50,0 point) and black at 100% (the 150,0 point).
Lastly, create a class (line 8) that fills an object with the gradient, and then apply the class to your square (line 20).
Listing 7.4 Creating a Linear Gradient
01: <?xml version="1.0" standalone="no"?> 02: <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 03: 04: <svg width="500" height="300"> 05: 06: <style type="text/css"> 07: <![CDATA[ 08: .FillBlendLinear{fill:url(#BlendLinear);} 09: .Stroke000000{stroke:#000000;} 10: .StrokeWidth1{stroke-width:1;} 11: ]]> 12: </style> 13: 14: <linearGradient id="BlendLinear" gradientUnits="userSpaceOnUse" 15: x1="50" y1="0" x2="150" y2="0"> 16: <stop offset="0%" style="stop-color:#FFFFFF"/> 17: <stop offset="100%" style="stop-color:#000000"/> 18: </linearGradient> 19: 20: <rect class="FillBlendLinear StrokeWidth1 Stroke000000" x="50" y="50" width="100" height="100"/> 21: 22: </svg>
Figure 7.6 shows the results of the added code.
Figure 7.6 Linear gradients can be used to create the blend apparent in this rectangle's fill.
Gradients can have multiple colors and stop points. You can add multiple stop elements to create a blend that spans several colors. Each stop element will then blend towards the color on either side of it. For instance, subtle metal effects are possible by blending across several light shades of gray.
To experiment with this possibility, you can alter your previous code (Listing 7.4) to include additional stop points, as in Listing 7.5. First, copy the two stop elements and paste between them, resulting in a total of four stop elements within your linearGradient element (lines 16 through 19 in Listing 7.5). Then, change the color values of each stop to a gray, and modify the two interior stop elements (lines 17 and 18) so that their offset value is somewhere between 0 and 100%. Figure 7.7 shows the result: a rectangle filled with various shades of gray, suggesting the appearance of a metal cylinder.
Listing 7.5 Adding Multiple Stops and Colors to a Gradient
01: <?xml version="1.0" standalone="no"?> 02: <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 03: 04: <svg width="500" height="300"> 05: 06: <style type="text/css"> 07: <![CDATA[ 08: .FillBlendLinear{fill:url(#BlendLinear);} 09: .Stroke000000{stroke:#000000;} 10: .StrokeWidth1{stroke-width:1;} 11: ]]> 12: </style> 13: 14: <linearGradient id="BlendLinear" gradientUnits="userSpaceOnUse" 15: x1="50" y1="0" x2="150" y2="0"> 16: <stop offset="0%" style="stop-color:#666666"/> 17: <stop offset="35%" style="stop-color:#999999"/> 18: <stop offset="80%" style="stop-color:#333333"/> 19: <stop offset="100%" style="stop-color:#666666"/> 20: </linearGradient> 21: 22: <rect class="FillBlendLinear StrokeWidth1 Stroke000000" x="50" y="50" width="100" height="100"/> 23: 24: </svg>
Figure 7.7 Linear gradients with multiple stops can create multiple blends within one object.
Gradients need not go only from left to right; they can angle as well. By altering your line coordinates, you can change the direction of a gradient. Using Listing 7.5 as a starting point, you can alter your gradient by a 45º angle. Simply change the values in line 15 to reflect a line going from the lower left-hand corner of your square to the top right corner, as shown in Listing 7.6. Figure 7.8 shows the resulting angled gradient.
Listing 7.6 Changing the Gradient Vector Alters the Angle of the Gradient's Display
01: <?xml version="1.0" standalone="no"?> 02: <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 03: 04: <svg width="500" height="300"> 05: 06: <style type="text/css"> 07: <![CDATA[ 08: .FillBlendLinear{fill:url(#BlendLinear);} 09: .Stroke000000{stroke:#000000;} 10: .StrokeWidth1{stroke-width:1;} 11: ]]> 12: </style> 13: 14: <linearGradient id="BlendLinear" gradientUnits="userSpaceOnUse" 15: x1="5" y1="95" x2="95" y2="5"> 16: <stop offset="0%" style="stop-color:#FF0000"/> 17: <stop offset="35%" style="stop-color:#FFFFFF"/> 18: <stop offset="80%" style="stop-color:#FFFFCC"/> 19: <stop offset="100%" style="stop-color:#000000"/> 20: </linearGradient> 21: 22: <rect class="FillBlendLinear StrokeWidth1 Stroke000000" x="50" y="50" width="100" height="100"/> 23: 24: </svg>
Figure 7.8 A linear gradient can be displayed on an angle by altering its directional line.
You can also leave off the line coordinates, at which point the gradient start point will be the left edge of the object, and the gradient will increase as it moves rightwards. To do so, you'll also need to remove the gradientUnits property. Thus, instead of <linearGradient x1="A" x2="B" y1="C" y2="D">...</linearGradient>, you can define your simplified gradient as <linearGradient>...</linearGradient>.
Radial Gradients
In the case of the radial blend, the radialGradient element contains attributes similar to the circle element. cx and cy define the circle, and r defines the radius of said circle. There are two additional properties that can be used to offset the circle's center: fx and fy. (As with the linearGradient element's directional attributes, all of these attributes can be left out.) The stop element functions just as it did for the linearGradient element.
To illustrate the radial blend, you'll create a glowing center for the news center graphic's sun in Listing 7.7. Using Listing 7.1 as a base, add a radialGradient element (line 15 in Listing 7.7). To determine how the cx and cy values will be interpreted, you will need to add a gradientUnits attribute.
In the last example, you used the value userSpaceOnUse, resulting in values that related to the document's coordinate system. In this case, use objectBoundingBox so that the other attribute's values are in relation to the coordinates of the object to which the gradient will be applied.
The cx and cy values (both defined as 50%) determine that the gradient will start in the middle of the applied object. The r value (also 50%) determines that the gradient will extend to the edges of its applied circle (as the radius of any circle is 50% of its actual dimensions). Two stop elements are created on lines 16 and 17, each defining a shade of yellow at their respective point along the gradient's radius (moving outward from the center point).
Lastly, the gradient is given an id value of GradientSunCenter (line 15). This value is then referenced when you create a style rule (on line 8) filling an object with that specific gradient. The rule is then applied to the circle on line 14, completing your document. Figure 7.9 shows the resulting image: a "glowing" sun.
Listing 7.7 Creating a Radial Gradient
01: <?xml version="1.0" standalone="no"?> 02: <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> 03: 04: <svg width="500" height="300"> 05: 06: <style type="text/css"> 07: <![CDATA[ 08: .GradientSun{fill:url(#GradientSunCenter);} 09: .Fill99CCFF{fill:#99CCFF;} 10: ]]> 11: </style> 12: 13: <rect id="Sky" x="10" y="45" width="200" height="245" class="Fill99CCFF"/> 14: <circle id="Sun" cx="105" cy="160" r="56" class="GradientSun"/> 15: <radialGradient id="GradientSunCenter" cx="50%" cy="50%" r="50%" gradientUnits="objectBoundingBox"> 16: <stop offset="50%" style="stop-color:#FFFFCC"/> 17: <stop offset="85%" style="stop-color:#FFFF00"/> 18: </radialGradient> 19: 20: </svg>
Figure 7.9 A radial gradient can be used to create a glowing effect.
Lastly, note how even though the gradient elements existed within the SVG file, they did not display unless applied through the style command. You can store your gradient elements inside many elements, including svg and g elements, as well as definition and symbol elements (see Hour 8, "Symbols").