Prerequisites:
David Dailey, An SVG Primer for Today’s Browsers:
Read enough of this, and carefully enough, that you are able to meet the learning objectives immediately below. Don’t try to understand all the details of all the filters; in particular, don’t fret about anything that involves a matrix.
Be able to:
We are familiar with gradients and patterns from our study of the canvas. The concepts are the same in SVG; the syntax, of course, is different. Masks and clip paths are also available in the canvas, although we did not study them. Filters are something new.
If you don’t remember what a gradient is, review Colors and Gradients.
To create a linear gradient from white to black, identified as grad0:
<linearGradient id="grad0">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</linearGradient>
Note that there is no need to specify coordinates for the gradient; it will automatically fit the width of the element being filled or stroked.1
To use this gradient to fill a rectangle:
<rect x="10" y="25" width="100" height="150" fill="url(#grad0)"/>
The gradient flows from left to right along the width of the rectangle. The fill attribute references the gradient using the url “function”; this is similar in meaning to the xlink:xref we’ve encountered earlier, but the notation is different.
But what if you don’t want the gradient to flow from left to right? For example, if you want a vertical gradient, from top to bottom? Or a diagonal gradient? In SVG, you can transform a gradient, using any transformation (such as translation, rotation, scale), or combination of transformations, that can be applied to a figure you would draw (such as a rectangle or ellipse). This is specified with the gradientTransform attribute:
<linearGradient id="grad0" gradientTransform="rotate(30)">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</linearGradient>
In this example, I attempt to duplicate the appearance of Example 06-02, using SVG. Note the use of scaling in cases 2 (diagonal), 5 (squeezed), and 6 (stretched). In case 2, because the gradient is automatically fitted to the width of the rectangle (which is a square), it must be scaled by the square root of 2 to fit along the diagonal; otherwise it would end prematurely and we would have a larger bright yellow area in the bottom right corner.
Here is a basic radial gradient, flowing from a point of white to an outer blackness:
<radialGradient id="grad1">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</radialGradient>
Note that the SVG radial gradient simply goes from the center to the circumference of a circle. You don’t have to specify two circles, as in the canvas. In fact, you cannot.
You can offset the focus (“center of radiance”) from the actual center of the circle using attributes fx, fy. The values should be between 0 and 1; with the default value 0.5 being the center, and values < 0.5 being left or upwards from center. For example, to make the “light” come from a point leftwards and down from the center:
<radialGradient id="grad1" fx="0.25" fy="0.75">
<stop offset="0" stop-color="white"/>
<stop offset="1" stop-color="black"/>
</radialGradient>
In this example, I aim to produce effects similar but not identical to those in the canvas example Example 06-03. The rectangles are no longer squares, so the gradients have an elliptical look. There is no inner circle, but an inner circle can be simulating by having an intermediate color stop with the same color as the initial color stop. I make no attempt to imitate the non-intersecting circles.
If you don’t remember what a pattern is, review Images and Patterns.
To create a pattern:
<pattern id="my-pattern"
patternUnits="userSpaceOnUse" width="32" height="32">
...
</pattern>
The width and height default to zero, so be sure to specify their values! The patternUnits can be either userSpaceOnUse or objectBoundingBox; the latter is the default, and means the width and height are interpreted as a fraction or a percent of the smallest rectangle that would enclose the figure you are filling or stroking with the pattern. This is usually not what you want to use, but it is the default; so specify patternUnits="userSpaceOnUse". If you omit any of these three attributes, your pattern will probably be invisible.
The ... represents whatever is going to be in the pattern, e.g., an image element.
To use the pattern to fill a rectangle:
<rect x="10" y="10" width="100" height="50"
fill="url(#my-pattern)"/>
Unlike the canvas, which allows only using an image as the pattern data, you can use any SVG content to make a pattern.
Use two patterns to fill and/or stroke two shapes. One pattern is based on an image; the other on a vector drawing.
Clipping paths and masks allow a drawing to be partly exposed to view.
Imagine that you have a picture covered up with a sheet of black paper. You can’t see the picture. But if you cut a circle out of the black paper, you can look through it to see part of the picture. This circle is an example of a clipping path. In general, you could cut any parts out of the black paper and see through those parts to the underlying picture. This is what clipping paths do.
In SVG, you can create clipping paths using any combination of graphical elements such as rect, circle, ellipse, path, text, etc. Just put them in a clipPath element, and then reference the clipPath from the element that you want to be partially revealed:
<clipPath id="clippy">
PATH ELEMENTS
</clipPath>
...
<image ... clip-path="url(#clippy)"/>
Of course, it does not have to be an image that is partly exposed by the clipping path; it can be any arrangement of vector drawing elements.
Now imagine that, instead of black paper, you’ve got a sheet of opaque film that can be rubbed away to various degrees. If you rub a lot, it’s completely transparent, but if you rub less, it’s only partly transparent. The less you rub an area, the more opaque it is. Unrubbed areas have an alpha value of 1 (opaque), while completely rubbed areas have alpha = 0 (transparent), and moderately rubbed areas have alpha values between 0 and 1. This sheet can be called an alpha mask, or just mask.
In SVG, you can create alpha masks using any combination of graphical elements. When a mask is applied to a drawing, a white area in the mask causes the corresponding area in the drawing to have alpha = 1, a black area causes the drawing area to have alpha = 0, and gray areas cause the drawing areas to have alpha between 0 and 1. So you use lighter colors in the mask where you want the drawing to be more visible, and you use darker colors where you want it to be less visible and to see more of the background.
To create and use a mask:
<mask id="masky">
MASK ELEMENTS
</mask>
...
<image ... mask="url(#masky)"/>
Filters can transform images (vector or bitmap) in all sorts of ways—altering colors, blurring, distorting shapes, etc. SVG has a collection of filter primitives (building blocks) which can be combined to make composite filters. We won’t go into all that much detail, but just focus one filter primitive, the Gaussian blur.
To create and apply this filter, use code such as this:
<filter id="blur1">
<feGaussianBlur stdDeviation="2"/>
</filter>
...
<image ... filter="url(#blur1)"/>
The standard deviation is the amount of blurring: the higher it is, the more blur.
You can actually give two values for standard deviation: the first is horizontal blur, and the second vertical. So in this case, there is a strong horizontal blur and no vertical blur, giving the impression of fast horizontal motion:
<feGaussianBlur stdDeviation="10, 0"/>
You can specify gradient coordinates with the attributes x1, y1, x2, y2, if you want to.↩