优化动图
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user