Baktiyar Ablaikhan

Liquid Glass

Source
Aceternity UI ↗
Author
Aceternity UI
Licence
Aceternity UI licence (free component)

Loading…

A draggable glass lens refracts the photo behind it through an SVG displacement filter.

Code

"use client";

import { useRef } from "react";
import { motion, useReducedMotion } from "motion/react";
import { LiquidGlass } from "@/lab/aceternity/ui/liquid-glass";

const SIZE = 150;

export default function LiquidGlassDemo() {
  const constraintsRef = useRef<HTMLDivElement>(null);
  const reduceMotion = useReducedMotion();

  return (
    <div
      ref={constraintsRef}
      className="relative h-full w-full overflow-hidden bg-neutral-900 [container-type:inline-size]"
    >
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src="https://assets.aceternity.com/screenshots/colourful-office.webp"
        alt=""
        className="absolute inset-0 size-full object-cover"
        draggable={false}
      />
      <div className="pointer-events-none absolute inset-0 flex flex-col items-center justify-center p-[5%] text-center select-none">
        <p className="text-[clamp(2rem,11cqw,6rem)] leading-[0.95] font-bold tracking-tighter text-white">
          Bend the
          <br />
          light.
        </p>
        <div className="mt-[4cqw] grid w-full max-w-md grid-cols-12 gap-1.5">
          {Array.from({ length: 48 }).map((_, i) => (
            <span key={i} className="h-1.5 rounded-full bg-white/80" />
          ))}
        </div>
      </div>

      <motion.div
        drag
        dragConstraints={constraintsRef}
        dragElastic={0.1}
        whileDrag={reduceMotion ? undefined : { scale: 1.04 }}
        className="absolute top-1/2 left-1/2 cursor-grab touch-none active:cursor-grabbing"
        style={{
          width: SIZE,
          height: SIZE,
          marginLeft: -SIZE / 2,
          marginTop: -SIZE / 2,
        }}
        initial={reduceMotion ? false : { x: -60, y: -20 }}
        animate={{ x: 0, y: 0 }}
        transition={{ type: "spring", stiffness: 60, damping: 12, delay: 0.3 }}
      >
        <LiquidGlass
          radius={SIZE / 2}
          scale={48}
          aberration={14}
          bevelDepth={30}
          frost={0.4}
          tint={0.12}
          className="size-full shadow-[0_12px_40px_rgb(0_0_0/0.25),inset_0_1px_0_rgb(255_255_255/0.5)]"
        />
      </motion.div>
      <p className="pointer-events-none absolute bottom-3 left-0 w-full text-center font-mono text-[11px] tracking-wide text-white/80">
        drag the lens
      </p>
    </div>
  );
}
Prompt

Build "Liquid Glass", a other animation. What it does: A draggable glass lens refracts the photo behind it through an SVG displacement filter. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS, using motion. Technique: an HTML canvas, the Motion library, inline SVG. It sits on a dark background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://ui.aceternity.com/components/liquid-glass (Aceternity UI, Aceternity UI licence (free component)).