Web InnoventixFreeCode

Dot Frame Effect

Original · free

A dotted border frame animates around the image on hover.

byWeb InnoventixReact + Tailwind
dotframeimageeffect
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-dot-frame.json
imgfx-dot-frame.tsx
"use client";

export default function ImgfxDotFrame() {
  return (
    <section className="relative w-full bg-neutral-50 px-6 py-20 dark:bg-neutral-950 sm:px-10 sm:py-28">
      <style>{`
        @keyframes imgfxDotFrame-march {
          to { stroke-dashoffset: -100; }
        }
        @keyframes imgfxDotFrame-draw {
          from { stroke-dashoffset: 900; }
          to { stroke-dashoffset: 0; }
        }
        .imgfxDotFrame-card:hover .imgfxDotFrame-march {
          animation: imgfxDotFrame-march 6s linear infinite;
          opacity: 1;
        }
        .imgfxDotFrame-card:hover .imgfxDotFrame-draw {
          animation: imgfxDotFrame-draw 0.9s cubic-bezier(0.65, 0, 0.35, 1) forwards;
          opacity: 1;
        }
        .imgfxDotFrame-card:hover .imgfxDotFrame-inset {
          transform: scale(1);
          opacity: 1;
        }
        .imgfxDotFrame-card:hover .imgfxDotFrame-photo {
          transform: scale(1.04);
        }
        .imgfxDotFrame-card:hover .imgfxDotFrame-corner {
          width: 30px;
          height: 30px;
        }
        @media (prefers-reduced-motion: reduce) {
          .imgfxDotFrame-card:hover .imgfxDotFrame-march,
          .imgfxDotFrame-card:hover .imgfxDotFrame-draw {
            animation: none;
            opacity: 1;
          }
          .imgfxDotFrame-card:hover .imgfxDotFrame-photo { transform: none; }
          .imgfxDotFrame-card:hover .imgfxDotFrame-inset { transform: none; }
          .imgfxDotFrame-card:hover .imgfxDotFrame-corner { width: 20px; height: 20px; }
        }
      `}</style>

      <div className="mx-auto max-w-3xl">
        <p className="mb-3 text-xs font-semibold uppercase tracking-[0.28em] text-indigo-600 dark:text-indigo-400">
          Image Effect / Dot Frame
        </p>
        <h2 className="mb-10 text-2xl font-semibold tracking-tight text-neutral-900 dark:text-neutral-50 sm:text-3xl">
          A dotted border traces the frame on hover
        </h2>

        <div className="imgfxDotFrame-card group relative mx-auto aspect-[4/3] w-full max-w-2xl cursor-pointer select-none">
          {/* Photo */}
          <div className="absolute inset-[14px] overflow-hidden rounded-lg bg-neutral-200 shadow-sm dark:bg-neutral-800">
            {/* eslint-disable-next-line @next/next/no-img-element */}
            <img
              src="/img/gallery/g14.webp"
              alt="Sunlit architectural facade with repeating geometric windows"
              loading="lazy"
              draggable={false}
              className="imgfxDotFrame-photo h-full w-full object-cover transition-transform duration-[900ms] ease-out"
            />
            {/* Inset accent frame */}
            <span
              className="imgfxDotFrame-inset pointer-events-none absolute inset-3 origin-center scale-95 rounded border border-white/70 opacity-0 transition-all duration-500 ease-out"
              aria-hidden="true"
            />
          </div>

          {/* Dotted animated frame */}
          <svg
            className="pointer-events-none absolute inset-0 h-full w-full"
            viewBox="0 0 400 300"
            preserveAspectRatio="none"
            fill="none"
            aria-hidden="true"
          >
            {/* Static faint guide */}
            <rect
              x="3"
              y="3"
              width="394"
              height="294"
              rx="10"
              className="stroke-neutral-300 dark:stroke-neutral-700"
              strokeWidth="1.5"
              strokeDasharray="1 9"
              strokeLinecap="round"
              vectorEffect="non-scaling-stroke"
            />
            {/* Marching dots */}
            <rect
              className="imgfxDotFrame-march stroke-indigo-500 opacity-0 transition-opacity duration-300 dark:stroke-indigo-400"
              x="3"
              y="3"
              width="394"
              height="294"
              rx="10"
              strokeWidth="2"
              strokeDasharray="1 9"
              strokeLinecap="round"
              vectorEffect="non-scaling-stroke"
            />
            {/* Drawing solid trace */}
            <rect
              className="imgfxDotFrame-draw stroke-indigo-500 opacity-0 transition-opacity duration-300 dark:stroke-violet-400"
              x="3"
              y="3"
              width="394"
              height="294"
              rx="10"
              strokeWidth="2"
              strokeDasharray="900"
              strokeDashoffset="900"
              strokeLinecap="round"
              vectorEffect="non-scaling-stroke"
            />
          </svg>

          {/* Corner brackets */}
          <span className="imgfxDotFrame-corner absolute left-0 top-0 h-5 w-5 rounded-tl-lg border-l-2 border-t-2 border-indigo-500 transition-all duration-500 ease-out dark:border-indigo-400" aria-hidden="true" />
          <span className="imgfxDotFrame-corner absolute right-0 top-0 h-5 w-5 rounded-tr-lg border-r-2 border-t-2 border-indigo-500 transition-all duration-500 ease-out dark:border-indigo-400" aria-hidden="true" />
          <span className="imgfxDotFrame-corner absolute bottom-0 left-0 h-5 w-5 rounded-bl-lg border-b-2 border-l-2 border-indigo-500 transition-all duration-500 ease-out dark:border-indigo-400" aria-hidden="true" />
          <span className="imgfxDotFrame-corner absolute bottom-0 right-0 h-5 w-5 rounded-br-lg border-b-2 border-r-2 border-indigo-500 transition-all duration-500 ease-out dark:border-indigo-400" aria-hidden="true" />
        </div>

        <p className="mt-8 text-center text-sm text-neutral-500 dark:text-neutral-400">
          Hover the photo — the dotted border marches while the corners reach out.
        </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 →