DepUnPr

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>