Day13 要做的是類似視差滾動的圖片效果
const images = [
{ src: "https://unsplash.it/400/400", alt: "Placeholder 1" },
{ src: "https://unsplash.it/400/320", alt: "Placeholder 2" },
{ src: "https://unsplash.it/300/300", alt: "Placeholder 3" },
];
export default function SlideInImages() {
return (
<div className="min-h-screen bg-gradient-to-br from-blue-100 to-purple-100 p-8">
<h1 className="text-4xl font-bold mb-8 text-center text-gray-800 bg-white bg-opacity-50 py-4 rounded-lg shadow-md">
Slide In on Scroll
</h1>
<div className="space-y-64 md:space-y-96">
{images.map((image, index) => (
<div
key={index}
className="min-h-fit flex items-center justify-center p-4 bg-white bg-opacity-30 rounded-xl shadow-xl"
>
<Image src={image.src} alt={image.alt} />
</div>
))}
</div>
</div>
);
}
可以用 Intersection Observer API 來處理
function Image({ src, alt }: ImagePropsType) {
const [isVisible, setIsVisible] = useState(false);
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
setIsVisible(entry.isIntersecting);
});
},
{ threshold: 0.1 }
);
const refCallback = useCallback((node: HTMLImageElement | null) => {
if (node !== null) {
observer.observe(node);
}
return () => {
observer.disconnect();
};
}, []);
return (
<img
ref={refCallback}
src={src}
alt={alt}
className={`
transition-all duration-500 ease-out
rounded-lg shadow-lg
${
isVisible
? "opacity-100 translate-x-0 rotate-0 scale-100"
: "opacity-0 translate-x-full rotate-12 scale-90"
}
`}
/>
);
}