I saw this button on X and I was mesmerized by it:
I felt compelled to recreate it. However, I wasn't sure where to start. Luckily, Mike provided a brief explanation of the effect on X:
Under the hood: I used SVG filters with feTurbulence for random noise and feDisplacementMap to create that smooth dissolve. feDisplacementMap warps the image based on noise intensity, shifting pixels horizontally and vertically in unique ways each time. By resetting the noise seed, every delete effect gets its own randomized distortion, giving a fresh look every time
And after some tinkering, I got to what looks pretty close to the original effect:
Click on the "Delete" button to see the effect in action.
In this tutorial, I'll walk you through how to create this dissolve effect using SVG and React.
Understanding SVG Filters
SVG filters are powerful tools that allow you to apply advanced visual effects to SVG elements. They can manipulate graphics in various ways, such as blurring, distorting, or adding textures. In our case, we'll use SVG filters to create a dissolve effect by distorting the button's appearance and gradually reducing its opacity.
The Building Blocks of the Dissolve Effect
To create the dissolve effect, we'll use the following SVG filter primitives:
<feTurbulence>: Generates an image using the Perlin turbulence function. It's useful for creating cloud-like or noisy textures.
<feDisplacementMap>: Uses the pixel values from one image to spatially displace the pixels in another image, creating a distortion effect.
<feComponentTransfer>: Allows you to manipulate pixel values via component-wise transfer functions.
<feMerge>: Combines multiple filter effects into one.
By combining these primitives, we can create a noise pattern that distorts the button, giving the illusion of it dissolving away.
There is too much here to go deeper than this. If you are interested in learning more about SVG filters, I recommend these two articles: article 1, article 2.
Creating the DissolveFilter Component
The DissolveFilter component defines the SVG filter that creates the dissolve effect.
I used Chrome's DevTools "Break on subtree modifications" feature to inspect how the effect is rendered on https://refero.design/. It showed me an SVG that is being added to create the effect. The below code recreates that logic using React components and hooks.
<feTurbulence> (bigNoise and fineNoise): We create two turbulence effects with different frequencies to simulate large and fine noise patterns.
<feComponentTransfer>: Adjusts the noise levels to get the desired effect.
<feMerge>: Combines the large and fine noise into one.
<feDisplacementMap>: Applies the combined noise to distort the source graphic (our button). The scale attribute controls the intensity of the displacement.
Creating the useDissolveEffect Hook
This hook manages the animation state and updates the filter's displacement scale over time to create the animation.
Ref Assignment: We assign a ref to the button element to manipulate it directly.
Event Handling: The onClick event triggers the dissolve function.
Styles: We apply the styles from the useDissolveEffect hook to apply the SVG filter.
Rendering the Effect: We include the DissolveEffect component to render the SVG filter when needed.
Demo
Finally, once we put it all together, we get this:
You can find the full code in the GitHub gist. I am by no means an expert in React, so I welcome any feedback on how to improve this code.
The next step is to add this effect to Glama. I want to use the dissolve effect when deleting a chat session. A very cool eye-catching effect that I think we will see more in the future.
Shout out to Mike Bespalov for coming up with this effect. I was heavil inspired by his work on https://refero.design/ when creating this button.