SVG Backdrop Refraction

Applies an SVG filter chain (feTurbulence + feDisplacementMap + feGaussianBlur) via backdrop-filter: url(#filter) for glass-like refraction of background content. Chromium only.

Preview

Loading preview…

Customize

Blur8
Scale20
Radius16
"use client";

import { useId } from "react";
import styles from "./SvgBackdropRefraction.module.css";

type SvgBackdropRefractionProps = {
  blur?: number;
  scale?: number;
  radius?: number;
  className?: string;
};

export default function SvgBackdropRefraction({
  blur = 8,
  scale = 20,
  radius = 16,
  className,
}: SvgBackdropRefractionProps) {
  const id = useId().replace(/:/g, "");
  const filterId = `refract-${id}`;

  return (
    <div
      className={[styles.panel, className].filter(Boolean).join(" ")}
      style={{ borderRadius: radius }}
    >
      <svg className={styles.svg} aria-hidden="true">
        <defs>
          <filter id={filterId} x="-20%" y="-20%" width="140%" height="140%">
            <feTurbulence
              type="fractalNoise"
              baseFrequency="0.012 0.012"
              numOctaves={3}
              seed={2}
              result="noise"
            />
            <feDisplacementMap
              in="SourceGraphic"
              in2="noise"
              scale={scale}
              xChannelSelector="R"
              yChannelSelector="G"
              result="displaced"
            />
            <feGaussianBlur
              in="displaced"
              stdDeviation={blur}
              result="blurred"
            />
          </filter>
        </defs>
      </svg>
      <div
        className={styles.backdrop}
        style={{
          backdropFilter: `url(#${filterId})`,
          WebkitBackdropFilter: `url(#${filterId})`,
        }}
      />
    </div>
  );
}