UNPKG

tldraw

Version:

A tiny little drawing editor.

95 lines (94 loc) 3.3 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 previousAssetId = useRef(null); const shouldRunImmediately = useRef(false); const previousUrl = useRef(null); useEffect(() => { const assetIdChanged = previousAssetId.current !== assetId; previousAssetId.current = assetId; if (assetIdChanged) { shouldRunImmediately.current = true; } 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.getEfficientZoomLevel() * (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 && !shouldRunImmediately.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 { cancelDebounceFn?.(); resolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url)); shouldRunImmediately.current = false; } }); 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); }); } export { useImageOrVideoAsset }; //# sourceMappingURL=useImageOrVideoAsset.mjs.map