Scroll Reveal Animation
November 2024
TSX
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>
</>
);
}