iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0

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 來處理

    • threshold 設定當圖片出現 10% 的時候再出現
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"
        }
      `}
    />
  );
}

DEMO

https://codesandbox.io/p/devbox/3lcwz6


上一篇
[Day12]_Key-Sequence-Detection
下一篇
[Day14]_JavaScript-References-VS-Copying
系列文
React30——用 React 探索 JavaScript30 的魅力17
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言