DocsDeveloper

Reveal

Overview

The Reveal component utilizes the Framer Motion library for animation and the React Intersection Observer hook to detect when the component comes into view. It provides a smooth transition by gradually revealing or moving the child elements based on the specified direction, duration and delay. That's triple D's right there! I use this component and variations similar, accross this entire site!

Demo

JRui

JRui the mascot!

Say hello to Jrui! He's the mascot of these parts!

SCooty

Scooty the mascot!

Say hello to Scooty! She's Jrui's step-sis!

TOoty

Tooty the mascot!

Say hello to Tooty! He's Jrui's step-bro!

Easy CLI Install

jrui add reveal

Props

The `Reveal` component accepts the following props for controlling its animation behavior:

  • direction?: "up" | "down" | "left" | "right" (default: "up")
    This prop determines the direction from which the component will be revealed. Possible values: "up", "down", "left", or "right".
  • delay?: number (default: 0.2)
    Specifies the delay before the animation starts after the component comes into view. Measured in seconds.
  • duration?: number (default: 0.5)
    Determines the duration of the animation. Measured in seconds.
  • children: ReactNode:
    Required prop representing the content that you want to animate.
  • className?: string:
    Prop for adding custom classes to the animated component for styling purposes.

Props Demo

JRui

Component File

components > Reveal.tsx

"use client";
import React, { FC, ReactNode, useEffect } from "react";
import { motion, useAnimation } from "framer-motion";
import { useInView } from "react-intersection-observer";

interface RevealProps {
  direction?: "up" | "down" | "left" | "right";
  delay?: number;
  duration?: number;
  children: ReactNode;
  className?: string;
}

const Reveal: FC<RevealProps> = ({
  direction = "up",
  delay = 0.2,
  duration = 0.5,
  children,
  className,
}) => {
  const controls = useAnimation();
  const [ref, inView] = useInView({
    triggerOnce: true,
  });

  useEffect(() => {
    if (inView) {
      controls.start({
        opacity: 1,
        y: 0,
        x: 0,
        transition: { duration: duration, delay },
      });
    }
  }, [controls, inView, delay]);

  // Set initial styles before the animation
  const initialStyles = {
    opacity: 0,
    y: direction === "up" ? 20 : direction === "down" ? -20 : 0,
    x: direction === "left" ? 20 : direction === "right" ? -20 : 0,
  };

  return (
    <motion.Reveal
      className={className}
      ref={ref}
      initial={initialStyles}
      animate={controls}
    >
      {children}
    </motion.Reveal>
  );
};

export default Reveal;
              
              

Example Use Case

Example.tsx

import React from "react";
import Reveal from "./Reveal"; // Adjust the import path based on your project structure

const Example: React.FC = () => {
  return (
    <Reveal>
      <h1>Your Content Before Reveal</h1>

      {/* Example with default settings (up direction, default delay) */}
      <Reveal>
        <p>This content will be revealed with default settings.</p>
      </Reveal>

      {/* Example with custom direction (right) and delay */}
      <Reveal direction="right" delay={0.5}>
        <p>This content will be revealed from the right with a delay of 0.5 seconds.</p>
      </Reveal>

      {/* Example with custom direction (down) and no delay */}
      <Reveal direction="down">
        <p>This content will be revealed from the bottom with no delay.</p>
      </Reveal>

      {/* Example with custom direction (left), duration and custom class name */}
      <Reveal duration={1} direction="left" className="ligma-nutz">
        <p>This content will be revealed from the left with default delay.</p>
      </Reveal>

      <h1>Your Content After Reveal</h1>
    </Reveal>
  );
};

export default Example;