tldraw
Version:
A tiny little drawing editor.
88 lines (87 loc) • 2.69 kB
JavaScript
import {
debounce,
react,
useDelaySvgExport,
useEditor,
useSvgExportContext
} from "@tldraw/editor";
import { useEffect, useMemo, useRef, useState } from "react";
function useImageOrVideoAsset({
shapeId,
assetId
}) {
const editor = useEditor();
const isExport = !!useSvgExportContext();
const isReady = useDelaySvgExport();
const resolveAssetUrlDebounced = useMemo(() => debounce(resolveAssetUrl, 500), []);
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 (!isExport && editor.getCulledShapes().has(shapeId)) return;
const asset = editor.getAsset(assetId);
if (!asset) return;
const shape = editor.getShape(shapeId);
if (!shape) 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 }));
isReady();
}
return;
}
}
const screenScale = editor.getZoomLevel() * (shape.props.w / 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 });
isReady();
}
if (didAlreadyResolve.current) {
resolveAssetUrlDebounced(
editor,
assetId,
screenScale,
isExport,
(url) => resolve(asset, url)
);
cancelDebounceFn = resolveAssetUrlDebounced.cancel;
} else {
resolveAssetUrl(editor, assetId, screenScale, isExport, (url) => resolve(asset, url));
}
});
return () => {
cleanupEffectScheduler();
cancelDebounceFn?.();
isCancelled = true;
};
}, [editor, assetId, isExport, isReady, shapeId, resolveAssetUrlDebounced]);
return result;
}
function resolveAssetUrl(editor, assetId, screenScale, isExport, callback) {
editor.resolveAssetUrl(assetId, {
screenScale,
shouldResolveToOriginal: isExport
}).then((url) => {
callback(url);
});
}
const useAsset = useImageOrVideoAsset;
export {
useAsset,
useImageOrVideoAsset
};
//# sourceMappingURL=useImageOrVideoAsset.mjs.map