优化动图

This commit is contained in:
2025-10-23 10:30:43 +08:00
parent 77bc2c5775
commit 590b26c420
10 changed files with 254 additions and 49 deletions
@@ -46,9 +46,14 @@ export function useBackgroundCanvas({
} else {
const scroller = scrollerRef.current;
if (scroller) {
const currentImgContainer = scroller.children[idx] as HTMLElement;
if (currentImgContainer) {
sourceElement = currentImgContainer.querySelector("img");
// 虚拟滚动:查找所有图片容器,找到当前显示的那个
const containers = scroller.querySelectorAll<HTMLElement>('div[style*="translateX"]');
for (const container of containers) {
const img = container.querySelector("img, video");
if (img && container.style.transform.includes(`${idx * 100}%`)) {
sourceElement = img as HTMLImageElement | HTMLVideoElement;
break;
}
}
}
}
+25 -7
View File
@@ -68,8 +68,17 @@ export function useImageCarousel({
let localIdx = idxRef.current;
let elapsed = ts - start;
while (elapsed >= segmentMs) {
elapsed -= segmentMs;
// 获取当前图片的显示时长(动图使用其 duration,静态图片使用 segmentMs)
const getCurrentSegmentDuration = (index: number) => {
const img = images[index];
return img?.duration ?? segmentMs;
};
let currentSegmentDuration = getCurrentSegmentDuration(localIdx);
while (elapsed >= currentSegmentDuration) {
elapsed -= currentSegmentDuration;
if (localIdx >= images.length - 1) {
if (loopMode === "sequential" && neighbors?.next) {
@@ -80,19 +89,28 @@ export function useImageCarousel({
} else {
localIdx = localIdx + 1;
}
// 更新下一张图片的时长
currentSegmentDuration = getCurrentSegmentDuration(localIdx);
}
segStartRef.current = ts - elapsed;
if (localIdx !== idxRef.current) {
idxRef.current = localIdx;
setIdx(localIdx);
const el = scrollerRef.current;
if (el) el.scrollTo({ left: localIdx * el.clientWidth, behavior: "smooth" });
// 虚拟滚动不需要实际滚动 DOM
}
const localSeg = Math.max(0, Math.min(1, elapsed / segmentMs));
const localSeg = Math.max(0, Math.min(1, elapsed / currentSegmentDuration));
setSegProgress(localSeg);
setProgress((localIdx + localSeg) / images.length);
// 计算总进度:已完成的图片 + 当前图片的进度
let totalProgress = 0;
for (let i = 0; i < localIdx; i++) {
totalProgress += 1;
}
totalProgress += localSeg;
setProgress(totalProgress / images.length);
rafRef.current = requestAnimationFrame(tick);
};
@@ -102,7 +120,7 @@ export function useImageCarousel({
if (rafRef.current) cancelAnimationFrame(rafRef.current);
rafRef.current = null;
};
}, [images?.length, isPlaying, loopMode, neighbors?.next, router, scrollerRef, setProgress, segmentMs]);
}, [images, isPlaying, loopMode, neighbors?.next, router, scrollerRef, setProgress, segmentMs]);
return {
idx,