UNPKG

tldraw

Version:

A tiny little drawing editor.

88 lines (87 loc) 2.97 kB
import { react, useDelaySvgExport, useEditor, useSvgExportContext } from "@tldraw/editor"; import { useEffect, useRef, useState } from "react"; function useImageOrVideoAsset({ shapeId, assetId, width }) { const editor = useEditor(); const exportInfo = useSvgExportContext(); const exportIsReady = useDelaySvgExport(); const [result, setResult] = useState(() => ({ asset: assetId ? editor.getAsset(assetId) ?? null : null, url: null })); const didAlreadyResolve = useRef(false); const previousUrl = useRef(null); useEffect(() => { if (!assetId) return; let isCancelled = false; let cancelDebounceFn; const cleanupEffectScheduler = react("update state", () => { if (!exportInfo && shapeId && editor.getCulledShapes().has(shapeId)) return; const asset = editor.getAsset(assetId); if (!asset) { setResult((prev) => ({ ...prev, asset: null, url: null })); return; } if (!asset.props.src) { const preview = editor.getTemporaryAssetPreview(asset.id); if (preview) { if (previousUrl.current !== preview) { previousUrl.current = preview; setResult((prev) => ({ ...prev, isPlaceholder: true, url: preview })); exportIsReady(); } return; } } const screenScale = exportInfo ? exportInfo.scale * (width / asset.props.w) : editor.getZoomLevel() * (width / asset.props.w); function resolve(asset2, url) { if (isCancelled) return; if (previousUrl.current === url) return; didAlreadyResolve.current = true; previousUrl.current = url; setResult({ asset: asset2, url }); exportIsReady(); } if (didAlreadyResolve.current) { let tick = 0; const resolveAssetAfterAWhile = () => { tick++; if (tick > 500 / 16) { resolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url)); cancelDebounceFn?.(); } }; cancelDebounceFn?.(); editor.on("tick", resolveAssetAfterAWhile); cancelDebounceFn = () => editor.off("tick", resolveAssetAfterAWhile); } else { resolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url)); } }); return () => { cleanupEffectScheduler(); cancelDebounceFn?.(); isCancelled = true; }; }, [editor, assetId, exportInfo, exportIsReady, shapeId, width]); return result; } function resolveAssetUrl(editor, assetId, screenScale, exportInfo, callback) { editor.resolveAssetUrl(assetId, { screenScale, shouldResolveToOriginal: exportInfo ? exportInfo.pixelRatio === null : false, dpr: exportInfo?.pixelRatio ?? void 0 }).then((url) => { callback(url); }); } const useAsset = useImageOrVideoAsset; export { useAsset, useImageOrVideoAsset }; //# sourceMappingURL=useImageOrVideoAsset.mjs.map