Web InnoventixFreeCode

Curtain Left Effect

Original · free

A colour curtain wipes left to reveal the image on hover.

byWeb InnoventixReact + Tailwind
curtainleftimageeffect
Open

Copy prompt gives Claude Code, Cursor or v0 a ready-to-paste prompt that recreates this exact component.

npx shadcn@latest add https://webinnoventix.com/r/imgfx-curtain-left.json
imgfx-curtain-left.tsx
"use client";

export default function ImgFxCurtainLeft() {
  return (
    <section className="relative w-full bg-slate-50 px-6 py-20 dark:bg-slate-950 sm:px-10 sm:py-28">
      <style>{`
        @keyframes imgfx-curtain-left-sheen {
          0% { transform: translateX(-120%) skewX(-12deg); }
          100% { transform: translateX(220%) skewX(-12deg); }
        }
        @media (prefers-reduced-motion: reduce) {
          .imgfx-curtain-left-panel,
          .imgfx-curtain-left-img,
          .imgfx-curtain-left-sheen { transition: none !important; animation: none !important; }
          .imgfx-curtain-left-group:hover .imgfx-curtain-left-panel { transform: translateX(-100%); }
        }
      `}</style>

      <div className="mx-auto max-w-2xl">
        <div className="mb-8 text-center">
          <p className="text-xs font-semibold uppercase tracking-[0.28em] text-indigo-600 dark:text-indigo-400">
            Image Effect
          </p>
          <h2 className="mt-3 text-2xl font-bold tracking-tight text-slate-900 dark:text-slate-50 sm:text-3xl">
            Curtain Wipe Left
          </h2>
          <p className="mt-3 text-sm text-slate-500 dark:text-slate-400">
            A colour curtain slides away to the left, revealing the photo beneath.
          </p>
        </div>

        <figure className="imgfx-curtain-left-group group relative isolate mx-auto aspect-[4/5] w-full overflow-hidden rounded-2xl shadow-xl ring-1 ring-slate-900/10 dark:ring-white/10">
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src="/img/gallery/g14.webp"
            alt="Framed studio portrait revealed as the colour curtain retreats"
            loading="lazy"
            draggable={false}
            className="imgfx-curtain-left-img absolute inset-0 h-full w-full scale-105 object-cover transition-transform duration-[900ms] ease-[cubic-bezier(0.22,1,0.36,1)] group-hover:scale-100"
          />

          {/* Colour curtain */}
          <div
            aria-hidden="true"
            className="imgfx-curtain-left-panel pointer-events-none absolute inset-0 z-10 overflow-hidden bg-gradient-to-br from-indigo-500 via-violet-600 to-fuchsia-600 transition-transform duration-[900ms] ease-[cubic-bezier(0.83,0,0.17,1)] will-change-transform group-hover:-translate-x-full dark:from-indigo-600 dark:via-violet-700 dark:to-fuchsia-700"
          >
            {/* leading accent edge */}
            <span className="absolute inset-y-0 left-0 w-[3px] bg-white/70 shadow-[0_0_24px_6px_rgba(255,255,255,0.45)]" />
            {/* moving sheen */}
            <span className="imgfx-curtain-left-sheen absolute inset-y-0 left-0 w-1/3 bg-gradient-to-r from-transparent via-white/25 to-transparent [animation:imgfx-curtain-left-sheen_3.2s_ease-in-out_infinite]" />
            {/* curtain label */}
            <span className="absolute inset-0 flex items-center justify-center">
              <span className="text-xs font-semibold uppercase tracking-[0.3em] text-white/90">
                Hover to reveal
              </span>
            </span>
          </div>

          {/* trailing edge shadow for depth as curtain lifts */}
          <div
            aria-hidden="true"
            className="pointer-events-none absolute inset-0 z-0 bg-gradient-to-l from-transparent via-transparent to-slate-950/20"
          />

          <figcaption className="absolute bottom-0 left-0 right-0 z-20 translate-y-2 bg-gradient-to-t from-slate-950/70 to-transparent px-4 pb-3 pt-10 text-sm font-medium text-white opacity-0 transition-all duration-500 group-hover:translate-y-0 group-hover:opacity-100">
            Portrait 14 · natural light
          </figcaption>
        </figure>

        <p className="mt-6 text-center text-xs text-slate-400 dark:text-slate-500">
          Hover the frame to sweep the curtain aside.
        </p>
      </div>
    </section>
  );
}

Dependencies

None (React + Tailwind only).

Licence

Built by Web Innoventix. Free for personal and commercial use, no attribution required.

Built by Web Innoventix

Need a custom interface, a full website, or SEO that gets you cited by AI? We design, build and rank it end to end.

Get a free quote

Similar components

Browse all →