From a3a7602e9ea547d888e1acc069d19aef0d35e70b Mon Sep 17 00:00:00 2001 From: buyfakett Date: Wed, 8 Jan 2025 22:39:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E7=89=87=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Pictures/index.jsx | 163 ++++++++++++++++++++++-------- 1 file changed, 122 insertions(+), 41 deletions(-) diff --git a/src/components/Pictures/index.jsx b/src/components/Pictures/index.jsx index 2321c2a..f8c05cc 100644 --- a/src/components/Pictures/index.jsx +++ b/src/components/Pictures/index.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import { motion } from 'framer-motion'; import { apiList, pageVariants } from '../../config'; import { Button, Empty, Image, Spin } from '@douyinfe/semi-ui'; @@ -14,8 +14,18 @@ const Pictures = () => { const [pictureList, setPictureList] = useState({ urls: [], count: 0 }); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [displayCount, setDisplayCount] = useState(10); - const PHOTOS_PER_LOAD = 10; + const PHOTOS_PER_LOAD = 5; + const PHOTOS_PER_ROW = 3; // 假设每行显示3张图片 + const observerRef = useRef(null); + const loadTriggerRef = useRef(null); + + // 计算图片在一行中应该占据的宽度百分比 + const calculateImageWidth = (width, height) => { + const aspectRatio = width / height; + return `${aspectRatio * 30}%`; // 基础高度为30%,根据宽高比调整宽度 + }; // 获取图片列表 useEffect(() => { @@ -51,7 +61,9 @@ const Pictures = () => { img.onerror = resolve; }); setLoadedPhotos((prevPhotos) => { - if (!prevPhotos.some(photo => photo.url === photoData.url)) { + if ( + !prevPhotos.some((photo) => photo.url === photoData.url) + ) { return [...prevPhotos, photoData]; } return prevPhotos; @@ -62,18 +74,23 @@ const Pictures = () => { loadImages(); }, [currentIndex, pictureList.urls]); - // 无限滚动触发逻辑 + // 修改无限滚动触发逻辑 useEffect(() => { - const handleScroll = () => { - const { scrollTop, scrollHeight, clientHeight } = - document.documentElement; - const footerHeight = - document.querySelector('footer')?.offsetHeight || 0; + if (!pictureList?.urls?.length) return; + + const options = { + root: null, + rootMargin: '0px', + threshold: 0.1, + }; - if (scrollTop + clientHeight >= scrollHeight - footerHeight - 100) { + const handleIntersection = (entries) => { + const entry = entries[0]; + if (entry.isIntersecting) { setCurrentIndex((prevIndex) => { const newIndex = prevIndex + PHOTOS_PER_LOAD; if (newIndex < pictureList.count) { + setDisplayCount((prev) => prev + PHOTOS_PER_LOAD); return newIndex; } return prevIndex; @@ -81,11 +98,28 @@ const Pictures = () => { } }; - window.addEventListener('scroll', handleScroll); + observerRef.current = new IntersectionObserver( + handleIntersection, + options, + ); + + if (loadTriggerRef.current) { + observerRef.current.observe(loadTriggerRef.current); + } + return () => { - window.removeEventListener('scroll', handleScroll); + if (observerRef.current) { + observerRef.current.disconnect(); + } }; - }, [pictureList]); + }, [pictureList, displayCount]); + + // 计算触发加载的元素位置 + const getTriggerElementIndex = () => { + const totalDisplayed = Math.min(displayCount, pictureList.urls.length); + const rowCount = Math.ceil(totalDisplayed / PHOTOS_PER_ROW); + return Math.max(0, (rowCount - 2) * PHOTOS_PER_ROW - 1); + }; return ( {
- {loadedPhotos.map((photo, index) => ( - - {`Photo ( + - console.log('图片信息: ', photo) + animate={ + loadedPhotos.some( + (p) => p.url === photo.url, + ) + ? { + opacity: 1, + x: 0, + scale: 1, + } + : { + opacity: 0, + x: -20, + scale: 0.98, + } } - preview - /> - - ))} + transition={{ + duration: 0.3, + ease: 'easeOut', + delay: loadedPhotos.some( + (p) => p.url === photo.url, + ) + ? 0.1 + : 0, + }} + whileHover={{ scale: 1.05 }} + whileTap={{ scale: 0.95 }} + style={{ + width: calculateImageWidth( + photo.width, + photo.height, + ), + aspectRatio: `${photo.width} / ${photo.height}`, + minWidth: '300px', + maxWidth: '800px', + }}> + {loadedPhotos.some( + (p) => p.url === photo.url, + ) ? ( + {`Photo + console.log('图片信息: ', photo) + } + preview + /> + ) : ( +
+ )} + + ))}
)}