react-components
Scroll in View Trigger

Scroll-Into-View Animation Guide

This guide walks through the process of creating a scroll-into-view triggered animation using Next.js (in TypeScript), TailwindCSS. The animation is a gradient text animation that is triggered when the text is scrolled into view which can be seen here.

Scroll into view gif react hook Live Demo: Here/ (opens in a new tab)

Source code (opens in a new tab)https://github.com/remcostoeten/remco-tools/tree/master/hooks/UseInView.tsx (opens in a new tab)

Steps

1. Create

In the hooks folder, create a file named useInView.tsx:

'use client';
go
import { useState, useEffect, Ref } from 'react';
 
interface Options extends IntersectionObserverInit {
  freezeOnceVisible?: boolean;
}
 
function useInView(options: Options): [Ref<any>, boolean] {
  const [ref, setRef] = useState<Element | null>(null);
  const [isVisible, setIsVisible] = useState<boolean>(false);
 
  useEffect(() => {
    const observer = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setIsVisible(true);
        console.log("Element is in view!");
        if (options.freezeOnceVisible) {
          observer.unobserve(entry.target);
        }
      } else {
        setIsVisible(false);
        console.log("Element is out of view!");
      }
    }, options);
 
    if (ref) {
      observer.observe(ref);
    }
 
    return () => {
      if (ref) {
        observer.unobserve(ref);
      }
    };
  }, [ref, options]);
 
  return [setRef, isVisible];
}
 
export default useInView;```
 
### 2. Create the Animation Component
 
In the `components` folder create `AnimatedText.tsx`:
 
```tsx filename="AnimatedText.tsx"
'use client';
 
import React from 'react';
import useInView from '../hooks/useInView';  // Adjust the path as necessary
 
interface AnimatedTextProps {
  text: string;
  italic?: boolean;
}
 
const AnimatedText: React.FC<AnimatedTextProps> = ({ text, italic = false }) => {
  const [ref, inView] = useInView({
    threshold: 0.1,
    freezeOnceVisible: true
  });
 
  const animationClass = inView ? 'animate-gradient-text' : '';
 
  return (
    <span ref={ref} className={`gradient-text ${animationClass} ${italic ? 'italic' : ''}`}>
      {text}
    </span>
  );
}
 
export default AnimatedText;

3. Style the Animation

@keyframes gradienText {
    50% {
        background-size: 200% 4px;
    }
    100% {
        background-position: 0 100%;
    }
}
 
@keyframes gradientTextGrow {
    0% {
        width: 0;
    }
    100% {
        width: 100%;
    }
}

4. Use the Animation Component

'use client';
 
import AnimatedText from '@/components/AnimatedText';
 
function SomeComponent() {
  return (
    <div className="my-page-content p-4 screen-h border ">
      Scroll down to see the animation:
    </div>
    <div className='screen-h p-4 border'>
        <AnimatedText text="Passion" />
    </div>
  );
}
 
export default SomeComponent;