diff --git a/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx b/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx index 957b58c0..d6d053c9 100644 --- a/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx +++ b/src/forge/Information/Pages/homepage/component/newsByNSCC.jsx @@ -19,6 +19,11 @@ function News(props) { const [activeDirId, setActiveDirId] = useState(undefined); const [total, setTotal] = useState(0); const newsSectionRef = useRef(null); + const topBoxRef = useRef(null); + const [hasAppended, setHasAppended] = useState(false); + const [activeIndex, setActiveIndex] = useState(0); + const scrollIndexRef = useRef(0); + const scrollTimerRef = useRef(null); useEffect(() => { let hasAnimated = false; // 标记动画是否已触发 @@ -61,7 +66,7 @@ function News(props) { setDocListByFirstDir(data) }) - getPointsDoc(rows[1].id); + getPointsDoc(); } }) }, [id]) @@ -72,8 +77,82 @@ function News(props) { }, (data)=>{setTotal(data)}) }, [activeDirId]) - async function getPointsDoc(rowId) { - let res = await + // 监控topBox高度,当高度>593时复制docListBySecondDir追加到自身 + useEffect(() => { + if (!topBoxRef.current || !docListBySecondDir.length) return; + + const observer = new ResizeObserver((entries) => { + for (const entry of entries) { + const height = entry.contentRect.height; + if (height > 593 && !hasAppended) { + setDocListBySecondDir(prev => [...prev, ...docListBySecondDir]); + setHasAppended(true); + // 滚动动画由hasAppended变化触发的useEffect自动启动 + } + } + }); + + observer.observe(topBoxRef.current); + + return () => { + observer.disconnect(); + }; + }, [docListBySecondDir, hasAppended]) + + // 滚动动画:每隔3秒将下一个docBySecondDir_NSCC元素滚动到topBox顶部 + useEffect(() => { + if (!hasAppended || !topBoxRef.current) return; + + const topBox = topBoxRef.current; + scrollIndexRef.current = 0; + // 给topBox添加transition实现平滑动画 + topBox.style.transition = 'transform 0.5s linear'; + + scrollTimerRef.current = setInterval(() => { + const items = topBox.querySelectorAll('.docBySecondDir_NSCC'); + if (!items.length) return; + + const targetIndex = scrollIndexRef.current % items.length; + + // 计算目标元素之前所有元素的总高度(含margin),作为translateY偏移量 + let offset = 0; + for (let i = 0; i < targetIndex; i++) { + offset += items[i].offsetHeight; + const styles = window.getComputedStyle(items[i]); + offset += parseFloat(styles.marginBottom) || 0; + } + topBox.style.transform = `translateY(-${offset}px)`; + + // 滚动到第一个复制元素时,等待动画完成后瞬间重置offset为0,实现无缝循环 + if (targetIndex === docListBySecondDir.length / 2) { + setActiveIndex((targetIndex + 1) % (docListBySecondDir.length / 2)); + setTimeout(() => { + topBox.style.transition = 'none'; + topBox.style.transform = 'translateY(0)'; + void topBox.offsetWidth; + topBox.style.transition = 'transform 0.5s linear'; + setActiveIndex(1); + }, 500); + scrollIndexRef.current = 0; + } else { + setActiveIndex((targetIndex + 1) % (docListBySecondDir.length / 2)); + } + + scrollIndexRef.current++; + }, 3000); + + return () => { + if (scrollTimerRef.current) { + clearInterval(scrollTimerRef.current); + scrollTimerRef.current = null; + } + // 清理时恢复topBox样式 + topBox.style.transition = ''; + topBox.style.transform = ''; + }; + }, [hasAppended]) + + function getPointsDoc() { getPointsDocList(id).then(result=>{ let docList = []; if(result && Array.isArray(result.data.data) && result.data.data.length){ @@ -85,7 +164,6 @@ function News(props) { return item; }); } - setDocListBySecondDir(docList); }); } @@ -132,18 +210,28 @@ function News(props) { {secondDir &&
- {window.scrollTo(0,450)}}>{item.name} -
-+ {window.scrollTo(0,450)}}>{item.name} +
+