loading
Just a moment.

Scroll Reveal Animation

November 2024

    import React, { useEffect, useRef, useState } from 'react';
    
    interface IconProps {
      className?: string;
    }
    
    const StarFilledIcon = (props: IconProps) => {
      return (
        <svg
          xmlns="http://www.w3.org/2000/svg"
          fill="none"
          viewBox="0 0 24 24"
          strokeWidth={1.5}
          stroke="currentColor"
          className={props.className}
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
          />
        </svg>
      );
    };
    
    export default function ScrollRevealAnimationCSS() {
      const containerRef = useRef(null);
    
      const [githubFollower, setGithubFollower] = useState<
        {
          id: number;
          name: string;
          avatar: string;
          randomStar: number;
        }[]
      >([]);
    
      useEffect(() => {
        const fetchLast20GithubFollowers = async () => {
          try {
            const response = await fetch(
              'https://api.github.com/users/zkxdex/followers'
            );
            const data = await response.json();
    
            const newGithubFollowers = data
              // eslint-disable-next-line @typescript-eslint/no-explicit-any
              .map((follower: any) => {
                return {
                  id: follower.id,
                  name: follower.login,
                  avatar: follower.avatar_url,
                  randomStar: Math.floor(Math.random() * 90) + 10,
                };
              })
              .slice(0, 20);
    
            setGithubFollower(newGithubFollowers);
          } catch (error) {
            console.error(error);
          }
        };
    
        fetchLast20GithubFollowers();
      }, []);
    
      return (
        <>
          <div
            className="h-[500px] w-full overflow-y-scroll p-4"
            ref={containerRef}
          >
            <ul className="flex w-full flex-col space-y-2 pb-[10%] p-0">
              {githubFollower?.map((item) => {
                return (
                  <li
                    key={item.id}
                    className="items flex items-center justify-between rounded-xl bg-primary-light-5 bg-opacity-50 px-2 py-2 backdrop-blur-xl dark:bg-primary-dark-5"
                  >
                    <div className="flex items-center">
                      <img
                        src={item.avatar}
                        alt="Avatar"
                        className="h-8 w-8 rounded-full"
                      />
                      <span className="ml-2 text-sm text-primary-light-12 dark:text-primary-dark-12">
                        {item.name}
                      </span>
                    </div>
                    <div className="flex items-end">
                      <StarFilledIcon className="h-4 w-4 text-primary-light-9 dark:text-primary-dark-9" />
                      <span className="ml-1 text-xs text-primary-light-11 dark:text-primary-dark-11">
                        {item.randomStar}
                      </span>
                    </div>
                  </li>
                );
              })}
            </ul>
          </div>
          <style jsx>{`
            @keyframes appear {
              from {
                filter: blur(2px);
                scale: 0.95;
              }
              to {
                opacity: 1;
                filter: blur(0);
                scale: 1;
              }
            }
    
            .items {
              animation: appear linear both;
              animation-timeline: view();
              animation-range: entry cover 20%;
            }
          `}</style>
        </>
      );
    }