优化动图

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
+37 -14
View File
@@ -41,7 +41,7 @@ export default function AwemeDetailClient({ data, neighbors }: AwemeDetailClient
const backgroundCanvasRef = useRef<HTMLCanvasElement | null>(null);
// 图文轮播状态
const images = isVideo ? [] : (data as ImageData).images;
const images = isVideo ? [] : (data as ImageData).images;
const imageCarouselState = useImageCarousel({
images,
isPlaying: playerState.isPlaying,
@@ -80,18 +80,43 @@ export default function AwemeDetailClient({ data, neighbors }: AwemeDetailClient
return;
}
if (!images?.length) return;
const total = images.length;
const exact = ratio * total;
const targetIdx = Math.min(total - 1, Math.floor(exact));
const remainder = exact - targetIdx;
// 计算每张图片的时长
const durations = images.map(img => img.duration ?? SEGMENT_MS);
const totalDuration = durations.reduce((sum, d) => sum + d, 0);
const targetTime = ratio * totalDuration;
// 找到目标时间对应的图片索引和进度
let accumulatedTime = 0;
let targetIdx = 0;
let remainder = 0;
for (let i = 0; i < images.length; i++) {
if (accumulatedTime + durations[i] > targetTime) {
targetIdx = i;
remainder = (targetTime - accumulatedTime) / durations[i];
break;
}
accumulatedTime += durations[i];
if (i === images.length - 1) {
targetIdx = i;
remainder = 1;
}
}
imageCarouselState.idxRef.current = targetIdx;
imageCarouselState.setIdx(targetIdx);
imageCarouselState.segStartRef.current = performance.now() - remainder * SEGMENT_MS;
playerState.setProgress((targetIdx + remainder) / total);
const el = scrollerRef.current;
if (el) el.scrollTo({ left: targetIdx * el.clientWidth, behavior: "smooth" });
imageCarouselState.segStartRef.current = performance.now() - remainder * durations[targetIdx];
// 重新计算总进度
let totalProgress = 0;
for (let i = 0; i < targetIdx; i++) {
totalProgress += 1;
}
totalProgress += remainder;
playerState.setProgress(totalProgress / images.length);
// 虚拟滚动不需要实际滚动 DOM
};
const togglePlay = async () => {
@@ -141,8 +166,7 @@ export default function AwemeDetailClient({ data, neighbors }: AwemeDetailClient
imageCarouselState.idxRef.current = next;
imageCarouselState.setIdx(next);
imageCarouselState.segStartRef.current = performance.now();
const el = scrollerRef.current;
if (el) el.scrollTo({ left: next * el.clientWidth, behavior: "smooth" });
// 虚拟滚动不需要实际滚动 DOM
};
const nextImg = () => {
@@ -151,8 +175,7 @@ export default function AwemeDetailClient({ data, neighbors }: AwemeDetailClient
imageCarouselState.idxRef.current = next;
imageCarouselState.setIdx(next);
imageCarouselState.segStartRef.current = performance.now();
const el = scrollerRef.current;
if (el) el.scrollTo({ left: next * el.clientWidth, behavior: "smooth" });
// 虚拟滚动不需要实际滚动 DOM
};
const handleDownload = () => {