UNPKG

@remotion/gif

Version:

Embed GIFs in a Remotion video

96 lines (95 loc) 4.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GifForRendering = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const remotion_1 = require("remotion"); const canvas_1 = require("./canvas"); const gif_cache_1 = require("./gif-cache"); const is_cors_error_1 = require("./is-cors-error"); const react_tools_1 = require("./react-tools"); const resolve_gif_source_1 = require("./resolve-gif-source"); const useCurrentGifIndex_1 = require("./useCurrentGifIndex"); exports.GifForRendering = (0, react_1.forwardRef)(({ src, width, height, onLoad, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', ...props }, ref) => { const resolvedSrc = (0, resolve_gif_source_1.resolveGifSource)(src); const [state, update] = (0, react_1.useState)(() => { const parsedGif = gif_cache_1.volatileGifCache.get(resolvedSrc); if (parsedGif === undefined) { return { delays: [], frames: [], width: 0, height: 0, }; } return parsedGif; }); const [error, setError] = (0, react_1.useState)(null); const [renderHandle] = (0, react_1.useState)(() => (0, remotion_1.delayRender)(`Rendering <Gif/> with src="${resolvedSrc}"`)); const logLevel = remotion_1.Internals.useLogLevel(); (0, react_1.useEffect)(() => { return () => { (0, remotion_1.continueRender)(renderHandle); }; }, [renderHandle]); const index = (0, useCurrentGifIndex_1.useCurrentGifIndex)({ delays: state.delays, loopBehavior, playbackRate, }); const currentOnLoad = (0, react_1.useRef)(onLoad); const currentOnError = (0, react_1.useRef)(onError); currentOnLoad.current = onLoad; currentOnError.current = onError; (0, react_1.useEffect)(() => { const controller = new AbortController(); let done = false; let aborted = false; const newHandle = (0, remotion_1.delayRender)('Loading <Gif /> with src=' + resolvedSrc); remotion_1.Internals.Log.verbose(logLevel, 'Loading GIF with source', resolvedSrc); const time = Date.now(); (0, react_tools_1.parseGif)({ controller, src: resolvedSrc }) .then((parsed) => { var _a; remotion_1.Internals.Log.verbose(logLevel, 'Parsed GIF in', Date.now() - time, 'ms'); (_a = currentOnLoad.current) === null || _a === void 0 ? void 0 : _a.call(currentOnLoad, parsed); update(parsed); gif_cache_1.volatileGifCache.set(resolvedSrc, parsed); done = true; (0, remotion_1.continueRender)(newHandle); (0, remotion_1.continueRender)(renderHandle); }) .catch((err) => { if (aborted) { (0, remotion_1.continueRender)(newHandle); return; } remotion_1.Internals.Log.error('Failed to load GIF', err); if (currentOnError.current) { currentOnError.current(err); } else { setError(err); } }); return () => { if (!done) { aborted = true; controller.abort(); } (0, remotion_1.continueRender)(newHandle); (0, remotion_1.continueRender)(renderHandle); }; }, [renderHandle, logLevel, resolvedSrc]); if (error) { remotion_1.Internals.Log.error(error.stack); if ((0, is_cors_error_1.isCorsError)(error)) { throw new Error(`Failed to render GIF with source ${src}: "${error.message}". You must enable CORS for this URL.`); } throw new Error(`Failed to render GIF with source ${src}: "${error.message}". Render with --log=verbose to see the full stack.`); } if (index === -1) { return null; } return ((0, jsx_runtime_1.jsx)(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, ...props, ref: ref })); });