UNPKG

@tldraw/editor

Version:

tldraw infinite canvas SDK (editor).

517 lines (516 loc) • 26 kB
"use strict"; 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