tldraw
Version:
A tiny little drawing editor.
103 lines (102 loc) • 4.03 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var useImageOrVideoAsset_exports = {};
__export(useImageOrVideoAsset_exports, {
useAsset: () => useAsset,
useImageOrVideoAsset: () => useImageOrVideoAsset
});
module.exports = __toCommonJS(useImageOrVideoAsset_exports);
var import_editor = require("@tldraw/editor");
var import_react = require("react");
function useImageOrVideoAsset({ shapeId, assetId, width }) {
const editor = (0, import_editor.useEditor)();
const exportInfo = (0, import_editor.useSvgExportContext)();
const exportIsReady = (0, import_editor.useDelaySvgExport)();
const [result, setResult] = (0, import_react.useState)(() => ({
asset: assetId ? editor.getAsset(assetId) ?? null : null,
url: null
}));
const didAlreadyResolve = (0, import_react.useRef)(false);
const previousUrl = (0, import_react.useRef)(null);
(0, import_react.useEffect)(() => {
if (!assetId) return;
let isCancelled = false;
let cancelDebounceFn;
const cleanupEffectScheduler = (0, import_editor.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;
//# sourceMappingURL=useImageOrVideoAsset.js.map