# Distorted Glass

> Frosted glass divider for React and shadcn/ui using an SVG fractal noise displacement filter, for section transitions and headers.

Source: https://www.cult-ui.com/docs/components/distorted-glass

## Example

```tsx title="distorted-glass-demo.tsx"
"use client"

import { useRef } from "react"
import { motion, useScroll, useTransform } from "motion/react"

import { DistortedGlass } from "@/components/ui/distorted-glass"

export default function DistortedGlassDemo() {
  const containerRef = useRef<HTMLDivElement>(null)
  const { scrollYProgress } = useScroll({
    target: containerRef,
    offset: ["start start", "end end"],
  })

  // Transform values for parallax effects
  const parallaxY = useTransform(scrollYProgress, [0, 1], [0, -200])
  const parallaxYSlow = useTransform(scrollYProgress, [0, 1], [0, -100])
  const parallaxYFast = useTransform(scrollYProgress, [0, 1], [0, -300])

  return (
    <div className="relative flex h-screen flex-col overflow-hidden">
      {/* Fixed Distorted Glass Header */}

      {/* Scrollable Content Area - Content scrolls behind the glass */}
      <div ref={containerRef} className="flex-1 overflow-y-auto pt-[50px]">
        <div className="absolute top-0 right-0 left-0 -mt-[1px] w-full">
          <DistortedGlass className="h-48 w-full" />
        </div>
        {/* Section 1: Large Moving Text - Easy to see distortion */}
        <section className="from-primary/20 via-primary/10 relative flex h-96 items-center justify-center bg-gradient-to-br to-transparent">
          <div className="absolute inset-0 overflow-hidden">
            <motion.div
              className="text-primary/30 absolute top-20 left-10 text-8xl font-black select-none"
              style={{ y: parallaxY }}
              animate={{
                x: [0, 50, 0],
              }}
              transition={{
                duration: 8,
                repeat: Infinity,
                ease: "easeInOut",
              }}
            >
              DISTORTED
            </motion.div>
            <motion.div
              className="text-primary/30 absolute top-40 right-10 text-8xl font-black select-none"
              style={{ y: parallaxYSlow }}
              animate={{
                x: [0, -50, 0],
              }}
              transition={{
                duration: 10,
                repeat: Infinity,
                ease: "easeInOut",
              }}
            >
              GLASS
            </motion.div>
          </div>
        </section>

        {/* Section 2: Grid of Moving Squares */}
        <section className="via-primary/10 to-primary/20 relative flex h-[700px] items-center justify-center bg-gradient-to-br from-transparent">
          <div className="absolute inset-0 overflow-hidden">
            <div className="grid grid-cols-8 gap-4 p-8">
              {Array.from({ length: 64 }).map((_, i) => {
                const row = Math.floor(i / 8)
                const col = i % 8
                const squareId = `square-${row}-${col}`
                return (
                  <motion.div
                    key={squareId}
                    className="bg-primary border-primary/50 h-16 w-16 rounded-lg border-2"
                    initial={{ opacity: 0.3 }}
                    animate={{
                      scale: [1, 1.2, 1],
                      opacity: [0.3, 0.8, 0.3],
                      rotate: [0, 90, 0],
                    }}
                    transition={{
                      duration: 3,
                      repeat: Infinity,
                      delay: (row + col) * 0.1,
                      ease: "easeInOut",
                    }}
                    style={{
                      y: parallaxY,
                    }}
                  />
                )
              })}
            </div>
          </div>
        </section>

        {/* Section 3: Radial Circles */}
        <section className="from-primary/20 to-primary/10 relative flex h-[600px] items-center justify-center bg-gradient-to-br via-transparent">
          <div className="absolute inset-0 flex items-center justify-center overflow-hidden">
            {Array.from({ length: 5 }).map((_, i) => {
              const size = 200 + i * 80
              const circleId = `circle-${size}`
              return (
                <motion.div
                  key={circleId}
                  className="border-primary/40 absolute rounded-full border-4"
                  style={{
                    width: size,
                    height: size,
                    y: parallaxYSlow,
                  }}
                  animate={{
                    rotate: [0, 360],
                    scale: [1, 1.1, 1],
                  }}
                  transition={{
                    duration: 20 + i * 5,
                    repeat: Infinity,
                    ease: "linear",
                  }}
                />
              )
            })}
          </div>
        </section>

        {/* Section 4: Lines Pattern */}
        <section className="via-primary/10 to-primary/20 relative flex min-h-screen items-center justify-center bg-gradient-to-br from-transparent">
          <div className="absolute inset-0 overflow-hidden">
            {Array.from({ length: 20 }).map((_, i) => {
              const lineTop = i * 10
              const lineId = `line-${lineTop}`
              return (
                <motion.div
                  key={lineId}
                  className="bg-primary/40 absolute right-0 left-0 h-1"
                  style={{
                    top: `${lineTop}%`,
                    y: parallaxYFast,
                  }}
                  animate={{
                    opacity: [0.2, 0.8, 0.2],
                    scaleX: [1, 1.5, 1],
                  }}
                  transition={{
                    duration: 2,
                    repeat: Infinity,
                    delay: i * 0.1,
                    ease: "easeInOut",
                  }}
                />
              )
            })}
          </div>
        </section>

        {/* Final Info Section */}
        <section className="bg-muted/30 flex min-h-screen items-center justify-center">
          <div className="mx-auto max-w-2xl space-y-4 p-8 text-center">
            <h2 className="text-foreground text-3xl font-bold">
              About Distorted Glass
            </h2>
            <p className="text-muted-foreground">
              The DistortedGlass component uses SVG filters with fractal noise
              to create a unique glass morphism effect.
            </p>
          </div>
        </section>
      </div>
    </div>
  )
}
```

