Filter art
In SVG shapes are drawn with geometric precision.
A <circle> element with a given radius. <path> elements detailing a series of lines point by point. The browser follows the instructions you add in the elements’ attributes to the letter and to the number. And the result is remarkable — you get to draw close to anything with only code —, but often time, precise to a fault.
The previous painting, for instance, might excel as an abstract piece, but there’s no emotion behind the shapes, no character. To add character, to try and evoke a particular feeling, a different mood, you have access to SVG filters.
It is fair to admit that the topic is vast — you’ll discover there are a total of 17 dedicated elements, setting up all kinds of operations with numerous attributes and innumerable combinations. That being said, you need to consider only a portion of the available syntax to approach the subject and appreciate the possibilities.
In theory
Before we try to give a new meaning to the painting, it helps to nail down a few, founding traits. In the body of an <svg> element a filter works like a mask, or again a clip, a pattern or a gradient. Define an instance with a unique id.
<filter id="unique-id"></filter> Apply the filter to a shape, or a group of shapes, with the filter attribute.
<rect filter="url(#unique-id)" /> How the helper affects the drawing depends on the contents of the filter itself. And in this instance, the element works rather differently from other, defined constructs.
In between the opening and closing tags you don’t add shapes, be it circles, paths, or rectangles. Instead, you add filter primitives, elements prefixed with “fe” with a specific function. But instead of professing their use, it is perhaps more effective to show their influence in practice.
In practice
Let’s consider the starting visual. It would be intriguing to have the shapes drawn with an imperfect stroke, as the tentative marks of a fledgling artist. You can achieve this in many ways, but also two primitives: feTurbulence and feDisplacementMap.
The first function produces a texture with Perlin noise.
<filter id="noise">
<feTurbulence baseFrequency="0.05" numOctaves="3" />
</filter> There’s plenty to learn about noise functions — fancy words such as octaves, frequency and amplitude —, but with the values you find an image.
You might wonder what happens to the filtered rectangle. Every primitive has one or two input images you can detail with the in and in2 attributes. What is more, each function has one output you name with result. feTurbulence, for instance, takes the input graphic, almost without telling you, and returns the texture in its place.
In terms of input you have three options. Immediately, you have two keywords, describing a specific version of the original shape: the entire, colored-filled figure with SourceGraphic, or its transparent values with SourceAlpha. You pick the latter the moment you want to strip out the color and consider only the opacity, only the alpha channel.
Past these two values, a primitive defaults to the input image. Or, the result of a previous, primitive function. Exactly like feTurbulence, which picks up the very first shape.
Essentially, you can rewrite the element to be more explicit. To highlight the behavior lurking behind the scenes.
<feTurbulence in="SourceGraphic" result="noise" baseFrequency="0.05" numOctaves="3" /> feTurbulence returns the texture, but replaces the graphic. feDisplacementMap enters the scene to complete the effect.
<filter id="map">
<!-- ...feTurbulence -->
<feDisplacementMap in="SourceGraphic" in2="noise" scale="1" />
</filter> The element takes two inputs with the in and in2 attributes. Based on these, it takes the pixels, the values of the second image to offset, to displace the pixels of the first.
The primitive takes two inputs, but once again you can get away marking only the first, the original picture.
<!-- ...feTurbulence -->
<feDisplacementMap in="SourceGraphic" scale="1" /> Following feTurbulence, in2 would refer to the earlier output, to the very same texture.
Either way, the filter works to produce a texture, and then use the noise to “mess up” the shape.
Gone are the rigid segments. Gone is the perfect polygon. Instead you find an irregular sketch, one you could almost draw yourself on a fleeting scrap of paper. The close to perfect manner to take the painting and produce a proud work of art. One you could almost showcase in a gallery provided with the right frame.
As mentioned, there’s a lot to SVG filters, a laundry list of elements, attributes and combinations. Understanding the basics, however, is more than enough to crack open the topic. Once you grasp how a filter works, how primitives operate on a specific set of inputs and return one output, you can dive in the syntax and eagerly sample the rest.