Chamaac
Components
  • Overview

    • Introduction
  • Gallery

    • CarouselNew
  • Animated Icons
    • CopyNew
    • WavyNew
    • AdjustmentsNew
  • Buttons

    • Slide Up Button
  • Navigation

    • Dock
  • Cards

    • Random Image Reveal
    • Orbiting IconsNew

Random Image Reveal

A card component that reveals a random image on hover with smooth animations, as the image card rotates and moves upward.

Reveal card image

Installation

Install Dependencies

npm install motion

Component Code

Copy and paste the component code into your project.

"use client";

import { motion } from "motion/react";
import { useState } from "react";
import Image from "next/image";

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

interface RandomImageRevealProps {
  images: string[];
  duration?: number;
  className?: string;
  width?: string;
  height?: string;
  innerWidth?: string;
  innerHeight?: string;
}

const RandomImageReveal = ({
  images,
  duration = 0.3,
  className,
  width = "350px",
  height = "270px",
  innerWidth = "200px",
  innerHeight = "135px",
}: RandomImageRevealProps) => {
  const [isHovered, setIsHovered] = useState<boolean>(false);
  const [currentImage, setCurrentImage] = useState(images[0] || "");

  const getRandomImage = () => {
    if (images.length > 0) {
      const randomIndex = Math.floor(Math.random() * images.length);
      setCurrentImage(images[randomIndex]);
    }
  };

  return (
    <motion.div
      onHoverStart={() => {
        setIsHovered(true);
        getRandomImage();
      }}
      onHoverEnd={() => setIsHovered(false)}
      style={{ width, height }}
      className={cn(
        "relative bg-white dark:bg-black border border-neutral-200 dark:border-neutral-800 rounded-4xl  cursor-pointer",
        className
      )}
    >
      <div className="absolute top-30/100 bottom-0 left-0 right-0 backdrop-blur-sm rounded-4xl z-10 border border-neutral-200 dark:border-neutral-800" />

      <motion.div
        animate={{
          rotate: isHovered ? -15 : 15,
          y: isHovered ? -200 : 0,
          scale: isHovered ? 1.2 : 1,
        }}
        transition={{
          duration: duration,
          ease: "easeIn",
        }}
        style={{ width: innerWidth, height: innerHeight }}
        className="absolute top-40/100 rounded-3xl left-1/2 -translate-x-1/2 overflow-hidden"
      >
        <Image
          src={currentImage}
          alt="Reveal card image"
          fill
          className="object-cover"
          sizes="300px"
          priority={true}
        />
      </motion.div>
    </motion.div>
  );
};

export default RandomImageReveal;

Props

PropTypeDefaultDescription
images*string[]-Array of image paths to randomly display on hover
durationnumber0.2The duration of the animation transition in seconds
classNamestring""Custom class names for styling the card container
widthstring"350px"Width of the outer card container
heightstring"270px"Height of the outer card container
innerWidthstring"200px"Width of the inner revealing image
innerHeightstring"135px"Height of the inner revealing image