@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
517 lines (516 loc) • 26 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var DefaultCanvas_exports = {};
__export(DefaultCanvas_exports, {
DefaultCanvas: () => DefaultCanvas
});
module.exports = __toCommonJS(DefaultCanvas_exports);
var import_jsx_runtime = require("react/jsx-runtime");
var import_state = require("@tldraw/state");
var import_state_react = require("@tldraw/state-react");
var import_utils = require("@tldraw/utils");
var import_classnames = __toESM(require("classnames"));
var import_react = require("react");
var import_environment = require("../../globals/environment");
var import_useCanvasEvents = require("../../hooks/useCanvasEvents");
var import_useCoarsePointer = require("../../hooks/useCoarsePointer");
var import_useContainer = require("../../hooks/useContainer");
var import_useDocumentEvents = require("../../hooks/useDocumentEvents");
var import_useEditor = require("../../hooks/useEditor");
var import_useEditorComponents = require("../../hooks/useEditorComponents");
var import_useFixSafariDoubleTapZoomPencilEvents = require("../../hooks/useFixSafariDoubleTapZoomPencilEvents");
var import_useGestureEvents = require("../../hooks/useGestureEvents");
var import_useHandleEvents = require("../../hooks/useHandleEvents");
var import_useSafeId = require("../../hooks/useSafeId");
var import_useScreenBounds = require("../../hooks/useScreenBounds");
var import_Mat = require("../../primitives/Mat");
var import_Vec = require("../../primitives/Vec");
var import_utils2 = require("../../primitives/utils");
var import_debug_flags = require("../../utils/debug-flags");
var import_dom = require("../../utils/dom");
var import_nearestMultiple = require("../../utils/nearestMultiple");
var import_GeometryDebuggingView = require("../GeometryDebuggingView");
var import_LiveCollaborators = require("../LiveCollaborators");
var import_MenuClickCapture = require("../MenuClickCapture");
var import_Shape = require("../Shape");
function DefaultCanvas({ className }) {
const editor = (0, import_useEditor.useEditor)();
const { SelectionBackground, Background, SvgDefs, ShapeIndicators } = (0, import_useEditorComponents.useEditorComponents)();
const rCanvas = (0, import_react.useRef)(null);
const rHtmlLayer = (0, import_react.useRef)(null);
const rHtmlLayer2 = (0, import_react.useRef)(null);
const container = (0, import_useContainer.useContainer)();
(0, import_useScreenBounds.useScreenBounds)(rCanvas);
(0, import_useDocumentEvents.useDocumentEvents)();
(0, import_useCoarsePointer.useCoarsePointer)();
(0, import_useGestureEvents.useGestureEvents)(rCanvas);
(0, import_useFixSafariDoubleTapZoomPencilEvents.useFixSafariDoubleTapZoomPencilEvents)(rCanvas);
const rMemoizedStuff = (0, import_react.useRef)({ lodDisableTextOutline: false, allowTextOutline: true });
(0, import_state_react.useQuickReactor)(
"position layers",
function positionLayersWhenCameraMoves() {
const { x, y, z } = editor.getCamera();
if (rMemoizedStuff.current.allowTextOutline && import_environment.tlenv.isSafari) {
container.style.setProperty("--tl-text-outline", "none");
rMemoizedStuff.current.allowTextOutline = false;
}
if (rMemoizedStuff.current.allowTextOutline && z < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline) {
const lodDisableTextOutline = z < editor.options.textShadowLod;
container.style.setProperty(
"--tl-text-outline",
lodDisableTextOutline ? "none" : `var(--tl-text-outline-reference)`
);
rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline;
}
const offset = z >= 1 ? (0, import_utils.modulate)(z, [1, 8], [0.125, 0.5], true) : (0, import_utils.modulate)(z, [0.1, 1], [-2, 0.125], true);
const transform = `scale(${(0, import_utils2.toDomPrecision)(z)}) translate(${(0, import_utils2.toDomPrecision)(
x + offset
)}px,${(0, import_utils2.toDomPrecision)(y + offset)}px)`;
(0, import_dom.setStyleProperty)(rHtmlLayer.current, "transform", transform);
(0, import_dom.setStyleProperty)(rHtmlLayer2.current, "transform", transform);
},
[editor, container]
);
const events = (0, import_useCanvasEvents.useCanvasEvents)();
const shapeSvgDefs = (0, import_state_react.useValue)(
"shapeSvgDefs",
() => {
const shapeSvgDefsByKey = /* @__PURE__ */ new Map();
for (const util of (0, import_utils.objectMapValues)(editor.shapeUtils)) {
if (!util) return;
const defs = util.getCanvasSvgDefs();
for (const { key, component: Component } of defs) {
if (shapeSvgDefsByKey.has(key)) continue;
shapeSvgDefsByKey.set(key, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, {}, key));
}
}
return [...shapeSvgDefsByKey.values()];
},
[editor]
);
const hideShapes = (0, import_state_react.useValue)("debug_shapes", () => import_debug_flags.debugFlags.hideShapes.get(), [import_debug_flags.debugFlags]);
const debugSvg = (0, import_state_react.useValue)("debug_svg", () => import_debug_flags.debugFlags.debugSvg.get(), [import_debug_flags.debugFlags]);
const debugGeometry = (0, import_state_react.useValue)("debug_geometry", () => import_debug_flags.debugFlags.debugGeometry.get(), [
import_debug_flags.debugFlags
]);
const isEditingAnything = (0, import_state_react.useValue)(
"isEditingAnything",
() => editor.getEditingShapeId() !== null,
[editor]
);
const isSelectingAnything = (0, import_state_react.useValue)(
"isSelectingAnything",
() => !!editor.getSelectedShapeIds().length,
[editor]
);
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
"div",
{
ref: rCanvas,
draggable: false,
"data-iseditinganything": isEditingAnything,
"data-isselectinganything": isSelectingAnything,
className: (0, import_classnames.default)("tl-canvas", className),
"data-testid": "canvas",
...events,
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className: "tl-svg-context", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("defs", { children: [
shapeSvgDefs,
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CursorDef, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CollaboratorHintDef, {}),
SvgDefs && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgDefs, {})
] }) }),
Background && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tl-background__wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Background, {}) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GridWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: rHtmlLayer, className: "tl-html-layer tl-shapes", draggable: false, children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(OnTheCanvasWrapper, {}),
SelectionBackground && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectionBackgroundWrapper, {}),
hideShapes ? null : debugSvg ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapesWithSVGs, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapesToDisplay, {})
] }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tl-overlays", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref: rHtmlLayer2, className: "tl-html-layer", children: [
debugGeometry ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_GeometryDebuggingView.GeometryDebuggingView, {}) : null,
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(BrushWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScribbleWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZoomBrushWrapper, {}),
ShapeIndicators && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeIndicators, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(HintedShapeIndicator, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SnapIndicatorWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectionForegroundWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(HandlesWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(OverlaysWrapper, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_LiveCollaborators.LiveCollaborators, {})
] }) }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MovingCameraHitTestBlocker, {})
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_MenuClickCapture.MenuClickCapture, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(InFrontOfTheCanvasWrapper, {})
] });
}
function InFrontOfTheCanvasWrapper() {
const { InFrontOfTheCanvas } = (0, import_useEditorComponents.useEditorComponents)();
if (!InFrontOfTheCanvas) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InFrontOfTheCanvas, {});
}
function GridWrapper() {
const editor = (0, import_useEditor.useEditor)();
const gridSize = (0, import_state_react.useValue)("gridSize", () => editor.getDocumentSettings().gridSize, [editor]);
const { x, y, z } = (0, import_state_react.useValue)("camera", () => editor.getCamera(), [editor]);
const isGridMode = (0, import_state_react.useValue)("isGridMode", () => editor.getInstanceState().isGridMode, [editor]);
const { Grid } = (0, import_useEditorComponents.useEditorComponents)();
if (!(Grid && isGridMode)) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Grid, { x, y, z, size: gridSize });
}
function ScribbleWrapper() {
const editor = (0, import_useEditor.useEditor)();
const scribbles = (0, import_state_react.useValue)("scribbles", () => editor.getInstanceState().scribbles, [editor]);
const zoomLevel = (0, import_state_react.useValue)("zoomLevel", () => editor.getZoomLevel(), [editor]);
const { Scribble } = (0, import_useEditorComponents.useEditorComponents)();
if (!(Scribble && scribbles.length)) return null;
return scribbles.map((scribble) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Scribble, { className: "tl-user-scribble", scribble, zoom: zoomLevel }, scribble.id));
}
function BrushWrapper() {
const editor = (0, import_useEditor.useEditor)();
const brush = (0, import_state_react.useValue)("brush", () => editor.getInstanceState().brush, [editor]);
const { Brush } = (0, import_useEditorComponents.useEditorComponents)();
if (!(Brush && brush)) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Brush, { className: "tl-user-brush", brush });
}
function ZoomBrushWrapper() {
const editor = (0, import_useEditor.useEditor)();
const zoomBrush = (0, import_state_react.useValue)("zoomBrush", () => editor.getInstanceState().zoomBrush, [editor]);
const { ZoomBrush } = (0, import_useEditorComponents.useEditorComponents)();
if (!(ZoomBrush && zoomBrush)) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ZoomBrush, { className: "tl-user-brush tl-zoom-brush", brush: zoomBrush });
}
function SnapIndicatorWrapper() {
const editor = (0, import_useEditor.useEditor)();
const lines = (0, import_state_react.useValue)("snapLines", () => editor.snaps.getIndicators(), [editor]);
const zoomLevel = (0, import_state_react.useValue)("zoomLevel", () => editor.getZoomLevel(), [editor]);
const { SnapIndicator } = (0, import_useEditorComponents.useEditorComponents)();
if (!(SnapIndicator && lines.length > 0)) return null;
return lines.map((line) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SnapIndicator, { className: "tl-user-snapline", line, zoom: zoomLevel }, line.id));
}
function HandlesWrapper() {
const editor = (0, import_useEditor.useEditor)();
const shapeIdWithHandles = (0, import_state_react.useValue)(
"handles shapeIdWithHandles",
() => {
const { isReadonly, isChangingStyle } = editor.getInstanceState();
if (isReadonly || isChangingStyle) return false;
const onlySelectedShape = editor.getOnlySelectedShape();
if (!onlySelectedShape) return false;
const handles = editor.getShapeHandles(onlySelectedShape);
if (!handles) return false;
return onlySelectedShape.id;
},
[editor]
);
if (!shapeIdWithHandles) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HandlesWrapperInner, { shapeId: shapeIdWithHandles });
}
function HandlesWrapperInner({ shapeId }) {
const editor = (0, import_useEditor.useEditor)();
const { Handles } = (0, import_useEditorComponents.useEditorComponents)();
const zoomLevel = (0, import_state_react.useValue)("zoomLevel", () => editor.getZoomLevel(), [editor]);
const isCoarse = (0, import_state_react.useValue)("coarse pointer", () => editor.getInstanceState().isCoarsePointer, [
editor
]);
const transform = (0, import_state_react.useValue)("handles transform", () => editor.getShapePageTransform(shapeId), [
editor,
shapeId
]);
const handles = (0, import_state_react.useValue)(
"handles",
() => {
const handles2 = editor.getShapeHandles(shapeId);
if (!handles2) return null;
const minDistBetweenVirtualHandlesAndRegularHandles = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoomLevel * 2;
return handles2.filter(
(handle) => (
// if the handle isn't a virtual handle, we'll display it
handle.type !== "virtual" || // but for virtual handles, we'll only display them if they're far enough away from vertex handles
!handles2.some(
(h) => (
// skip the handle we're checking against
h !== handle && // only check against vertex handles
h.type === "vertex" && // and check that their distance isn't below the minimum distance
import_Vec.Vec.Dist(handle, h) < minDistBetweenVirtualHandlesAndRegularHandles
)
)
)
).sort((a) => a.type === "vertex" ? 1 : -1);
},
[editor, zoomLevel, isCoarse, shapeId]
);
const isHidden = (0, import_state_react.useValue)("isHidden", () => editor.isShapeHidden(shapeId), [editor, shapeId]);
if (!Handles || !handles || !transform || isHidden) {
return null;
}
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Handles, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("g", { transform: import_Mat.Mat.toCssString(transform), children: handles.map((handle) => {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
HandleWrapper,
{
shapeId,
handle,
zoom: zoomLevel,
isCoarse
},
handle.id
);
}) }) });
}
function HandleWrapper({
shapeId,
handle,
zoom,
isCoarse
}) {
const events = (0, import_useHandleEvents.useHandleEvents)(shapeId, handle.id);
const { Handle } = (0, import_useEditorComponents.useEditorComponents)();
if (!Handle) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"g",
{
role: "button",
"aria-label": handle.label || "handle",
transform: `translate(${handle.x}, ${handle.y})`,
...events,
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Handle, { shapeId, handle, zoom, isCoarse })
}
);
}
function OverlaysWrapper() {
const { Overlays } = (0, import_useEditorComponents.useEditorComponents)();
if (!Overlays) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "tl-custom-overlays tl-overlays__item", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Overlays, {}) });
}
function ShapesWithSVGs() {
const editor = (0, import_useEditor.useEditor)();
const renderingShapes = (0, import_state_react.useValue)("rendering shapes", () => editor.getRenderingShapes(), [editor]);
const dprMultiple = (0, import_state_react.useValue)(
"dpr multiple",
() => (
// dprMultiple is the smallest number we can multiply dpr by to get an integer
// it's usually 1, 2, or 4 (for e.g. dpr of 2, 2.5 and 2.25 respectively)
(0, import_nearestMultiple.nearestMultiple)(Math.floor(editor.getInstanceState().devicePixelRatio * 100) / 100)
),
[editor]
);
return renderingShapes.map((result) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Shape.Shape, { ...result, dprMultiple }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DebugSvgCopy, { id: result.id, mode: "iframe" })
] }, result.id + "_fragment"));
}
function ReflowIfNeeded() {
const editor = (0, import_useEditor.useEditor)();
const culledShapesRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
(0, import_state_react.useQuickReactor)(
"reflow for culled shapes",
() => {
const culledShapes = editor.getCulledShapes();
if (culledShapesRef.current.size === culledShapes.size && [...culledShapes].every((id) => culledShapesRef.current.has(id)))
return;
culledShapesRef.current = culledShapes;
const canvas = document.getElementsByClassName("tl-canvas");
if (canvas.length === 0) return;
const _height = canvas[0].offsetHeight;
},
[editor]
);
return null;
}
function ShapesToDisplay() {
const editor = (0, import_useEditor.useEditor)();
const renderingShapes = (0, import_state_react.useValue)("rendering shapes", () => editor.getRenderingShapes(), [editor]);
const dprMultiple = (0, import_state_react.useValue)(
"dpr multiple",
() => (
// dprMultiple is the smallest number we can multiply dpr by to get an integer
// it's usually 1, 2, or 4 (for e.g. dpr of 2, 2.5 and 2.25 respectively)
(0, import_nearestMultiple.nearestMultiple)(Math.floor(editor.getInstanceState().devicePixelRatio * 100) / 100)
),
[editor]
);
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
renderingShapes.map((result) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_Shape.Shape, { ...result, dprMultiple }, result.id + "_shape")),
import_environment.tlenv.isSafari && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReflowIfNeeded, {})
] });
}
function HintedShapeIndicator() {
const editor = (0, import_useEditor.useEditor)();
const { ShapeIndicator } = (0, import_useEditorComponents.useEditorComponents)();
const ids = (0, import_state_react.useValue)("hinting shape ids", () => (0, import_utils.dedupe)(editor.getHintingShapeIds()), [editor]);
if (!ids.length) return null;
if (!ShapeIndicator) return null;
return ids.map((id) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ShapeIndicator, { className: "tl-user-indicator__hint", shapeId: id }, id + "_hinting"));
}
function CursorDef() {
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { id: (0, import_useSafeId.useSharedSafeId)("cursor"), children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { fill: "rgba(0,0,0,.2)", transform: "translate(-11,-11)", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { fill: "white", transform: "translate(-12,-12)", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" })
] }),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("g", { fill: "currentColor", transform: "translate(-12,-12)", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "m13 10.814v11.188l2.969-2.866.428-.139h4.768z" })
] })
] });
}
function CollaboratorHintDef() {
const cursorHintId = (0, import_useSafeId.useSharedSafeId)("cursor_hint");
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { id: cursorHintId, fill: "currentColor", d: "M -2,-5 2,0 -2,5 Z" });
}
function DebugSvgCopy({ id, mode }) {
const editor = (0, import_useEditor.useEditor)();
const [image, setImage] = (0, import_react.useState)(null);
const isInRoot = (0, import_state_react.useValue)(
"is in root",
() => {
const shape = editor.getShape(id);
return shape?.parentId === editor.getCurrentPageId();
},
[editor, id]
);
(0, import_react.useEffect)(() => {
if (!isInRoot) return;
let latest = null;
const unsubscribe = (0, import_state.react)("shape to svg", async () => {
const renderId = Math.random();
latest = renderId;
const isSingleFrame = editor.isShapeOfType(id, "frame");
const padding = isSingleFrame ? 0 : 10;
let bounds = editor.getShapePageBounds(id);
if (!bounds) return;
bounds = bounds.clone().expandBy(padding);
const result = await editor.getSvgString([id], { padding });
if (latest !== renderId || !result) return;
const svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`;
setImage({ src: svgDataUrl, bounds });
});
return () => {
latest = null;
unsubscribe();
};
}, [editor, id, isInRoot]);
if (!isInRoot || !image) return null;
if (mode === "iframe") {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"iframe",
{
src: image.src,
width: image.bounds.width,
height: image.bounds.height,
referrerPolicy: "no-referrer",
style: {
position: "absolute",
top: 0,
left: 0,
border: "none",
transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,
outline: "1px solid black",
maxWidth: "none"
}
}
);
}
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"img",
{
src: image.src,
width: image.bounds.width,
height: image.bounds.height,
referrerPolicy: "no-referrer",
style: {
position: "absolute",
top: 0,
left: 0,
transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`,
outline: "1px solid black",
maxWidth: "none"
}
}
);
}
function SelectionForegroundWrapper() {
const editor = (0, import_useEditor.useEditor)();
const selectionRotation = (0, import_state_react.useValue)(
"selection rotation",
function getSelectionRotation() {
return editor.getSelectionRotation();
},
[editor]
);
const selectionBounds = (0, import_state_react.useValue)(
"selection bounds",
() => editor.getSelectionRotatedPageBounds(),
[editor]
);
const { SelectionForeground } = (0, import_useEditorComponents.useEditorComponents)();
if (!selectionBounds || !SelectionForeground) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectionForeground, { bounds: selectionBounds, rotation: selectionRotation });
}
function SelectionBackgroundWrapper() {
const editor = (0, import_useEditor.useEditor)();
const selectionRotation = (0, import_state_react.useValue)("selection rotation", () => editor.getSelectionRotation(), [
editor
]);
const selectionBounds = (0, import_state_react.useValue)(
"selection bounds",
() => editor.getSelectionRotatedPageBounds(),
[editor]
);
const { SelectionBackground } = (0, import_useEditorComponents.useEditorComponents)();
if (!selectionBounds || !SelectionBackground) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectionBackground, { bounds: selectionBounds, rotation: selectionRotation });
}
function OnTheCanvasWrapper() {
const { OnTheCanvas } = (0, import_useEditorComponents.useEditorComponents)();
if (!OnTheCanvas) return null;
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(OnTheCanvas, {});
}
function MovingCameraHitTestBlocker() {
const editor = (0, import_useEditor.useEditor)();
const cameraState = (0, import_state_react.useValue)("camera state", () => editor.getCameraState(), [editor]);
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
className: (0, import_classnames.default)("tl-hit-test-blocker", {
"tl-hit-test-blocker__hidden": cameraState === "idle"
})
}
);
}
//# sourceMappingURL=DefaultCanvas.js.map