UNPKG

react-vegas

Version:
117 lines (102 loc) 2.93 kB
import { useState, useCallback } from "react"; import { SlideProps, Logger } from "../types"; /** * 预加载资源的自定义钩子 * @param slides * @param preloadImage * @param preloadVideo * @param preLoadImageBatch * @param log * @param logWarn * @param logError */ export const usePreload = ( slides: SlideProps[], preloadImage: boolean, preloadVideo: boolean, preLoadImageBatch: number, log: Logger, logWarn: Logger, logError: Logger ) => { const [loading, setLoading] = useState(false); const [loadProgress, setLoadProgress] = useState(0); const [loadedImages, setLoadedImages] = useState<Record<string, boolean>>({}); // 批量预加载图片 const batchPreloadImages = useCallback(async () => { if (!preloadImage) return; setLoading(true); const batchSize = preLoadImageBatch; const imageSlides = slides.filter(slide => !slide.video); try { for (let i = 0; i < imageSlides.length; i += batchSize) { const batch = imageSlides.slice(i, i + batchSize); const promises = batch.map(slide => { return new Promise<void>((resolve) => { const img = new Image(); img.onload = () => { setLoadedImages(prev => ({...prev, [slide.src]: true})); resolve(); }; img.onerror = () => { logWarn(`图片加载失败: ${slide.src}`); resolve(); }; img.src = slide.src; }); }); await Promise.all(promises); setLoadProgress(Math.min(100, Math.floor(((i + batch.length) / imageSlides.length) * 100))); } } catch (error) { logError("预加载图片时发生错误:", error); } finally { setLoading(false); } }, [slides, preloadImage, preLoadImageBatch, log, logWarn, logError]); // 预加载视频资源 const preloadVideoResources = useCallback(() => { if (!preloadVideo) return; log("开始预加载视频资源"); slides.forEach(slide => { if (slide.video) { slide.video.src.forEach(src => { const link = document.createElement("link"); link.rel = "preload"; link.as = "video"; link.href = src; document.head.appendChild(link); log(`预加载视频: ${src}`); }); } }); }, [slides, preloadVideo, log]); // 执行所有预加载操作 const preloadResources = useCallback(async () => { log("开始预加载资源"); setLoading(true); const preloadPromises: Promise<void>[] = []; if (preloadImage) { preloadPromises.push(batchPreloadImages()); } if (preloadVideo) { preloadVideoResources(); } try { await Promise.all(preloadPromises); log("所有资源预加载完成"); } catch (error) { logError("预加载资源时发生错误:", error); } finally { setLoading(false); } }, [batchPreloadImages, preloadVideoResources, preloadImage, preloadVideo, log, logError]); return { loading, loadProgress, loadedImages, preloadResources, batchPreloadImages, preloadVideoResources }; };