DEV Community

Cover image for Animate on scroll
karam koujan
karam koujan

Posted on

Animate on scroll

Introduction

Animation on scroll is a feature that we see often on modern websites, it grabs user attention and add interactivity to your web application rather than just a static page.

In this article I am going to show you how to implement on-scroll animation using the intersection observer api.

Intersection Observer API

The Intersection Observer API provides a way to asynchronously observe changes in the intersection of a target element with an ancestor element or with the viewport, It used for lazy loading Images, infinite scrolling and on-scroll animation. For more information about this api you can check the docs.

A Simple example

I created three section, Each one is going to fade in when we intersect with it.

<section class="hidden">
 <h2>title 1</h2>
</section>
<section class="hidden">
 <h2>title 2</h2>
</section>
<section class="hidden">
 <h2>title 2</h2>
</section>
Enter fullscreen mode Exit fullscreen mode
h2{
    color: #4b6cc1;
}
.hidden{
    display: flex;
    padding-block:15rem ;
    flex-direction: column;
    opacity: 0;
    transition: opacity 1s .5s ease-in;
}
Enter fullscreen mode Exit fullscreen mode
const targets = document.querySelectorAll(".hidden")
const options = {
    root : null,
    threshold:0.5
}

const callback = (entries)=>{
    console.log(entries)
    entries.forEach(entry => {
          if(entry.isIntersecting){
            entry.target.classList.add("show")
          }else{
            entry.target.classList.remove("show")
          }
    });

}
const observer = new IntersectionObserver(callback,options)

targets.forEach(target=>observer.observe(target))
Enter fullscreen mode Exit fullscreen mode
.show{
 opacity:1;
 }
Enter fullscreen mode Exit fullscreen mode

we will get all elements that have class "hidden" and add the "show" class to the element that intersects with 50% of the viewport, that’s what 0.5 in the threshold means.

Demo

Intersection Observer API as react hook

This is the react version

import {useState,useRef,useEffect} from "react"
export const useOnScreen = (options)=>{
    const ref = useRef(null);
    const [isVisible,setIsVisible] = useState(false)

   useEffect(()=>{
     const observer = new IntersectionObserver(([entry])=>{
         if(entry.isIntersecting){
         setIsVisible(true)         
         }
     },options)
     if(ref.current){
         observer.observe(ref.current)
     }
     return ()=> ref.current ? observer.unobserve(ref.current):null

   },[ref,options])

   return [isVisible,ref]
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)