tldraw 4.3.0-canary.b19495d1a0fa → 4.3.0-canary.b2e9b1218a6b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist-cjs/index.d.ts +3 -0
  2. package/dist-cjs/index.js +2 -1
  3. package/dist-cjs/index.js.map +2 -2
  4. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js +2 -2
  5. package/dist-cjs/lib/canvas/TldrawSelectionForeground.js.map +2 -2
  6. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js +5 -10
  7. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  8. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +3 -3
  9. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  10. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js +1 -1
  11. package/dist-cjs/lib/shapes/frame/FrameShapeUtil.js.map +2 -2
  12. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +3 -4
  13. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  14. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +1 -1
  15. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  16. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +4 -5
  17. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  18. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js +2 -1
  19. package/dist-cjs/lib/shapes/shared/HyperlinkButton.js.map +2 -2
  20. package/dist-cjs/lib/shapes/shared/ShapeFill.js +2 -2
  21. package/dist-cjs/lib/shapes/shared/ShapeFill.js.map +2 -2
  22. package/dist-cjs/lib/shapes/shared/{useForceSolid.js → useEfficientZoomThreshold.js} +10 -7
  23. package/dist-cjs/lib/shapes/shared/useEfficientZoomThreshold.js.map +7 -0
  24. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +1 -1
  25. package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
  26. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js +1 -1
  27. package/dist-cjs/lib/shapes/video/VideoShapeUtil.js.map +2 -2
  28. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js +3 -9
  29. package/dist-cjs/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.js.map +2 -2
  30. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js +1 -1
  31. package/dist-cjs/lib/ui/components/ZoomMenu/DefaultZoomMenu.js.map +2 -2
  32. package/dist-cjs/lib/ui/components/menu-items.js +3 -1
  33. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  34. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js +1 -1
  35. package/dist-cjs/lib/ui/components/primitives/TldrawUiSlider.js.map +2 -2
  36. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +143 -88
  37. package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
  38. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js +1 -1
  39. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuItem.js.map +2 -2
  40. package/dist-cjs/lib/ui/version.js +3 -3
  41. package/dist-cjs/lib/ui/version.js.map +1 -1
  42. package/dist-cjs/lib/utils/text/richText.js +7 -17
  43. package/dist-cjs/lib/utils/text/richText.js.map +3 -3
  44. package/dist-esm/index.d.mts +3 -0
  45. package/dist-esm/index.mjs +3 -1
  46. package/dist-esm/index.mjs.map +2 -2
  47. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs +2 -2
  48. package/dist-esm/lib/canvas/TldrawSelectionForeground.mjs.map +2 -2
  49. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs +6 -12
  50. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  51. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -3
  52. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  53. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs +1 -1
  54. package/dist-esm/lib/shapes/frame/FrameShapeUtil.mjs.map +2 -2
  55. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +3 -4
  56. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  57. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +1 -1
  58. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  59. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +4 -5
  60. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  61. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs +3 -2
  62. package/dist-esm/lib/shapes/shared/HyperlinkButton.mjs.map +2 -2
  63. package/dist-esm/lib/shapes/shared/ShapeFill.mjs +2 -2
  64. package/dist-esm/lib/shapes/shared/ShapeFill.mjs.map +2 -2
  65. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs +12 -0
  66. package/dist-esm/lib/shapes/shared/useEfficientZoomThreshold.mjs.map +7 -0
  67. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +1 -1
  68. package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
  69. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs +1 -1
  70. package/dist-esm/lib/shapes/video/VideoShapeUtil.mjs.map +2 -2
  71. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs +2 -8
  72. package/dist-esm/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.mjs.map +2 -2
  73. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs +1 -1
  74. package/dist-esm/lib/ui/components/ZoomMenu/DefaultZoomMenu.mjs.map +2 -2
  75. package/dist-esm/lib/ui/components/menu-items.mjs +3 -1
  76. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  77. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs +2 -2
  78. package/dist-esm/lib/ui/components/primitives/TldrawUiSlider.mjs.map +2 -2
  79. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +151 -90
  80. package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
  81. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs +2 -2
  82. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuItem.mjs.map +2 -2
  83. package/dist-esm/lib/ui/version.mjs +3 -3
  84. package/dist-esm/lib/ui/version.mjs.map +1 -1
  85. package/dist-esm/lib/utils/text/richText.mjs +3 -3
  86. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  87. package/package.json +3 -3
  88. package/src/index.ts +1 -0
  89. package/src/lib/canvas/TldrawSelectionForeground.tsx +2 -2
  90. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +6 -11
  91. package/src/lib/shapes/draw/DrawShapeUtil.tsx +3 -3
  92. package/src/lib/shapes/frame/FrameShapeUtil.tsx +1 -1
  93. package/src/lib/shapes/geo/GeoShapeUtil.tsx +3 -4
  94. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +1 -1
  95. package/src/lib/shapes/note/NoteShapeUtil.tsx +6 -8
  96. package/src/lib/shapes/shared/HyperlinkButton.tsx +3 -2
  97. package/src/lib/shapes/shared/ShapeFill.tsx +2 -2
  98. package/src/lib/shapes/shared/useEfficientZoomThreshold.ts +10 -0
  99. package/src/lib/shapes/shared/useImageOrVideoAsset.ts +1 -1
  100. package/src/lib/shapes/video/VideoShapeUtil.tsx +2 -1
  101. package/src/lib/ui/components/ActionsMenu/DefaultActionsMenuContent.tsx +1 -9
  102. package/src/lib/ui/components/ZoomMenu/DefaultZoomMenu.tsx +1 -1
  103. package/src/lib/ui/components/menu-items.tsx +3 -1
  104. package/src/lib/ui/components/primitives/TldrawUiSlider.tsx +2 -2
  105. package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +196 -108
  106. package/src/lib/ui/components/primitives/menus/TldrawUiMenuItem.tsx +2 -2
  107. package/src/lib/ui/version.ts +3 -3
  108. package/src/lib/utils/text/richText.ts +3 -3
  109. package/src/test/commands/cameraState.test.ts +299 -0
  110. package/dist-cjs/lib/shapes/shared/useForceSolid.js.map +0 -7
  111. package/dist-esm/lib/shapes/shared/useForceSolid.mjs +0 -9
  112. package/dist-esm/lib/shapes/shared/useForceSolid.mjs.map +0 -7
  113. package/src/lib/shapes/shared/useForceSolid.ts +0 -6
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/geo/GeoShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBaseBoxShapeUtil,\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tHTMLContainer,\n\tHandleSnapGeometry,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLGeoShape,\n\tTLGeoShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\texhaustiveSwitchError,\n\tgeoShapeMigrations,\n\tgeoShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\ttoRichText,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tSTROKE_SIZES,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { GeoShapeBody } from './components/GeoShapeBody'\nimport { getGeoShapePath } from './getGeoShapePath'\n\nconst MIN_SIZE_WITH_LABEL = 17 * 3\n\n/** @public */\nexport class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {\n\tstatic override type = 'geo' as const\n\tstatic override props = geoShapeProps\n\tstatic override migrations = geoShapeMigrations\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLGeoShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tgeo: 'rectangle',\n\t\t\tdash: 'draw',\n\t\t\tgrowY: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\n\t\t\t// Text properties\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tfill: 'none',\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLGeoShape) {\n\t\tconst w = Math.max(1, shape.props.w)\n\t\tconst h = Math.max(1, shape.props.h + shape.props.growY)\n\n\t\tconst path = getGeoShapePath(shape)\n\t\tconst unscaledlabelSize = getUnscaledLabelSize(this.editor, shape)\n\t\t// unscaled w and h\n\t\tconst unscaledW = w / shape.props.scale\n\t\tconst unscaledH = h / shape.props.scale\n\t\tconst unscaledminWidth = Math.min(100, unscaledW / 2)\n\t\tconst unscaledMinHeight = Math.min(\n\t\t\tLABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,\n\t\t\tunscaledH / 2\n\t\t)\n\n\t\tconst unscaledLabelWidth = Math.min(\n\t\t\tunscaledW,\n\t\t\tMath.max(unscaledlabelSize.w, Math.min(unscaledminWidth, Math.max(1, unscaledW - 8)))\n\t\t)\n\t\tconst unscaledLabelHeight = Math.min(\n\t\t\tunscaledH,\n\t\t\tMath.max(unscaledlabelSize.h, Math.min(unscaledMinHeight, Math.max(1, unscaledH - 8)))\n\t\t)\n\n\t\t// todo: use centroid for label position\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tpath.toGeometry(),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? (unscaledW - unscaledLabelWidth) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledW - unscaledLabelWidth) / 2) * shape.props.scale,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? (unscaledH - unscaledLabelHeight) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledH - unscaledLabelHeight) / 2) * shape.props.scale,\n\t\t\t\t\twidth: unscaledLabelWidth * shape.props.scale,\n\t\t\t\t\theight: unscaledLabelHeight * shape.props.scale,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t\tisEmptyLabel: isEmptyRichText(shape.props.richText),\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLGeoShape): HandleSnapGeometry {\n\t\tconst geometry = this.getGeometry(shape)\n\t\t// we only want to snap handles to the outline of the shape - not to its label etc.\n\t\tconst outline = geometry.children[0]\n\t\tswitch (shape.props.geo) {\n\t\t\tcase 'arrow-down':\n\t\t\tcase 'arrow-left':\n\t\t\tcase 'arrow-right':\n\t\t\tcase 'arrow-up':\n\t\t\tcase 'check-box':\n\t\t\tcase 'diamond':\n\t\t\tcase 'hexagon':\n\t\t\tcase 'octagon':\n\t\t\tcase 'pentagon':\n\t\t\tcase 'rectangle':\n\t\t\tcase 'rhombus':\n\t\t\tcase 'rhombus-2':\n\t\t\tcase 'star':\n\t\t\tcase 'trapezoid':\n\t\t\tcase 'triangle':\n\t\t\tcase 'x-box':\n\t\t\t\t// poly-line type shapes hand snap points for each vertex & the center\n\t\t\t\treturn { outline: outline, points: [...outline.vertices, geometry.bounds.center] }\n\t\t\tcase 'cloud':\n\t\t\tcase 'ellipse':\n\t\t\tcase 'heart':\n\t\t\tcase 'oval':\n\t\t\t\t// blobby shapes only have a snap point in their center\n\t\t\t\treturn { outline: outline, points: [geometry.bounds.center] }\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(shape.props.geo)\n\t\t}\n\t}\n\n\toverride getText(shape: TLGeoShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLGeoShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { fill, font, align, verticalAlign, size, richText } = props\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst { editor } = this\n\t\tconst isOnlySelected = useValue(\n\t\t\t'isGeoOnlySelected',\n\t\t\t() => shape.id === editor.getOnlySelectedShapeId(),\n\t\t\t[editor]\n\t\t)\n\t\tconst isReadyForEditing = useIsReadyForEditing(editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\t\tconst showHtmlContainer = isReadyForEditing || !isEmpty\n\t\tconst isForceSolid = useValue('force solid', () => editor.getZoomLevel() < 0.2, [editor])\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<GeoShapeBody shape={shape} shouldScale={true} forceSolid={isForceSolid} />\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showHtmlContainer && (\n\t\t\t\t\t<HTMLContainer\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\t\t\theight: shape.props.h + props.growY,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={LABEL_FONT_SIZES[size] * shape.props.scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * shape.props.scale}\n\t\t\t\t\t\t\tfill={fill}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isOnlySelected}\n\t\t\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t/>\n\t\t\t\t\t</HTMLContainer>\n\t\t\t\t)}\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLGeoShape) {\n\t\tconst isZoomedOut = useValue('isZoomedOut', () => this.editor.getZoomLevel() < 0.25, [\n\t\t\tthis.editor,\n\t\t])\n\n\t\tconst { size, dash, scale } = shape.props\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\n\t\tconst path = getGeoShapePath(shape)\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2 * scale,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t\tforceSolid: isZoomedOut,\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLGeoShape, ctx: SvgExportContext) {\n\t\tconst scale = shape.props.scale\n\t\t// We need to scale the shape to 1x for export\n\t\tconst newShape = {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tw: shape.props.w / scale,\n\t\t\t\th: (shape.props.h + shape.props.growY) / scale,\n\t\t\t\tgrowY: 0, // growY throws off the path calculations, so we set it to 0\n\t\t\t},\n\t\t}\n\t\tconst props = newShape.props\n\t\tctx.addExportDef(getFillDefForExport(props.fill))\n\n\t\tlet textEl\n\t\tif (!isEmptyRichText(props.richText)) {\n\t\t\tconst theme = getDefaultColorTheme(ctx)\n\t\t\tconst bounds = new Box(0, 0, props.w, (shape.props.h + shape.props.growY) / scale)\n\t\t\ttextEl = (\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={LABEL_FONT_SIZES[props.size]}\n\t\t\t\t\tfont={props.font}\n\t\t\t\t\talign={props.align}\n\t\t\t\t\tverticalAlign={props.verticalAlign}\n\t\t\t\t\trichText={props.richText}\n\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<GeoShapeBody shouldScale={false} shape={newShape} forceSolid={false} />\n\t\t\t\t{textEl}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(\n\t\tshape: TLGeoShape,\n\t\t{ handle, newPoint, scaleX, scaleY, initialShape }: TLResizeInfo<TLGeoShape>\n\t) {\n\t\tconst unscaledInitialW = initialShape.props.w / initialShape.props.scale\n\t\tconst unscaledInitialH = initialShape.props.h / initialShape.props.scale\n\t\tconst unscaledGrowY = initialShape.props.growY / initialShape.props.scale\n\t\t// use the w/h from props here instead of the initialBounds here,\n\t\t// since cloud shapes calculated bounds can differ from the props w/h.\n\t\tlet unscaledW = unscaledInitialW * scaleX\n\t\tlet unscaledH = (unscaledInitialH + unscaledGrowY) * scaleY\n\t\tlet overShrinkX = 0\n\t\tlet overShrinkY = 0\n\n\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\tif (!isEmptyRichText(shape.props.richText)) {\n\t\t\tlet newW = Math.max(Math.abs(unscaledW), min)\n\t\t\tlet newH = Math.max(Math.abs(unscaledH), min)\n\n\t\t\tif (newW < min && newH === min) newW = min\n\t\t\tif (newW === min && newH < min) newH = min\n\n\t\t\tconst unscaledLabelSize = getUnscaledLabelSize(this.editor, {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tw: newW * shape.props.scale,\n\t\t\t\t\th: newH * shape.props.scale,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconst nextW = Math.max(Math.abs(unscaledW), unscaledLabelSize.w) * Math.sign(unscaledW)\n\t\t\tconst nextH = Math.max(Math.abs(unscaledH), unscaledLabelSize.h) * Math.sign(unscaledH)\n\t\t\toverShrinkX = Math.abs(nextW) - Math.abs(unscaledW)\n\t\t\toverShrinkY = Math.abs(nextH) - Math.abs(unscaledH)\n\n\t\t\tunscaledW = nextW\n\t\t\tunscaledH = nextH\n\t\t}\n\n\t\tconst scaledW = unscaledW * shape.props.scale\n\t\tconst scaledH = unscaledH * shape.props.scale\n\n\t\tconst offset = new Vec(0, 0)\n\n\t\t// x offsets\n\n\t\tif (scaleX < 0) {\n\t\t\toffset.x += scaledW\n\t\t}\n\n\t\tif (handle === 'left' || handle === 'top_left' || handle === 'bottom_left') {\n\t\t\toffset.x += scaleX < 0 ? overShrinkX : -overShrinkX\n\t\t}\n\n\t\t// y offsets\n\n\t\tif (scaleY < 0) {\n\t\t\toffset.y += scaledH\n\t\t}\n\n\t\tif (handle === 'top' || handle === 'top_left' || handle === 'top_right') {\n\t\t\toffset.y += scaleY < 0 ? overShrinkY : -overShrinkY\n\t\t}\n\n\t\tconst { x, y } = offset.rot(shape.rotation).add(newPoint)\n\n\t\treturn {\n\t\t\tx,\n\t\t\ty,\n\t\t\tprops: {\n\t\t\t\tw: Math.max(Math.abs(scaledW), 1),\n\t\t\t\th: Math.max(Math.abs(scaledH), 1),\n\t\t\t\tgrowY: 0,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\tif (shape.props.growY) {\n\t\t\t\t// No text / some growY, set growY to 0\n\t\t\t\treturn {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tgrowY: 0,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// No text / no growY, nothing to change\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst unscaledPrevHeight = shape.props.h / shape.props.scale\n\t\tconst unscaledNextHeight = getUnscaledLabelSize(this.editor, shape).h\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextHeight > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextHeight - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (shape.props.growY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\t// scale the growY\n\t\t\t\t\tgrowY: growY * shape.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLGeoShape, next: TLGeoShape) {\n\t\t// No change to text, font, or size, no need to update update\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// If we got rid of the text, cancel out any growY from the prev text\n\t\tconst wasEmpty = isEmptyRichText(prev.props.richText)\n\t\tconst isEmpty = isEmptyRichText(next.props.richText)\n\t\tif (!wasEmpty && isEmpty) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// Get the prev width and height in unscaled values\n\t\tconst unscaledPrevWidth = prev.props.w / prev.props.scale\n\t\tconst unscaledPrevHeight = prev.props.h / prev.props.scale\n\t\tconst unscaledPrevGrowY = prev.props.growY / prev.props.scale\n\n\t\t// Get the next width and height in unscaled values\n\t\tconst unscaledNextLabelSize = getUnscaledLabelSize(this.editor, next)\n\n\t\t// When entering the first character in a label (not pasting in multiple characters...)\n\t\tif (wasEmpty && !isEmpty && renderPlaintextFromRichText(this.editor, next.props.richText)) {\n\t\t\tlet unscaledW = Math.max(unscaledPrevWidth, unscaledNextLabelSize.w)\n\t\t\tlet unscaledH = Math.max(unscaledPrevHeight, unscaledNextLabelSize.h)\n\n\t\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\t\t// If both the width and height were less than the minimum size, make the shape square\n\t\t\tif (unscaledPrevWidth < min && unscaledPrevHeight < min) {\n\t\t\t\tunscaledW = Math.max(unscaledW, min)\n\t\t\t\tunscaledH = Math.max(unscaledH, min)\n\t\t\t\tunscaledW = Math.max(unscaledW, unscaledH)\n\t\t\t\tunscaledH = Math.max(unscaledW, unscaledH)\n\t\t\t}\n\n\t\t\t// Don't set a growY\u2014at least, not until we've implemented a growX property\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledW * next.props.scale,\n\t\t\t\t\th: unscaledH * next.props.scale,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextLabelSize.h > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextLabelSize.h - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (unscaledPrevGrowY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\tconst unscaledNextWidth = next.props.w / next.props.scale\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tgrowY: growY * next.props.scale,\n\t\t\t\t\tw: Math.max(unscaledNextWidth, unscaledNextLabelSize.w) * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tif (unscaledNextLabelSize.w > unscaledPrevWidth) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledNextLabelSize.w * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, no update needed\n\t}\n\n\toverride onDoubleClick(shape: TLGeoShape) {\n\t\t// Little easter egg: double-clicking a rectangle / checkbox while\n\t\t// holding alt will toggle between check-box and rectangle\n\t\tif (this.editor.inputs.altKey) {\n\t\t\tswitch (shape.props.geo) {\n\t\t\t\tcase 'rectangle': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'check-box' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase 'check-box': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'rectangle' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLGeoShape,\n\t\tendShape: TLGeoShape,\n\t\tt: number\n\t): TLGeoShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n// imperfect but good enough, should be the width of the W in the font / size combo\nconst minWidths = {\n\ts: 12,\n\tm: 14,\n\tl: 16,\n\txl: 20,\n}\n\nconst extraPaddings = {\n\ts: 2,\n\tm: 3.5,\n\tl: 5,\n\txl: 10,\n}\n\nfunction getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {\n\tconst { richText, font, size, w } = shape.props\n\n\tif (!richText || isEmptyRichText(richText)) {\n\t\treturn { w: 0, h: 0 }\n\t}\n\n\t// way too expensive to be recomputing on every update\n\tconst minWidth = minWidths[size]\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst textSize = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: LABEL_FONT_SIZES[size],\n\t\tminWidth: minWidth,\n\t\tmaxWidth: Math.max(\n\t\t\t// Guard because a DOM nodes can't be less 0\n\t\t\t0,\n\t\t\t// A 'w' width that we're setting as the min-width\n\t\t\tMath.ceil(minWidth + extraPaddings[size]),\n\t\t\t// The actual text size\n\t\t\tMath.ceil(w / shape.props.scale - LABEL_PADDING * 2)\n\t\t),\n\t})\n\n\treturn {\n\t\tw: textSize.w + LABEL_PADDING * 2,\n\t\th: textSize.h + LABEL_PADDING * 2,\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBaseBoxShapeUtil,\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tHTMLContainer,\n\tHandleSnapGeometry,\n\tRectangle2d,\n\tSVGContainer,\n\tSvgExportContext,\n\tTLGeoShape,\n\tTLGeoShapeProps,\n\tTLResizeInfo,\n\tTLShapeUtilCanvasSvgDef,\n\tVec,\n\texhaustiveSwitchError,\n\tgeoShapeMigrations,\n\tgeoShapeProps,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\ttoRichText,\n\tuseValue,\n} from '@tldraw/editor'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tSTROKE_SIZES,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { getFillDefForCanvas, getFillDefForExport } from '../shared/defaultStyleDefs'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'\nimport { GeoShapeBody } from './components/GeoShapeBody'\nimport { getGeoShapePath } from './getGeoShapePath'\n\nconst MIN_SIZE_WITH_LABEL = 17 * 3\n\n/** @public */\nexport class GeoShapeUtil extends BaseBoxShapeUtil<TLGeoShape> {\n\tstatic override type = 'geo' as const\n\tstatic override props = geoShapeProps\n\tstatic override migrations = geoShapeMigrations\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\n\toverride getDefaultProps(): TLGeoShape['props'] {\n\t\treturn {\n\t\t\tw: 100,\n\t\t\th: 100,\n\t\t\tgeo: 'rectangle',\n\t\t\tdash: 'draw',\n\t\t\tgrowY: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\n\t\t\t// Text properties\n\t\t\tcolor: 'black',\n\t\t\tlabelColor: 'black',\n\t\t\tfill: 'none',\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\trichText: toRichText(''),\n\t\t}\n\t}\n\n\toverride getGeometry(shape: TLGeoShape) {\n\t\tconst w = Math.max(1, shape.props.w)\n\t\tconst h = Math.max(1, shape.props.h + shape.props.growY)\n\n\t\tconst path = getGeoShapePath(shape)\n\t\tconst unscaledlabelSize = getUnscaledLabelSize(this.editor, shape)\n\t\t// unscaled w and h\n\t\tconst unscaledW = w / shape.props.scale\n\t\tconst unscaledH = h / shape.props.scale\n\t\tconst unscaledminWidth = Math.min(100, unscaledW / 2)\n\t\tconst unscaledMinHeight = Math.min(\n\t\t\tLABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2,\n\t\t\tunscaledH / 2\n\t\t)\n\n\t\tconst unscaledLabelWidth = Math.min(\n\t\t\tunscaledW,\n\t\t\tMath.max(unscaledlabelSize.w, Math.min(unscaledminWidth, Math.max(1, unscaledW - 8)))\n\t\t)\n\t\tconst unscaledLabelHeight = Math.min(\n\t\t\tunscaledH,\n\t\t\tMath.max(unscaledlabelSize.h, Math.min(unscaledMinHeight, Math.max(1, unscaledH - 8)))\n\t\t)\n\n\t\t// todo: use centroid for label position\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tpath.toGeometry(),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? (unscaledW - unscaledLabelWidth) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledW - unscaledLabelWidth) / 2) * shape.props.scale,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? (unscaledH - unscaledLabelHeight) * shape.props.scale\n\t\t\t\t\t\t\t\t: ((unscaledH - unscaledLabelHeight) / 2) * shape.props.scale,\n\t\t\t\t\twidth: unscaledLabelWidth * shape.props.scale,\n\t\t\t\t\theight: unscaledLabelHeight * shape.props.scale,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t\tisEmptyLabel: isEmptyRichText(shape.props.richText),\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandleSnapGeometry(shape: TLGeoShape): HandleSnapGeometry {\n\t\tconst geometry = this.getGeometry(shape)\n\t\t// we only want to snap handles to the outline of the shape - not to its label etc.\n\t\tconst outline = geometry.children[0]\n\t\tswitch (shape.props.geo) {\n\t\t\tcase 'arrow-down':\n\t\t\tcase 'arrow-left':\n\t\t\tcase 'arrow-right':\n\t\t\tcase 'arrow-up':\n\t\t\tcase 'check-box':\n\t\t\tcase 'diamond':\n\t\t\tcase 'hexagon':\n\t\t\tcase 'octagon':\n\t\t\tcase 'pentagon':\n\t\t\tcase 'rectangle':\n\t\t\tcase 'rhombus':\n\t\t\tcase 'rhombus-2':\n\t\t\tcase 'star':\n\t\t\tcase 'trapezoid':\n\t\t\tcase 'triangle':\n\t\t\tcase 'x-box':\n\t\t\t\t// poly-line type shapes hand snap points for each vertex & the center\n\t\t\t\treturn { outline: outline, points: [...outline.vertices, geometry.bounds.center] }\n\t\t\tcase 'cloud':\n\t\t\tcase 'ellipse':\n\t\t\tcase 'heart':\n\t\t\tcase 'oval':\n\t\t\t\t// blobby shapes only have a snap point in their center\n\t\t\t\treturn { outline: outline, points: [geometry.bounds.center] }\n\t\t\tdefault:\n\t\t\t\texhaustiveSwitchError(shape.props.geo)\n\t\t}\n\t}\n\n\toverride getText(shape: TLGeoShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLGeoShape) {\n\t\tconst { id, type, props } = shape\n\t\tconst { fill, font, align, verticalAlign, size, richText } = props\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst { editor } = this\n\t\tconst isOnlySelected = useValue(\n\t\t\t'isGeoOnlySelected',\n\t\t\t() => shape.id === editor.getOnlySelectedShapeId(),\n\t\t\t[editor]\n\t\t)\n\t\tconst isReadyForEditing = useIsReadyForEditing(editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(shape.props.richText)\n\t\tconst showHtmlContainer = isReadyForEditing || !isEmpty\n\t\tconst isForceSolid = useEfficientZoomThreshold(shape.props.scale * 0.25)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<SVGContainer>\n\t\t\t\t\t<GeoShapeBody shape={shape} shouldScale={true} forceSolid={isForceSolid} />\n\t\t\t\t</SVGContainer>\n\t\t\t\t{showHtmlContainer && (\n\t\t\t\t\t<HTMLContainer\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\t\twidth: shape.props.w,\n\t\t\t\t\t\t\theight: shape.props.h + props.growY,\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={LABEL_FONT_SIZES[size] * shape.props.scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * shape.props.scale}\n\t\t\t\t\t\t\tfill={fill}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isOnlySelected}\n\t\t\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t/>\n\t\t\t\t\t</HTMLContainer>\n\t\t\t\t)}\n\t\t\t\t{shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLGeoShape) {\n\t\tconst isZoomedOut = useEfficientZoomThreshold(shape.props.scale * 0.25)\n\n\t\tconst { size, dash, scale } = shape.props\n\t\tconst strokeWidth = STROKE_SIZES[size]\n\n\t\tconst path = getGeoShapePath(shape)\n\n\t\treturn path.toSvg({\n\t\t\tstyle: dash === 'draw' ? 'draw' : 'solid',\n\t\t\tstrokeWidth: 1,\n\t\t\tpasses: 1,\n\t\t\trandomSeed: shape.id,\n\t\t\toffset: 0,\n\t\t\troundness: strokeWidth * 2 * scale,\n\t\t\tprops: { strokeWidth: undefined },\n\t\t\tforceSolid: isZoomedOut,\n\t\t})\n\t}\n\n\toverride toSvg(shape: TLGeoShape, ctx: SvgExportContext) {\n\t\tconst scale = shape.props.scale\n\t\t// We need to scale the shape to 1x for export\n\t\tconst newShape = {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tw: shape.props.w / scale,\n\t\t\t\th: (shape.props.h + shape.props.growY) / scale,\n\t\t\t\tgrowY: 0, // growY throws off the path calculations, so we set it to 0\n\t\t\t},\n\t\t}\n\t\tconst props = newShape.props\n\t\tctx.addExportDef(getFillDefForExport(props.fill))\n\n\t\tlet textEl\n\t\tif (!isEmptyRichText(props.richText)) {\n\t\t\tconst theme = getDefaultColorTheme(ctx)\n\t\t\tconst bounds = new Box(0, 0, props.w, (shape.props.h + shape.props.growY) / scale)\n\t\t\ttextEl = (\n\t\t\t\t<RichTextSVG\n\t\t\t\t\tfontSize={LABEL_FONT_SIZES[props.size]}\n\t\t\t\t\tfont={props.font}\n\t\t\t\t\talign={props.align}\n\t\t\t\t\tverticalAlign={props.verticalAlign}\n\t\t\t\t\trichText={props.richText}\n\t\t\t\t\tlabelColor={getColorValue(theme, props.labelColor, 'solid')}\n\t\t\t\t\tbounds={bounds}\n\t\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\t/>\n\t\t\t)\n\t\t}\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<GeoShapeBody shouldScale={false} shape={newShape} forceSolid={false} />\n\t\t\t\t{textEl}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride getCanvasSvgDefs(): TLShapeUtilCanvasSvgDef[] {\n\t\treturn [getFillDefForCanvas()]\n\t}\n\n\toverride onResize(\n\t\tshape: TLGeoShape,\n\t\t{ handle, newPoint, scaleX, scaleY, initialShape }: TLResizeInfo<TLGeoShape>\n\t) {\n\t\tconst unscaledInitialW = initialShape.props.w / initialShape.props.scale\n\t\tconst unscaledInitialH = initialShape.props.h / initialShape.props.scale\n\t\tconst unscaledGrowY = initialShape.props.growY / initialShape.props.scale\n\t\t// use the w/h from props here instead of the initialBounds here,\n\t\t// since cloud shapes calculated bounds can differ from the props w/h.\n\t\tlet unscaledW = unscaledInitialW * scaleX\n\t\tlet unscaledH = (unscaledInitialH + unscaledGrowY) * scaleY\n\t\tlet overShrinkX = 0\n\t\tlet overShrinkY = 0\n\n\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\tif (!isEmptyRichText(shape.props.richText)) {\n\t\t\tlet newW = Math.max(Math.abs(unscaledW), min)\n\t\t\tlet newH = Math.max(Math.abs(unscaledH), min)\n\n\t\t\tif (newW < min && newH === min) newW = min\n\t\t\tif (newW === min && newH < min) newH = min\n\n\t\t\tconst unscaledLabelSize = getUnscaledLabelSize(this.editor, {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\tw: newW * shape.props.scale,\n\t\t\t\t\th: newH * shape.props.scale,\n\t\t\t\t},\n\t\t\t})\n\n\t\t\tconst nextW = Math.max(Math.abs(unscaledW), unscaledLabelSize.w) * Math.sign(unscaledW)\n\t\t\tconst nextH = Math.max(Math.abs(unscaledH), unscaledLabelSize.h) * Math.sign(unscaledH)\n\t\t\toverShrinkX = Math.abs(nextW) - Math.abs(unscaledW)\n\t\t\toverShrinkY = Math.abs(nextH) - Math.abs(unscaledH)\n\n\t\t\tunscaledW = nextW\n\t\t\tunscaledH = nextH\n\t\t}\n\n\t\tconst scaledW = unscaledW * shape.props.scale\n\t\tconst scaledH = unscaledH * shape.props.scale\n\n\t\tconst offset = new Vec(0, 0)\n\n\t\t// x offsets\n\n\t\tif (scaleX < 0) {\n\t\t\toffset.x += scaledW\n\t\t}\n\n\t\tif (handle === 'left' || handle === 'top_left' || handle === 'bottom_left') {\n\t\t\toffset.x += scaleX < 0 ? overShrinkX : -overShrinkX\n\t\t}\n\n\t\t// y offsets\n\n\t\tif (scaleY < 0) {\n\t\t\toffset.y += scaledH\n\t\t}\n\n\t\tif (handle === 'top' || handle === 'top_left' || handle === 'top_right') {\n\t\t\toffset.y += scaleY < 0 ? overShrinkY : -overShrinkY\n\t\t}\n\n\t\tconst { x, y } = offset.rot(shape.rotation).add(newPoint)\n\n\t\treturn {\n\t\t\tx,\n\t\t\ty,\n\t\t\tprops: {\n\t\t\t\tw: Math.max(Math.abs(scaledW), 1),\n\t\t\t\th: Math.max(Math.abs(scaledH), 1),\n\t\t\t\tgrowY: 0,\n\t\t\t},\n\t\t}\n\t}\n\n\toverride onBeforeCreate(shape: TLGeoShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\tif (shape.props.growY) {\n\t\t\t\t// No text / some growY, set growY to 0\n\t\t\t\treturn {\n\t\t\t\t\t...shape,\n\t\t\t\t\tprops: {\n\t\t\t\t\t\t...shape.props,\n\t\t\t\t\t\tgrowY: 0,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// No text / no growY, nothing to change\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tconst unscaledPrevHeight = shape.props.h / shape.props.scale\n\t\tconst unscaledNextHeight = getUnscaledLabelSize(this.editor, shape).h\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextHeight > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextHeight - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (shape.props.growY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\treturn {\n\t\t\t\t...shape,\n\t\t\t\tprops: {\n\t\t\t\t\t...shape.props,\n\t\t\t\t\t// scale the growY\n\t\t\t\t\tgrowY: growY * shape.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t}\n\n\toverride onBeforeUpdate(prev: TLGeoShape, next: TLGeoShape) {\n\t\t// No change to text, font, or size, no need to update update\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\t// If we got rid of the text, cancel out any growY from the prev text\n\t\tconst wasEmpty = isEmptyRichText(prev.props.richText)\n\t\tconst isEmpty = isEmptyRichText(next.props.richText)\n\t\tif (!wasEmpty && isEmpty) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// Get the prev width and height in unscaled values\n\t\tconst unscaledPrevWidth = prev.props.w / prev.props.scale\n\t\tconst unscaledPrevHeight = prev.props.h / prev.props.scale\n\t\tconst unscaledPrevGrowY = prev.props.growY / prev.props.scale\n\n\t\t// Get the next width and height in unscaled values\n\t\tconst unscaledNextLabelSize = getUnscaledLabelSize(this.editor, next)\n\n\t\t// When entering the first character in a label (not pasting in multiple characters...)\n\t\tif (wasEmpty && !isEmpty && renderPlaintextFromRichText(this.editor, next.props.richText)) {\n\t\t\tlet unscaledW = Math.max(unscaledPrevWidth, unscaledNextLabelSize.w)\n\t\t\tlet unscaledH = Math.max(unscaledPrevHeight, unscaledNextLabelSize.h)\n\n\t\t\tconst min = MIN_SIZE_WITH_LABEL\n\n\t\t\t// If both the width and height were less than the minimum size, make the shape square\n\t\t\tif (unscaledPrevWidth < min && unscaledPrevHeight < min) {\n\t\t\t\tunscaledW = Math.max(unscaledW, min)\n\t\t\t\tunscaledH = Math.max(unscaledH, min)\n\t\t\t\tunscaledW = Math.max(unscaledW, unscaledH)\n\t\t\t\tunscaledH = Math.max(unscaledW, unscaledH)\n\t\t\t}\n\n\t\t\t// Don't set a growY\u2014at least, not until we've implemented a growX property\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledW * next.props.scale,\n\t\t\t\t\th: unscaledH * next.props.scale,\n\t\t\t\t\tgrowY: 0,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tlet growY: number | null = null\n\n\t\tif (unscaledNextLabelSize.h > unscaledPrevHeight) {\n\t\t\tgrowY = unscaledNextLabelSize.h - unscaledPrevHeight\n\t\t} else {\n\t\t\tif (unscaledPrevGrowY) {\n\t\t\t\tgrowY = 0\n\t\t\t}\n\t\t}\n\n\t\tif (growY !== null) {\n\t\t\tconst unscaledNextWidth = next.props.w / next.props.scale\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tgrowY: growY * next.props.scale,\n\t\t\t\t\tw: Math.max(unscaledNextWidth, unscaledNextLabelSize.w) * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\tif (unscaledNextLabelSize.w > unscaledPrevWidth) {\n\t\t\treturn {\n\t\t\t\t...next,\n\t\t\t\tprops: {\n\t\t\t\t\t...next.props,\n\t\t\t\t\t// Scale the results\n\t\t\t\t\tw: unscaledNextLabelSize.w * next.props.scale,\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\n\t\t// otherwise, no update needed\n\t}\n\n\toverride onDoubleClick(shape: TLGeoShape) {\n\t\t// Little easter egg: double-clicking a rectangle / checkbox while\n\t\t// holding alt will toggle between check-box and rectangle\n\t\tif (this.editor.inputs.altKey) {\n\t\t\tswitch (shape.props.geo) {\n\t\t\t\tcase 'rectangle': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'check-box' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcase 'check-box': {\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...shape,\n\t\t\t\t\t\tprops: {\n\t\t\t\t\t\t\tgeo: 'rectangle' as const,\n\t\t\t\t\t\t},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLGeoShape,\n\t\tendShape: TLGeoShape,\n\t\tt: number\n\t): TLGeoShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tw: lerp(startShape.props.w, endShape.props.w, t),\n\t\t\th: lerp(startShape.props.h, endShape.props.h, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n// imperfect but good enough, should be the width of the W in the font / size combo\nconst minWidths = {\n\ts: 12,\n\tm: 14,\n\tl: 16,\n\txl: 20,\n}\n\nconst extraPaddings = {\n\ts: 2,\n\tm: 3.5,\n\tl: 5,\n\txl: 10,\n}\n\nfunction getUnscaledLabelSize(editor: Editor, shape: TLGeoShape) {\n\tconst { richText, font, size, w } = shape.props\n\n\tif (!richText || isEmptyRichText(richText)) {\n\t\treturn { w: 0, h: 0 }\n\t}\n\n\t// way too expensive to be recomputing on every update\n\tconst minWidth = minWidths[size]\n\n\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\tconst textSize = editor.textMeasure.measureHtml(html, {\n\t\t...TEXT_PROPS,\n\t\tfontFamily: FONT_FAMILIES[font],\n\t\tfontSize: LABEL_FONT_SIZES[size],\n\t\tminWidth: minWidth,\n\t\tmaxWidth: Math.max(\n\t\t\t// Guard because a DOM nodes can't be less 0\n\t\t\t0,\n\t\t\t// A 'w' width that we're setting as the min-width\n\t\t\tMath.ceil(minWidth + extraPaddings[size]),\n\t\t\t// The actual text size\n\t\t\tMath.ceil(w / shape.props.scale - LABEL_PADDING * 2)\n\t\t),\n\t})\n\n\treturn {\n\t\tw: textSize.w + LABEL_PADDING * 2,\n\t\th: textSize.h + LABEL_PADDING * 2,\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -234,7 +234,7 @@ function useHighlightForceSolid(editor, shape) {
234
234
  "forceSolid",
235
235
  () => {
236
236
  const sw = getStrokeWidth(shape);
237
- const zoomLevel = editor.getZoomLevel();
237
+ const zoomLevel = editor.getEfficientZoomLevel();
238
238
  if (sw / zoomLevel < 1.5) {
239
239
  return true;
240
240
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/highlight/HighlightShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\tgetColorValue,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: scaleX * x,\n\t\t\t\t\t\ty: scaleY * y,\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tforceSolid,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tforceSolid: boolean\n\tshape: TLHighlightShape\n\topacity: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === 'straight',\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(shape.props.segments[0].points[0])\n\n\tconst colorSpace = useColorSpace()\n\n\tconst color = getColorValue(\n\t\ttheme,\n\t\tshape.props.color,\n\t\tcolorSpace === 'p3' ? 'highlightP3' : 'highlightSrgb'\n\t)\n\n\treturn (\n\t\t<path\n\t\t\td={solidStrokePath}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tfill=\"none\"\n\t\t\tpointerEvents=\"all\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={sw}\n\t\t\topacity={opacity}\n\t\t/>\n\t)\n}\n\nfunction useHighlightForceSolid(editor: Editor, shape: TLHighlightShape) {\n\treturn useValue(\n\t\t'forceSolid',\n\t\t() => {\n\t\t\tconst sw = getStrokeWidth(shape)\n\t\t\tconst zoomLevel = editor.getZoomLevel()\n\t\t\tif (sw / zoomLevel < 1.5) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\t\t[editor]\n\t)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tCircle2d,\n\tEditor,\n\tPolygon2d,\n\tSVGContainer,\n\tShapeUtil,\n\tTLDrawShapeSegment,\n\tTLHighlightShape,\n\tTLHighlightShapeProps,\n\tTLResizeInfo,\n\tVecLike,\n\tgetColorValue,\n\thighlightShapeMigrations,\n\thighlightShapeProps,\n\tlast,\n\tlerp,\n\trng,\n\tuseValue,\n} from '@tldraw/editor'\n\nimport { getHighlightFreehandSettings, getPointsFromSegments } from '../draw/getPath'\nimport { FONT_SIZES } from '../shared/default-shape-constants'\nimport { getStrokeOutlinePoints } from '../shared/freehand/getStrokeOutlinePoints'\nimport { getStrokePoints } from '../shared/freehand/getStrokePoints'\nimport { setStrokePointRadii } from '../shared/freehand/setStrokePointRadii'\nimport { getSvgPathFromStrokePoints } from '../shared/freehand/svg'\nimport { interpolateSegments } from '../shared/interpolate-props'\nimport { useColorSpace } from '../shared/useColorSpace'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\n\n/** @public */\nexport interface HighlightShapeOptions {\n\t/**\n\t * The maximum number of points in a line before the draw tool will begin a new shape.\n\t * A higher number will lead to poor performance while drawing very long lines.\n\t */\n\treadonly maxPointsPerShape: number\n\treadonly underlayOpacity: number\n\treadonly overlayOpacity: number\n}\n\n/** @public */\nexport class HighlightShapeUtil extends ShapeUtil<TLHighlightShape> {\n\tstatic override type = 'highlight' as const\n\tstatic override props = highlightShapeProps\n\tstatic override migrations = highlightShapeMigrations\n\n\toverride options: HighlightShapeOptions = {\n\t\tmaxPointsPerShape: 600,\n\t\tunderlayOpacity: 0.82,\n\t\toverlayOpacity: 0.35,\n\t}\n\n\toverride hideResizeHandles(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideRotateHandle(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\toverride hideSelectionBoundsFg(shape: TLHighlightShape) {\n\t\treturn getIsDot(shape)\n\t}\n\n\toverride getDefaultProps(): TLHighlightShape['props'] {\n\t\treturn {\n\t\t\tsegments: [],\n\t\t\tcolor: 'black',\n\t\t\tsize: 'm',\n\t\t\tisComplete: false,\n\t\t\tisPen: false,\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tif (getIsDot(shape)) {\n\t\t\treturn new Circle2d({\n\t\t\t\tx: -strokeWidth / 2,\n\t\t\t\ty: -strokeWidth / 2,\n\t\t\t\tradius: strokeWidth / 2,\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true)\n\t\tconst opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true })\n\t\tsetStrokePointRadii(strokePoints, opts)\n\n\t\treturn new Polygon2d({\n\t\t\tpoints: getStrokeOutlinePoints(strokePoints, opts),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tcomponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\toverride backgroundComponent(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\treturn (\n\t\t\t<SVGContainer>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tshape={shape}\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</SVGContainer>\n\t\t)\n\t}\n\n\tindicator(shape: TLHighlightShape) {\n\t\tconst forceSolid = useHighlightForceSolid(this.editor, shape)\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\n\t\tconst { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid)\n\t\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\t\tlet strokePath\n\t\tif (strokePoints.length < 2) {\n\t\t\tstrokePath = getIndicatorDot(allPointsFromSegments[0], sw)\n\t\t} else {\n\t\t\tstrokePath = getSvgPathFromStrokePoints(strokePoints, false)\n\t\t}\n\n\t\treturn <path d={strokePath} />\n\t}\n\n\toverride toSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.overlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride toBackgroundSvg(shape: TLHighlightShape) {\n\t\tconst strokeWidth = getStrokeWidth(shape)\n\t\tconst forceSolid = strokeWidth < 1.5\n\t\tconst scaleFactor = 1 / shape.props.scale\n\t\treturn (\n\t\t\t<g transform={`scale(${scaleFactor})`}>\n\t\t\t\t<HighlightRenderer\n\t\t\t\t\tforceSolid={forceSolid}\n\t\t\t\t\tstrokeWidth={strokeWidth}\n\t\t\t\t\tshape={shape}\n\t\t\t\t\topacity={this.options.underlayOpacity}\n\t\t\t\t/>\n\t\t\t</g>\n\t\t)\n\t}\n\n\toverride onResize(shape: TLHighlightShape, info: TLResizeInfo<TLHighlightShape>) {\n\t\tconst { scaleX, scaleY } = info\n\n\t\tconst newSegments: TLDrawShapeSegment[] = []\n\n\t\tfor (const segment of shape.props.segments) {\n\t\t\tnewSegments.push({\n\t\t\t\t...segment,\n\t\t\t\tpoints: segment.points.map(({ x, y, z }) => {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tx: scaleX * x,\n\t\t\t\t\t\ty: scaleY * y,\n\t\t\t\t\t\tz,\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t})\n\t\t}\n\n\t\treturn {\n\t\t\tprops: {\n\t\t\t\tsegments: newSegments,\n\t\t\t},\n\t\t}\n\t}\n\toverride getInterpolatedProps(\n\t\tstartShape: TLHighlightShape,\n\t\tendShape: TLHighlightShape,\n\t\tt: number\n\t): TLHighlightShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\t...endShape.props,\n\t\t\tsegments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\nfunction getShapeDot(point: VecLike) {\n\tconst r = 0.1\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getIndicatorDot(point: VecLike, sw: number) {\n\tconst r = sw / 2\n\treturn `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${\n\t\tr * 2\n\t},0`\n}\n\nfunction getHighlightStrokePoints(\n\tshape: TLHighlightShape,\n\tstrokeWidth: number,\n\tforceSolid: boolean\n) {\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\tconst showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === 'straight'\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (strokeWidth / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete,\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\treturn { strokePoints, sw }\n}\n\nfunction getStrokeWidth(shape: TLHighlightShape) {\n\treturn FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale\n}\n\nfunction getIsDot(shape: TLHighlightShape) {\n\treturn shape.props.segments.length === 1 && shape.props.segments[0].points.length < 2\n}\n\nfunction HighlightRenderer({\n\tstrokeWidth,\n\tforceSolid,\n\tshape,\n\topacity,\n}: {\n\tstrokeWidth: number\n\tforceSolid: boolean\n\tshape: TLHighlightShape\n\topacity: number\n}) {\n\tconst theme = useDefaultColorTheme()\n\n\tconst allPointsFromSegments = getPointsFromSegments(shape.props.segments)\n\n\tlet sw = strokeWidth\n\tif (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {\n\t\tsw += rng(shape.id)() * (sw / 6)\n\t}\n\n\tconst options = getHighlightFreehandSettings({\n\t\tstrokeWidth: sw,\n\t\tshowAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === 'straight',\n\t})\n\n\tconst strokePoints = getStrokePoints(allPointsFromSegments, options)\n\n\tconst solidStrokePath =\n\t\tstrokePoints.length > 1\n\t\t\t? getSvgPathFromStrokePoints(strokePoints, false)\n\t\t\t: getShapeDot(shape.props.segments[0].points[0])\n\n\tconst colorSpace = useColorSpace()\n\n\tconst color = getColorValue(\n\t\ttheme,\n\t\tshape.props.color,\n\t\tcolorSpace === 'p3' ? 'highlightP3' : 'highlightSrgb'\n\t)\n\n\treturn (\n\t\t<path\n\t\t\td={solidStrokePath}\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tfill=\"none\"\n\t\t\tpointerEvents=\"all\"\n\t\t\tstroke={color}\n\t\t\tstrokeWidth={sw}\n\t\t\topacity={opacity}\n\t\t/>\n\t)\n}\n\nfunction useHighlightForceSolid(editor: Editor, shape: TLHighlightShape) {\n\treturn useValue(\n\t\t'forceSolid',\n\t\t() => {\n\t\t\tconst sw = getStrokeWidth(shape)\n\t\t\tconst zoomLevel = editor.getEfficientZoomLevel()\n\t\t\tif (sw / zoomLevel < 1.5) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\treturn false\n\t\t},\n\t\t[editor]\n\t)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -41,6 +41,7 @@ import {
41
41
  } from "../shared/default-shape-constants.mjs";
42
42
  import { useDefaultColorTheme } from "../shared/useDefaultColorTheme.mjs";
43
43
  import { useIsReadyForEditing } from "../shared/useEditablePlainText.mjs";
44
+ import { useEfficientZoomThreshold } from "../shared/useEfficientZoomThreshold.mjs";
44
45
  import {
45
46
  CLONE_HANDLE_MARGIN,
46
47
  NOTE_CENTER_OFFSET,
@@ -118,7 +119,7 @@ class NoteShapeUtil extends ShapeUtil {
118
119
  const { scale } = shape.props;
119
120
  const isCoarsePointer = this.editor.getInstanceState().isCoarsePointer;
120
121
  if (isCoarsePointer) return [];
121
- const zoom = this.editor.getZoomLevel();
122
+ const zoom = this.editor.getEfficientZoomLevel();
122
123
  if (zoom * scale < 0.25) return [];
123
124
  const nh = getNoteHeight(shape);
124
125
  const nw = NOTE_SIZE * scale;
@@ -217,11 +218,9 @@ class NoteShapeUtil extends ShapeUtil {
217
218
  () => this.editor.getShapePageTransform(id)?.rotation() ?? 0,
218
219
  [this.editor]
219
220
  );
220
- const hideShadows = useValue("zoom", () => this.editor.getZoomLevel() < 0.35 / scale, [
221
- scale,
222
- this.editor
223
- ]);
224
221
  const isDarkMode = useValue("dark mode", () => this.editor.user.getIsDarkMode(), [this.editor]);
222
+ let hideShadows = useEfficientZoomThreshold(scale * 0.25);
223
+ if (isDarkMode) hideShadows = true;
225
224
  const isSelected = shape.id === this.editor.getOnlySelectedShapeId();
226
225
  const isReadyForEditing = useIsReadyForEditing(this.editor, shape.id);
227
226
  const isEmpty = isEmptyRichText(richText);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/note/NoteShapeUtil.tsx"],
4
- "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tIndexKey,\n\tRectangle2d,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLHandle,\n\tTLNoteShape,\n\tTLNoteShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tWeakCache,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\tnoteShapeMigrations,\n\tnoteShapeProps,\n\tresizeScaled,\n\trng,\n\ttoDomPrecision,\n\ttoRichText,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useContext } from 'react'\nimport { startEditingShapeWithLabel } from '../../tools/SelectTool/selectHelpers'\nimport { TranslationsContext } from '../../ui/hooks/useTranslation/useTranslation'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { isRightToLeftLanguage } from '../../utils/text/text'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport {\n\tCLONE_HANDLE_MARGIN,\n\tNOTE_CENTER_OFFSET,\n\tNOTE_SIZE,\n\tgetNoteShapeForAdjacentPosition,\n} from './noteHelpers'\n\n/** @public */\nexport interface NoteShapeOptions {\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\tresizeMode: 'none' | 'scale'\n}\n\n/** @public */\nexport class NoteShapeUtil extends ShapeUtil<TLNoteShape> {\n\tstatic override type = 'note' as const\n\tstatic override props = noteShapeProps\n\tstatic override migrations = noteShapeMigrations\n\n\toverride options: NoteShapeOptions = {\n\t\tresizeMode: 'none',\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride hideResizeHandles() {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked() {\n\t\treturn this.options.resizeMode === 'scale'\n\t}\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn false\n\t}\n\n\tgetDefaultProps(): TLNoteShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\trichText: toRichText(''),\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tlabelColor: 'black',\n\t\t\tgrowY: 0,\n\t\t\tfontSizeAdjustment: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLNoteShape) {\n\t\tconst { labelHeight, labelWidth } = getLabelSize(this.editor, shape)\n\t\tconst { scale } = shape.props\n\n\t\tconst lh = labelHeight * scale\n\t\tconst lw = labelWidth * scale\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst nh = getNoteHeight(shape)\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({ width: nw, height: nh, isFilled: true }),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? nw - lw\n\t\t\t\t\t\t\t\t: (nw - lw) / 2,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? nh - lh\n\t\t\t\t\t\t\t\t: (nh - lh) / 2,\n\t\t\t\t\twidth: lw,\n\t\t\t\t\theight: lh,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLNoteShape): TLHandle[] {\n\t\tconst { scale } = shape.props\n\t\tconst isCoarsePointer = this.editor.getInstanceState().isCoarsePointer\n\t\tif (isCoarsePointer) return []\n\n\t\tconst zoom = this.editor.getZoomLevel()\n\t\tif (zoom * scale < 0.25) return []\n\n\t\tconst nh = getNoteHeight(shape)\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst offset = (CLONE_HANDLE_MARGIN / zoom) * scale\n\n\t\tif (zoom * scale < 0.5) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'bottom',\n\t\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\t\ttype: 'clone',\n\t\t\t\t\tx: nw / 2,\n\t\t\t\t\ty: nh + offset,\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: 'top',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: -offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'right',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw + offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bottom',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: nh + offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'left',\n\t\t\t\tindex: 'a4' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: -offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t]\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn resizeScaled(shape, info)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride getText(shape: TLNoteShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLNoteShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLNoteShape) {\n\t\tconst {\n\t\t\tid,\n\t\t\ttype,\n\t\t\tprops: {\n\t\t\t\tlabelColor,\n\t\t\t\tscale,\n\t\t\t\tcolor,\n\t\t\t\tfont,\n\t\t\t\tsize,\n\t\t\t\talign,\n\t\t\t\trichText,\n\t\t\t\tverticalAlign,\n\t\t\t\tfontSizeAdjustment,\n\t\t\t},\n\t\t} = shape\n\n\t\tconst handleKeyDown = useNoteKeydownHandler(id)\n\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst nh = getNoteHeight(shape)\n\n\t\tconst rotation = useValue(\n\t\t\t'shape rotation',\n\t\t\t() => this.editor.getShapePageTransform(id)?.rotation() ?? 0,\n\t\t\t[this.editor]\n\t\t)\n\n\t\t// todo: consider hiding shadows on dark mode if they're invisible anyway\n\n\t\tconst hideShadows = useValue('zoom', () => this.editor.getZoomLevel() < 0.35 / scale, [\n\t\t\tscale,\n\t\t\tthis.editor,\n\t\t])\n\n\t\tconst isDarkMode = useValue('dark mode', () => this.editor.user.getIsDarkMode(), [this.editor])\n\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\n\t\tconst isReadyForEditing = useIsReadyForEditing(this.editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(richText)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div\n\t\t\t\t\tid={id}\n\t\t\t\t\tclassName=\"tl-note__container\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: nw,\n\t\t\t\t\t\theight: nh,\n\t\t\t\t\t\tbackgroundColor: getColorValue(theme, color, 'noteFill'),\n\t\t\t\t\t\tborderBottom: hideShadows\n\t\t\t\t\t\t\t? isDarkMode\n\t\t\t\t\t\t\t\t? `${2 * scale}px solid rgb(20, 20, 20)`\n\t\t\t\t\t\t\t\t: `${2 * scale}px solid rgb(144, 144, 144)`\n\t\t\t\t\t\t\t: 'none',\n\t\t\t\t\t\tboxShadow: hideShadows ? 'none' : getNoteShadow(shape.id, rotation, scale),\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{(isSelected || isReadyForEditing || !isEmpty) && (\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={(fontSizeAdjustment || LABEL_FONT_SIZES[size]) * scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\t\tlabelColor={\n\t\t\t\t\t\t\t\tlabelColor === 'black'\n\t\t\t\t\t\t\t\t\t? getColorValue(theme, color, 'noteText')\n\t\t\t\t\t\t\t\t\t: getColorValue(theme, labelColor, 'fill')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * scale}\n\t\t\t\t\t\t\thasCustomTabBehavior\n\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLNoteShape) {\n\t\tconst { scale } = shape.props\n\t\treturn (\n\t\t\t<rect\n\t\t\t\trx={scale}\n\t\t\t\twidth={toDomPrecision(NOTE_SIZE * scale)}\n\t\t\t\theight={toDomPrecision(getNoteHeight(shape))}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLNoteShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\t\tconst bounds = getBoundsForSVG(shape)\n\n\t\tconst textLabel = (\n\t\t\t<RichTextSVG\n\t\t\t\tfontSize={shape.props.fontSizeAdjustment || LABEL_FONT_SIZES[shape.props.size]}\n\t\t\t\tfont={shape.props.font}\n\t\t\t\talign={shape.props.align}\n\t\t\t\tverticalAlign={shape.props.verticalAlign}\n\t\t\t\trichText={shape.props.richText}\n\t\t\t\tlabelColor={getColorValue(theme, shape.props.color, 'noteText')}\n\t\t\t\tbounds={bounds}\n\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\tshowTextOutline={false}\n\t\t\t/>\n\t\t)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect x={5} y={5} rx={1} width={NOTE_SIZE - 10} height={bounds.h} fill=\"rgba(0,0,0,.1)\" />\n\t\t\t\t<rect\n\t\t\t\t\trx={1}\n\t\t\t\t\twidth={NOTE_SIZE}\n\t\t\t\t\theight={bounds.h}\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'noteFill')}\n\t\t\t\t/>\n\t\t\t\t{textLabel}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLNoteShape) {\n\t\treturn getNoteSizeAdjustments(this.editor, next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLNoteShape, next: TLNoteShape) {\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\treturn getNoteSizeAdjustments(this.editor, next)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLNoteShape,\n\t\tendShape: TLNoteShape,\n\t\tt: number\n\t): TLNoteShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n/**\n * Get the growY and fontSizeAdjustment for a shape.\n */\nfunction getNoteSizeAdjustments(editor: Editor, shape: TLNoteShape) {\n\tconst { labelHeight, fontSizeAdjustment } = getLabelSize(editor, shape)\n\t// When the label height is more than the height of the shape, we add extra height to it\n\tconst growY = Math.max(0, labelHeight - NOTE_SIZE)\n\n\tif (growY !== shape.props.growY || fontSizeAdjustment !== shape.props.fontSizeAdjustment) {\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tgrowY,\n\t\t\t\tfontSizeAdjustment,\n\t\t\t},\n\t\t}\n\t}\n}\n\n/**\n * Get the label size for a note.\n */\nfunction getNoteLabelSize(editor: Editor, shape: TLNoteShape) {\n\tconst { richText } = shape.props\n\n\tif (isEmptyRichText(richText)) {\n\t\tconst minHeight = LABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2\n\t\treturn { labelHeight: minHeight, labelWidth: 100, fontSizeAdjustment: 0 }\n\t}\n\n\tconst unadjustedFontSize = LABEL_FONT_SIZES[shape.props.size]\n\n\tlet fontSizeAdjustment = 0\n\tlet iterations = 0\n\tlet labelHeight = NOTE_SIZE\n\tlet labelWidth = NOTE_SIZE\n\n\t// N.B. For some note shapes with text like 'hjhjhjhjhjhjhjhj', you'll run into\n\t// some text measurement fuzziness where the browser swears there's no overflow (scrollWidth === width)\n\t// but really there is when you enable overflow-wrap again. This helps account for that little bit\n\t// of give.\n\tconst FUZZ = 1\n\n\t// We slightly make the font smaller if the text is too big for the note, width-wise.\n\tdo {\n\t\tfontSizeAdjustment = Math.min(unadjustedFontSize, unadjustedFontSize - iterations)\n\t\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\t\tconst nextTextSize = editor.textMeasure.measureHtml(html, {\n\t\t\t...TEXT_PROPS,\n\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\tfontSize: fontSizeAdjustment,\n\t\t\tmaxWidth: NOTE_SIZE - LABEL_PADDING * 2 - FUZZ,\n\t\t\tdisableOverflowWrapBreaking: true,\n\t\t\tmeasureScrollWidth: true,\n\t\t})\n\n\t\tlabelHeight = nextTextSize.h + LABEL_PADDING * 2\n\t\tlabelWidth = nextTextSize.w + LABEL_PADDING * 2\n\n\t\tif (fontSizeAdjustment <= 14) {\n\t\t\t// Too small, just rely now on CSS `overflow-wrap: break-word`\n\t\t\t// We need to recalculate the text measurement here with break-word enabled.\n\t\t\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\t\t\tconst nextTextSizeWithOverflowBreak = editor.textMeasure.measureHtml(html, {\n\t\t\t\t...TEXT_PROPS,\n\t\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\tmaxWidth: NOTE_SIZE - LABEL_PADDING * 2 - FUZZ,\n\t\t\t})\n\t\t\tlabelHeight = nextTextSizeWithOverflowBreak.h + LABEL_PADDING * 2\n\t\t\tlabelWidth = nextTextSizeWithOverflowBreak.w + LABEL_PADDING * 2\n\t\t\tbreak\n\t\t}\n\n\t\tif (nextTextSize.scrollWidth.toFixed(0) === nextTextSize.w.toFixed(0)) {\n\t\t\tbreak\n\t\t}\n\t} while (iterations++ < 50)\n\n\treturn {\n\t\tlabelHeight: labelHeight,\n\t\tlabelWidth: labelWidth,\n\t\tfontSizeAdjustment: fontSizeAdjustment,\n\t}\n}\n\nconst labelSizesForNote = new WeakCache<TLShape, ReturnType<typeof getNoteLabelSize>>()\n\nfunction getLabelSize(editor: Editor, shape: TLNoteShape) {\n\treturn labelSizesForNote.get(shape, () => getNoteLabelSize(editor, shape))\n}\n\nfunction useNoteKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\t// Try to get the translation context, but fallback to ltr if it doesn't exist\n\tconst translation = useContext(TranslationsContext)\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst shape = editor.getShape<TLNoteShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst isTab = e.key === 'Tab'\n\t\t\tconst isCmdEnter = (e.metaKey || e.ctrlKey) && e.key === 'Enter'\n\t\t\tif (isTab || isCmdEnter) {\n\t\t\t\te.preventDefault()\n\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\t\t// Based on the inputs, calculate the offset to the next note\n\t\t\t\t// tab controls x axis (shift inverts direction set by RTL)\n\t\t\t\t// cmd enter is the y axis (shift inverts direction)\n\t\t\t\tconst isRTL = !!(\n\t\t\t\t\ttranslation?.dir === 'rtl' ||\n\t\t\t\t\t// todo: can we check a partial of the text, so that we don't have to render the whole thing?\n\t\t\t\t\tisRightToLeftLanguage(renderPlaintextFromRichText(editor, shape.props.richText))\n\t\t\t\t)\n\n\t\t\t\tconst offsetLength =\n\t\t\t\t\t(NOTE_SIZE +\n\t\t\t\t\t\teditor.options.adjacentShapeMargin +\n\t\t\t\t\t\t// If we're growing down, we need to account for the current shape's growY\n\t\t\t\t\t\t(isCmdEnter && !e.shiftKey ? shape.props.growY : 0)) *\n\t\t\t\t\tshape.props.scale\n\n\t\t\t\tconst adjacentCenter = new Vec(\n\t\t\t\t\tisTab ? (e.shiftKey != isRTL ? -1 : 1) : 0,\n\t\t\t\t\tisCmdEnter ? (e.shiftKey ? -1 : 1) : 0\n\t\t\t\t)\n\t\t\t\t\t.mul(offsetLength)\n\t\t\t\t\t.add(NOTE_CENTER_OFFSET.clone().mul(shape.props.scale))\n\t\t\t\t\t.rot(pageRotation)\n\t\t\t\t\t.add(pageTransform.point())\n\n\t\t\t\tconst newNote = getNoteShapeForAdjacentPosition(editor, shape, adjacentCenter, pageRotation)\n\n\t\t\t\tif (newNote) {\n\t\t\t\t\tstartEditingShapeWithLabel(editor, newNote, true /* selectAll */)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[id, editor, translation?.dir]\n\t)\n}\n\nfunction getNoteHeight(shape: TLNoteShape) {\n\treturn (NOTE_SIZE + shape.props.growY) * shape.props.scale\n}\n\nfunction getNoteShadow(id: string, rotation: number, scale: number) {\n\tconst random = rng(id) // seeded based on id\n\tconst lift = Math.abs(random()) + 0.5 // 0 to 1.5\n\tconst oy = Math.cos(rotation)\n\tconst a = 5 * scale\n\tconst b = 4 * scale\n\tconst c = 6 * scale\n\tconst d = 7 * scale\n\treturn `0px ${a - lift}px ${a}px -${a}px rgba(15, 23, 31, .6),\n\t0px ${(b + lift * d) * Math.max(0, oy)}px ${c + lift * d}px -${b + lift * c}px rgba(15, 23, 31, ${(0.3 + lift * 0.1).toFixed(2)}), \n\t0px ${48 * scale}px ${10 * scale}px -${10 * scale}px inset rgba(15, 23, 44, ${((0.022 + random() * 0.005) * ((1 + oy) / 2)).toFixed(2)})`\n}\n\nfunction getBoundsForSVG(shape: TLNoteShape) {\n\t// When rendering the SVG we don't want to adjust for scale\n\treturn new Box(0, 0, NOTE_SIZE, NOTE_SIZE + shape.props.growY)\n}\n"],
5
- "mappings": "AA6RG,mBAiBG,KAjBH;AA5RH;AAAA,EACC;AAAA,EACA;AAAA,EAEA;AAAA,EAEA;AAAA,EACA;AAAA,EAQA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,aAAa,kBAAkB;AACxC,SAAS,kCAAkC;AAC3C,SAAS,2BAA2B;AACpC;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAChC,SAAS,eAAe,mBAAmB;AAC3C;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,4BAA4B;AACrC,SAAS,4BAA4B;AACrC;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AAYA,MAAM,sBAAsB,UAAuB;AAAA,EACzD,OAAgB,OAAO;AAAA,EACvB,OAAgB,QAAQ;AAAA,EACxB,OAAgB,aAAa;AAAA,EAEpB,UAA4B;AAAA,IACpC,YAAY;AAAA,EACb;AAAA,EAES,UAAU;AAClB,WAAO;AAAA,EACR;AAAA,EACS,oBAAoB;AAC5B,UAAM,EAAE,WAAW,IAAI,KAAK;AAC5B,YAAQ,YAAY;AAAA,MACnB,KAAK,QAAQ;AACZ,eAAO;AAAA,MACR;AAAA,MACA,KAAK,SAAS;AACb,eAAO;AAAA,MACR;AAAA,MACA,SAAS;AACR,cAAM,sBAAsB,UAAU;AAAA,MACvC;AAAA,IACD;AAAA,EACD;AAAA,EAES,sBAAsB;AAC9B,WAAO,KAAK,QAAQ,eAAe;AAAA,EACpC;AAAA,EAES,wBAAwB;AAChC,WAAO;AAAA,EACR;AAAA,EAEA,kBAAwC;AACvC,WAAO;AAAA,MACN,OAAO;AAAA,MACP,UAAU,WAAW,EAAE;AAAA,MACvB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO;AAAA,MACP,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,oBAAoB;AAAA,MACpB,KAAK;AAAA,MACL,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,YAAY,OAAoB;AAC/B,UAAM,EAAE,aAAa,WAAW,IAAI,aAAa,KAAK,QAAQ,KAAK;AACnE,UAAM,EAAE,MAAM,IAAI,MAAM;AAExB,UAAM,KAAK,cAAc;AACzB,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK,cAAc,KAAK;AAE9B,WAAO,IAAI,QAAQ;AAAA,MAClB,UAAU;AAAA,QACT,IAAI,YAAY,EAAE,OAAO,IAAI,QAAQ,IAAI,UAAU,KAAK,CAAC;AAAA,QACzD,IAAI,YAAY;AAAA,UACf,GACC,MAAM,MAAM,UAAU,UACnB,IACA,MAAM,MAAM,UAAU,QACrB,KAAK,MACJ,KAAK,MAAM;AAAA,UACjB,GACC,MAAM,MAAM,kBAAkB,UAC3B,IACA,MAAM,MAAM,kBAAkB,QAC7B,KAAK,MACJ,KAAK,MAAM;AAAA,UACjB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,SAAS;AAAA,UACT,wBAAwB;AAAA,QACzB,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAES,WAAW,OAAgC;AACnD,UAAM,EAAE,MAAM,IAAI,MAAM;AACxB,UAAM,kBAAkB,KAAK,OAAO,iBAAiB,EAAE;AACvD,QAAI,gBAAiB,QAAO,CAAC;AAE7B,UAAM,OAAO,KAAK,OAAO,aAAa;AACtC,QAAI,OAAO,QAAQ,KAAM,QAAO,CAAC;AAEjC,UAAM,KAAK,cAAc,KAAK;AAC9B,UAAM,KAAK,YAAY;AACvB,UAAM,SAAU,sBAAsB,OAAQ;AAE9C,QAAI,OAAO,QAAQ,KAAK;AACvB,aAAO;AAAA,QACN;AAAA,UACC,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,MAAM;AAAA,UACN,GAAG,KAAK;AAAA,UACR,GAAG,KAAK;AAAA,QACT;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,MACN;AAAA,QACC,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,GAAG,KAAK;AAAA,QACR,GAAG,CAAC;AAAA,MACL;AAAA,MACA;AAAA,QACC,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,GAAG,KAAK;AAAA,QACR,GAAG,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACC,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,GAAG,KAAK;AAAA,QACR,GAAG,KAAK;AAAA,MACT;AAAA,MACA;AAAA,QACC,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,GAAG,CAAC;AAAA,QACJ,GAAG,KAAK;AAAA,MACT;AAAA,IACD;AAAA,EACD;AAAA,EAES,SAAS,OAAY,MAAyB;AACtD,UAAM,EAAE,WAAW,IAAI,KAAK;AAC5B,YAAQ,YAAY;AAAA,MACnB,KAAK,QAAQ;AACZ,eAAO;AAAA,MACR;AAAA,MACA,KAAK,SAAS;AACb,eAAO,aAAa,OAAO,IAAI;AAAA,MAChC;AAAA,MACA,SAAS;AACR,cAAM,sBAAsB,UAAU;AAAA,MACvC;AAAA,IACD;AAAA,EACD;AAAA,EAES,QAAQ,OAAoB;AACpC,WAAO,4BAA4B,KAAK,QAAQ,MAAM,MAAM,QAAQ;AAAA,EACrE;AAAA,EAES,aAAa,OAAoB;AACzC,QAAI,gBAAgB,MAAM,MAAM,QAAQ,GAAG;AAC1C,aAAO;AAAA,IACR;AACA,WAAO,qBAAqB,KAAK,QAAQ,MAAM,MAAM,UAAU;AAAA,MAC9D,QAAQ,UAAU,MAAM,MAAM,IAAI;AAAA,MAClC,QAAQ;AAAA,MACR,OAAO;AAAA,IACR,CAAC;AAAA,EACF;AAAA,EAEA,UAAU,OAAoB;AAC7B,UAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD,IAAI;AAEJ,UAAM,gBAAgB,sBAAsB,EAAE;AAE9C,UAAM,QAAQ,qBAAqB;AACnC,UAAM,KAAK,YAAY;AACvB,UAAM,KAAK,cAAc,KAAK;AAE9B,UAAM,WAAW;AAAA,MAChB;AAAA,MACA,MAAM,KAAK,OAAO,sBAAsB,EAAE,GAAG,SAAS,KAAK;AAAA,MAC3D,CAAC,KAAK,MAAM;AAAA,IACb;AAIA,UAAM,cAAc,SAAS,QAAQ,MAAM,KAAK,OAAO,aAAa,IAAI,OAAO,OAAO;AAAA,MACrF;AAAA,MACA,KAAK;AAAA,IACN,CAAC;AAED,UAAM,aAAa,SAAS,aAAa,MAAM,KAAK,OAAO,KAAK,cAAc,GAAG,CAAC,KAAK,MAAM,CAAC;AAE9F,UAAM,aAAa,MAAM,OAAO,KAAK,OAAO,uBAAuB;AAEnE,UAAM,oBAAoB,qBAAqB,KAAK,QAAQ,MAAM,EAAE;AACpE,UAAM,UAAU,gBAAgB,QAAQ;AAExC,WACC,iCACC;AAAA;AAAA,QAAC;AAAA;AAAA,UACA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,iBAAiB,cAAc,OAAO,OAAO,UAAU;AAAA,YACvD,cAAc,cACX,aACC,GAAG,IAAI,KAAK,6BACZ,GAAG,IAAI,KAAK,gCACb;AAAA,YACH,WAAW,cAAc,SAAS,cAAc,MAAM,IAAI,UAAU,KAAK;AAAA,UAC1E;AAAA,UAEE,yBAAc,qBAAqB,CAAC,YACrC;AAAA,YAAC;AAAA;AAAA,cACA,SAAS;AAAA,cACT;AAAA,cACA;AAAA,cACA,WAAW,sBAAsB,iBAAiB,IAAI,KAAK;AAAA,cAC3D,YAAY,WAAW;AAAA,cACvB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA,YACC,eAAe,UACZ,cAAc,OAAO,OAAO,UAAU,IACtC,cAAc,OAAO,YAAY,MAAM;AAAA,cAE3C,MAAI;AAAA,cACJ,SAAS,gBAAgB;AAAA,cACzB,sBAAoB;AAAA,cACpB,WAAW;AAAA;AAAA,UACZ;AAAA;AAAA,MAEF;AAAA,MACC,SAAS,MAAM,SAAS,MAAM,MAAM,OAAO,oBAAC,mBAAgB,KAAK,MAAM,MAAM,KAAK;AAAA,OACpF;AAAA,EAEF;AAAA,EAEA,UAAU,OAAoB;AAC7B,UAAM,EAAE,MAAM,IAAI,MAAM;AACxB,WACC;AAAA,MAAC;AAAA;AAAA,QACA,IAAI;AAAA,QACJ,OAAO,eAAe,YAAY,KAAK;AAAA,QACvC,QAAQ,eAAe,cAAc,KAAK,CAAC;AAAA;AAAA,IAC5C;AAAA,EAEF;AAAA,EAES,MAAM,OAAoB,KAAuB;AACzD,UAAM,QAAQ,qBAAqB,EAAE,YAAY,IAAI,WAAW,CAAC;AACjE,UAAM,SAAS,gBAAgB,KAAK;AAEpC,UAAM,YACL;AAAA,MAAC;AAAA;AAAA,QACA,UAAU,MAAM,MAAM,sBAAsB,iBAAiB,MAAM,MAAM,IAAI;AAAA,QAC7E,MAAM,MAAM,MAAM;AAAA,QAClB,OAAO,MAAM,MAAM;AAAA,QACnB,eAAe,MAAM,MAAM;AAAA,QAC3B,UAAU,MAAM,MAAM;AAAA,QACtB,YAAY,cAAc,OAAO,MAAM,MAAM,OAAO,UAAU;AAAA,QAC9D;AAAA,QACA,SAAS;AAAA,QACT,iBAAiB;AAAA;AAAA,IAClB;AAGD,WACC,iCACC;AAAA,0BAAC,UAAK,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,OAAO,YAAY,IAAI,QAAQ,OAAO,GAAG,MAAK,kBAAiB;AAAA,MACxF;AAAA,QAAC;AAAA;AAAA,UACA,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,QAAQ,OAAO;AAAA,UACf,MAAM,cAAc,OAAO,MAAM,MAAM,OAAO,UAAU;AAAA;AAAA,MACzD;AAAA,MACC;AAAA,OACF;AAAA,EAEF;AAAA,EAES,eAAe,MAAmB;AAC1C,WAAO,uBAAuB,KAAK,QAAQ,IAAI;AAAA,EAChD;AAAA,EAES,eAAe,MAAmB,MAAmB;AAC7D,QACC,QAAQ,KAAK,MAAM,UAAU,KAAK,MAAM,QAAQ,KAChD,KAAK,MAAM,SAAS,KAAK,MAAM,QAC/B,KAAK,MAAM,SAAS,KAAK,MAAM,MAC9B;AACD;AAAA,IACD;AAEA,WAAO,uBAAuB,KAAK,QAAQ,IAAI;AAAA,EAChD;AAAA,EAES,qBACR,YACA,UACA,GACmB;AACnB,WAAO;AAAA,MACN,GAAI,IAAI,MAAM,SAAS,QAAQ,WAAW;AAAA,MAC1C,OAAO,KAAK,WAAW,MAAM,OAAO,SAAS,MAAM,OAAO,CAAC;AAAA,IAC5D;AAAA,EACD;AACD;AAKA,SAAS,uBAAuB,QAAgB,OAAoB;AACnE,QAAM,EAAE,aAAa,mBAAmB,IAAI,aAAa,QAAQ,KAAK;AAEtE,QAAM,QAAQ,KAAK,IAAI,GAAG,cAAc,SAAS;AAEjD,MAAI,UAAU,MAAM,MAAM,SAAS,uBAAuB,MAAM,MAAM,oBAAoB;AACzF,WAAO;AAAA,MACN,GAAG;AAAA,MACH,OAAO;AAAA,QACN,GAAG,MAAM;AAAA,QACT;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAAA,EACD;AACD;AAKA,SAAS,iBAAiB,QAAgB,OAAoB;AAC7D,QAAM,EAAE,SAAS,IAAI,MAAM;AAE3B,MAAI,gBAAgB,QAAQ,GAAG;AAC9B,UAAM,YAAY,iBAAiB,MAAM,MAAM,IAAI,IAAI,WAAW,aAAa,gBAAgB;AAC/F,WAAO,EAAE,aAAa,WAAW,YAAY,KAAK,oBAAoB,EAAE;AAAA,EACzE;AAEA,QAAM,qBAAqB,iBAAiB,MAAM,MAAM,IAAI;AAE5D,MAAI,qBAAqB;AACzB,MAAI,aAAa;AACjB,MAAI,cAAc;AAClB,MAAI,aAAa;AAMjB,QAAM,OAAO;AAGb,KAAG;AACF,yBAAqB,KAAK,IAAI,oBAAoB,qBAAqB,UAAU;AACjF,UAAM,OAAO,qCAAqC,QAAQ,QAAQ;AAClE,UAAM,eAAe,OAAO,YAAY,YAAY,MAAM;AAAA,MACzD,GAAG;AAAA,MACH,YAAY,cAAc,MAAM,MAAM,IAAI;AAAA,MAC1C,UAAU;AAAA,MACV,UAAU,YAAY,gBAAgB,IAAI;AAAA,MAC1C,6BAA6B;AAAA,MAC7B,oBAAoB;AAAA,IACrB,CAAC;AAED,kBAAc,aAAa,IAAI,gBAAgB;AAC/C,iBAAa,aAAa,IAAI,gBAAgB;AAE9C,QAAI,sBAAsB,IAAI;AAG7B,YAAMA,QAAO,qCAAqC,QAAQ,QAAQ;AAClE,YAAM,gCAAgC,OAAO,YAAY,YAAYA,OAAM;AAAA,QAC1E,GAAG;AAAA,QACH,YAAY,cAAc,MAAM,MAAM,IAAI;AAAA,QAC1C,UAAU;AAAA,QACV,UAAU,YAAY,gBAAgB,IAAI;AAAA,MAC3C,CAAC;AACD,oBAAc,8BAA8B,IAAI,gBAAgB;AAChE,mBAAa,8BAA8B,IAAI,gBAAgB;AAC/D;AAAA,IACD;AAEA,QAAI,aAAa,YAAY,QAAQ,CAAC,MAAM,aAAa,EAAE,QAAQ,CAAC,GAAG;AACtE;AAAA,IACD;AAAA,EACD,SAAS,eAAe;AAExB,SAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;AAEA,MAAM,oBAAoB,IAAI,UAAwD;AAEtF,SAAS,aAAa,QAAgB,OAAoB;AACzD,SAAO,kBAAkB,IAAI,OAAO,MAAM,iBAAiB,QAAQ,KAAK,CAAC;AAC1E;AAEA,SAAS,sBAAsB,IAAe;AAC7C,QAAM,SAAS,UAAU;AAEzB,QAAM,cAAc,WAAW,mBAAmB;AAElD,SAAO;AAAA,IACN,CAAC,MAAqB;AACrB,YAAM,QAAQ,OAAO,SAAsB,EAAE;AAC7C,UAAI,CAAC,MAAO;AAEZ,YAAM,QAAQ,EAAE,QAAQ;AACxB,YAAM,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ;AACzD,UAAI,SAAS,YAAY;AACxB,UAAE,eAAe;AAEjB,cAAM,gBAAgB,OAAO,sBAAsB,EAAE;AACrD,cAAM,eAAe,cAAc,SAAS;AAK5C,cAAM,QAAQ,CAAC,EACd,aAAa,QAAQ;AAAA,QAErB,sBAAsB,4BAA4B,QAAQ,MAAM,MAAM,QAAQ,CAAC;AAGhF,cAAM,gBACJ,YACA,OAAO,QAAQ;AAAA,SAEd,cAAc,CAAC,EAAE,WAAW,MAAM,MAAM,QAAQ,MAClD,MAAM,MAAM;AAEb,cAAM,iBAAiB,IAAI;AAAA,UAC1B,QAAS,EAAE,YAAY,QAAQ,KAAK,IAAK;AAAA,UACzC,aAAc,EAAE,WAAW,KAAK,IAAK;AAAA,QACtC,EACE,IAAI,YAAY,EAChB,IAAI,mBAAmB,MAAM,EAAE,IAAI,MAAM,MAAM,KAAK,CAAC,EACrD,IAAI,YAAY,EAChB,IAAI,cAAc,MAAM,CAAC;AAE3B,cAAM,UAAU,gCAAgC,QAAQ,OAAO,gBAAgB,YAAY;AAE3F,YAAI,SAAS;AACZ;AAAA,YAA2B;AAAA,YAAQ;AAAA,YAAS;AAAA;AAAA,UAAoB;AAAA,QACjE;AAAA,MACD;AAAA,IACD;AAAA,IACA,CAAC,IAAI,QAAQ,aAAa,GAAG;AAAA,EAC9B;AACD;AAEA,SAAS,cAAc,OAAoB;AAC1C,UAAQ,YAAY,MAAM,MAAM,SAAS,MAAM,MAAM;AACtD;AAEA,SAAS,cAAc,IAAY,UAAkB,OAAe;AACnE,QAAM,SAAS,IAAI,EAAE;AACrB,QAAM,OAAO,KAAK,IAAI,OAAO,CAAC,IAAI;AAClC,QAAM,KAAK,KAAK,IAAI,QAAQ;AAC5B,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,QAAM,IAAI,IAAI;AACd,SAAO,OAAO,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC;AAAA,QAC9B,IAAI,OAAO,KAAK,KAAK,IAAI,GAAG,EAAE,CAAC,MAAM,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,wBAAwB,MAAM,OAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,OACzH,KAAK,KAAK,MAAM,KAAK,KAAK,OAAO,KAAK,KAAK,+BAA+B,QAAQ,OAAO,IAAI,UAAW,IAAI,MAAM,IAAI,QAAQ,CAAC,CAAC;AACvI;AAEA,SAAS,gBAAgB,OAAoB;AAE5C,SAAO,IAAI,IAAI,GAAG,GAAG,WAAW,YAAY,MAAM,MAAM,KAAK;AAC9D;",
4
+ "sourcesContent": ["/* eslint-disable react-hooks/rules-of-hooks */\nimport {\n\tBox,\n\tEMPTY_ARRAY,\n\tEditor,\n\tGroup2d,\n\tIndexKey,\n\tRectangle2d,\n\tShapeUtil,\n\tSvgExportContext,\n\tTLHandle,\n\tTLNoteShape,\n\tTLNoteShapeProps,\n\tTLResizeInfo,\n\tTLShape,\n\tTLShapeId,\n\tVec,\n\tWeakCache,\n\texhaustiveSwitchError,\n\tgetColorValue,\n\tgetDefaultColorTheme,\n\tgetFontsFromRichText,\n\tisEqual,\n\tlerp,\n\tnoteShapeMigrations,\n\tnoteShapeProps,\n\tresizeScaled,\n\trng,\n\ttoDomPrecision,\n\ttoRichText,\n\tuseEditor,\n\tuseValue,\n} from '@tldraw/editor'\nimport { useCallback, useContext } from 'react'\nimport { startEditingShapeWithLabel } from '../../tools/SelectTool/selectHelpers'\nimport { TranslationsContext } from '../../ui/hooks/useTranslation/useTranslation'\nimport {\n\tisEmptyRichText,\n\trenderHtmlFromRichTextForMeasurement,\n\trenderPlaintextFromRichText,\n} from '../../utils/text/richText'\nimport { isRightToLeftLanguage } from '../../utils/text/text'\nimport { HyperlinkButton } from '../shared/HyperlinkButton'\nimport { RichTextLabel, RichTextSVG } from '../shared/RichTextLabel'\nimport {\n\tFONT_FAMILIES,\n\tLABEL_FONT_SIZES,\n\tLABEL_PADDING,\n\tTEXT_PROPS,\n} from '../shared/default-shape-constants'\nimport { useDefaultColorTheme } from '../shared/useDefaultColorTheme'\nimport { useIsReadyForEditing } from '../shared/useEditablePlainText'\nimport { useEfficientZoomThreshold } from '../shared/useEfficientZoomThreshold'\nimport {\n\tCLONE_HANDLE_MARGIN,\n\tNOTE_CENTER_OFFSET,\n\tNOTE_SIZE,\n\tgetNoteShapeForAdjacentPosition,\n} from './noteHelpers'\n\n/** @public */\nexport interface NoteShapeOptions {\n\t/**\n\t * How should the note shape resize? By default it does not resize (except automatically based on its text content),\n\t * but you can set it to be user-resizable using scale.\n\t */\n\tresizeMode: 'none' | 'scale'\n}\n\n/** @public */\nexport class NoteShapeUtil extends ShapeUtil<TLNoteShape> {\n\tstatic override type = 'note' as const\n\tstatic override props = noteShapeProps\n\tstatic override migrations = noteShapeMigrations\n\n\toverride options: NoteShapeOptions = {\n\t\tresizeMode: 'none',\n\t}\n\n\toverride canEdit() {\n\t\treturn true\n\t}\n\toverride hideResizeHandles() {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride isAspectRatioLocked() {\n\t\treturn this.options.resizeMode === 'scale'\n\t}\n\n\toverride hideSelectionBoundsFg() {\n\t\treturn false\n\t}\n\n\tgetDefaultProps(): TLNoteShape['props'] {\n\t\treturn {\n\t\t\tcolor: 'black',\n\t\t\trichText: toRichText(''),\n\t\t\tsize: 'm',\n\t\t\tfont: 'draw',\n\t\t\talign: 'middle',\n\t\t\tverticalAlign: 'middle',\n\t\t\tlabelColor: 'black',\n\t\t\tgrowY: 0,\n\t\t\tfontSizeAdjustment: 0,\n\t\t\turl: '',\n\t\t\tscale: 1,\n\t\t}\n\t}\n\n\tgetGeometry(shape: TLNoteShape) {\n\t\tconst { labelHeight, labelWidth } = getLabelSize(this.editor, shape)\n\t\tconst { scale } = shape.props\n\n\t\tconst lh = labelHeight * scale\n\t\tconst lw = labelWidth * scale\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst nh = getNoteHeight(shape)\n\n\t\treturn new Group2d({\n\t\t\tchildren: [\n\t\t\t\tnew Rectangle2d({ width: nw, height: nh, isFilled: true }),\n\t\t\t\tnew Rectangle2d({\n\t\t\t\t\tx:\n\t\t\t\t\t\tshape.props.align === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.align === 'end'\n\t\t\t\t\t\t\t\t? nw - lw\n\t\t\t\t\t\t\t\t: (nw - lw) / 2,\n\t\t\t\t\ty:\n\t\t\t\t\t\tshape.props.verticalAlign === 'start'\n\t\t\t\t\t\t\t? 0\n\t\t\t\t\t\t\t: shape.props.verticalAlign === 'end'\n\t\t\t\t\t\t\t\t? nh - lh\n\t\t\t\t\t\t\t\t: (nh - lh) / 2,\n\t\t\t\t\twidth: lw,\n\t\t\t\t\theight: lh,\n\t\t\t\t\tisFilled: true,\n\t\t\t\t\tisLabel: true,\n\t\t\t\t\texcludeFromShapeBounds: true,\n\t\t\t\t}),\n\t\t\t],\n\t\t})\n\t}\n\n\toverride getHandles(shape: TLNoteShape): TLHandle[] {\n\t\tconst { scale } = shape.props\n\t\tconst isCoarsePointer = this.editor.getInstanceState().isCoarsePointer\n\t\tif (isCoarsePointer) return []\n\n\t\tconst zoom = this.editor.getEfficientZoomLevel()\n\t\tif (zoom * scale < 0.25) return []\n\n\t\tconst nh = getNoteHeight(shape)\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst offset = (CLONE_HANDLE_MARGIN / zoom) * scale\n\n\t\tif (zoom * scale < 0.5) {\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tid: 'bottom',\n\t\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\t\ttype: 'clone',\n\t\t\t\t\tx: nw / 2,\n\t\t\t\t\ty: nh + offset,\n\t\t\t\t},\n\t\t\t]\n\t\t}\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tid: 'top',\n\t\t\t\tindex: 'a1' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: -offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'right',\n\t\t\t\tindex: 'a2' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw + offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'bottom',\n\t\t\t\tindex: 'a3' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: nw / 2,\n\t\t\t\ty: nh + offset,\n\t\t\t},\n\t\t\t{\n\t\t\t\tid: 'left',\n\t\t\t\tindex: 'a4' as IndexKey,\n\t\t\t\ttype: 'clone',\n\t\t\t\tx: -offset,\n\t\t\t\ty: nh / 2,\n\t\t\t},\n\t\t]\n\t}\n\n\toverride onResize(shape: any, info: TLResizeInfo<any>) {\n\t\tconst { resizeMode } = this.options\n\t\tswitch (resizeMode) {\n\t\t\tcase 'none': {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tcase 'scale': {\n\t\t\t\treturn resizeScaled(shape, info)\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow exhaustiveSwitchError(resizeMode)\n\t\t\t}\n\t\t}\n\t}\n\n\toverride getText(shape: TLNoteShape) {\n\t\treturn renderPlaintextFromRichText(this.editor, shape.props.richText)\n\t}\n\n\toverride getFontFaces(shape: TLNoteShape) {\n\t\tif (isEmptyRichText(shape.props.richText)) {\n\t\t\treturn EMPTY_ARRAY\n\t\t}\n\t\treturn getFontsFromRichText(this.editor, shape.props.richText, {\n\t\t\tfamily: `tldraw_${shape.props.font}`,\n\t\t\tweight: 'normal',\n\t\t\tstyle: 'normal',\n\t\t})\n\t}\n\n\tcomponent(shape: TLNoteShape) {\n\t\tconst {\n\t\t\tid,\n\t\t\ttype,\n\t\t\tprops: {\n\t\t\t\tlabelColor,\n\t\t\t\tscale,\n\t\t\t\tcolor,\n\t\t\t\tfont,\n\t\t\t\tsize,\n\t\t\t\talign,\n\t\t\t\trichText,\n\t\t\t\tverticalAlign,\n\t\t\t\tfontSizeAdjustment,\n\t\t\t},\n\t\t} = shape\n\n\t\tconst handleKeyDown = useNoteKeydownHandler(id)\n\n\t\tconst theme = useDefaultColorTheme()\n\t\tconst nw = NOTE_SIZE * scale\n\t\tconst nh = getNoteHeight(shape)\n\n\t\tconst rotation = useValue(\n\t\t\t'shape rotation',\n\t\t\t() => this.editor.getShapePageTransform(id)?.rotation() ?? 0,\n\t\t\t[this.editor]\n\t\t)\n\n\t\tconst isDarkMode = useValue('dark mode', () => this.editor.user.getIsDarkMode(), [this.editor])\n\n\t\t// Shadows are hidden when zoomed out far enough or in dark mode\n\t\tlet hideShadows = useEfficientZoomThreshold(scale * 0.25)\n\t\tif (isDarkMode) hideShadows = true\n\n\t\tconst isSelected = shape.id === this.editor.getOnlySelectedShapeId()\n\n\t\tconst isReadyForEditing = useIsReadyForEditing(this.editor, shape.id)\n\t\tconst isEmpty = isEmptyRichText(richText)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<div\n\t\t\t\t\tid={id}\n\t\t\t\t\tclassName=\"tl-note__container\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\twidth: nw,\n\t\t\t\t\t\theight: nh,\n\t\t\t\t\t\tbackgroundColor: getColorValue(theme, color, 'noteFill'),\n\t\t\t\t\t\tborderBottom: hideShadows\n\t\t\t\t\t\t\t? isDarkMode\n\t\t\t\t\t\t\t\t? `${2 * scale}px solid rgb(20, 20, 20)`\n\t\t\t\t\t\t\t\t: `${2 * scale}px solid rgb(144, 144, 144)`\n\t\t\t\t\t\t\t: 'none',\n\t\t\t\t\t\tboxShadow: hideShadows ? 'none' : getNoteShadow(shape.id, rotation, scale),\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{(isSelected || isReadyForEditing || !isEmpty) && (\n\t\t\t\t\t\t<RichTextLabel\n\t\t\t\t\t\t\tshapeId={id}\n\t\t\t\t\t\t\ttype={type}\n\t\t\t\t\t\t\tfont={font}\n\t\t\t\t\t\t\tfontSize={(fontSizeAdjustment || LABEL_FONT_SIZES[size]) * scale}\n\t\t\t\t\t\t\tlineHeight={TEXT_PROPS.lineHeight}\n\t\t\t\t\t\t\talign={align}\n\t\t\t\t\t\t\tverticalAlign={verticalAlign}\n\t\t\t\t\t\t\trichText={richText}\n\t\t\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\t\t\tlabelColor={\n\t\t\t\t\t\t\t\tlabelColor === 'black'\n\t\t\t\t\t\t\t\t\t? getColorValue(theme, color, 'noteText')\n\t\t\t\t\t\t\t\t\t: getColorValue(theme, labelColor, 'fill')\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrap\n\t\t\t\t\t\t\tpadding={LABEL_PADDING * scale}\n\t\t\t\t\t\t\thasCustomTabBehavior\n\t\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\t/>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t{'url' in shape.props && shape.props.url && <HyperlinkButton url={shape.props.url} />}\n\t\t\t</>\n\t\t)\n\t}\n\n\tindicator(shape: TLNoteShape) {\n\t\tconst { scale } = shape.props\n\t\treturn (\n\t\t\t<rect\n\t\t\t\trx={scale}\n\t\t\t\twidth={toDomPrecision(NOTE_SIZE * scale)}\n\t\t\t\theight={toDomPrecision(getNoteHeight(shape))}\n\t\t\t/>\n\t\t)\n\t}\n\n\toverride toSvg(shape: TLNoteShape, ctx: SvgExportContext) {\n\t\tconst theme = getDefaultColorTheme({ isDarkMode: ctx.isDarkMode })\n\t\tconst bounds = getBoundsForSVG(shape)\n\n\t\tconst textLabel = (\n\t\t\t<RichTextSVG\n\t\t\t\tfontSize={shape.props.fontSizeAdjustment || LABEL_FONT_SIZES[shape.props.size]}\n\t\t\t\tfont={shape.props.font}\n\t\t\t\talign={shape.props.align}\n\t\t\t\tverticalAlign={shape.props.verticalAlign}\n\t\t\t\trichText={shape.props.richText}\n\t\t\t\tlabelColor={getColorValue(theme, shape.props.color, 'noteText')}\n\t\t\t\tbounds={bounds}\n\t\t\t\tpadding={LABEL_PADDING}\n\t\t\t\tshowTextOutline={false}\n\t\t\t/>\n\t\t)\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<rect x={5} y={5} rx={1} width={NOTE_SIZE - 10} height={bounds.h} fill=\"rgba(0,0,0,.1)\" />\n\t\t\t\t<rect\n\t\t\t\t\trx={1}\n\t\t\t\t\twidth={NOTE_SIZE}\n\t\t\t\t\theight={bounds.h}\n\t\t\t\t\tfill={getColorValue(theme, shape.props.color, 'noteFill')}\n\t\t\t\t/>\n\t\t\t\t{textLabel}\n\t\t\t</>\n\t\t)\n\t}\n\n\toverride onBeforeCreate(next: TLNoteShape) {\n\t\treturn getNoteSizeAdjustments(this.editor, next)\n\t}\n\n\toverride onBeforeUpdate(prev: TLNoteShape, next: TLNoteShape) {\n\t\tif (\n\t\t\tisEqual(prev.props.richText, next.props.richText) &&\n\t\t\tprev.props.font === next.props.font &&\n\t\t\tprev.props.size === next.props.size\n\t\t) {\n\t\t\treturn\n\t\t}\n\n\t\treturn getNoteSizeAdjustments(this.editor, next)\n\t}\n\n\toverride getInterpolatedProps(\n\t\tstartShape: TLNoteShape,\n\t\tendShape: TLNoteShape,\n\t\tt: number\n\t): TLNoteShapeProps {\n\t\treturn {\n\t\t\t...(t > 0.5 ? endShape.props : startShape.props),\n\t\t\tscale: lerp(startShape.props.scale, endShape.props.scale, t),\n\t\t}\n\t}\n}\n\n/**\n * Get the growY and fontSizeAdjustment for a shape.\n */\nfunction getNoteSizeAdjustments(editor: Editor, shape: TLNoteShape) {\n\tconst { labelHeight, fontSizeAdjustment } = getLabelSize(editor, shape)\n\t// When the label height is more than the height of the shape, we add extra height to it\n\tconst growY = Math.max(0, labelHeight - NOTE_SIZE)\n\n\tif (growY !== shape.props.growY || fontSizeAdjustment !== shape.props.fontSizeAdjustment) {\n\t\treturn {\n\t\t\t...shape,\n\t\t\tprops: {\n\t\t\t\t...shape.props,\n\t\t\t\tgrowY,\n\t\t\t\tfontSizeAdjustment,\n\t\t\t},\n\t\t}\n\t}\n}\n\n/**\n * Get the label size for a note.\n */\nfunction getNoteLabelSize(editor: Editor, shape: TLNoteShape) {\n\tconst { richText } = shape.props\n\n\tif (isEmptyRichText(richText)) {\n\t\tconst minHeight = LABEL_FONT_SIZES[shape.props.size] * TEXT_PROPS.lineHeight + LABEL_PADDING * 2\n\t\treturn { labelHeight: minHeight, labelWidth: 100, fontSizeAdjustment: 0 }\n\t}\n\n\tconst unadjustedFontSize = LABEL_FONT_SIZES[shape.props.size]\n\n\tlet fontSizeAdjustment = 0\n\tlet iterations = 0\n\tlet labelHeight = NOTE_SIZE\n\tlet labelWidth = NOTE_SIZE\n\n\t// N.B. For some note shapes with text like 'hjhjhjhjhjhjhjhj', you'll run into\n\t// some text measurement fuzziness where the browser swears there's no overflow (scrollWidth === width)\n\t// but really there is when you enable overflow-wrap again. This helps account for that little bit\n\t// of give.\n\tconst FUZZ = 1\n\n\t// We slightly make the font smaller if the text is too big for the note, width-wise.\n\tdo {\n\t\tfontSizeAdjustment = Math.min(unadjustedFontSize, unadjustedFontSize - iterations)\n\t\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\t\tconst nextTextSize = editor.textMeasure.measureHtml(html, {\n\t\t\t...TEXT_PROPS,\n\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\tfontSize: fontSizeAdjustment,\n\t\t\tmaxWidth: NOTE_SIZE - LABEL_PADDING * 2 - FUZZ,\n\t\t\tdisableOverflowWrapBreaking: true,\n\t\t\tmeasureScrollWidth: true,\n\t\t})\n\n\t\tlabelHeight = nextTextSize.h + LABEL_PADDING * 2\n\t\tlabelWidth = nextTextSize.w + LABEL_PADDING * 2\n\n\t\tif (fontSizeAdjustment <= 14) {\n\t\t\t// Too small, just rely now on CSS `overflow-wrap: break-word`\n\t\t\t// We need to recalculate the text measurement here with break-word enabled.\n\t\t\tconst html = renderHtmlFromRichTextForMeasurement(editor, richText)\n\t\t\tconst nextTextSizeWithOverflowBreak = editor.textMeasure.measureHtml(html, {\n\t\t\t\t...TEXT_PROPS,\n\t\t\t\tfontFamily: FONT_FAMILIES[shape.props.font],\n\t\t\t\tfontSize: fontSizeAdjustment,\n\t\t\t\tmaxWidth: NOTE_SIZE - LABEL_PADDING * 2 - FUZZ,\n\t\t\t})\n\t\t\tlabelHeight = nextTextSizeWithOverflowBreak.h + LABEL_PADDING * 2\n\t\t\tlabelWidth = nextTextSizeWithOverflowBreak.w + LABEL_PADDING * 2\n\t\t\tbreak\n\t\t}\n\n\t\tif (nextTextSize.scrollWidth.toFixed(0) === nextTextSize.w.toFixed(0)) {\n\t\t\tbreak\n\t\t}\n\t} while (iterations++ < 50)\n\n\treturn {\n\t\tlabelHeight: labelHeight,\n\t\tlabelWidth: labelWidth,\n\t\tfontSizeAdjustment: fontSizeAdjustment,\n\t}\n}\n\nconst labelSizesForNote = new WeakCache<TLShape, ReturnType<typeof getNoteLabelSize>>()\n\nfunction getLabelSize(editor: Editor, shape: TLNoteShape) {\n\treturn labelSizesForNote.get(shape, () => getNoteLabelSize(editor, shape))\n}\n\nfunction useNoteKeydownHandler(id: TLShapeId) {\n\tconst editor = useEditor()\n\t// Try to get the translation context, but fallback to ltr if it doesn't exist\n\tconst translation = useContext(TranslationsContext)\n\n\treturn useCallback(\n\t\t(e: KeyboardEvent) => {\n\t\t\tconst shape = editor.getShape<TLNoteShape>(id)\n\t\t\tif (!shape) return\n\n\t\t\tconst isTab = e.key === 'Tab'\n\t\t\tconst isCmdEnter = (e.metaKey || e.ctrlKey) && e.key === 'Enter'\n\t\t\tif (isTab || isCmdEnter) {\n\t\t\t\te.preventDefault()\n\n\t\t\t\tconst pageTransform = editor.getShapePageTransform(id)\n\t\t\t\tconst pageRotation = pageTransform.rotation()\n\n\t\t\t\t// Based on the inputs, calculate the offset to the next note\n\t\t\t\t// tab controls x axis (shift inverts direction set by RTL)\n\t\t\t\t// cmd enter is the y axis (shift inverts direction)\n\t\t\t\tconst isRTL = !!(\n\t\t\t\t\ttranslation?.dir === 'rtl' ||\n\t\t\t\t\t// todo: can we check a partial of the text, so that we don't have to render the whole thing?\n\t\t\t\t\tisRightToLeftLanguage(renderPlaintextFromRichText(editor, shape.props.richText))\n\t\t\t\t)\n\n\t\t\t\tconst offsetLength =\n\t\t\t\t\t(NOTE_SIZE +\n\t\t\t\t\t\teditor.options.adjacentShapeMargin +\n\t\t\t\t\t\t// If we're growing down, we need to account for the current shape's growY\n\t\t\t\t\t\t(isCmdEnter && !e.shiftKey ? shape.props.growY : 0)) *\n\t\t\t\t\tshape.props.scale\n\n\t\t\t\tconst adjacentCenter = new Vec(\n\t\t\t\t\tisTab ? (e.shiftKey != isRTL ? -1 : 1) : 0,\n\t\t\t\t\tisCmdEnter ? (e.shiftKey ? -1 : 1) : 0\n\t\t\t\t)\n\t\t\t\t\t.mul(offsetLength)\n\t\t\t\t\t.add(NOTE_CENTER_OFFSET.clone().mul(shape.props.scale))\n\t\t\t\t\t.rot(pageRotation)\n\t\t\t\t\t.add(pageTransform.point())\n\n\t\t\t\tconst newNote = getNoteShapeForAdjacentPosition(editor, shape, adjacentCenter, pageRotation)\n\n\t\t\t\tif (newNote) {\n\t\t\t\t\tstartEditingShapeWithLabel(editor, newNote, true /* selectAll */)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[id, editor, translation?.dir]\n\t)\n}\n\nfunction getNoteHeight(shape: TLNoteShape) {\n\treturn (NOTE_SIZE + shape.props.growY) * shape.props.scale\n}\n\nfunction getNoteShadow(id: string, rotation: number, scale: number) {\n\tconst random = rng(id) // seeded based on id\n\tconst lift = Math.abs(random()) + 0.5 // 0 to 1.5\n\tconst oy = Math.cos(rotation)\n\tconst a = 5 * scale\n\tconst b = 4 * scale\n\tconst c = 6 * scale\n\tconst d = 7 * scale\n\treturn `0px ${a - lift}px ${a}px -${a}px rgba(15, 23, 31, .6),\n\t0px ${(b + lift * d) * Math.max(0, oy)}px ${c + lift * d}px -${b + lift * c}px rgba(15, 23, 31, ${(0.3 + lift * 0.1).toFixed(2)}), \n\t0px ${48 * scale}px ${10 * scale}px -${10 * scale}px inset rgba(15, 23, 44, ${((0.022 + random() * 0.005) * ((1 + oy) / 2)).toFixed(2)})`\n}\n\nfunction getBoundsForSVG(shape: TLNoteShape) {\n\t// When rendering the SVG we don't want to adjust for scale\n\treturn new Box(0, 0, NOTE_SIZE, NOTE_SIZE + shape.props.growY)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["html"]
7
7
  }
@@ -1,11 +1,12 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { useEditor, useValue } from "@tldraw/editor";
2
+ import { useEditor } from "@tldraw/editor";
3
3
  import classNames from "classnames";
4
4
  import { useCallback } from "react";
5
+ import { useEfficientZoomThreshold } from "./useEfficientZoomThreshold.mjs";
5
6
  const LINK_ICON = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E";
6
7
  function HyperlinkButton({ url }) {
7
8
  const editor = useEditor();
8
- const hideButton = useValue("zoomLevel", () => editor.getZoomLevel() < 0.32, [editor]);
9
+ const hideButton = useEfficientZoomThreshold();
9
10
  const markAsHandledOnShiftKey = useCallback(
10
11
  (e) => {
11
12
  if (!editor.inputs.shiftKey) editor.markEventAsHandled(e);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/HyperlinkButton.tsx"],
4
- "sourcesContent": ["import { useEditor, useValue } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback } from 'react'\n\nconst LINK_ICON =\n\t\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E\"\n\nexport function HyperlinkButton({ url }: { url: string }) {\n\tconst editor = useEditor()\n\tconst hideButton = useValue('zoomLevel', () => editor.getZoomLevel() < 0.32, [editor])\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) editor.markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\treturn (\n\t\t<a\n\t\t\tclassName={classNames('tl-hyperlink-button', {\n\t\t\t\t'tl-hyperlink-button__hidden': hideButton,\n\t\t\t})}\n\t\t\thref={url}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\ttitle={url}\n\t\t\tdraggable={false}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\tstyle={{\n\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t}}\n\t\t\t/>\n\t\t</a>\n\t)\n}\n"],
5
- "mappings": "AA6BG;AA7BH,SAAS,WAAW,gBAAgB;AACpC,OAAO,gBAAgB;AACvB,SAA8B,mBAAmB;AAEjD,MAAM,YACL;AAEM,SAAS,gBAAgB,EAAE,IAAI,GAAoB;AACzD,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,SAAS,aAAa,MAAM,OAAO,aAAa,IAAI,MAAM,CAAC,MAAM,CAAC;AACrF,QAAM,0BAA0B;AAAA,IAC/B,CAAC,MAAM;AACN,UAAI,CAAC,OAAO,OAAO,SAAU,QAAO,mBAAmB,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,WAAW,uBAAuB;AAAA,QAC5C,+BAA+B;AAAA,MAChC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,MAAM,QAAQ,SAAS;AAAA,YACvB,YAAY,QAAQ,SAAS;AAAA,UAC9B;AAAA;AAAA,MACD;AAAA;AAAA,EACD;AAEF;",
4
+ "sourcesContent": ["import { useEditor } from '@tldraw/editor'\nimport classNames from 'classnames'\nimport { PointerEventHandler, useCallback } from 'react'\nimport { useEfficientZoomThreshold } from './useEfficientZoomThreshold'\n\nconst LINK_ICON =\n\t\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' fill='none'%3E%3Cpath stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M13 5H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6M19 5h6m0 0v6m0-6L13 17'/%3E%3C/svg%3E\"\n\nexport function HyperlinkButton({ url }: { url: string }) {\n\tconst editor = useEditor()\n\tconst hideButton = useEfficientZoomThreshold()\n\tconst markAsHandledOnShiftKey = useCallback<PointerEventHandler>(\n\t\t(e) => {\n\t\t\tif (!editor.inputs.shiftKey) editor.markEventAsHandled(e)\n\t\t},\n\t\t[editor]\n\t)\n\treturn (\n\t\t<a\n\t\t\tclassName={classNames('tl-hyperlink-button', {\n\t\t\t\t'tl-hyperlink-button__hidden': hideButton,\n\t\t\t})}\n\t\t\thref={url}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noopener noreferrer\"\n\t\t\tonPointerDown={markAsHandledOnShiftKey}\n\t\t\tonPointerUp={markAsHandledOnShiftKey}\n\t\t\ttitle={url}\n\t\t\tdraggable={false}\n\t\t>\n\t\t\t<div\n\t\t\t\tclassName=\"tl-hyperlink__icon\"\n\t\t\t\tstyle={{\n\t\t\t\t\tmask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t\tWebkitMask: `url(\"${LINK_ICON}\") center 100% / 100% no-repeat`,\n\t\t\t\t}}\n\t\t\t/>\n\t\t</a>\n\t)\n}\n"],
5
+ "mappings": "AA8BG;AA9BH,SAAS,iBAAiB;AAC1B,OAAO,gBAAgB;AACvB,SAA8B,mBAAmB;AACjD,SAAS,iCAAiC;AAE1C,MAAM,YACL;AAEM,SAAS,gBAAgB,EAAE,IAAI,GAAoB;AACzD,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,0BAA0B;AAC7C,QAAM,0BAA0B;AAAA,IAC/B,CAAC,MAAM;AACN,UAAI,CAAC,OAAO,OAAO,SAAU,QAAO,mBAAmB,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,MAAM;AAAA,EACR;AACA,SACC;AAAA,IAAC;AAAA;AAAA,MACA,WAAW,WAAW,uBAAuB;AAAA,QAC5C,+BAA+B;AAAA,MAChC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,eAAe;AAAA,MACf,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,MAEX;AAAA,QAAC;AAAA;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,YACN,MAAM,QAAQ,SAAS;AAAA,YACvB,YAAY,QAAQ,SAAS;AAAA,UAC9B;AAAA;AAAA,MACD;AAAA;AAAA,EACD;AAEF;",
6
6
  "names": []
7
7
  }
@@ -38,9 +38,9 @@ const ShapeFill = React.memo(function ShapeFill2({
38
38
  function PatternFill({ d, color, theme }) {
39
39
  const editor = useEditor();
40
40
  const svgExport = useSvgExportContext();
41
- const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]);
41
+ const zoomLevel = useValue("zoomLevel", () => editor.getEfficientZoomLevel(), [editor]);
42
42
  const getHashPatternZoomName = useGetHashPatternZoomName();
43
- const teenyTiny = editor.getZoomLevel() <= 0.18;
43
+ const teenyTiny = zoomLevel <= 0.18;
44
44
  return /* @__PURE__ */ jsxs(Fragment, { children: [
45
45
  /* @__PURE__ */ jsx("path", { fill: getColorValue(theme, color, "pattern"), d }),
46
46
  /* @__PURE__ */ jsx(
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/ShapeFill.tsx"],
4
- "sourcesContent": ["import {\n\tgetColorValue,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tTLDefaultFillStyle,\n\tuseEditor,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useGetHashPatternZoomName } from './defaultStyleDefs'\n\ninterface ShapeFillProps {\n\td: string\n\tfill: TLDefaultFillStyle\n\tcolor: TLDefaultColorStyle\n\ttheme: TLDefaultColorTheme\n\tscale: number\n}\n\nexport const ShapeFill = React.memo(function ShapeFill({\n\ttheme,\n\td,\n\tcolor,\n\tfill,\n\tscale,\n}: ShapeFillProps) {\n\tswitch (fill) {\n\t\tcase 'none': {\n\t\t\treturn null\n\t\t}\n\t\tcase 'solid': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'semi')} d={d} />\n\t\t}\n\t\tcase 'semi': {\n\t\t\treturn <path fill={theme.solid} d={d} />\n\t\t}\n\t\tcase 'fill': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'fill')} d={d} />\n\t\t}\n\t\tcase 'pattern': {\n\t\t\treturn <PatternFill theme={theme} color={color} fill={fill} d={d} scale={scale} />\n\t\t}\n\t\tcase 'lined-fill': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'linedFill')} d={d} />\n\t\t}\n\t}\n})\n\nexport function PatternFill({ d, color, theme }: ShapeFillProps) {\n\tconst editor = useEditor()\n\tconst svgExport = useSvgExportContext()\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getZoomLevel(), [editor])\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tconst teenyTiny = editor.getZoomLevel() <= 0.18\n\n\treturn (\n\t\t<>\n\t\t\t<path fill={getColorValue(theme, color, 'pattern')} d={d} />\n\t\t\t<path\n\t\t\t\tfill={\n\t\t\t\t\tsvgExport\n\t\t\t\t\t\t? `url(#${getHashPatternZoomName(1, theme.id)})`\n\t\t\t\t\t\t: teenyTiny\n\t\t\t\t\t\t\t? getColorValue(theme, color, 'semi')\n\t\t\t\t\t\t\t: `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`\n\t\t\t\t}\n\t\t\t\td={d}\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
- "mappings": "AAgCU,SA0BR,UA1BQ,KA0BR,YA1BQ;AAhCV;AAAA,EACC;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,WAAW;AAClB,SAAS,iCAAiC;AAUnC,MAAM,YAAY,MAAM,KAAK,SAASA,WAAU;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAmB;AAClB,UAAQ,MAAM;AAAA,IACb,KAAK,QAAQ;AACZ,aAAO;AAAA,IACR;AAAA,IACA,KAAK,SAAS;AACb,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,MAAM,OAAO,GAAM;AAAA,IACvC;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,WAAW;AACf,aAAO,oBAAC,eAAY,OAAc,OAAc,MAAY,GAAM,OAAc;AAAA,IACjF;AAAA,IACA,KAAK,cAAc;AAClB,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,WAAW,GAAG,GAAM;AAAA,IACpE;AAAA,EACD;AACD,CAAC;AAEM,SAAS,YAAY,EAAE,GAAG,OAAO,MAAM,GAAmB;AAChE,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,oBAAoB;AACtC,QAAM,YAAY,SAAS,aAAa,MAAM,OAAO,aAAa,GAAG,CAAC,MAAM,CAAC;AAC7E,QAAM,yBAAyB,0BAA0B;AAEzD,QAAM,YAAY,OAAO,aAAa,KAAK;AAE3C,SACC,iCACC;AAAA,wBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,SAAS,GAAG,GAAM;AAAA,IAC1D;AAAA,MAAC;AAAA;AAAA,QACA,MACC,YACG,QAAQ,uBAAuB,GAAG,MAAM,EAAE,CAAC,MAC3C,YACC,cAAc,OAAO,OAAO,MAAM,IAClC,QAAQ,uBAAuB,WAAW,MAAM,EAAE,CAAC;AAAA,QAExD;AAAA;AAAA,IACD;AAAA,KACD;AAEF;",
4
+ "sourcesContent": ["import {\n\tgetColorValue,\n\tTLDefaultColorStyle,\n\tTLDefaultColorTheme,\n\tTLDefaultFillStyle,\n\tuseEditor,\n\tuseSvgExportContext,\n\tuseValue,\n} from '@tldraw/editor'\nimport React from 'react'\nimport { useGetHashPatternZoomName } from './defaultStyleDefs'\n\ninterface ShapeFillProps {\n\td: string\n\tfill: TLDefaultFillStyle\n\tcolor: TLDefaultColorStyle\n\ttheme: TLDefaultColorTheme\n\tscale: number\n}\n\nexport const ShapeFill = React.memo(function ShapeFill({\n\ttheme,\n\td,\n\tcolor,\n\tfill,\n\tscale,\n}: ShapeFillProps) {\n\tswitch (fill) {\n\t\tcase 'none': {\n\t\t\treturn null\n\t\t}\n\t\tcase 'solid': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'semi')} d={d} />\n\t\t}\n\t\tcase 'semi': {\n\t\t\treturn <path fill={theme.solid} d={d} />\n\t\t}\n\t\tcase 'fill': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'fill')} d={d} />\n\t\t}\n\t\tcase 'pattern': {\n\t\t\treturn <PatternFill theme={theme} color={color} fill={fill} d={d} scale={scale} />\n\t\t}\n\t\tcase 'lined-fill': {\n\t\t\treturn <path fill={getColorValue(theme, color, 'linedFill')} d={d} />\n\t\t}\n\t}\n})\n\nexport function PatternFill({ d, color, theme }: ShapeFillProps) {\n\tconst editor = useEditor()\n\tconst svgExport = useSvgExportContext()\n\tconst zoomLevel = useValue('zoomLevel', () => editor.getEfficientZoomLevel(), [editor])\n\tconst getHashPatternZoomName = useGetHashPatternZoomName()\n\n\tconst teenyTiny = zoomLevel <= 0.18\n\n\treturn (\n\t\t<>\n\t\t\t<path fill={getColorValue(theme, color, 'pattern')} d={d} />\n\t\t\t<path\n\t\t\t\tfill={\n\t\t\t\t\tsvgExport\n\t\t\t\t\t\t? `url(#${getHashPatternZoomName(1, theme.id)})`\n\t\t\t\t\t\t: teenyTiny\n\t\t\t\t\t\t\t? getColorValue(theme, color, 'semi')\n\t\t\t\t\t\t\t: `url(#${getHashPatternZoomName(zoomLevel, theme.id)})`\n\t\t\t\t}\n\t\t\t\td={d}\n\t\t\t/>\n\t\t</>\n\t)\n}\n"],
5
+ "mappings": "AAgCU,SA0BR,UA1BQ,KA0BR,YA1BQ;AAhCV;AAAA,EACC;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,OAAO,WAAW;AAClB,SAAS,iCAAiC;AAUnC,MAAM,YAAY,MAAM,KAAK,SAASA,WAAU;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAAmB;AAClB,UAAQ,MAAM;AAAA,IACb,KAAK,QAAQ;AACZ,aAAO;AAAA,IACR;AAAA,IACA,KAAK,SAAS;AACb,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,MAAM,OAAO,GAAM;AAAA,IACvC;AAAA,IACA,KAAK,QAAQ;AACZ,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,MAAM,GAAG,GAAM;AAAA,IAC/D;AAAA,IACA,KAAK,WAAW;AACf,aAAO,oBAAC,eAAY,OAAc,OAAc,MAAY,GAAM,OAAc;AAAA,IACjF;AAAA,IACA,KAAK,cAAc;AAClB,aAAO,oBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,WAAW,GAAG,GAAM;AAAA,IACpE;AAAA,EACD;AACD,CAAC;AAEM,SAAS,YAAY,EAAE,GAAG,OAAO,MAAM,GAAmB;AAChE,QAAM,SAAS,UAAU;AACzB,QAAM,YAAY,oBAAoB;AACtC,QAAM,YAAY,SAAS,aAAa,MAAM,OAAO,sBAAsB,GAAG,CAAC,MAAM,CAAC;AACtF,QAAM,yBAAyB,0BAA0B;AAEzD,QAAM,YAAY,aAAa;AAE/B,SACC,iCACC;AAAA,wBAAC,UAAK,MAAM,cAAc,OAAO,OAAO,SAAS,GAAG,GAAM;AAAA,IAC1D;AAAA,MAAC;AAAA;AAAA,QACA,MACC,YACG,QAAQ,uBAAuB,GAAG,MAAM,EAAE,CAAC,MAC3C,YACC,cAAc,OAAO,OAAO,MAAM,IAClC,QAAQ,uBAAuB,WAAW,MAAM,EAAE,CAAC;AAAA,QAExD;AAAA;AAAA,IACD;AAAA,KACD;AAEF;",
6
6
  "names": ["ShapeFill"]
7
7
  }
@@ -0,0 +1,12 @@
1
+ import { useEditor, useValue } from "@tldraw/editor";
2
+ function useEfficientZoomThreshold(threshold = 0.25) {
3
+ const editor = useEditor();
4
+ return useValue("efficient zoom threshold", () => editor.getEfficientZoomLevel() < threshold, [
5
+ editor,
6
+ threshold
7
+ ]);
8
+ }
9
+ export {
10
+ useEfficientZoomThreshold
11
+ };
12
+ //# sourceMappingURL=useEfficientZoomThreshold.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/lib/shapes/shared/useEfficientZoomThreshold.ts"],
4
+ "sourcesContent": ["import { useEditor, useValue } from '@tldraw/editor'\n\n/** Returns true when zoomed out far enough that shapes should render in a simplified \"solid\" style. */\nexport function useEfficientZoomThreshold(threshold = 0.25) {\n\tconst editor = useEditor()\n\treturn useValue('efficient zoom threshold', () => editor.getEfficientZoomLevel() < threshold, [\n\t\teditor,\n\t\tthreshold,\n\t])\n}\n"],
5
+ "mappings": "AAAA,SAAS,WAAW,gBAAgB;AAG7B,SAAS,0BAA0B,YAAY,MAAM;AAC3D,QAAM,SAAS,UAAU;AACzB,SAAO,SAAS,4BAA4B,MAAM,OAAO,sBAAsB,IAAI,WAAW;AAAA,IAC7F;AAAA,IACA;AAAA,EACD,CAAC;AACF;",
6
+ "names": []
7
+ }
@@ -37,7 +37,7 @@ function useImageOrVideoAsset({ shapeId, assetId, width }) {
37
37
  return;
38
38
  }
39
39
  }
40
- const screenScale = exportInfo ? exportInfo.scale * (width / asset.props.w) : editor.getZoomLevel() * (width / asset.props.w);
40
+ const screenScale = exportInfo ? exportInfo.scale * (width / asset.props.w) : editor.getEfficientZoomLevel() * (width / asset.props.w);
41
41
  function resolve(asset2, url) {
42
42
  if (isCancelled) return;
43
43
  if (previousUrl.current === url) return;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/shapes/shared/useImageOrVideoAsset.ts"],
4
- "sourcesContent": ["import {\n\tEditor,\n\tSvgExportContext,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLShapeId,\n\tTLVideoAsset,\n\treact,\n\tuseDelaySvgExport,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\n\n/**\n * Options for {@link useImageOrVideoAsset}.\n *\n * @public\n */\nexport interface UseImageOrVideoAssetOptions {\n\t/** The asset ID you want a URL for. */\n\tassetId: TLAssetId | null\n\t/**\n\t * The shape the asset is being used for. We won't update the resolved URL while the shape is\n\t * off-screen.\n\t */\n\tshapeId?: TLShapeId\n\t/**\n\t * The width at which the asset will be displayed, in shape-space pixels.\n\t */\n\twidth: number\n}\n\n/**\n * This is a handy helper hook that resolves an asset to an optimized URL for a given shape, or its\n * {@link @tldraw/editor#Editor.createTemporaryAssetPreview | placeholder} if the asset is still\n * uploading. This is used in particular for high-resolution images when you want lower and higher\n * resolution depending on the size of the image on the canvas and the zoom level.\n *\n * For image scaling to work, you need to implement scaled URLs in\n * {@link @tldraw/tlschema#TLAssetStore.resolve}.\n *\n * @public\n */\nexport function useImageOrVideoAsset({ shapeId, assetId, width }: UseImageOrVideoAssetOptions) {\n\tconst editor = useEditor()\n\tconst exportInfo = useSvgExportContext()\n\tconst exportIsReady = useDelaySvgExport()\n\n\t// We use a state to store the result of the asset resolution, and we're going to avoid updating this whenever we can\n\tconst [result, setResult] = useState<{\n\t\tasset: (TLImageAsset | TLVideoAsset) | null\n\t\turl: string | null\n\t}>(() => ({\n\t\tasset: assetId ? (editor.getAsset<TLImageAsset | TLVideoAsset>(assetId) ?? null) : null,\n\t\turl: null as string | null,\n\t}))\n\n\t// A flag for whether we've resolved the asset URL at least once, after which we can debounce\n\tconst didAlreadyResolve = useRef(false)\n\n\t// The last URL that we've seen for the shape\n\tconst previousUrl = useRef<string | null>(null)\n\n\tuseEffect(() => {\n\t\tif (!assetId) return\n\n\t\tlet isCancelled = false\n\t\tlet cancelDebounceFn: (() => void) | undefined\n\n\t\tconst cleanupEffectScheduler = react('update state', () => {\n\t\t\tif (!exportInfo && shapeId && editor.getCulledShapes().has(shapeId)) return\n\n\t\t\t// Get the fresh asset\n\t\t\tconst asset = editor.getAsset<TLImageAsset | TLVideoAsset>(assetId)\n\t\t\tif (!asset) {\n\t\t\t\t// If the asset is deleted, such as when an upload fails, set the URL to null\n\t\t\t\tsetResult((prev) => ({ ...prev, asset: null, url: null }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Set initial preview for the shape if it has no source (if it was pasted into a local project as base64)\n\t\t\tif (!asset.props.src) {\n\t\t\t\tconst preview = editor.getTemporaryAssetPreview(asset.id)\n\t\t\t\tif (preview) {\n\t\t\t\t\tif (previousUrl.current !== preview) {\n\t\t\t\t\t\tpreviousUrl.current = preview // just for kicks, let's save the url as the previous URL\n\t\t\t\t\t\tsetResult((prev) => ({ ...prev, isPlaceholder: true, url: preview })) // set the preview as the URL\n\t\t\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// aside ...we could bail here if the only thing that has changed is the shape has changed from culled to not culled\n\n\t\t\tconst screenScale = exportInfo\n\t\t\t\t? exportInfo.scale * (width / asset.props.w)\n\t\t\t\t: editor.getZoomLevel() * (width / asset.props.w)\n\n\t\t\tfunction resolve(asset: TLImageAsset | TLVideoAsset, url: string | null) {\n\t\t\t\tif (isCancelled) return // don't update if the hook has remounted\n\t\t\t\tif (previousUrl.current === url) return // don't update the state if the url is the same\n\t\t\t\tdidAlreadyResolve.current = true // mark that we've resolved our first image\n\t\t\t\tpreviousUrl.current = url // keep the url around to compare with the next one\n\t\t\t\tsetResult({ asset, url })\n\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t}\n\n\t\t\t// If we already resolved the URL, debounce fetching potentially multiple image variations.\n\t\t\tif (didAlreadyResolve.current) {\n\t\t\t\tlet tick = 0\n\n\t\t\t\tconst resolveAssetAfterAWhile = () => {\n\t\t\t\t\ttick++\n\t\t\t\t\tif (tick > 500 / 16) {\n\t\t\t\t\t\t// debounce for 500ms\n\t\t\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t\t\t\tcancelDebounceFn?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcancelDebounceFn?.()\n\t\t\t\teditor.on('tick', resolveAssetAfterAWhile)\n\t\t\t\tcancelDebounceFn = () => editor.off('tick', resolveAssetAfterAWhile)\n\t\t\t} else {\n\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t}\n\t\t})\n\n\t\treturn () => {\n\t\t\tcleanupEffectScheduler()\n\t\t\tcancelDebounceFn?.()\n\t\t\tisCancelled = true\n\t\t}\n\t}, [editor, assetId, exportInfo, exportIsReady, shapeId, width])\n\n\treturn result\n}\n\nfunction resolveAssetUrl(\n\teditor: Editor,\n\tassetId: TLAssetId,\n\tscreenScale: number,\n\texportInfo: SvgExportContext | null,\n\tcallback: (url: string | null) => void\n) {\n\teditor\n\t\t.resolveAssetUrl(assetId, {\n\t\t\tscreenScale,\n\t\t\tshouldResolveToOriginal: exportInfo ? exportInfo.pixelRatio === null : false,\n\t\t\tdpr: exportInfo?.pixelRatio ?? undefined,\n\t\t})\n\t\t// There's a weird bug with out debounce function that doesn't\n\t\t// make it work right with async functions, so we use a callback\n\t\t// here instead of returning a promise.\n\t\t.then((url) => {\n\t\t\tcallback(url)\n\t\t})\n}\n"],
5
- "mappings": "AAAA;AAAA,EAOC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,QAAQ,gBAAgB;AAgCrC,SAAS,qBAAqB,EAAE,SAAS,SAAS,MAAM,GAAgC;AAC9F,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,oBAAoB;AACvC,QAAM,gBAAgB,kBAAkB;AAGxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAGzB,OAAO;AAAA,IACT,OAAO,UAAW,OAAO,SAAsC,OAAO,KAAK,OAAQ;AAAA,IACnF,KAAK;AAAA,EACN,EAAE;AAGF,QAAM,oBAAoB,OAAO,KAAK;AAGtC,QAAM,cAAc,OAAsB,IAAI;AAE9C,YAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,QAAI,cAAc;AAClB,QAAI;AAEJ,UAAM,yBAAyB,MAAM,gBAAgB,MAAM;AAC1D,UAAI,CAAC,cAAc,WAAW,OAAO,gBAAgB,EAAE,IAAI,OAAO,EAAG;AAGrE,YAAM,QAAQ,OAAO,SAAsC,OAAO;AAClE,UAAI,CAAC,OAAO;AAEX,kBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AACzD;AAAA,MACD;AAGA,UAAI,CAAC,MAAM,MAAM,KAAK;AACrB,cAAM,UAAU,OAAO,yBAAyB,MAAM,EAAE;AACxD,YAAI,SAAS;AACZ,cAAI,YAAY,YAAY,SAAS;AACpC,wBAAY,UAAU;AACtB,sBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,eAAe,MAAM,KAAK,QAAQ,EAAE;AACpE,0BAAc;AAAA,UACf;AACA;AAAA,QACD;AAAA,MACD;AAIA,YAAM,cAAc,aACjB,WAAW,SAAS,QAAQ,MAAM,MAAM,KACxC,OAAO,aAAa,KAAK,QAAQ,MAAM,MAAM;AAEhD,eAAS,QAAQA,QAAoC,KAAoB;AACxE,YAAI,YAAa;AACjB,YAAI,YAAY,YAAY,IAAK;AACjC,0BAAkB,UAAU;AAC5B,oBAAY,UAAU;AACtB,kBAAU,EAAE,OAAAA,QAAO,IAAI,CAAC;AACxB,sBAAc;AAAA,MACf;AAGA,UAAI,kBAAkB,SAAS;AAC9B,YAAI,OAAO;AAEX,cAAM,0BAA0B,MAAM;AACrC;AACA,cAAI,OAAO,MAAM,IAAI;AAEpB,4BAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACtF,+BAAmB;AAAA,UACpB;AAAA,QACD;AAEA,2BAAmB;AACnB,eAAO,GAAG,QAAQ,uBAAuB;AACzC,2BAAmB,MAAM,OAAO,IAAI,QAAQ,uBAAuB;AAAA,MACpE,OAAO;AACN,wBAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACD,CAAC;AAED,WAAO,MAAM;AACZ,6BAAuB;AACvB,yBAAmB;AACnB,oBAAc;AAAA,IACf;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,YAAY,eAAe,SAAS,KAAK,CAAC;AAE/D,SAAO;AACR;AAEA,SAAS,gBACR,QACA,SACA,aACA,YACA,UACC;AACD,SACE,gBAAgB,SAAS;AAAA,IACzB;AAAA,IACA,yBAAyB,aAAa,WAAW,eAAe,OAAO;AAAA,IACvE,KAAK,YAAY,cAAc;AAAA,EAChC,CAAC,EAIA,KAAK,CAAC,QAAQ;AACd,aAAS,GAAG;AAAA,EACb,CAAC;AACH;",
4
+ "sourcesContent": ["import {\n\tEditor,\n\tSvgExportContext,\n\tTLAssetId,\n\tTLImageAsset,\n\tTLShapeId,\n\tTLVideoAsset,\n\treact,\n\tuseDelaySvgExport,\n\tuseEditor,\n\tuseSvgExportContext,\n} from '@tldraw/editor'\nimport { useEffect, useRef, useState } from 'react'\n\n/**\n * Options for {@link useImageOrVideoAsset}.\n *\n * @public\n */\nexport interface UseImageOrVideoAssetOptions {\n\t/** The asset ID you want a URL for. */\n\tassetId: TLAssetId | null\n\t/**\n\t * The shape the asset is being used for. We won't update the resolved URL while the shape is\n\t * off-screen.\n\t */\n\tshapeId?: TLShapeId\n\t/**\n\t * The width at which the asset will be displayed, in shape-space pixels.\n\t */\n\twidth: number\n}\n\n/**\n * This is a handy helper hook that resolves an asset to an optimized URL for a given shape, or its\n * {@link @tldraw/editor#Editor.createTemporaryAssetPreview | placeholder} if the asset is still\n * uploading. This is used in particular for high-resolution images when you want lower and higher\n * resolution depending on the size of the image on the canvas and the zoom level.\n *\n * For image scaling to work, you need to implement scaled URLs in\n * {@link @tldraw/tlschema#TLAssetStore.resolve}.\n *\n * @public\n */\nexport function useImageOrVideoAsset({ shapeId, assetId, width }: UseImageOrVideoAssetOptions) {\n\tconst editor = useEditor()\n\tconst exportInfo = useSvgExportContext()\n\tconst exportIsReady = useDelaySvgExport()\n\n\t// We use a state to store the result of the asset resolution, and we're going to avoid updating this whenever we can\n\tconst [result, setResult] = useState<{\n\t\tasset: (TLImageAsset | TLVideoAsset) | null\n\t\turl: string | null\n\t}>(() => ({\n\t\tasset: assetId ? (editor.getAsset<TLImageAsset | TLVideoAsset>(assetId) ?? null) : null,\n\t\turl: null as string | null,\n\t}))\n\n\t// A flag for whether we've resolved the asset URL at least once, after which we can debounce\n\tconst didAlreadyResolve = useRef(false)\n\n\t// The last URL that we've seen for the shape\n\tconst previousUrl = useRef<string | null>(null)\n\n\tuseEffect(() => {\n\t\tif (!assetId) return\n\n\t\tlet isCancelled = false\n\t\tlet cancelDebounceFn: (() => void) | undefined\n\n\t\tconst cleanupEffectScheduler = react('update state', () => {\n\t\t\tif (!exportInfo && shapeId && editor.getCulledShapes().has(shapeId)) return\n\n\t\t\t// Get the fresh asset\n\t\t\tconst asset = editor.getAsset<TLImageAsset | TLVideoAsset>(assetId)\n\t\t\tif (!asset) {\n\t\t\t\t// If the asset is deleted, such as when an upload fails, set the URL to null\n\t\t\t\tsetResult((prev) => ({ ...prev, asset: null, url: null }))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Set initial preview for the shape if it has no source (if it was pasted into a local project as base64)\n\t\t\tif (!asset.props.src) {\n\t\t\t\tconst preview = editor.getTemporaryAssetPreview(asset.id)\n\t\t\t\tif (preview) {\n\t\t\t\t\tif (previousUrl.current !== preview) {\n\t\t\t\t\t\tpreviousUrl.current = preview // just for kicks, let's save the url as the previous URL\n\t\t\t\t\t\tsetResult((prev) => ({ ...prev, isPlaceholder: true, url: preview })) // set the preview as the URL\n\t\t\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// aside ...we could bail here if the only thing that has changed is the shape has changed from culled to not culled\n\n\t\t\tconst screenScale = exportInfo\n\t\t\t\t? exportInfo.scale * (width / asset.props.w)\n\t\t\t\t: editor.getEfficientZoomLevel() * (width / asset.props.w)\n\n\t\t\tfunction resolve(asset: TLImageAsset | TLVideoAsset, url: string | null) {\n\t\t\t\tif (isCancelled) return // don't update if the hook has remounted\n\t\t\t\tif (previousUrl.current === url) return // don't update the state if the url is the same\n\t\t\t\tdidAlreadyResolve.current = true // mark that we've resolved our first image\n\t\t\t\tpreviousUrl.current = url // keep the url around to compare with the next one\n\t\t\t\tsetResult({ asset, url })\n\t\t\t\texportIsReady() // let the SVG export know we're ready for export\n\t\t\t}\n\n\t\t\t// If we already resolved the URL, debounce fetching potentially multiple image variations.\n\t\t\tif (didAlreadyResolve.current) {\n\t\t\t\tlet tick = 0\n\n\t\t\t\tconst resolveAssetAfterAWhile = () => {\n\t\t\t\t\ttick++\n\t\t\t\t\tif (tick > 500 / 16) {\n\t\t\t\t\t\t// debounce for 500ms\n\t\t\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t\t\t\tcancelDebounceFn?.()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcancelDebounceFn?.()\n\t\t\t\teditor.on('tick', resolveAssetAfterAWhile)\n\t\t\t\tcancelDebounceFn = () => editor.off('tick', resolveAssetAfterAWhile)\n\t\t\t} else {\n\t\t\t\tresolveAssetUrl(editor, assetId, screenScale, exportInfo, (url) => resolve(asset, url))\n\t\t\t}\n\t\t})\n\n\t\treturn () => {\n\t\t\tcleanupEffectScheduler()\n\t\t\tcancelDebounceFn?.()\n\t\t\tisCancelled = true\n\t\t}\n\t}, [editor, assetId, exportInfo, exportIsReady, shapeId, width])\n\n\treturn result\n}\n\nfunction resolveAssetUrl(\n\teditor: Editor,\n\tassetId: TLAssetId,\n\tscreenScale: number,\n\texportInfo: SvgExportContext | null,\n\tcallback: (url: string | null) => void\n) {\n\teditor\n\t\t.resolveAssetUrl(assetId, {\n\t\t\tscreenScale,\n\t\t\tshouldResolveToOriginal: exportInfo ? exportInfo.pixelRatio === null : false,\n\t\t\tdpr: exportInfo?.pixelRatio ?? undefined,\n\t\t})\n\t\t// There's a weird bug with out debounce function that doesn't\n\t\t// make it work right with async functions, so we use a callback\n\t\t// here instead of returning a promise.\n\t\t.then((url) => {\n\t\t\tcallback(url)\n\t\t})\n}\n"],
5
+ "mappings": "AAAA;AAAA,EAOC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,QAAQ,gBAAgB;AAgCrC,SAAS,qBAAqB,EAAE,SAAS,SAAS,MAAM,GAAgC;AAC9F,QAAM,SAAS,UAAU;AACzB,QAAM,aAAa,oBAAoB;AACvC,QAAM,gBAAgB,kBAAkB;AAGxC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAGzB,OAAO;AAAA,IACT,OAAO,UAAW,OAAO,SAAsC,OAAO,KAAK,OAAQ;AAAA,IACnF,KAAK;AAAA,EACN,EAAE;AAGF,QAAM,oBAAoB,OAAO,KAAK;AAGtC,QAAM,cAAc,OAAsB,IAAI;AAE9C,YAAU,MAAM;AACf,QAAI,CAAC,QAAS;AAEd,QAAI,cAAc;AAClB,QAAI;AAEJ,UAAM,yBAAyB,MAAM,gBAAgB,MAAM;AAC1D,UAAI,CAAC,cAAc,WAAW,OAAO,gBAAgB,EAAE,IAAI,OAAO,EAAG;AAGrE,YAAM,QAAQ,OAAO,SAAsC,OAAO;AAClE,UAAI,CAAC,OAAO;AAEX,kBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AACzD;AAAA,MACD;AAGA,UAAI,CAAC,MAAM,MAAM,KAAK;AACrB,cAAM,UAAU,OAAO,yBAAyB,MAAM,EAAE;AACxD,YAAI,SAAS;AACZ,cAAI,YAAY,YAAY,SAAS;AACpC,wBAAY,UAAU;AACtB,sBAAU,CAAC,UAAU,EAAE,GAAG,MAAM,eAAe,MAAM,KAAK,QAAQ,EAAE;AACpE,0BAAc;AAAA,UACf;AACA;AAAA,QACD;AAAA,MACD;AAIA,YAAM,cAAc,aACjB,WAAW,SAAS,QAAQ,MAAM,MAAM,KACxC,OAAO,sBAAsB,KAAK,QAAQ,MAAM,MAAM;AAEzD,eAAS,QAAQA,QAAoC,KAAoB;AACxE,YAAI,YAAa;AACjB,YAAI,YAAY,YAAY,IAAK;AACjC,0BAAkB,UAAU;AAC5B,oBAAY,UAAU;AACtB,kBAAU,EAAE,OAAAA,QAAO,IAAI,CAAC;AACxB,sBAAc;AAAA,MACf;AAGA,UAAI,kBAAkB,SAAS;AAC9B,YAAI,OAAO;AAEX,cAAM,0BAA0B,MAAM;AACrC;AACA,cAAI,OAAO,MAAM,IAAI;AAEpB,4BAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AACtF,+BAAmB;AAAA,UACpB;AAAA,QACD;AAEA,2BAAmB;AACnB,eAAO,GAAG,QAAQ,uBAAuB;AACzC,2BAAmB,MAAM,OAAO,IAAI,QAAQ,uBAAuB;AAAA,MACpE,OAAO;AACN,wBAAgB,QAAQ,SAAS,aAAa,YAAY,CAAC,QAAQ,QAAQ,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACD,CAAC;AAED,WAAO,MAAM;AACZ,6BAAuB;AACvB,yBAAmB;AACnB,oBAAc;AAAA,IACf;AAAA,EACD,GAAG,CAAC,QAAQ,SAAS,YAAY,eAAe,SAAS,KAAK,CAAC;AAE/D,SAAO;AACR;AAEA,SAAS,gBACR,QACA,SACA,aACA,YACA,UACC;AACD,SACE,gBAAgB,SAAS;AAAA,IACzB;AAAA,IACA,yBAAyB,aAAa,WAAW,eAAe,OAAO;AAAA,IACvE,KAAK,YAAY,cAAc;AAAA,EAChC,CAAC,EAIA,KAAK,CAAC,QAAQ;AACd,aAAS,GAAG;AAAA,EACb,CAAC;AACH;",
6
6
  "names": ["asset"]
7
7
  }
@@ -70,7 +70,7 @@ class VideoShapeUtil extends BaseBoxShapeUtil {
70
70
  }
71
71
  const VideoShape = memo(function VideoShape2({ shape }) {
72
72
  const editor = useEditor();
73
- const showControls = editor.getShapeGeometry(shape).bounds.w * editor.getZoomLevel() >= 110;
73
+ const showControls = editor.getShapeGeometry(shape).bounds.w * editor.getEfficientZoomLevel() >= 110;
74
74
  const isEditing = useIsEditing(shape.id);
75
75
  const prefersReducedMotion = usePrefersReducedMotion();
76
76
  const { Spinner } = useEditorComponents();