
Diving in to SVG Filters
PermalinkWrapping my head around SVG filters to create a distessed effect for text and images.
Someone was looking for a quick CSS solution to a distressed text effect, and I thought I'd seen similar things done with SVG filters. I don't remember where or what exactly, and even though I once attended a talk on SVG by Chris Coyier at An Event Apart — which included a print copy of of his book, Practical SVG — I really didn't have any idea of how to do anything with SVG code.
I need more texture …
Somehow I knew enough to know that feTurbulence could do something. It's used to make textures, right? So I started with the MDN article and began playing around, modifying, adding to, breaking, and trying to learn from the example there.
I next took a look at Bence Szabó's CSS-Tricks article "Creating Patterns with SVG Filters."
I wish I had actually read Bence's article instead of skipping through the page and grabbing and playing with code because I might have learned some things sooner, so read it if you're interested.
What I was able to do, though, was decipher to some extent what the thing I'd hacked together was doing and just begin to understand this stuff and realize it may not be as opaque as I thought.
Prepare for some turbulence
Step 0 is just to get a texture, and we do that with feTurbulence. This creates an image using Perlin Noise, which won Ken Perlin an Academy Award for Technical Achievement after he got frustrated with the boxy limitations of computer graphics while working on Disney's Tron. We owe this to Tron! It's used to simulate natural textures through "pseudo-random noise," and it can be used to do all sorts of amazing things. But we're just going to use it to find a nice, irregular texture.
The baseFrequency and numOctaves attributes determine the granularity and level of detail in the texture. The seed gives us some variety. There's a default value, but you can pick any number you want to get a different starting set of pseudo-random numbers used to generate the texture. I'm calling the resulting texture "texture." Majestical.
<feTurbulence
baseFrequency="0.08"
numOctaves="2"
seed="666"
result="texture" />
Let's shake things up
Next, we'll use feDisplacementMap to eventually displace whatever this filter is applied to (via the keyword "sourceGraphic") by using the pixel values from the texture. And scale controls how much it's displaced. We just want it displaced a little so it's still readable as text or recognizable as an image, but sort of a lo-fi version, with rough edges and details. So I'm calling it "lo-fi."
<feDisplacementMap
in="SourceGraphic"
in2="texture"
scale="4"
result="lo-fi" />
A little transparency would be nice
Then we want to use the texture again to create some confetti-like flecks that will be used in the last step. We could start with another texture, but that's more work — for us and for the comptuer — so we'll reuse the same texture. To do this, we use feComponentTransfer which remaps the component color channels: R, G, B, and A (i.e., red, green, blue, and alpha, for transparency). We can focus on the alpha channel using feFuncA. The type "discrete" followed by tableValues indicates a step function. We only want two values, making the resulting "flecks" either fully transparent or fully opaque ("0" or "1").
<feComponentTransfer
in="texture"
result="flecks">
<feFuncA type="discrete" tableValues="0 1" />
</feComponentTransfer>
It's what on the outside that counts
Finally, we want to use the "flecks" like a mask on our "lo-fi" filter so it looks kind of distressed, weathered, and broken. We do that with feComposite, which combines images. In this case, the parts of in that outside of in2 are what we see, because of the operator "out".
<feComposite
in="lo-fi"
in2="flecks"
operator="out" />
Check out the demo on Codepen. The SVG has an id="broken", and in CSS I have a class called .broken that will apply it to any element that has that class:
.broken {
filter: url(#broken);
}
You can play with the values there, make it more or less distorted, make the "holes" bigger or smaller (and more numerous because they're smaller, like zooming out on a star field), etc. Have fun it, learn from it, and make things that are cooler.