Simulating Hand-Drawn Motion with SVG Filters Without JS
A small note on a practical guide to implementing the boiling line animation effect using SVG filter primitives, without JavaScript
I stumbled on this post.
It describe a nice way to add an “Hand-Drawn Motion” effect to an image using SVG filters and JavaScript to animate filter parameters.
The effect at the end is something like this:
(original image Red Apple by cyanidecupcake)
As the article explain, the animation is the result of a chain of two effects, feTurbulence
and feDisplacementMap
, and a bit of js to change feTurbulence
baseFrequency
attribute.
While js allow maximum flexibility on the output result, the same effect can be achieved without a single line of js.
Can I Use says about SVG SMIL Animation
Since January 2020, this feature works across the latest devices and major browser versions
So we can use SMIL to animate the baseFrequency
attribute directly in svg:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="400" height="400" viewBox="0 0 400 400">
<defs>
<filter id="distortionFilter">
<!-- Step 1: Create a turbulence field to generate noise -->
<feTurbulence
type="turbulence"
baseFrequency="0.01"
numOctaves="2"
seed="1"
result="noise"
id="feTurbulence1">
<!-- Step 2: Use SMIL animation to loop between baseFrequency values -->
<animate
id="turbolente-baseFrequency-anim"
attributeName="baseFrequency"
values="0.01;0.025;0.015;0.03"
calcMode="discrete"
repeatCount="indefinite"
dur=".9" />
</feTurbulence>
<!-- Step 3: Use the noise (in2) to displace the image (in) -->
<feDisplacementMap
in="SourceGraphic"
in2="noise"
scale="5"
xChannelSelector="R"
yChannelSelector="G"
id="feDisplacementMap1" />
</filter>
</defs>
<!-- Step 4: Apply the filter to the image -->
<image
x="0" y="0" width="400" height="400"
href="cherry.png"
filter="url(#distortionFilter)" />
</svg>