DistortedGlass is an SVG filter component for React and shadcn/ui. Use it as a divider between landing page sections or under a sticky header to soften the transition.

## Installation

### CLI

```bash
npx shadcn@latest add @cult-ui/distorted-glass
```

### Manual

**Copy and paste the following code into your project.**

```tsx title="distorted-glass.tsx"
"use client"

import { cn } from "@/lib/utils"

export const DistortedGlass = ({ className }: { className?: string }) => {
  return (
    <>
      <div
        className={cn(
          "relative hidden h-[50px] w-[360px] overflow-hidden rounded-b-2xl lg:w-[600px] xl:block xl:w-full",
          className
        )}
      >
        <div className="pointer-events-none absolute bottom-0 z-10 size-full overflow-hidden rounded-b-2xl border border-[#f5f5f51a]">
          <div className="glass-effect size-full"></div>
        </div>
        <svg>
          <title>Distorted Glass</title>
          <defs>
            <filter id="fractal-noise-glass">
              <feTurbulence
                type="fractalNoise"
                baseFrequency="0.12 0.12"
                numOctaves="1"
                result="warp"
              ></feTurbulence>
              <feDisplacementMap
                xChannelSelector="R"
                yChannelSelector="G"
                scale="30"
                in="SourceGraphic"
                in2="warp"
              />
            </filter>
          </defs>
        </svg>
      </div>

      <style jsx>{`
        .glass-effect {
          background: rgba(0, 0, 0, 0.2);
          background: repeating-radial-gradient(
            circle at 50%50%,
            rgb(255 255 255 / 0),
            rgba(255, 255, 255, 0.2) 10px,
            rgb(255 255 255) 31px
          );
          filter: url(#fractal-noise-glass);
          background-size: 6px 6px;
          backdrop-filter: blur(0px);
        }
      `}</style>
    </>
  )
}
```

**Update the import paths to match your project setup.**

## Usage

```tsx
import { DistortedGlass } from "@/components/ui/distorted-glass";
```

### Basic Usage

```tsx
<DistortedGlass />
```

### Header Navigation Example

Use the distorted glass effect to create a smooth transition between header and content:

```tsx
<div className="rounded-lg border bg-white dark:bg-slate-900 overflow-hidden shadow-lg">
  <div className="flex h-14 items-center px-6 border-b">
    <div className="flex flex-1 items-center justify-between">
      <div className="flex items-center space-x-6">
        <span className="font-semibold">Logo</span>
        <nav className="hidden md:flex space-x-4">
          <span className="text-sm text-muted-foreground">Home</span>
          <span className="text-sm text-muted-foreground">About</span>
          <span className="text-sm text-muted-foreground">Contact</span>
        </nav>
      </div>
      <button className="text-sm px-4 py-2 rounded-md bg-primary text-primary-foreground">
        Sign In
      </button>
    </div>
  </div>
  <div className="relative w-full -mt-[17px]">
    <DistortedGlass />
  </div>
  <div className="p-8 space-y-4">
    <h3 className="text-xl font-semibold">Hero Section</h3>
    <p className="text-muted-foreground">
      The distorted glass effect creates a beautiful transition between the
      header and content areas.
    </p>
  </div>
</div>
```

### Content Overlay Example

Create a frosted glass effect over content:

```tsx
<div className="relative rounded-lg border overflow-hidden">
  <div className="aspect-video bg-gradient-to-r from-purple-400 via-pink-400 to-red-400 flex items-center justify-center">
    <div className="text-center space-y-2">
      <h3 className="text-3xl font-bold text-white">Beautiful Background</h3>
      <p className="text-white/80">Content visible through the glass effect</p>
    </div>
  </div>
  <div className="relative w-full -mt-[17px]">
    <DistortedGlass />
  </div>
  <div className="p-8 bg-white dark:bg-slate-900">
    <p className="text-muted-foreground">
      The distorted glass creates a frosted glass effect that provides visual
      separation while maintaining the connection to the content below.
    </p>
  </div>
</div>
```

### Standalone Example

Use as a decorative element between sections:

```tsx
<div className="rounded-lg border bg-white dark:bg-slate-900 overflow-hidden shadow-lg">
  <div className="p-8 space-y-4">
    <h3 className="text-xl font-semibold">Section Title</h3>
    <p className="text-muted-foreground">
      This is a content section with the distorted glass effect below it.
    </p>
  </div>
  <div className="relative w-full -mt-[17px]">
    <DistortedGlass />
  </div>
</div>
```

## API Reference

The `DistortedGlass` component is a presentational component with no props. It creates a glass morphism effect using SVG filters.

## Features

- **Glass Morphism Effect**: Uses SVG filters with fractal noise to create a unique glass-like appearance
- **Responsive**: Automatically hidden on smaller screens for optimal mobile experience
- **Performance Optimized**: Lightweight implementation using CSS and SVG filters
- **Visual Transitions**: Perfect for creating smooth transitions between sections
- **No Dependencies**: Pure CSS and SVG, no external dependencies required

## How It Works

The component uses an SVG filter with fractal noise (`feTurbulence`) combined with a displacement map (`feDisplacementMap`) to create the distorted glass effect. The effect is applied to a repeating radial gradient background to simulate the glass texture.

## Examples

### Between Card Sections

```tsx
<div className="rounded-lg border bg-white dark:bg-slate-900 overflow-hidden">
  <div className="p-8">
    <h2 className="text-2xl font-bold mb-4">Top Section</h2>
    <p className="text-muted-foreground">Content above the glass effect</p>
  </div>
  <div className="relative w-full -mt-[17px]">
    <DistortedGlass />
  </div>
  <div className="p-8 bg-white dark:bg-slate-900">
    <h2 className="text-2xl font-bold mb-4">Bottom Section</h2>
    <p className="text-muted-foreground">Content below the glass effect</p>
  </div>
</div>
```

### With Gradient Background

```tsx
<div className="relative rounded-lg overflow-hidden">
  <div className="h-64 bg-gradient-to-br from-blue-500 via-purple-500 to-pink-500 flex items-center justify-center">
    <h2 className="text-4xl font-bold text-white">Background Content</h2>
  </div>
  <div className="relative w-full -mt-[17px]">
    <DistortedGlass />
  </div>
  <div className="p-8 bg-white dark:bg-slate-900">
    <p>Content section with glass transition</p>
  </div>
</div>
```

## Notes

- The component is hidden on screens smaller than `xl` breakpoint for better mobile experience
- Use negative margin (`-mt-[17px]`) to overlap the glass effect with the content above
- The effect works best with contrasting backgrounds
- Ensure proper z-index layering when using with other elements
