tldraw 5.2.0-next.e2b8d10bf10e → 5.2.0

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 (420) hide show
  1. package/DOCS.md +20294 -0
  2. package/README.md +13 -1
  3. package/RELEASE_NOTES.md +2908 -0
  4. package/dist-cjs/index.d.ts +110 -23
  5. package/dist-cjs/index.js +3 -3
  6. package/dist-cjs/index.js.map +2 -2
  7. package/dist-cjs/lib/TldrawImage.js +0 -1
  8. package/dist-cjs/lib/TldrawImage.js.map +2 -2
  9. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js +2 -1
  10. package/dist-cjs/lib/bindings/arrow/ArrowBindingUtil.js.map +2 -2
  11. package/dist-cjs/lib/defaultEmbedDefinitions.js +3 -2
  12. package/dist-cjs/lib/defaultEmbedDefinitions.js.map +2 -2
  13. package/dist-cjs/lib/defaultOverlayUtils.js +11 -11
  14. package/dist-cjs/lib/defaultOverlayUtils.js.map +2 -2
  15. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js +76 -64
  16. package/dist-cjs/lib/overlays/SelectionForegroundOverlayUtil.js.map +2 -2
  17. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js +1 -1
  18. package/dist-cjs/lib/overlays/ShapeHandleOverlayUtil.js.map +2 -2
  19. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js +107 -0
  20. package/dist-cjs/lib/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
  21. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js +3 -0
  22. package/dist-cjs/lib/shapes/arrow/toolStates/Pointing.js.map +2 -2
  23. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js +12 -3
  24. package/dist-cjs/lib/shapes/bookmark/BookmarkShapeUtil.js.map +2 -2
  25. package/dist-cjs/lib/shapes/bookmark/bookmarks.js +54 -6
  26. package/dist-cjs/lib/shapes/bookmark/bookmarks.js.map +2 -2
  27. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js +2 -1
  28. package/dist-cjs/lib/shapes/draw/DrawShapeUtil.js.map +2 -2
  29. package/dist-cjs/lib/shapes/draw/getPath.js +1 -1
  30. package/dist-cjs/lib/shapes/draw/getPath.js.map +2 -2
  31. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js +45 -47
  32. package/dist-cjs/lib/shapes/draw/toolStates/Drawing.js.map +2 -2
  33. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js +2 -1
  34. package/dist-cjs/lib/shapes/embed/EmbedShapeUtil.js.map +2 -2
  35. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js +23 -18
  36. package/dist-cjs/lib/shapes/frame/FrameShapeTool.js.map +2 -2
  37. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js +1 -1
  38. package/dist-cjs/lib/shapes/geo/GeoShapeUtil.js.map +2 -2
  39. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js +3 -0
  40. package/dist-cjs/lib/shapes/geo/toolStates/Pointing.js.map +2 -2
  41. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js +11 -7
  42. package/dist-cjs/lib/shapes/highlight/HighlightShapeUtil.js.map +2 -2
  43. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js +3 -11
  44. package/dist-cjs/lib/shapes/image/ImageShapeUtil.js.map +2 -2
  45. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js +5 -1
  46. package/dist-cjs/lib/shapes/line/toolStates/Pointing.js.map +2 -2
  47. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js +31 -41
  48. package/dist-cjs/lib/shapes/note/NoteShapeUtil.js.map +2 -2
  49. package/dist-cjs/lib/shapes/note/noteHelpers.js +1 -1
  50. package/dist-cjs/lib/shapes/note/noteHelpers.js.map +2 -2
  51. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js +28 -6
  52. package/dist-cjs/lib/shapes/note/toolStates/Pointing.js.map +2 -2
  53. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +3 -2
  54. package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
  55. package/dist-cjs/lib/shapes/shared/RichTextLabel.js +3 -3
  56. package/dist-cjs/lib/shapes/shared/RichTextLabel.js.map +2 -2
  57. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js +17 -3
  58. package/dist-cjs/lib/shapes/shared/defaultStyleDefs.js.map +2 -2
  59. package/dist-cjs/lib/shapes/shared/freehand/core.js +424 -0
  60. package/dist-cjs/lib/shapes/shared/freehand/core.js.map +7 -0
  61. package/dist-cjs/lib/shapes/shared/freehand/fmt.js +106 -0
  62. package/dist-cjs/lib/shapes/shared/freehand/fmt.js.map +7 -0
  63. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js +6 -6
  64. package/dist-cjs/lib/shapes/shared/freehand/getStroke.js.map +2 -2
  65. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js +320 -86
  66. package/dist-cjs/lib/shapes/shared/freehand/getStrokeOutlinePoints.js.map +3 -3
  67. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js +20 -96
  68. package/dist-cjs/lib/shapes/shared/freehand/getStrokePoints.js.map +3 -3
  69. package/dist-cjs/lib/shapes/shared/freehand/svg.js +55 -19
  70. package/dist-cjs/lib/shapes/shared/freehand/svg.js.map +2 -2
  71. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js +189 -97
  72. package/dist-cjs/lib/shapes/shared/freehand/svgInk.js.map +3 -3
  73. package/dist-cjs/lib/shapes/shared/freehand/types.js.map +1 -1
  74. package/dist-cjs/lib/shapes/shared/interpolate-props.js +6 -2
  75. package/dist-cjs/lib/shapes/shared/interpolate-props.js.map +2 -2
  76. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js +3 -0
  77. package/dist-cjs/lib/shapes/text/toolStates/Pointing.js.map +2 -2
  78. package/dist-cjs/lib/tools/HandTool/HandTool.js +16 -6
  79. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  80. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js +10 -1
  81. package/dist-cjs/lib/tools/HandTool/childStates/Dragging.js.map +2 -2
  82. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js +84 -0
  83. package/dist-cjs/lib/tools/HandTool/childStates/OneFingerZooming.js.map +7 -0
  84. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js +12 -0
  85. package/dist-cjs/lib/tools/SelectTool/childStates/Idle.js.map +2 -2
  86. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js +4 -0
  87. package/dist-cjs/lib/tools/SelectTool/childStates/PointingShape.js.map +2 -2
  88. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js +107 -46
  89. package/dist-cjs/lib/tools/SelectTool/childStates/Resizing.js.map +2 -2
  90. package/dist-cjs/lib/ui/TldrawUi.js +4 -3
  91. package/dist-cjs/lib/ui/TldrawUi.js.map +2 -2
  92. package/dist-cjs/lib/ui/components/A11y.js +2 -0
  93. package/dist-cjs/lib/ui/components/A11y.js.map +2 -2
  94. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js +14 -1
  95. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenu.js.map +2 -2
  96. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js +0 -6
  97. package/dist-cjs/lib/ui/components/ContextMenu/DefaultContextMenuContent.js.map +2 -2
  98. package/dist-cjs/lib/ui/components/DefaultFollowingIndicator.js.map +2 -2
  99. package/dist-cjs/lib/ui/components/Dialogs.js +17 -37
  100. package/dist-cjs/lib/ui/components/Dialogs.js.map +2 -2
  101. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js +19 -4
  102. package/dist-cjs/lib/ui/components/HelperButtons/BackToContent.js.map +2 -2
  103. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js +12 -2
  104. package/dist-cjs/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.js.map +2 -2
  105. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js +47 -70
  106. package/dist-cjs/lib/ui/components/Minimap/DefaultMinimap.js.map +2 -2
  107. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js +25 -46
  108. package/dist-cjs/lib/ui/components/Minimap/MinimapManager.js.map +2 -2
  109. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.js.map +2 -2
  110. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuContent.js.map +2 -2
  111. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.js.map +2 -2
  112. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js +1 -1
  113. package/dist-cjs/lib/ui/components/SharePanel/DefaultPeopleMenuItem.js.map +2 -2
  114. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js +1 -0
  115. package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +2 -2
  116. package/dist-cjs/lib/ui/components/menu-items.js +7 -0
  117. package/dist-cjs/lib/ui/components/menu-items.js.map +2 -2
  118. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js +2 -1
  119. package/dist-cjs/lib/ui/components/primitives/TldrawUiDropdownMenu.js.map +2 -2
  120. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js +14 -3
  121. package/dist-cjs/lib/ui/components/primitives/TldrawUiIcon.js.map +2 -2
  122. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js +2 -0
  123. package/dist-cjs/lib/ui/components/primitives/TldrawUiInput.js.map +2 -2
  124. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js +2 -0
  125. package/dist-cjs/lib/ui/components/primitives/TldrawUiPopover.js.map +2 -2
  126. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js +0 -2
  127. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.js.map +2 -2
  128. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js +1 -2
  129. package/dist-cjs/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.js.map +2 -2
  130. package/dist-cjs/lib/ui/context/actions.js +70 -1
  131. package/dist-cjs/lib/ui/context/actions.js.map +2 -2
  132. package/dist-cjs/lib/ui/context/asset-urls.js +5 -8
  133. package/dist-cjs/lib/ui/context/asset-urls.js.map +2 -2
  134. package/dist-cjs/lib/ui/context/events.js.map +2 -2
  135. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js +13 -0
  136. package/dist-cjs/lib/ui/hooks/useKeyboardShortcuts.js.map +2 -2
  137. package/dist-cjs/lib/ui/hooks/useTools.js +1 -1
  138. package/dist-cjs/lib/ui/hooks/useTools.js.map +2 -2
  139. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  140. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +2 -0
  141. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  142. package/dist-cjs/lib/ui/version.js +3 -3
  143. package/dist-cjs/lib/ui/version.js.map +1 -1
  144. package/dist-cjs/lib/utils/embeds/embeds.js +4 -4
  145. package/dist-cjs/lib/utils/embeds/embeds.js.map +2 -2
  146. package/dist-cjs/lib/utils/test-helpers.js +2 -2
  147. package/dist-cjs/lib/utils/test-helpers.js.map +2 -2
  148. package/dist-cjs/lib/utils/text/richText.js +3 -1
  149. package/dist-cjs/lib/utils/text/richText.js.map +2 -2
  150. package/dist-esm/index.d.mts +110 -23
  151. package/dist-esm/index.mjs +5 -3
  152. package/dist-esm/index.mjs.map +2 -2
  153. package/dist-esm/lib/TldrawImage.mjs +0 -1
  154. package/dist-esm/lib/TldrawImage.mjs.map +2 -2
  155. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs +2 -1
  156. package/dist-esm/lib/bindings/arrow/ArrowBindingUtil.mjs.map +2 -2
  157. package/dist-esm/lib/defaultEmbedDefinitions.mjs +3 -2
  158. package/dist-esm/lib/defaultEmbedDefinitions.mjs.map +2 -2
  159. package/dist-esm/lib/defaultOverlayUtils.mjs +11 -11
  160. package/dist-esm/lib/defaultOverlayUtils.mjs.map +2 -2
  161. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs +77 -65
  162. package/dist-esm/lib/overlays/SelectionForegroundOverlayUtil.mjs.map +2 -2
  163. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs +1 -1
  164. package/dist-esm/lib/overlays/ShapeHandleOverlayUtil.mjs.map +2 -2
  165. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs +87 -0
  166. package/dist-esm/lib/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
  167. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs +9 -1
  168. package/dist-esm/lib/shapes/arrow/toolStates/Pointing.mjs.map +2 -2
  169. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs +15 -3
  170. package/dist-esm/lib/shapes/bookmark/BookmarkShapeUtil.mjs.map +2 -2
  171. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs +54 -6
  172. package/dist-esm/lib/shapes/bookmark/bookmarks.mjs.map +2 -2
  173. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs +3 -1
  174. package/dist-esm/lib/shapes/draw/DrawShapeUtil.mjs.map +2 -2
  175. package/dist-esm/lib/shapes/draw/getPath.mjs +1 -1
  176. package/dist-esm/lib/shapes/draw/getPath.mjs.map +2 -2
  177. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs +46 -47
  178. package/dist-esm/lib/shapes/draw/toolStates/Drawing.mjs.map +2 -2
  179. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs +2 -1
  180. package/dist-esm/lib/shapes/embed/EmbedShapeUtil.mjs.map +2 -2
  181. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs +23 -18
  182. package/dist-esm/lib/shapes/frame/FrameShapeTool.mjs.map +2 -2
  183. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs +2 -1
  184. package/dist-esm/lib/shapes/geo/GeoShapeUtil.mjs.map +2 -2
  185. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs +4 -0
  186. package/dist-esm/lib/shapes/geo/toolStates/Pointing.mjs.map +2 -2
  187. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs +12 -7
  188. package/dist-esm/lib/shapes/highlight/HighlightShapeUtil.mjs.map +2 -2
  189. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs +3 -11
  190. package/dist-esm/lib/shapes/image/ImageShapeUtil.mjs.map +2 -2
  191. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs +6 -1
  192. package/dist-esm/lib/shapes/line/toolStates/Pointing.mjs.map +2 -2
  193. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs +32 -42
  194. package/dist-esm/lib/shapes/note/NoteShapeUtil.mjs.map +2 -2
  195. package/dist-esm/lib/shapes/note/noteHelpers.mjs +1 -1
  196. package/dist-esm/lib/shapes/note/noteHelpers.mjs.map +2 -2
  197. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs +29 -6
  198. package/dist-esm/lib/shapes/note/toolStates/Pointing.mjs.map +2 -2
  199. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +3 -2
  200. package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
  201. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs +4 -3
  202. package/dist-esm/lib/shapes/shared/RichTextLabel.mjs.map +2 -2
  203. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs +17 -3
  204. package/dist-esm/lib/shapes/shared/defaultStyleDefs.mjs.map +2 -2
  205. package/dist-esm/lib/shapes/shared/freehand/core.mjs +404 -0
  206. package/dist-esm/lib/shapes/shared/freehand/core.mjs.map +7 -0
  207. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs +86 -0
  208. package/dist-esm/lib/shapes/shared/freehand/fmt.mjs.map +7 -0
  209. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs +7 -7
  210. package/dist-esm/lib/shapes/shared/freehand/getStroke.mjs.map +2 -2
  211. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs +332 -86
  212. package/dist-esm/lib/shapes/shared/freehand/getStrokeOutlinePoints.mjs.map +3 -3
  213. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs +31 -96
  214. package/dist-esm/lib/shapes/shared/freehand/getStrokePoints.mjs.map +3 -3
  215. package/dist-esm/lib/shapes/shared/freehand/svg.mjs +55 -19
  216. package/dist-esm/lib/shapes/shared/freehand/svg.mjs.map +2 -2
  217. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs +214 -99
  218. package/dist-esm/lib/shapes/shared/freehand/svgInk.mjs.map +3 -3
  219. package/dist-esm/lib/shapes/shared/interpolate-props.mjs +6 -2
  220. package/dist-esm/lib/shapes/shared/interpolate-props.mjs.map +2 -2
  221. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs +4 -0
  222. package/dist-esm/lib/shapes/text/toolStates/Pointing.mjs.map +2 -2
  223. package/dist-esm/lib/tools/HandTool/HandTool.mjs +16 -6
  224. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  225. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs +10 -1
  226. package/dist-esm/lib/tools/HandTool/childStates/Dragging.mjs.map +2 -2
  227. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs +64 -0
  228. package/dist-esm/lib/tools/HandTool/childStates/OneFingerZooming.mjs.map +7 -0
  229. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs +12 -0
  230. package/dist-esm/lib/tools/SelectTool/childStates/Idle.mjs.map +2 -2
  231. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs +4 -0
  232. package/dist-esm/lib/tools/SelectTool/childStates/PointingShape.mjs.map +2 -2
  233. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs +108 -46
  234. package/dist-esm/lib/tools/SelectTool/childStates/Resizing.mjs.map +2 -2
  235. package/dist-esm/lib/ui/TldrawUi.mjs +4 -3
  236. package/dist-esm/lib/ui/TldrawUi.mjs.map +2 -2
  237. package/dist-esm/lib/ui/components/A11y.mjs +2 -0
  238. package/dist-esm/lib/ui/components/A11y.mjs.map +2 -2
  239. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs +21 -2
  240. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenu.mjs.map +2 -2
  241. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs +0 -6
  242. package/dist-esm/lib/ui/components/ContextMenu/DefaultContextMenuContent.mjs.map +2 -2
  243. package/dist-esm/lib/ui/components/DefaultFollowingIndicator.mjs.map +2 -2
  244. package/dist-esm/lib/ui/components/Dialogs.mjs +19 -39
  245. package/dist-esm/lib/ui/components/Dialogs.mjs.map +2 -2
  246. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs +20 -5
  247. package/dist-esm/lib/ui/components/HelperButtons/BackToContent.mjs.map +2 -2
  248. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs +12 -2
  249. package/dist-esm/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.mjs.map +2 -2
  250. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs +47 -70
  251. package/dist-esm/lib/ui/components/Minimap/DefaultMinimap.mjs.map +2 -2
  252. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs +25 -46
  253. package/dist-esm/lib/ui/components/Minimap/MinimapManager.mjs.map +2 -2
  254. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.mjs.map +2 -2
  255. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuContent.mjs.map +2 -2
  256. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.mjs.map +2 -2
  257. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs +1 -1
  258. package/dist-esm/lib/ui/components/SharePanel/DefaultPeopleMenuItem.mjs.map +2 -2
  259. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs +1 -0
  260. package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +2 -2
  261. package/dist-esm/lib/ui/components/menu-items.mjs +7 -0
  262. package/dist-esm/lib/ui/components/menu-items.mjs.map +2 -2
  263. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs +2 -1
  264. package/dist-esm/lib/ui/components/primitives/TldrawUiDropdownMenu.mjs.map +2 -2
  265. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs +14 -3
  266. package/dist-esm/lib/ui/components/primitives/TldrawUiIcon.mjs.map +2 -2
  267. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs +2 -0
  268. package/dist-esm/lib/ui/components/primitives/TldrawUiInput.mjs.map +2 -2
  269. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs +2 -0
  270. package/dist-esm/lib/ui/components/primitives/TldrawUiPopover.mjs.map +2 -2
  271. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs +0 -2
  272. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.mjs.map +2 -2
  273. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs +1 -2
  274. package/dist-esm/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.mjs.map +2 -2
  275. package/dist-esm/lib/ui/context/actions.mjs +71 -1
  276. package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
  277. package/dist-esm/lib/ui/context/asset-urls.mjs +5 -8
  278. package/dist-esm/lib/ui/context/asset-urls.mjs.map +2 -2
  279. package/dist-esm/lib/ui/context/events.mjs.map +2 -2
  280. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs +13 -0
  281. package/dist-esm/lib/ui/hooks/useKeyboardShortcuts.mjs.map +2 -2
  282. package/dist-esm/lib/ui/hooks/useTools.mjs +1 -1
  283. package/dist-esm/lib/ui/hooks/useTools.mjs.map +2 -2
  284. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +2 -0
  285. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  286. package/dist-esm/lib/ui/version.mjs +3 -3
  287. package/dist-esm/lib/ui/version.mjs.map +1 -1
  288. package/dist-esm/lib/utils/embeds/embeds.mjs +4 -4
  289. package/dist-esm/lib/utils/embeds/embeds.mjs.map +2 -2
  290. package/dist-esm/lib/utils/test-helpers.mjs +2 -2
  291. package/dist-esm/lib/utils/test-helpers.mjs.map +2 -2
  292. package/dist-esm/lib/utils/text/richText.mjs +3 -1
  293. package/dist-esm/lib/utils/text/richText.mjs.map +2 -2
  294. package/package.json +11 -6
  295. package/src/index.ts +6 -1
  296. package/src/lib/TldrawImage.tsx +2 -2
  297. package/src/lib/bindings/arrow/ArrowBindingUtil.ts +5 -1
  298. package/src/lib/defaultEmbedDefinitions.ts +28 -6
  299. package/src/lib/defaultOverlayUtils.ts +11 -11
  300. package/src/lib/overlays/SelectionForegroundOverlayUtil.ts +91 -72
  301. package/src/lib/overlays/ShapeHandleOverlayUtil.ts +3 -1
  302. package/src/lib/overlays/ShapeIndicatorOverlayUtil.ts +133 -0
  303. package/src/lib/shapes/arrow/toolStates/Pointing.tsx +11 -1
  304. package/src/lib/shapes/bookmark/BookmarkShapeUtil.tsx +16 -3
  305. package/src/lib/shapes/bookmark/bookmarks.ts +105 -15
  306. package/src/lib/shapes/draw/DrawShapeUtil.tsx +7 -5
  307. package/src/lib/shapes/draw/getPath.ts +1 -1
  308. package/src/lib/shapes/draw/toolStates/Drawing.ts +55 -48
  309. package/src/lib/shapes/embed/EmbedShapeUtil.tsx +14 -4
  310. package/src/lib/shapes/frame/FrameShapeTool.ts +35 -24
  311. package/src/lib/shapes/geo/GeoShapeUtil.test.tsx +46 -0
  312. package/src/lib/shapes/geo/GeoShapeUtil.tsx +2 -1
  313. package/src/lib/shapes/geo/toolStates/Pointing.ts +5 -0
  314. package/src/lib/shapes/highlight/HighlightShapeUtil.tsx +14 -11
  315. package/src/lib/shapes/image/ImageShapeUtil.tsx +7 -11
  316. package/src/lib/shapes/line/LineShapeTool.test.ts +41 -0
  317. package/src/lib/shapes/line/toolStates/Pointing.ts +12 -2
  318. package/src/lib/shapes/note/NoteShapeUtil.tsx +36 -51
  319. package/src/lib/shapes/note/noteCloning.test.ts +5 -5
  320. package/src/lib/shapes/note/noteHelpers.ts +1 -1
  321. package/src/lib/shapes/note/toolStates/Pointing.ts +40 -7
  322. package/src/lib/shapes/shared/PlainTextLabel.tsx +3 -3
  323. package/src/lib/shapes/shared/RichTextLabel.tsx +4 -3
  324. package/src/lib/shapes/shared/defaultStyleDefs.tsx +25 -3
  325. package/src/lib/shapes/shared/freehand/core.ts +547 -0
  326. package/src/lib/shapes/shared/freehand/fmt.ts +106 -0
  327. package/src/lib/shapes/shared/freehand/getStroke.ts +7 -7
  328. package/src/lib/shapes/shared/freehand/getStrokeOutlinePoints.ts +451 -139
  329. package/src/lib/shapes/shared/freehand/getStrokePoints.ts +33 -153
  330. package/src/lib/shapes/shared/freehand/svg.ts +72 -23
  331. package/src/lib/shapes/shared/freehand/svgInk.ts +281 -136
  332. package/src/lib/shapes/shared/freehand/types.ts +0 -1
  333. package/src/lib/shapes/shared/interpolate-props.ts +6 -2
  334. package/src/lib/shapes/text/toolStates/Pointing.ts +5 -0
  335. package/src/lib/tools/HandTool/HandTool.ts +19 -6
  336. package/src/lib/tools/HandTool/childStates/Dragging.ts +17 -1
  337. package/src/lib/tools/HandTool/childStates/OneFingerZooming.ts +79 -0
  338. package/src/lib/tools/SelectTool/childStates/Idle.ts +16 -2
  339. package/src/lib/tools/SelectTool/childStates/PointingShape.ts +8 -0
  340. package/src/lib/tools/SelectTool/childStates/Resizing.ts +137 -49
  341. package/src/lib/ui/TldrawUi.tsx +3 -3
  342. package/src/lib/ui/components/A11y.tsx +2 -0
  343. package/src/lib/ui/components/ContextMenu/DefaultContextMenu.tsx +32 -2
  344. package/src/lib/ui/components/ContextMenu/DefaultContextMenuContent.tsx +5 -6
  345. package/src/lib/ui/components/DefaultFollowingIndicator.tsx +2 -2
  346. package/src/lib/ui/components/Dialogs.tsx +20 -23
  347. package/src/lib/ui/components/HelperButtons/BackToContent.tsx +32 -4
  348. package/src/lib/ui/components/KeyboardShortcutsDialog/DefaultKeyboardShortcutsDialogContent.tsx +10 -0
  349. package/src/lib/ui/components/Minimap/DefaultMinimap.tsx +60 -74
  350. package/src/lib/ui/components/Minimap/MinimapManager.ts +35 -57
  351. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuAvatar.tsx +2 -2
  352. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuContent.tsx +2 -1
  353. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuFacePile.tsx +2 -1
  354. package/src/lib/ui/components/SharePanel/DefaultPeopleMenuItem.tsx +3 -3
  355. package/src/lib/ui/components/StylePanel/StylePanelButtonPicker.tsx +5 -0
  356. package/src/lib/ui/components/menu-items.tsx +9 -0
  357. package/src/lib/ui/components/primitives/TldrawUiDropdownMenu.tsx +3 -1
  358. package/src/lib/ui/components/primitives/TldrawUiIcon.tsx +15 -3
  359. package/src/lib/ui/components/primitives/TldrawUiInput.tsx +4 -0
  360. package/src/lib/ui/components/primitives/TldrawUiPopover.tsx +7 -0
  361. package/src/lib/ui/components/primitives/menus/TldrawUiMenuCheckboxItem.tsx +0 -2
  362. package/src/lib/ui/components/primitives/menus/TldrawUiMenuSubmenu.tsx +0 -1
  363. package/src/lib/ui/context/actions.tsx +88 -1
  364. package/src/lib/ui/context/asset-urls.tsx +9 -8
  365. package/src/lib/ui/context/events.tsx +2 -0
  366. package/src/lib/ui/hooks/useKeyboardShortcuts.ts +45 -7
  367. package/src/lib/ui/hooks/useTools.tsx +7 -1
  368. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +2 -0
  369. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +2 -0
  370. package/src/lib/ui/version.ts +3 -3
  371. package/src/lib/ui.css +20 -9
  372. package/src/lib/utils/embeds/embeds.test.ts +14 -12
  373. package/src/lib/utils/embeds/embeds.ts +10 -4
  374. package/src/lib/utils/test-helpers.ts +3 -3
  375. package/src/lib/utils/text/richText.test.ts +36 -0
  376. package/src/lib/utils/text/richText.ts +9 -1
  377. package/src/test/HandTool.test.ts +93 -0
  378. package/src/test/ImageShapeUtil.test.ts +88 -0
  379. package/src/test/SelectTool.test.ts +102 -1
  380. package/src/test/__snapshots__/drawing.test.ts.snap +2 -1
  381. package/src/test/attribution.test.ts +40 -29
  382. package/src/test/bookmark-shapes.test.ts +256 -28
  383. package/src/test/commands/__snapshots__/getSvgString.test.ts.snap +2 -2
  384. package/src/test/commands/clipboardCallbacks.test.ts +3 -1
  385. package/src/test/commands/getSvgString.test.ts +30 -0
  386. package/src/test/commands/penmode.test.ts +97 -1
  387. package/src/test/commands/setCamera.test.ts +12 -0
  388. package/src/test/dragFromToolbar.test.ts +67 -0
  389. package/src/test/drawing.test.ts +48 -7
  390. package/src/test/frames.test.ts +72 -0
  391. package/src/test/freehand/corpus/presets.ts +71 -0
  392. package/src/test/freehand/corpus/real.ts +370 -0
  393. package/src/test/freehand/corpus/strokes.ts +50 -0
  394. package/src/test/freehand/svg.test.ts +20 -0
  395. package/src/test/freehand/wellformed.test.ts +30 -0
  396. package/src/test/long-press-create.test.ts +102 -0
  397. package/src/test/overlays/CollaboratorBrushOverlayUtil.test.ts +4 -4
  398. package/src/test/overlays/CollaboratorCursorOverlayUtil.test.ts +18 -18
  399. package/src/test/overlays/CollaboratorHintOverlayUtil.test.ts +7 -7
  400. package/src/test/overlays/CollaboratorScribbleOverlayUtil.test.ts +3 -3
  401. package/src/test/overlays/OverlayManager.test.ts +1 -1
  402. package/src/test/overlays/SelectionForegroundOverlayUtil.test.ts +58 -0
  403. package/src/test/overlays/ShapeHandleOverlayUtil.test.ts +2 -2
  404. package/src/test/overlays/ShapeIndicatorOverlayUtil.test.ts +36 -0
  405. package/src/test/resizing.test.ts +250 -0
  406. package/src/test/right-click-context-menu.test.ts +90 -0
  407. package/src/test/rightClickPanning.test.ts +11 -0
  408. package/src/test/selection-omnibus.test.ts +15 -2
  409. package/src/test/spatialIndex.test.ts +132 -0
  410. package/src/test/translating.test.ts +0 -6
  411. package/src/test/ui/ContextMenu.test.tsx +146 -3
  412. package/src/test/ui/Dialogs.test.tsx +256 -0
  413. package/src/test/ui/copyHoveredStyles.test.tsx +154 -0
  414. package/src/test/ui/keyboardShortcuts.test.tsx +266 -0
  415. package/tldraw.css +35 -12
  416. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js +0 -100
  417. package/dist-cjs/lib/shapes/shared/freehand/setStrokePointRadii.js.map +0 -7
  418. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs +0 -80
  419. package/dist-esm/lib/shapes/shared/freehand/setStrokePointRadii.mjs.map +0 -7
  420. package/src/lib/shapes/shared/freehand/setStrokePointRadii.ts +0 -127
@@ -21,7 +21,6 @@ __export(defaultOverlayUtils_exports, {
21
21
  defaultOverlayUtils: () => defaultOverlayUtils
22
22
  });
23
23
  module.exports = __toCommonJS(defaultOverlayUtils_exports);
24
- var import_editor = require("@tldraw/editor");
25
24
  var import_ArrowBindingHintOverlayUtil = require("./overlays/ArrowBindingHintOverlayUtil");
26
25
  var import_ArrowHintOverlayUtil = require("./overlays/ArrowHintOverlayUtil");
27
26
  var import_BrushOverlayUtil = require("./overlays/BrushOverlayUtil");
@@ -33,22 +32,23 @@ var import_CollaboratorShapeIndicatorOverlayUtil = require("./overlays/Collabora
33
32
  var import_ScribbleOverlayUtil = require("./overlays/ScribbleOverlayUtil");
34
33
  var import_SelectionForegroundOverlayUtil = require("./overlays/SelectionForegroundOverlayUtil");
35
34
  var import_ShapeHandleOverlayUtil = require("./overlays/ShapeHandleOverlayUtil");
35
+ var import_ShapeIndicatorOverlayUtil = require("./overlays/ShapeIndicatorOverlayUtil");
36
36
  var import_SnapIndicatorOverlayUtil = require("./overlays/SnapIndicatorOverlayUtil");
37
37
  var import_ZoomBrushOverlayUtil = require("./overlays/ZoomBrushOverlayUtil");
38
38
  const defaultOverlayUtils = [
39
+ import_ArrowBindingHintOverlayUtil.ArrowBindingHintOverlayUtil,
40
+ import_ArrowHintOverlayUtil.ArrowHintOverlayUtil,
41
+ import_BrushOverlayUtil.BrushOverlayUtil,
42
+ import_CollaboratorBrushOverlayUtil.CollaboratorBrushOverlayUtil,
43
+ import_CollaboratorCursorOverlayUtil.CollaboratorCursorOverlayUtil,
44
+ import_CollaboratorHintOverlayUtil.CollaboratorHintOverlayUtil,
45
+ import_CollaboratorScribbleOverlayUtil.CollaboratorScribbleOverlayUtil,
39
46
  import_CollaboratorShapeIndicatorOverlayUtil.CollaboratorShapeIndicatorOverlayUtil,
40
- import_editor.ShapeIndicatorOverlayUtil,
47
+ import_ScribbleOverlayUtil.ScribbleOverlayUtil,
41
48
  import_SelectionForegroundOverlayUtil.SelectionForegroundOverlayUtil,
42
49
  import_ShapeHandleOverlayUtil.ShapeHandleOverlayUtil,
43
- import_BrushOverlayUtil.BrushOverlayUtil,
44
- import_ZoomBrushOverlayUtil.ZoomBrushOverlayUtil,
50
+ import_ShapeIndicatorOverlayUtil.ShapeIndicatorOverlayUtil,
45
51
  import_SnapIndicatorOverlayUtil.SnapIndicatorOverlayUtil,
46
- import_ScribbleOverlayUtil.ScribbleOverlayUtil,
47
- import_CollaboratorBrushOverlayUtil.CollaboratorBrushOverlayUtil,
48
- import_CollaboratorScribbleOverlayUtil.CollaboratorScribbleOverlayUtil,
49
- import_CollaboratorHintOverlayUtil.CollaboratorHintOverlayUtil,
50
- import_ArrowHintOverlayUtil.ArrowHintOverlayUtil,
51
- import_ArrowBindingHintOverlayUtil.ArrowBindingHintOverlayUtil,
52
- import_CollaboratorCursorOverlayUtil.CollaboratorCursorOverlayUtil
52
+ import_ZoomBrushOverlayUtil.ZoomBrushOverlayUtil
53
53
  ];
54
54
  //# sourceMappingURL=defaultOverlayUtils.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/defaultOverlayUtils.ts"],
4
- "sourcesContent": ["import { ShapeIndicatorOverlayUtil } from '@tldraw/editor'\nimport { ArrowBindingHintOverlayUtil } from './overlays/ArrowBindingHintOverlayUtil'\nimport { ArrowHintOverlayUtil } from './overlays/ArrowHintOverlayUtil'\nimport { BrushOverlayUtil } from './overlays/BrushOverlayUtil'\nimport { CollaboratorBrushOverlayUtil } from './overlays/CollaboratorBrushOverlayUtil'\nimport { CollaboratorCursorOverlayUtil } from './overlays/CollaboratorCursorOverlayUtil'\nimport { CollaboratorHintOverlayUtil } from './overlays/CollaboratorHintOverlayUtil'\nimport { CollaboratorScribbleOverlayUtil } from './overlays/CollaboratorScribbleOverlayUtil'\nimport { CollaboratorShapeIndicatorOverlayUtil } from './overlays/CollaboratorShapeIndicatorOverlayUtil'\nimport { ScribbleOverlayUtil } from './overlays/ScribbleOverlayUtil'\nimport { SelectionForegroundOverlayUtil } from './overlays/SelectionForegroundOverlayUtil'\nimport { ShapeHandleOverlayUtil } from './overlays/ShapeHandleOverlayUtil'\nimport { SnapIndicatorOverlayUtil } from './overlays/SnapIndicatorOverlayUtil'\nimport { ZoomBrushOverlayUtil } from './overlays/ZoomBrushOverlayUtil'\n\n/** @public */\nexport const defaultOverlayUtils = [\n\tCollaboratorShapeIndicatorOverlayUtil,\n\tShapeIndicatorOverlayUtil,\n\tSelectionForegroundOverlayUtil,\n\tShapeHandleOverlayUtil,\n\tBrushOverlayUtil,\n\tZoomBrushOverlayUtil,\n\tSnapIndicatorOverlayUtil,\n\tScribbleOverlayUtil,\n\tCollaboratorBrushOverlayUtil,\n\tCollaboratorScribbleOverlayUtil,\n\tCollaboratorHintOverlayUtil,\n\tArrowHintOverlayUtil,\n\tArrowBindingHintOverlayUtil,\n\tCollaboratorCursorOverlayUtil,\n] as const\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA0C;AAC1C,yCAA4C;AAC5C,kCAAqC;AACrC,8BAAiC;AACjC,0CAA6C;AAC7C,2CAA8C;AAC9C,yCAA4C;AAC5C,6CAAgD;AAChD,mDAAsD;AACtD,iCAAoC;AACpC,4CAA+C;AAC/C,oCAAuC;AACvC,sCAAyC;AACzC,kCAAqC;AAG9B,MAAM,sBAAsB;AAAA,EAClC;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;AACD;",
4
+ "sourcesContent": ["import { ArrowBindingHintOverlayUtil } from './overlays/ArrowBindingHintOverlayUtil'\nimport { ArrowHintOverlayUtil } from './overlays/ArrowHintOverlayUtil'\nimport { BrushOverlayUtil } from './overlays/BrushOverlayUtil'\nimport { CollaboratorBrushOverlayUtil } from './overlays/CollaboratorBrushOverlayUtil'\nimport { CollaboratorCursorOverlayUtil } from './overlays/CollaboratorCursorOverlayUtil'\nimport { CollaboratorHintOverlayUtil } from './overlays/CollaboratorHintOverlayUtil'\nimport { CollaboratorScribbleOverlayUtil } from './overlays/CollaboratorScribbleOverlayUtil'\nimport { CollaboratorShapeIndicatorOverlayUtil } from './overlays/CollaboratorShapeIndicatorOverlayUtil'\nimport { ScribbleOverlayUtil } from './overlays/ScribbleOverlayUtil'\nimport { SelectionForegroundOverlayUtil } from './overlays/SelectionForegroundOverlayUtil'\nimport { ShapeHandleOverlayUtil } from './overlays/ShapeHandleOverlayUtil'\nimport { ShapeIndicatorOverlayUtil } from './overlays/ShapeIndicatorOverlayUtil'\nimport { SnapIndicatorOverlayUtil } from './overlays/SnapIndicatorOverlayUtil'\nimport { ZoomBrushOverlayUtil } from './overlays/ZoomBrushOverlayUtil'\n\n/** @public */\nexport const defaultOverlayUtils = [\n\tArrowBindingHintOverlayUtil,\n\tArrowHintOverlayUtil,\n\tBrushOverlayUtil,\n\tCollaboratorBrushOverlayUtil,\n\tCollaboratorCursorOverlayUtil,\n\tCollaboratorHintOverlayUtil,\n\tCollaboratorScribbleOverlayUtil,\n\tCollaboratorShapeIndicatorOverlayUtil,\n\tScribbleOverlayUtil,\n\tSelectionForegroundOverlayUtil,\n\tShapeHandleOverlayUtil,\n\tShapeIndicatorOverlayUtil,\n\tSnapIndicatorOverlayUtil,\n\tZoomBrushOverlayUtil,\n] as const\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAA4C;AAC5C,kCAAqC;AACrC,8BAAiC;AACjC,0CAA6C;AAC7C,2CAA8C;AAC9C,yCAA4C;AAC5C,6CAAgD;AAChD,mDAAsD;AACtD,iCAAoC;AACpC,4CAA+C;AAC/C,oCAAuC;AACvC,uCAA0C;AAC1C,sCAAyC;AACzC,kCAAqC;AAG9B,MAAM,sBAAsB;AAAA,EAClC;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;AACD;",
6
6
  "names": []
7
7
  }
@@ -52,6 +52,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
52
52
  "select.pointing_selection",
53
53
  "select.pointing_shape",
54
54
  "select.pointing_resize_handle",
55
+ "select.pointing_rotate_handle",
55
56
  "select.resizing",
56
57
  "select.crop.idle",
57
58
  "select.crop.pointing_crop",
@@ -73,7 +74,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
73
74
  const transform = import_editor.Mat.Compose(
74
75
  import_editor.Mat.Translate(state.bounds.x, state.bounds.y),
75
76
  import_editor.Mat.Rotate(state.rotation),
76
- import_editor.Mat.Translate(state.expandDx, state.expandDy)
77
+ import_editor.Mat.Translate(state.expandOffsetX, state.expandOffsetY)
77
78
  );
78
79
  const { overlayType, handle } = overlay.props;
79
80
  switch (overlayType) {
@@ -93,7 +94,7 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
93
94
  ctx.save();
94
95
  ctx.translate(state.bounds.x, state.bounds.y);
95
96
  ctx.rotate(state.rotation);
96
- ctx.translate(state.expandDx, state.expandDy);
97
+ ctx.translate(state.expandOffsetX, state.expandOffsetY);
97
98
  const colors = this._getThemeColors();
98
99
  this._renderSelectionBox(ctx, state, colors);
99
100
  this._renderResizeCorners(ctx, state, colors);
@@ -171,23 +172,31 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
171
172
  isFilled: true
172
173
  });
173
174
  }
174
- const cp = this._getCornerLocalPoint(handle, state.width, state.height);
175
- const s = Math.max(state.targetSizeX, state.targetSizeY) * 1.5;
175
+ const cornerPoint = this._getCornerLocalPoint(
176
+ handle,
177
+ state.width,
178
+ state.height
179
+ );
180
+ const cornerHitHalfSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.5;
176
181
  return new import_editor.Polygon2d({
177
- points: this._localRectToPoints(cp.x - s, cp.y - s, s * 2, s * 2).map(
178
- (p) => import_editor.Mat.applyToPoint(transform, p)
179
- ),
182
+ points: this._localRectToPoints(
183
+ cornerPoint.x - cornerHitHalfSize,
184
+ cornerPoint.y - cornerHitHalfSize,
185
+ cornerHitHalfSize * 2,
186
+ cornerHitHalfSize * 2
187
+ ).map((p) => import_editor.Mat.applyToPoint(transform, p)),
180
188
  isFilled: true
181
189
  });
182
190
  }
183
191
  _getRotateHandleGeometry(handle, state, transform) {
184
- const cornerSize = Math.max(state.targetSizeX, state.targetSizeY) * 1.5;
192
+ const cornerSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.62;
185
193
  const center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize);
186
194
  const radius = cornerSize;
187
- return new import_editor.Circle2d({
195
+ return new import_editor.Rectangle2d({
188
196
  x: center.x - radius,
189
197
  y: center.y - radius,
190
- radius,
198
+ width: radius * 2,
199
+ height: radius * 2,
191
200
  isFilled: true
192
201
  }).transform(transform);
193
202
  }
@@ -210,14 +219,14 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
210
219
  }
211
220
  _renderResizeCorners(ctx, state, colors) {
212
221
  if (!state.showResizeHandles) return;
213
- const { size, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state;
222
+ const { handleSize, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state;
214
223
  ctx.fillStyle = colors.bgColor;
215
224
  ctx.strokeStyle = colors.strokeColor;
216
225
  ctx.lineWidth = this.options.lineWidth / zoom;
217
226
  const drawCorner = (x, y, hidden) => {
218
227
  if (hidden) return;
219
- ctx.fillRect(x - size / 2, y - size / 2, size, size);
220
- ctx.strokeRect(x - size / 2, y - size / 2, size, size);
228
+ ctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize);
229
+ ctx.strokeRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize);
221
230
  };
222
231
  drawCorner(0, 0, false);
223
232
  drawCorner(width, 0, hideAlternateCornerHandles);
@@ -226,42 +235,42 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
226
235
  }
227
236
  _renderCropHandles(ctx, state, colors) {
228
237
  if (!state.showCropHandles) return;
229
- const { size, width, height, hideAlternateCropHandles } = state;
230
- const cropStrokeWidth = size / 3;
238
+ const { handleSize, width, height, hideAlternateCropHandles } = state;
239
+ const cropStrokeWidth = handleSize / 3;
231
240
  const offset = cropStrokeWidth / 2;
232
241
  ctx.beginPath();
233
242
  ctx.strokeStyle = colors.strokeColor;
234
243
  ctx.lineWidth = cropStrokeWidth;
235
244
  ctx.lineCap = "butt";
236
245
  ctx.lineJoin = "miter";
237
- ctx.moveTo(-offset, size);
246
+ ctx.moveTo(-offset, handleSize);
238
247
  ctx.lineTo(-offset, -offset);
239
- ctx.lineTo(size, -offset);
240
- ctx.moveTo(width + offset, height - size);
248
+ ctx.lineTo(handleSize, -offset);
249
+ ctx.moveTo(width + offset, height - handleSize);
241
250
  ctx.lineTo(width + offset, height + offset);
242
- ctx.lineTo(width - size, height + offset);
251
+ ctx.lineTo(width - handleSize, height + offset);
243
252
  if (!hideAlternateCropHandles) {
244
- ctx.moveTo(width - size, -offset);
253
+ ctx.moveTo(width - handleSize, -offset);
245
254
  ctx.lineTo(width + offset, -offset);
246
- ctx.lineTo(width + offset, size);
247
- ctx.moveTo(size, height + offset);
255
+ ctx.lineTo(width + offset, handleSize);
256
+ ctx.moveTo(handleSize, height + offset);
248
257
  ctx.lineTo(-offset, height + offset);
249
- ctx.lineTo(-offset, height - size);
250
- ctx.moveTo(width / 2 - size, -offset);
251
- ctx.lineTo(width / 2 + size, -offset);
252
- ctx.moveTo(width + offset, height / 2 - size);
253
- ctx.lineTo(width + offset, height / 2 + size);
254
- ctx.moveTo(width / 2 - size, height + offset);
255
- ctx.lineTo(width / 2 + size, height + offset);
256
- ctx.moveTo(-offset, height / 2 - size);
257
- ctx.lineTo(-offset, height / 2 + size);
258
+ ctx.lineTo(-offset, height - handleSize);
259
+ ctx.moveTo(width / 2 - handleSize, -offset);
260
+ ctx.lineTo(width / 2 + handleSize, -offset);
261
+ ctx.moveTo(width + offset, height / 2 - handleSize);
262
+ ctx.lineTo(width + offset, height / 2 + handleSize);
263
+ ctx.moveTo(width / 2 - handleSize, height + offset);
264
+ ctx.lineTo(width / 2 + handleSize, height + offset);
265
+ ctx.moveTo(-offset, height / 2 - handleSize);
266
+ ctx.lineTo(-offset, height / 2 + handleSize);
258
267
  }
259
268
  ctx.stroke();
260
269
  }
261
270
  _renderMobileRotateHandle(ctx, state, colors) {
262
271
  if (!state.showMobileRotateHandle) return;
263
272
  const { cx, cy } = this._getMobileRotateCenter(state);
264
- const fgRadius = state.size / SQUARE_ROOT_PI;
273
+ const fgRadius = state.handleSize / SQUARE_ROOT_PI;
265
274
  ctx.fillStyle = colors.bgColor;
266
275
  ctx.strokeStyle = colors.strokeColor;
267
276
  ctx.lineWidth = this.options.lineWidth / state.zoom;
@@ -278,16 +287,16 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
278
287
  zoom,
279
288
  width,
280
289
  height,
281
- size,
282
- targetSizeY
290
+ handleSize,
291
+ hitTargetSizeY
283
292
  } = state;
284
293
  if (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== "text") {
285
294
  return;
286
295
  }
287
- const textHandleHeight = Math.min(24 / zoom, height - targetSizeY * 3);
296
+ const textHandleHeight = Math.min(24 / zoom, height - hitTargetSizeY * 3);
288
297
  if (textHandleHeight * zoom < 4) return;
289
- const hw = size / 2;
290
- const r = size / 4;
298
+ const hw = handleSize / 2;
299
+ const r = handleSize / 4;
291
300
  ctx.fillStyle = colors.strokeColor;
292
301
  ctx.beginPath();
293
302
  ctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r);
@@ -321,23 +330,25 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
321
330
  const rotation = editor.getSelectionRotation();
322
331
  const width = expandedBounds.width;
323
332
  const height = expandedBounds.height;
324
- const size = 8 / zoom;
325
- const isTinyX = width < size * 2;
326
- const isTinyY = height < size * 2;
327
- const isSmallX = width < size * 4;
328
- const isSmallY = height < size * 4;
329
- const isSmallCropX = width < size * 5;
330
- const isSmallCropY = height < size * 5;
333
+ const handleSize = 8 / zoom;
334
+ const isTinyX = width < handleSize * 2;
335
+ const isTinyY = height < handleSize * 2;
336
+ const isSmallX = width < handleSize * 4;
337
+ const isSmallY = height < handleSize * 4;
338
+ const isSmallCropX = width < handleSize * 5;
339
+ const isSmallCropY = height < handleSize * 5;
331
340
  const mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1;
332
- const targetSize = 6 / zoom * mobileHandleMultiplier;
333
- const targetSizeX = (isSmallX ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75);
334
- const targetSizeY = (isSmallY ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75);
335
- const expandDx = expandedBounds.x - bounds.x;
336
- const expandDy = expandedBounds.y - bounds.y;
341
+ const hitTargetSize = 6 / zoom * mobileHandleMultiplier;
342
+ const hitTargetSizeX = (isSmallX ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75);
343
+ const hitTargetSizeY = (isSmallY ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75);
344
+ const expandOffsetX = expandedBounds.x - bounds.x;
345
+ const expandOffsetY = expandedBounds.y - bounds.y;
337
346
  const shouldDisplayControls = editor.isInAny(
338
347
  "select.idle",
339
348
  "select.pointing_selection",
340
349
  "select.pointing_shape",
350
+ "select.pointing_resize_handle",
351
+ "select.pointing_rotate_handle",
341
352
  "select.crop.idle"
342
353
  ) && !isChangingStyle && !isReadonly;
343
354
  const showCropHandles = editor.isInAny(
@@ -366,7 +377,8 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
366
377
  "select.crop.idle",
367
378
  "select.crop.pointing_crop",
368
379
  "select.crop.pointing_crop_handle",
369
- "select.pointing_resize_handle"
380
+ "select.pointing_resize_handle",
381
+ "select.pointing_rotate_handle"
370
382
  ) || showSelectionBounds && editor.isIn("select.resizing") && !!(onlyShape && editor.isShapeOfType(onlyShape, "text"));
371
383
  return {
372
384
  bounds,
@@ -376,12 +388,12 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
376
388
  rotation,
377
389
  width,
378
390
  height,
379
- size,
380
- targetSize,
381
- targetSizeX,
382
- targetSizeY,
383
- expandDx,
384
- expandDy,
391
+ handleSize,
392
+ hitTargetSize,
393
+ hitTargetSizeX,
394
+ hitTargetSizeY,
395
+ expandOffsetX,
396
+ expandOffsetY,
385
397
  isSmallX,
386
398
  shouldDisplayControls,
387
399
  shouldDisplayBox,
@@ -396,12 +408,12 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
396
408
  };
397
409
  }
398
410
  _getMobileRotateCenter(state) {
399
- const { width, height, targetSize, isSmallX, onlyShape, rotation } = state;
411
+ const { width, height, hitTargetSize, isSmallX, onlyShape, rotation } = state;
400
412
  const editor = this.editor;
401
413
  const isMediaShape = !!onlyShape && (editor.isShapeOfType(onlyShape, "image") || editor.isShapeOfType(onlyShape, "video"));
402
414
  const isShapeTooCloseToContextualToolbar = rotation / import_editor.HALF_PI > 1.6 && rotation / import_editor.HALF_PI < 2.4;
403
- const cx = isSmallX ? -targetSize * 1.5 : width / 2;
404
- const cy = isSmallX ? height / 2 : isMediaShape && !isShapeTooCloseToContextualToolbar ? height + targetSize * 1.5 : -targetSize * 1.5;
415
+ const cx = isSmallX ? -hitTargetSize * 1.5 : width / 2;
416
+ const cy = isSmallX ? height / 2 : isMediaShape && !isShapeTooCloseToContextualToolbar ? height + hitTargetSize * 1.5 : -hitTargetSize * 1.5;
405
417
  return { cx, cy };
406
418
  }
407
419
  _getThemeColors() {
@@ -420,16 +432,16 @@ class SelectionForegroundOverlayUtil extends import_editor.OverlayUtil {
420
432
  };
421
433
  }
422
434
  _getEdgeLocalRect(edge, state) {
423
- const { width, height, targetSizeX, targetSizeY } = state;
435
+ const { width, height, hitTargetSizeX, hitTargetSizeY } = state;
424
436
  switch (edge) {
425
437
  case "top":
426
- return { x: 0, y: -targetSizeY, w: width, h: targetSizeY * 2 };
438
+ return { x: 0, y: -hitTargetSizeY, w: width, h: hitTargetSizeY * 2 };
427
439
  case "right":
428
- return { x: width - targetSizeX, y: 0, w: targetSizeX * 2, h: height };
440
+ return { x: width - hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height };
429
441
  case "bottom":
430
- return { x: 0, y: height - targetSizeY, w: width, h: targetSizeY * 2 };
442
+ return { x: 0, y: height - hitTargetSizeY, w: width, h: hitTargetSizeY * 2 };
431
443
  case "left":
432
- return { x: -targetSizeX, y: 0, w: targetSizeX * 2, h: height };
444
+ return { x: -hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height };
433
445
  }
434
446
  }
435
447
  _getRotateHandleLocalCenter(corner, width, height, cornerSize) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/overlays/SelectionForegroundOverlayUtil.ts"],
4
- "sourcesContent": ["import {\n\tBox,\n\tCircle2d,\n\tGeometry2d,\n\tHALF_PI,\n\tMat,\n\tOverlayUtil,\n\tPolygon2d,\n\tRotateCorner,\n\tSelectionCorner,\n\tSelectionEdge,\n\tTLCursorType,\n\tTLOverlay,\n\tTLSelectionHandle,\n\tTLShape,\n\tVec,\n} from '@tldraw/editor'\n\nconst SQUARE_ROOT_PI = Math.sqrt(Math.PI)\n\nconst ROTATE_CURSORS: Partial<Record<RotateCorner, TLCursorType>> = {\n\ttop_left_rotate: 'nwse-rotate',\n\ttop_right_rotate: 'nesw-rotate',\n\tbottom_left_rotate: 'swne-rotate',\n\tbottom_right_rotate: 'senw-rotate',\n}\n\nconst RESIZE_CURSORS: Partial<Record<TLSelectionHandle, TLCursorType>> = {\n\ttop_left: 'nwse-resize',\n\ttop_right: 'nesw-resize',\n\tbottom_right: 'nwse-resize',\n\tbottom_left: 'nesw-resize',\n\ttop: 'ns-resize',\n\tbottom: 'ns-resize',\n\tleft: 'ew-resize',\n\tright: 'ew-resize',\n}\n\n/** @public */\nexport interface TLSelectionForegroundOverlay extends TLOverlay {\n\tprops: {\n\t\toverlayType: 'resize_handle' | 'rotate_handle' | 'mobile_rotate'\n\t\thandle: TLSelectionHandle | RotateCorner\n\t}\n}\n\ninterface SelectionState {\n\tbounds: Box\n\tonlyShape: TLShape | null\n\tisCoarsePointer: boolean\n\tzoom: number\n\trotation: number\n\twidth: number\n\theight: number\n\tsize: number\n\ttargetSize: number\n\ttargetSizeX: number\n\ttargetSizeY: number\n\texpandDx: number\n\texpandDy: number\n\tisSmallX: boolean\n\tshouldDisplayControls: boolean\n\tshouldDisplayBox: boolean\n\tshowCropHandles: boolean\n\tshowResizeHandles: boolean\n\tshowCornerRotateHandles: boolean\n\tshowMobileRotateHandle: boolean\n\tshowHandles: boolean\n\thideAlternateCornerHandles: boolean\n\thideAlternateCropHandles: boolean\n\tshowOnlyOneHandle: boolean\n}\n\ninterface SelectionForegroundColors {\n\tstrokeColor: string\n\tbgColor: string\n}\n\n/**\n * Overlay util for selection foreground handles (resize corners/edges, rotate corners, mobile rotate).\n * Each interactive element of the selection foreground becomes its own overlay instance.\n *\n * @public\n */\nexport class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForegroundOverlay> {\n\tstatic override type = 'selection_foreground'\n\toverride options = { zIndex: 100, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tif (!this.editor.getSelectionRotatedPageBounds()) return false\n\n\t\treturn this.editor.isInAny(\n\t\t\t'select.idle',\n\t\t\t'select.brushing',\n\t\t\t'select.scribble_brushing',\n\t\t\t'select.pointing_canvas',\n\t\t\t'select.pointing_selection',\n\t\t\t'select.pointing_shape',\n\t\t\t'select.pointing_resize_handle',\n\t\t\t'select.resizing',\n\t\t\t'select.crop.idle',\n\t\t\t'select.crop.pointing_crop',\n\t\t\t'select.crop.pointing_crop_handle'\n\t\t)\n\t}\n\n\toverride getOverlays(): TLSelectionForegroundOverlay[] {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return []\n\n\t\tconst overlays: TLSelectionForegroundOverlay[] = []\n\t\tthis._collectResizeCornerOverlays(state, overlays)\n\t\tthis._collectResizeEdgeOverlays(state, overlays)\n\t\tthis._collectRotateOverlays(state, overlays)\n\t\treturn overlays\n\t}\n\n\toverride getGeometry(overlay: TLSelectionForegroundOverlay): Geometry2d | null {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return null\n\n\t\tconst transform = Mat.Compose(\n\t\t\tMat.Translate(state.bounds.x, state.bounds.y),\n\t\t\tMat.Rotate(state.rotation),\n\t\t\tMat.Translate(state.expandDx, state.expandDy)\n\t\t)\n\n\t\tconst { overlayType, handle } = overlay.props\n\n\t\tswitch (overlayType) {\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn this._getResizeHandleGeometry(handle as TLSelectionHandle, state, transform)\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn this._getRotateHandleGeometry(handle as RotateCorner, state, transform)\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn this._getMobileRotateGeometry(state, transform)\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, _overlays: TLSelectionForegroundOverlay[]): void {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return\n\n\t\t// Transform to local selection space; each render helper assumes this is active.\n\t\tctx.save()\n\t\tctx.translate(state.bounds.x, state.bounds.y)\n\t\tctx.rotate(state.rotation)\n\t\tctx.translate(state.expandDx, state.expandDy)\n\n\t\tconst colors = this._getThemeColors()\n\t\tthis._renderSelectionBox(ctx, state, colors)\n\t\tthis._renderResizeCorners(ctx, state, colors)\n\t\tthis._renderCropHandles(ctx, state, colors)\n\t\tthis._renderMobileRotateHandle(ctx, state, colors)\n\t\tthis._renderTextResizeHandles(ctx, state, colors)\n\n\t\tctx.restore()\n\t}\n\n\toverride getCursor(overlay: TLSelectionForegroundOverlay): TLCursorType | undefined {\n\t\tconst { overlayType, handle } = overlay.props\n\t\tswitch (overlayType) {\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn ROTATE_CURSORS[handle as RotateCorner]\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn 'grab'\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn RESIZE_CURSORS[handle as TLSelectionHandle]\n\t\t\tdefault:\n\t\t\t\treturn undefined\n\t\t}\n\t}\n\n\t// --- Overlay collection ---\n\n\tprivate _collectResizeCornerOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\toverlays.push(this._makeOverlay('resize_handle', 'top_left'))\n\t\tif (!state.hideAlternateCornerHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top_right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_left'))\n\t\t}\n\t\tif (!state.showOnlyOneHandle || state.showCropHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_right'))\n\t\t}\n\t}\n\n\tprivate _collectResizeEdgeOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\tconst {\n\t\t\tshowCropHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t} = state\n\n\t\tconst hideVerticalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideAlternateCornerHandles || showOnlyOneHandle || isCoarsePointer\n\t\tconst isMobileAndTextShape = isCoarsePointer && !!onlyShape && onlyShape.type === 'text'\n\t\tconst hideHorizontalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideVerticalEdgeTargets && !isMobileAndTextShape\n\n\t\tif (!hideVerticalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom'))\n\t\t}\n\t\tif (!hideHorizontalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'left'))\n\t\t}\n\t}\n\n\tprivate _collectRotateOverlays(state: SelectionState, overlays: TLSelectionForegroundOverlay[]) {\n\t\tif (state.showCornerRotateHandles) {\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_right_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_right_rotate'))\n\t\t}\n\t\tif (state.showMobileRotateHandle) {\n\t\t\toverlays.push(this._makeOverlay('mobile_rotate', 'mobile_rotate'))\n\t\t}\n\t}\n\n\t// --- Geometry builders ---\n\n\tprivate _getResizeHandleGeometry(\n\t\thandle: TLSelectionHandle,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tif (handle === 'top' || handle === 'bottom' || handle === 'left' || handle === 'right') {\n\t\t\tconst rect = this._getEdgeLocalRect(handle, state)\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: this._localRectToPoints(rect.x, rect.y, rect.w, rect.h).map((p) =>\n\t\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t\t),\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst cp = this._getCornerLocalPoint(handle as SelectionCorner, state.width, state.height)\n\t\tconst s = Math.max(state.targetSizeX, state.targetSizeY) * 1.5\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cp.x - s, cp.y - s, s * 2, s * 2).map((p) =>\n\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tprivate _getRotateHandleGeometry(\n\t\thandle: RotateCorner,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tconst cornerSize = Math.max(state.targetSizeX, state.targetSizeY) * 1.5\n\t\tconst center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize)\n\t\tconst radius = cornerSize\n\t\treturn new Circle2d({\n\t\t\tx: center.x - radius,\n\t\t\ty: center.y - radius,\n\t\t\tradius,\n\t\t\tisFilled: true,\n\t\t}).transform(transform)\n\t}\n\n\tprivate _getMobileRotateGeometry(state: SelectionState, transform: Mat): Geometry2d {\n\t\tconst bgRadius = Math.max(14 * (1 / state.zoom), 20 / Math.max(1, state.zoom))\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cx - bgRadius, cy - bgRadius, bgRadius * 2, bgRadius * 2).map(\n\t\t\t\t(p) => Mat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\t// --- Rendering (all helpers assume ctx is in local selection space) ---\n\n\tprivate _renderSelectionBox(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.shouldDisplayBox) return\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.strokeRect(0, 0, state.width, state.height)\n\t}\n\n\tprivate _renderResizeCorners(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showResizeHandles) return\n\n\t\tconst { size, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\tconst drawCorner = (x: number, y: number, hidden: boolean) => {\n\t\t\tif (hidden) return\n\t\t\tctx.fillRect(x - size / 2, y - size / 2, size, size)\n\t\t\tctx.strokeRect(x - size / 2, y - size / 2, size, size)\n\t\t}\n\n\t\tdrawCorner(0, 0, false) // top-left always shown\n\t\tdrawCorner(width, 0, hideAlternateCornerHandles) // top-right\n\t\tdrawCorner(width, height, showOnlyOneHandle) // bottom-right\n\t\tdrawCorner(0, height, hideAlternateCornerHandles) // bottom-left\n\t}\n\n\tprivate _renderCropHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showCropHandles) return\n\n\t\tconst { size, width, height, hideAlternateCropHandles } = state\n\t\tconst cropStrokeWidth = size / 3\n\t\tconst offset = cropStrokeWidth / 2\n\n\t\tctx.beginPath()\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = cropStrokeWidth\n\t\tctx.lineCap = 'butt'\n\t\tctx.lineJoin = 'miter'\n\n\t\t// top_left corner (always shown)\n\t\tctx.moveTo(-offset, size)\n\t\tctx.lineTo(-offset, -offset)\n\t\tctx.lineTo(size, -offset)\n\n\t\t// bottom_right corner (always shown)\n\t\tctx.moveTo(width + offset, height - size)\n\t\tctx.lineTo(width + offset, height + offset)\n\t\tctx.lineTo(width - size, height + offset)\n\n\t\tif (!hideAlternateCropHandles) {\n\t\t\t// top_right corner\n\t\t\tctx.moveTo(width - size, -offset)\n\t\t\tctx.lineTo(width + offset, -offset)\n\t\t\tctx.lineTo(width + offset, size)\n\n\t\t\t// bottom_left corner\n\t\t\tctx.moveTo(size, height + offset)\n\t\t\tctx.lineTo(-offset, height + offset)\n\t\t\tctx.lineTo(-offset, height - size)\n\n\t\t\t// top edge\n\t\t\tctx.moveTo(width / 2 - size, -offset)\n\t\t\tctx.lineTo(width / 2 + size, -offset)\n\n\t\t\t// right edge\n\t\t\tctx.moveTo(width + offset, height / 2 - size)\n\t\t\tctx.lineTo(width + offset, height / 2 + size)\n\n\t\t\t// bottom edge\n\t\t\tctx.moveTo(width / 2 - size, height + offset)\n\t\t\tctx.lineTo(width / 2 + size, height + offset)\n\n\t\t\t// left edge\n\t\t\tctx.moveTo(-offset, height / 2 - size)\n\t\t\tctx.lineTo(-offset, height / 2 + size)\n\t\t}\n\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderMobileRotateHandle(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showMobileRotateHandle) return\n\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\tconst fgRadius = state.size / SQUARE_ROOT_PI\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.beginPath()\n\t\tctx.arc(cx, cy, fgRadius, 0, Math.PI * 2)\n\t\tctx.fill()\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderTextResizeHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tconst {\n\t\t\tshouldDisplayControls,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t\tzoom,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tsize,\n\t\t\ttargetSizeY,\n\t\t} = state\n\t\tif (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== 'text') {\n\t\t\treturn\n\t\t}\n\n\t\tconst textHandleHeight = Math.min(24 / zoom, height - targetSizeY * 3)\n\t\tif (textHandleHeight * zoom < 4) return\n\n\t\tconst hw = size / 2\n\t\tconst r = size / 4\n\n\t\tctx.fillStyle = colors.strokeColor\n\t\tctx.beginPath()\n\t\tctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t\tctx.beginPath()\n\t\tctx.roundRect(width - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t}\n\n\t// --- Shared helpers ---\n\n\t/**\n\t * Single source of truth for the derived state the selection foreground needs.\n\t * Called from `getOverlays()`, `getGeometry()`, and `render()` so their visibility\n\t * predicates can't drift. Returns `null` when no selection UI should appear at all\n\t * (nothing selected, or the only selected shape is hidden).\n\t */\n\tprivate _computeSelectionState(): SelectionState | null {\n\t\tconst editor = this.editor\n\t\tconst bounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return null\n\n\t\tconst onlyShape = editor.getOnlySelectedShape()\n\t\tif (onlyShape && editor.isShapeHidden(onlyShape)) return null\n\n\t\tconst onlyShapeUtil = onlyShape ? editor.getShapeUtil(onlyShape) : null\n\t\tconst isLockedShape = !!(onlyShape && editor.isShapeOrAncestorLocked(onlyShape))\n\n\t\tconst expandOutlineBy =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.expandSelectionOutlinePx(onlyShape) : 0\n\t\tconst expandedBounds =\n\t\t\texpandOutlineBy instanceof Box\n\t\t\t\t? bounds.clone().expand(expandOutlineBy).zeroFix()\n\t\t\t\t: bounds.clone().expandBy(expandOutlineBy).zeroFix()\n\n\t\tconst instanceState = editor.getInstanceState()\n\t\tconst isCoarsePointer = instanceState.isCoarsePointer\n\t\tconst isChangingStyle = instanceState.isChangingStyle\n\t\tconst isReadonly = editor.getIsReadonly()\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst rotation = editor.getSelectionRotation()\n\n\t\tconst width = expandedBounds.width\n\t\tconst height = expandedBounds.height\n\t\tconst size = 8 / zoom\n\t\tconst isTinyX = width < size * 2\n\t\tconst isTinyY = height < size * 2\n\t\tconst isSmallX = width < size * 4\n\t\tconst isSmallY = height < size * 4\n\t\tconst isSmallCropX = width < size * 5\n\t\tconst isSmallCropY = height < size * 5\n\n\t\tconst mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1\n\t\tconst targetSize = (6 / zoom) * mobileHandleMultiplier\n\t\tconst targetSizeX = (isSmallX ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75)\n\t\tconst targetSizeY = (isSmallY ? targetSize / 2 : targetSize) * (mobileHandleMultiplier * 0.75)\n\n\t\tconst expandDx = expandedBounds.x - bounds.x\n\t\tconst expandDy = expandedBounds.y - bounds.y\n\n\t\tconst shouldDisplayControls =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.crop.idle'\n\t\t\t) &&\n\t\t\t!isChangingStyle &&\n\t\t\t!isReadonly\n\n\t\tconst showCropHandles =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.idle',\n\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t'select.crop.pointing_crop_handle'\n\t\t\t) && !isReadonly\n\n\t\tconst canOnlyShapeResize =\n\t\t\tonlyShape && onlyShapeUtil\n\t\t\t\t? onlyShapeUtil.canResize(onlyShape) && !onlyShapeUtil.hideResizeHandles(onlyShape)\n\t\t\t\t: true\n\t\tconst hideOnlyShapeRotateHandle =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideRotateHandle(onlyShape) : false\n\t\tconst hideOnlyShapeSelectionBounds =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideSelectionBoundsFg(onlyShape) : false\n\n\t\tconst showResizeHandles =\n\t\t\tshouldDisplayControls && !isLockedShape && !showCropHandles && canOnlyShapeResize\n\n\t\tconst showCornerRotateHandles =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\t!isCoarsePointer &&\n\t\t\t!(isTinyX || isTinyY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst showMobileRotateHandle =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\tisCoarsePointer &&\n\t\t\t(!isSmallX || !isSmallY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst hideAlternateCornerHandles = isTinyX || isTinyY\n\t\tconst hideAlternateCropHandles = isSmallCropX || isSmallCropY\n\t\tconst showOnlyOneHandle = isTinyX && isTinyY\n\t\tconst showHandles = showResizeHandles || showCropHandles\n\n\t\tconst showSelectionBounds = !hideOnlyShapeSelectionBounds && !isChangingStyle\n\n\t\tconst shouldDisplayBox =\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isInAny(\n\t\t\t\t\t'select.idle',\n\t\t\t\t\t'select.brushing',\n\t\t\t\t\t'select.scribble_brushing',\n\t\t\t\t\t'select.pointing_canvas',\n\t\t\t\t\t'select.pointing_selection',\n\t\t\t\t\t'select.pointing_shape',\n\t\t\t\t\t'select.crop.idle',\n\t\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t\t'select.pointing_resize_handle'\n\t\t\t\t)) ||\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isIn('select.resizing') &&\n\t\t\t\t!!(onlyShape && editor.isShapeOfType(onlyShape, 'text')))\n\n\t\treturn {\n\t\t\tbounds,\n\t\t\tonlyShape,\n\t\t\tisCoarsePointer,\n\t\t\tzoom,\n\t\t\trotation,\n\t\t\twidth,\n\t\t\theight,\n\t\t\tsize,\n\t\t\ttargetSize,\n\t\t\ttargetSizeX,\n\t\t\ttargetSizeY,\n\t\t\texpandDx,\n\t\t\texpandDy,\n\t\t\tisSmallX,\n\t\t\tshouldDisplayControls,\n\t\t\tshouldDisplayBox,\n\t\t\tshowCropHandles,\n\t\t\tshowResizeHandles,\n\t\t\tshowCornerRotateHandles,\n\t\t\tshowMobileRotateHandle,\n\t\t\tshowHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t}\n\t}\n\n\tprivate _getMobileRotateCenter(state: SelectionState): { cx: number; cy: number } {\n\t\tconst { width, height, targetSize, isSmallX, onlyShape, rotation } = state\n\t\tconst editor = this.editor\n\t\tconst isMediaShape =\n\t\t\t!!onlyShape &&\n\t\t\t(editor.isShapeOfType(onlyShape, 'image') || editor.isShapeOfType(onlyShape, 'video'))\n\t\tconst isShapeTooCloseToContextualToolbar = rotation / HALF_PI > 1.6 && rotation / HALF_PI < 2.4\n\n\t\tconst cx = isSmallX ? -targetSize * 1.5 : width / 2\n\t\tconst cy = isSmallX\n\t\t\t? height / 2\n\t\t\t: isMediaShape && !isShapeTooCloseToContextualToolbar\n\t\t\t\t? height + targetSize * 1.5\n\t\t\t\t: -targetSize * 1.5\n\t\treturn { cx, cy }\n\t}\n\n\tprivate _getThemeColors(): SelectionForegroundColors {\n\t\tconst editor = this.editor\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\treturn {\n\t\t\tstrokeColor: themeColors.selectionStroke,\n\t\t\tbgColor: themeColors.background,\n\t\t}\n\t}\n\n\tprivate _makeOverlay(\n\t\toverlayType: TLSelectionForegroundOverlay['props']['overlayType'],\n\t\thandle: TLSelectionHandle | RotateCorner\n\t): TLSelectionForegroundOverlay {\n\t\treturn {\n\t\t\tid: `selection_fg:${handle}`,\n\t\t\ttype: 'selection_foreground',\n\t\t\tprops: { overlayType, handle },\n\t\t}\n\t}\n\n\tprivate _getEdgeLocalRect(\n\t\tedge: SelectionEdge,\n\t\tstate: SelectionState\n\t): { x: number; y: number; w: number; h: number } {\n\t\tconst { width, height, targetSizeX, targetSizeY } = state\n\t\tswitch (edge) {\n\t\t\tcase 'top':\n\t\t\t\treturn { x: 0, y: -targetSizeY, w: width, h: targetSizeY * 2 }\n\t\t\tcase 'right':\n\t\t\t\treturn { x: width - targetSizeX, y: 0, w: targetSizeX * 2, h: height }\n\t\t\tcase 'bottom':\n\t\t\t\treturn { x: 0, y: height - targetSizeY, w: width, h: targetSizeY * 2 }\n\t\t\tcase 'left':\n\t\t\t\treturn { x: -targetSizeX, y: 0, w: targetSizeX * 2, h: height }\n\t\t}\n\t}\n\n\tprivate _getRotateHandleLocalCenter(\n\t\tcorner: RotateCorner,\n\t\twidth: number,\n\t\theight: number,\n\t\tcornerSize: number\n\t): Vec {\n\t\t// Centered on the outside corner of the resize handle square\n\t\t// (the corner furthest from the selection interior)\n\t\tswitch (corner) {\n\t\t\tcase 'top_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, -cornerSize)\n\t\t\tcase 'top_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, -cornerSize)\n\t\t\tcase 'bottom_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, height + cornerSize)\n\t\t\tcase 'bottom_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, height + cornerSize)\n\t\t\tdefault:\n\t\t\t\treturn new Vec(0, 0)\n\t\t}\n\t}\n\n\tprivate _getCornerLocalPoint(corner: SelectionCorner, width: number, height: number): Vec {\n\t\tswitch (corner) {\n\t\t\tcase 'top_left':\n\t\t\t\treturn new Vec(0, 0)\n\t\t\tcase 'top_right':\n\t\t\t\treturn new Vec(width, 0)\n\t\t\tcase 'bottom_right':\n\t\t\t\treturn new Vec(width, height)\n\t\t\tcase 'bottom_left':\n\t\t\t\treturn new Vec(0, height)\n\t\t}\n\t}\n\n\tprivate _localRectToPoints(x: number, y: number, w: number, h: number): Vec[] {\n\t\treturn [new Vec(x, y), new Vec(x + w, y), new Vec(x + w, y + h), new Vec(x, y + h)]\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tBox,\n\tGeometry2d,\n\tHALF_PI,\n\tMat,\n\tOverlayUtil,\n\tPolygon2d,\n\tRectangle2d,\n\tRotateCorner,\n\tSelectionCorner,\n\tSelectionEdge,\n\tTLCursorType,\n\tTLOverlay,\n\tTLSelectionHandle,\n\tTLShape,\n\tVec,\n} from '@tldraw/editor'\n\nconst SQUARE_ROOT_PI = Math.sqrt(Math.PI)\n\nconst ROTATE_CURSORS: Partial<Record<RotateCorner, TLCursorType>> = {\n\ttop_left_rotate: 'nwse-rotate',\n\ttop_right_rotate: 'nesw-rotate',\n\tbottom_left_rotate: 'swne-rotate',\n\tbottom_right_rotate: 'senw-rotate',\n}\n\nconst RESIZE_CURSORS: Partial<Record<TLSelectionHandle, TLCursorType>> = {\n\ttop_left: 'nwse-resize',\n\ttop_right: 'nesw-resize',\n\tbottom_right: 'nwse-resize',\n\tbottom_left: 'nesw-resize',\n\ttop: 'ns-resize',\n\tbottom: 'ns-resize',\n\tleft: 'ew-resize',\n\tright: 'ew-resize',\n}\n\n/** @public */\nexport interface TLSelectionForegroundOverlay extends TLOverlay {\n\tprops: {\n\t\toverlayType: 'resize_handle' | 'rotate_handle' | 'mobile_rotate'\n\t\thandle: TLSelectionHandle | RotateCorner\n\t}\n}\n\ninterface SelectionState {\n\tbounds: Box\n\tonlyShape: TLShape | null\n\tisCoarsePointer: boolean\n\tzoom: number\n\trotation: number\n\twidth: number\n\theight: number\n\t/** Visual side length of the rendered resize-handle squares. */\n\thandleSize: number\n\t/** Base half-extent of the interactive hit target for handles. */\n\thitTargetSize: number\n\t/** Hit target half-extent along the x axis (narrower for small selections). */\n\thitTargetSizeX: number\n\t/** Hit target half-extent along the y axis (narrower for small selections). */\n\thitTargetSizeY: number\n\t/** Offset from the unexpanded bounds to the expanded selection outline. */\n\texpandOffsetX: number\n\texpandOffsetY: number\n\tisSmallX: boolean\n\tshouldDisplayControls: boolean\n\tshouldDisplayBox: boolean\n\tshowCropHandles: boolean\n\tshowResizeHandles: boolean\n\tshowCornerRotateHandles: boolean\n\tshowMobileRotateHandle: boolean\n\tshowHandles: boolean\n\thideAlternateCornerHandles: boolean\n\thideAlternateCropHandles: boolean\n\tshowOnlyOneHandle: boolean\n}\n\ninterface SelectionForegroundColors {\n\tstrokeColor: string\n\tbgColor: string\n}\n\n/**\n * Overlay util for selection foreground handles (resize corners/edges, rotate corners, mobile rotate).\n * Each interactive element of the selection foreground becomes its own overlay instance.\n *\n * @public\n */\nexport class SelectionForegroundOverlayUtil extends OverlayUtil<TLSelectionForegroundOverlay> {\n\tstatic override type = 'selection_foreground'\n\toverride options = { zIndex: 100, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tif (!this.editor.getSelectionRotatedPageBounds()) return false\n\n\t\treturn this.editor.isInAny(\n\t\t\t'select.idle',\n\t\t\t'select.brushing',\n\t\t\t'select.scribble_brushing',\n\t\t\t'select.pointing_canvas',\n\t\t\t'select.pointing_selection',\n\t\t\t'select.pointing_shape',\n\t\t\t'select.pointing_resize_handle',\n\t\t\t'select.pointing_rotate_handle',\n\t\t\t'select.resizing',\n\t\t\t'select.crop.idle',\n\t\t\t'select.crop.pointing_crop',\n\t\t\t'select.crop.pointing_crop_handle'\n\t\t)\n\t}\n\n\toverride getOverlays(): TLSelectionForegroundOverlay[] {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return []\n\n\t\tconst overlays: TLSelectionForegroundOverlay[] = []\n\t\tthis._collectResizeCornerOverlays(state, overlays)\n\t\tthis._collectResizeEdgeOverlays(state, overlays)\n\t\tthis._collectRotateOverlays(state, overlays)\n\t\treturn overlays\n\t}\n\n\toverride getGeometry(overlay: TLSelectionForegroundOverlay): Geometry2d | null {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return null\n\n\t\tconst transform = Mat.Compose(\n\t\t\tMat.Translate(state.bounds.x, state.bounds.y),\n\t\t\tMat.Rotate(state.rotation),\n\t\t\tMat.Translate(state.expandOffsetX, state.expandOffsetY)\n\t\t)\n\n\t\tconst { overlayType, handle } = overlay.props\n\n\t\tswitch (overlayType) {\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn this._getResizeHandleGeometry(handle as TLSelectionHandle, state, transform)\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn this._getRotateHandleGeometry(handle as RotateCorner, state, transform)\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn this._getMobileRotateGeometry(state, transform)\n\t\t\tdefault:\n\t\t\t\treturn null\n\t\t}\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, _overlays: TLSelectionForegroundOverlay[]): void {\n\t\tconst state = this._computeSelectionState()\n\t\tif (!state) return\n\n\t\t// Transform to local selection space; each render helper assumes this is active.\n\t\tctx.save()\n\t\tctx.translate(state.bounds.x, state.bounds.y)\n\t\tctx.rotate(state.rotation)\n\t\tctx.translate(state.expandOffsetX, state.expandOffsetY)\n\n\t\tconst colors = this._getThemeColors()\n\t\tthis._renderSelectionBox(ctx, state, colors)\n\t\tthis._renderResizeCorners(ctx, state, colors)\n\t\tthis._renderCropHandles(ctx, state, colors)\n\t\tthis._renderMobileRotateHandle(ctx, state, colors)\n\t\tthis._renderTextResizeHandles(ctx, state, colors)\n\n\t\tctx.restore()\n\t}\n\n\toverride getCursor(overlay: TLSelectionForegroundOverlay): TLCursorType | undefined {\n\t\tconst { overlayType, handle } = overlay.props\n\t\tswitch (overlayType) {\n\t\t\tcase 'rotate_handle':\n\t\t\t\treturn ROTATE_CURSORS[handle as RotateCorner]\n\t\t\tcase 'mobile_rotate':\n\t\t\t\treturn 'grab'\n\t\t\tcase 'resize_handle':\n\t\t\t\treturn RESIZE_CURSORS[handle as TLSelectionHandle]\n\t\t\tdefault:\n\t\t\t\treturn undefined\n\t\t}\n\t}\n\n\t// --- Overlay collection ---\n\n\tprivate _collectResizeCornerOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\toverlays.push(this._makeOverlay('resize_handle', 'top_left'))\n\t\tif (!state.hideAlternateCornerHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top_right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_left'))\n\t\t}\n\t\tif (!state.showOnlyOneHandle || state.showCropHandles) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom_right'))\n\t\t}\n\t}\n\n\tprivate _collectResizeEdgeOverlays(\n\t\tstate: SelectionState,\n\t\toverlays: TLSelectionForegroundOverlay[]\n\t) {\n\t\tif (!state.showHandles) return\n\n\t\tconst {\n\t\t\tshowCropHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t} = state\n\n\t\tconst hideVerticalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideAlternateCornerHandles || showOnlyOneHandle || isCoarsePointer\n\t\tconst isMobileAndTextShape = isCoarsePointer && !!onlyShape && onlyShape.type === 'text'\n\t\tconst hideHorizontalEdgeTargets = showCropHandles\n\t\t\t? hideAlternateCropHandles\n\t\t\t: hideVerticalEdgeTargets && !isMobileAndTextShape\n\n\t\tif (!hideVerticalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'top'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'bottom'))\n\t\t}\n\t\tif (!hideHorizontalEdgeTargets) {\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'right'))\n\t\t\toverlays.push(this._makeOverlay('resize_handle', 'left'))\n\t\t}\n\t}\n\n\tprivate _collectRotateOverlays(state: SelectionState, overlays: TLSelectionForegroundOverlay[]) {\n\t\tif (state.showCornerRotateHandles) {\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'top_right_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_left_rotate'))\n\t\t\toverlays.push(this._makeOverlay('rotate_handle', 'bottom_right_rotate'))\n\t\t}\n\t\tif (state.showMobileRotateHandle) {\n\t\t\toverlays.push(this._makeOverlay('mobile_rotate', 'mobile_rotate'))\n\t\t}\n\t}\n\n\t// --- Geometry builders ---\n\n\tprivate _getResizeHandleGeometry(\n\t\thandle: TLSelectionHandle,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tif (handle === 'top' || handle === 'bottom' || handle === 'left' || handle === 'right') {\n\t\t\tconst rect = this._getEdgeLocalRect(handle, state)\n\t\t\treturn new Polygon2d({\n\t\t\t\tpoints: this._localRectToPoints(rect.x, rect.y, rect.w, rect.h).map((p) =>\n\t\t\t\t\tMat.applyToPoint(transform, p)\n\t\t\t\t),\n\t\t\t\tisFilled: true,\n\t\t\t})\n\t\t}\n\n\t\tconst cornerPoint = this._getCornerLocalPoint(\n\t\t\thandle as SelectionCorner,\n\t\t\tstate.width,\n\t\t\tstate.height\n\t\t)\n\t\tconst cornerHitHalfSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.5\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(\n\t\t\t\tcornerPoint.x - cornerHitHalfSize,\n\t\t\t\tcornerPoint.y - cornerHitHalfSize,\n\t\t\t\tcornerHitHalfSize * 2,\n\t\t\t\tcornerHitHalfSize * 2\n\t\t\t).map((p) => Mat.applyToPoint(transform, p)),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\tprivate _getRotateHandleGeometry(\n\t\thandle: RotateCorner,\n\t\tstate: SelectionState,\n\t\ttransform: Mat\n\t): Geometry2d {\n\t\tconst cornerSize = Math.max(state.hitTargetSizeX, state.hitTargetSizeY) * 1.62\n\t\tconst center = this._getRotateHandleLocalCenter(handle, state.width, state.height, cornerSize)\n\t\tconst radius = cornerSize\n\t\treturn new Rectangle2d({\n\t\t\tx: center.x - radius,\n\t\t\ty: center.y - radius,\n\t\t\twidth: radius * 2,\n\t\t\theight: radius * 2,\n\t\t\tisFilled: true,\n\t\t}).transform(transform)\n\t}\n\n\tprivate _getMobileRotateGeometry(state: SelectionState, transform: Mat): Geometry2d {\n\t\tconst bgRadius = Math.max(14 * (1 / state.zoom), 20 / Math.max(1, state.zoom))\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\treturn new Polygon2d({\n\t\t\tpoints: this._localRectToPoints(cx - bgRadius, cy - bgRadius, bgRadius * 2, bgRadius * 2).map(\n\t\t\t\t(p) => Mat.applyToPoint(transform, p)\n\t\t\t),\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\t// --- Rendering (all helpers assume ctx is in local selection space) ---\n\n\tprivate _renderSelectionBox(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.shouldDisplayBox) return\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.strokeRect(0, 0, state.width, state.height)\n\t}\n\n\tprivate _renderResizeCorners(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showResizeHandles) return\n\n\t\tconst { handleSize, width, height, hideAlternateCornerHandles, showOnlyOneHandle, zoom } = state\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\tconst drawCorner = (x: number, y: number, hidden: boolean) => {\n\t\t\tif (hidden) return\n\t\t\tctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)\n\t\t\tctx.strokeRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize)\n\t\t}\n\n\t\tdrawCorner(0, 0, false) // top-left always shown\n\t\tdrawCorner(width, 0, hideAlternateCornerHandles) // top-right\n\t\tdrawCorner(width, height, showOnlyOneHandle) // bottom-right\n\t\tdrawCorner(0, height, hideAlternateCornerHandles) // bottom-left\n\t}\n\n\tprivate _renderCropHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showCropHandles) return\n\n\t\tconst { handleSize, width, height, hideAlternateCropHandles } = state\n\t\tconst cropStrokeWidth = handleSize / 3\n\t\tconst offset = cropStrokeWidth / 2\n\n\t\tctx.beginPath()\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = cropStrokeWidth\n\t\tctx.lineCap = 'butt'\n\t\tctx.lineJoin = 'miter'\n\n\t\t// top_left corner (always shown)\n\t\tctx.moveTo(-offset, handleSize)\n\t\tctx.lineTo(-offset, -offset)\n\t\tctx.lineTo(handleSize, -offset)\n\n\t\t// bottom_right corner (always shown)\n\t\tctx.moveTo(width + offset, height - handleSize)\n\t\tctx.lineTo(width + offset, height + offset)\n\t\tctx.lineTo(width - handleSize, height + offset)\n\n\t\tif (!hideAlternateCropHandles) {\n\t\t\t// top_right corner\n\t\t\tctx.moveTo(width - handleSize, -offset)\n\t\t\tctx.lineTo(width + offset, -offset)\n\t\t\tctx.lineTo(width + offset, handleSize)\n\n\t\t\t// bottom_left corner\n\t\t\tctx.moveTo(handleSize, height + offset)\n\t\t\tctx.lineTo(-offset, height + offset)\n\t\t\tctx.lineTo(-offset, height - handleSize)\n\n\t\t\t// top edge\n\t\t\tctx.moveTo(width / 2 - handleSize, -offset)\n\t\t\tctx.lineTo(width / 2 + handleSize, -offset)\n\n\t\t\t// right edge\n\t\t\tctx.moveTo(width + offset, height / 2 - handleSize)\n\t\t\tctx.lineTo(width + offset, height / 2 + handleSize)\n\n\t\t\t// bottom edge\n\t\t\tctx.moveTo(width / 2 - handleSize, height + offset)\n\t\t\tctx.lineTo(width / 2 + handleSize, height + offset)\n\n\t\t\t// left edge\n\t\t\tctx.moveTo(-offset, height / 2 - handleSize)\n\t\t\tctx.lineTo(-offset, height / 2 + handleSize)\n\t\t}\n\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderMobileRotateHandle(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tif (!state.showMobileRotateHandle) return\n\n\t\tconst { cx, cy } = this._getMobileRotateCenter(state)\n\t\tconst fgRadius = state.handleSize / SQUARE_ROOT_PI\n\n\t\tctx.fillStyle = colors.bgColor\n\t\tctx.strokeStyle = colors.strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / state.zoom\n\t\tctx.beginPath()\n\t\tctx.arc(cx, cy, fgRadius, 0, Math.PI * 2)\n\t\tctx.fill()\n\t\tctx.stroke()\n\t}\n\n\tprivate _renderTextResizeHandles(\n\t\tctx: CanvasRenderingContext2D,\n\t\tstate: SelectionState,\n\t\tcolors: SelectionForegroundColors\n\t) {\n\t\tconst {\n\t\t\tshouldDisplayControls,\n\t\t\tisCoarsePointer,\n\t\t\tonlyShape,\n\t\t\tzoom,\n\t\t\twidth,\n\t\t\theight,\n\t\t\thandleSize,\n\t\t\thitTargetSizeY,\n\t\t} = state\n\t\tif (!shouldDisplayControls || !isCoarsePointer || !onlyShape || onlyShape.type !== 'text') {\n\t\t\treturn\n\t\t}\n\n\t\tconst textHandleHeight = Math.min(24 / zoom, height - hitTargetSizeY * 3)\n\t\tif (textHandleHeight * zoom < 4) return\n\n\t\tconst hw = handleSize / 2\n\t\tconst r = handleSize / 4\n\n\t\tctx.fillStyle = colors.strokeColor\n\t\tctx.beginPath()\n\t\tctx.roundRect(0 - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t\tctx.beginPath()\n\t\tctx.roundRect(width - hw / 2, height / 2 - textHandleHeight / 2, hw, textHandleHeight, r)\n\t\tctx.fill()\n\t}\n\n\t// --- Shared helpers ---\n\n\t/**\n\t * Single source of truth for the derived state the selection foreground needs.\n\t * Called from `getOverlays()`, `getGeometry()`, and `render()` so their visibility\n\t * predicates can't drift. Returns `null` when no selection UI should appear at all\n\t * (nothing selected, or the only selected shape is hidden).\n\t */\n\tprivate _computeSelectionState(): SelectionState | null {\n\t\tconst editor = this.editor\n\t\tconst bounds = editor.getSelectionRotatedPageBounds()\n\t\tif (!bounds) return null\n\n\t\tconst onlyShape = editor.getOnlySelectedShape()\n\t\tif (onlyShape && editor.isShapeHidden(onlyShape)) return null\n\n\t\tconst onlyShapeUtil = onlyShape ? editor.getShapeUtil(onlyShape) : null\n\t\tconst isLockedShape = !!(onlyShape && editor.isShapeOrAncestorLocked(onlyShape))\n\n\t\tconst expandOutlineBy =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.expandSelectionOutlinePx(onlyShape) : 0\n\t\tconst expandedBounds =\n\t\t\texpandOutlineBy instanceof Box\n\t\t\t\t? bounds.clone().expand(expandOutlineBy).zeroFix()\n\t\t\t\t: bounds.clone().expandBy(expandOutlineBy).zeroFix()\n\n\t\tconst instanceState = editor.getInstanceState()\n\t\tconst isCoarsePointer = instanceState.isCoarsePointer\n\t\tconst isChangingStyle = instanceState.isChangingStyle\n\t\tconst isReadonly = editor.getIsReadonly()\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst rotation = editor.getSelectionRotation()\n\n\t\tconst width = expandedBounds.width\n\t\tconst height = expandedBounds.height\n\t\tconst handleSize = 8 / zoom\n\t\tconst isTinyX = width < handleSize * 2\n\t\tconst isTinyY = height < handleSize * 2\n\t\tconst isSmallX = width < handleSize * 4\n\t\tconst isSmallY = height < handleSize * 4\n\t\tconst isSmallCropX = width < handleSize * 5\n\t\tconst isSmallCropY = height < handleSize * 5\n\n\t\tconst mobileHandleMultiplier = isCoarsePointer ? 1.75 : 1\n\t\tconst hitTargetSize = (6 / zoom) * mobileHandleMultiplier\n\t\tconst hitTargetSizeX =\n\t\t\t(isSmallX ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)\n\t\tconst hitTargetSizeY =\n\t\t\t(isSmallY ? hitTargetSize / 2 : hitTargetSize) * (mobileHandleMultiplier * 0.75)\n\n\t\tconst expandOffsetX = expandedBounds.x - bounds.x\n\t\tconst expandOffsetY = expandedBounds.y - bounds.y\n\n\t\tconst shouldDisplayControls =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.idle',\n\t\t\t\t'select.pointing_selection',\n\t\t\t\t'select.pointing_shape',\n\t\t\t\t'select.pointing_resize_handle',\n\t\t\t\t'select.pointing_rotate_handle',\n\t\t\t\t'select.crop.idle'\n\t\t\t) &&\n\t\t\t!isChangingStyle &&\n\t\t\t!isReadonly\n\n\t\tconst showCropHandles =\n\t\t\teditor.isInAny(\n\t\t\t\t'select.crop.idle',\n\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t'select.crop.pointing_crop_handle'\n\t\t\t) && !isReadonly\n\n\t\tconst canOnlyShapeResize =\n\t\t\tonlyShape && onlyShapeUtil\n\t\t\t\t? onlyShapeUtil.canResize(onlyShape) && !onlyShapeUtil.hideResizeHandles(onlyShape)\n\t\t\t\t: true\n\t\tconst hideOnlyShapeRotateHandle =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideRotateHandle(onlyShape) : false\n\t\tconst hideOnlyShapeSelectionBounds =\n\t\t\tonlyShape && onlyShapeUtil ? onlyShapeUtil.hideSelectionBoundsFg(onlyShape) : false\n\n\t\tconst showResizeHandles =\n\t\t\tshouldDisplayControls && !isLockedShape && !showCropHandles && canOnlyShapeResize\n\n\t\tconst showCornerRotateHandles =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\t!isCoarsePointer &&\n\t\t\t!(isTinyX || isTinyY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst showMobileRotateHandle =\n\t\t\tshouldDisplayControls &&\n\t\t\t!isLockedShape &&\n\t\t\tisCoarsePointer &&\n\t\t\t(!isSmallX || !isSmallY) &&\n\t\t\t!hideOnlyShapeRotateHandle\n\n\t\tconst hideAlternateCornerHandles = isTinyX || isTinyY\n\t\tconst hideAlternateCropHandles = isSmallCropX || isSmallCropY\n\t\tconst showOnlyOneHandle = isTinyX && isTinyY\n\t\tconst showHandles = showResizeHandles || showCropHandles\n\n\t\tconst showSelectionBounds = !hideOnlyShapeSelectionBounds && !isChangingStyle\n\n\t\tconst shouldDisplayBox =\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isInAny(\n\t\t\t\t\t'select.idle',\n\t\t\t\t\t'select.brushing',\n\t\t\t\t\t'select.scribble_brushing',\n\t\t\t\t\t'select.pointing_canvas',\n\t\t\t\t\t'select.pointing_selection',\n\t\t\t\t\t'select.pointing_shape',\n\t\t\t\t\t'select.crop.idle',\n\t\t\t\t\t'select.crop.pointing_crop',\n\t\t\t\t\t'select.crop.pointing_crop_handle',\n\t\t\t\t\t'select.pointing_resize_handle',\n\t\t\t\t\t'select.pointing_rotate_handle'\n\t\t\t\t)) ||\n\t\t\t(showSelectionBounds &&\n\t\t\t\teditor.isIn('select.resizing') &&\n\t\t\t\t!!(onlyShape && editor.isShapeOfType(onlyShape, 'text')))\n\n\t\treturn {\n\t\t\tbounds,\n\t\t\tonlyShape,\n\t\t\tisCoarsePointer,\n\t\t\tzoom,\n\t\t\trotation,\n\t\t\twidth,\n\t\t\theight,\n\t\t\thandleSize,\n\t\t\thitTargetSize,\n\t\t\thitTargetSizeX,\n\t\t\thitTargetSizeY,\n\t\t\texpandOffsetX,\n\t\t\texpandOffsetY,\n\t\t\tisSmallX,\n\t\t\tshouldDisplayControls,\n\t\t\tshouldDisplayBox,\n\t\t\tshowCropHandles,\n\t\t\tshowResizeHandles,\n\t\t\tshowCornerRotateHandles,\n\t\t\tshowMobileRotateHandle,\n\t\t\tshowHandles,\n\t\t\thideAlternateCornerHandles,\n\t\t\thideAlternateCropHandles,\n\t\t\tshowOnlyOneHandle,\n\t\t}\n\t}\n\n\tprivate _getMobileRotateCenter(state: SelectionState): { cx: number; cy: number } {\n\t\tconst { width, height, hitTargetSize, isSmallX, onlyShape, rotation } = state\n\t\tconst editor = this.editor\n\t\tconst isMediaShape =\n\t\t\t!!onlyShape &&\n\t\t\t(editor.isShapeOfType(onlyShape, 'image') || editor.isShapeOfType(onlyShape, 'video'))\n\t\tconst isShapeTooCloseToContextualToolbar = rotation / HALF_PI > 1.6 && rotation / HALF_PI < 2.4\n\n\t\tconst cx = isSmallX ? -hitTargetSize * 1.5 : width / 2\n\t\tconst cy = isSmallX\n\t\t\t? height / 2\n\t\t\t: isMediaShape && !isShapeTooCloseToContextualToolbar\n\t\t\t\t? height + hitTargetSize * 1.5\n\t\t\t\t: -hitTargetSize * 1.5\n\t\treturn { cx, cy }\n\t}\n\n\tprivate _getThemeColors(): SelectionForegroundColors {\n\t\tconst editor = this.editor\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\treturn {\n\t\t\tstrokeColor: themeColors.selectionStroke,\n\t\t\tbgColor: themeColors.background,\n\t\t}\n\t}\n\n\tprivate _makeOverlay(\n\t\toverlayType: TLSelectionForegroundOverlay['props']['overlayType'],\n\t\thandle: TLSelectionHandle | RotateCorner\n\t): TLSelectionForegroundOverlay {\n\t\treturn {\n\t\t\tid: `selection_fg:${handle}`,\n\t\t\ttype: 'selection_foreground',\n\t\t\tprops: { overlayType, handle },\n\t\t}\n\t}\n\n\tprivate _getEdgeLocalRect(\n\t\tedge: SelectionEdge,\n\t\tstate: SelectionState\n\t): { x: number; y: number; w: number; h: number } {\n\t\tconst { width, height, hitTargetSizeX, hitTargetSizeY } = state\n\t\tswitch (edge) {\n\t\t\tcase 'top':\n\t\t\t\treturn { x: 0, y: -hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }\n\t\t\tcase 'right':\n\t\t\t\treturn { x: width - hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }\n\t\t\tcase 'bottom':\n\t\t\t\treturn { x: 0, y: height - hitTargetSizeY, w: width, h: hitTargetSizeY * 2 }\n\t\t\tcase 'left':\n\t\t\t\treturn { x: -hitTargetSizeX, y: 0, w: hitTargetSizeX * 2, h: height }\n\t\t}\n\t}\n\n\tprivate _getRotateHandleLocalCenter(\n\t\tcorner: RotateCorner,\n\t\twidth: number,\n\t\theight: number,\n\t\tcornerSize: number\n\t): Vec {\n\t\t// Centered on the outside corner of the resize handle square\n\t\t// (the corner furthest from the selection interior)\n\t\tswitch (corner) {\n\t\t\tcase 'top_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, -cornerSize)\n\t\t\tcase 'top_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, -cornerSize)\n\t\t\tcase 'bottom_left_rotate':\n\t\t\t\treturn new Vec(-cornerSize, height + cornerSize)\n\t\t\tcase 'bottom_right_rotate':\n\t\t\t\treturn new Vec(width + cornerSize, height + cornerSize)\n\t\t\tdefault:\n\t\t\t\treturn new Vec(0, 0)\n\t\t}\n\t}\n\n\tprivate _getCornerLocalPoint(corner: SelectionCorner, width: number, height: number): Vec {\n\t\tswitch (corner) {\n\t\t\tcase 'top_left':\n\t\t\t\treturn new Vec(0, 0)\n\t\t\tcase 'top_right':\n\t\t\t\treturn new Vec(width, 0)\n\t\t\tcase 'bottom_right':\n\t\t\t\treturn new Vec(width, height)\n\t\t\tcase 'bottom_left':\n\t\t\t\treturn new Vec(0, height)\n\t\t}\n\t}\n\n\tprivate _localRectToPoints(x: number, y: number, w: number, h: number): Vec[] {\n\t\treturn [new Vec(x, y), new Vec(x + w, y), new Vec(x + w, y + h), new Vec(x, y + h)]\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -32,7 +32,7 @@ class ShapeHandleOverlayUtil extends import_editor.OverlayUtil {
32
32
  if (!onlySelectedShape) return false;
33
33
  const handles = editor.getShapeHandles(onlySelectedShape);
34
34
  if (!handles) return false;
35
- if (editor.isInAny("select.idle", "select.pointing_handle", "select.pointing_shape")) {
35
+ if (editor.isInAny("select.idle", "select.pointing_handle")) {
36
36
  return true;
37
37
  }
38
38
  if (editor.isIn("select.editing_shape")) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/overlays/ShapeHandleOverlayUtil.ts"],
4
- "sourcesContent": ["import {\n\tCircle2d,\n\tGeometry2d,\n\tMat,\n\tOverlayUtil,\n\tSIDES,\n\tTLCursorType,\n\tTLHandle,\n\tTLOverlay,\n\tTLShapeId,\n\tVec,\n} from '@tldraw/editor'\n\n/** @public */\nexport interface TLShapeHandleOverlay extends TLOverlay {\n\tprops: {\n\t\tshapeId: TLShapeId\n\t\thandle: TLHandle\n\t}\n}\n\n/**\n * Overlay util for shape handles (arrow endpoints, line vertices, etc.).\n *\n * @public\n */\nexport class ShapeHandleOverlayUtil extends OverlayUtil<TLShapeHandleOverlay> {\n\tstatic override type = 'shape_handle'\n\toverride options = { zIndex: 200, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tconst editor = this.editor\n\t\tif (editor.getIsReadonly() || editor.getInstanceState().isChangingStyle) return false\n\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return false\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return false\n\n\t\tif (editor.isInAny('select.idle', 'select.pointing_handle', 'select.pointing_shape')) {\n\t\t\treturn true\n\t\t}\n\n\t\tif (editor.isIn('select.editing_shape')) {\n\t\t\treturn editor.isShapeOfType(onlySelectedShape, 'note')\n\t\t}\n\n\t\treturn false\n\t}\n\n\toverride getOverlays(): TLShapeHandleOverlay[] {\n\t\tconst editor = this.editor\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return []\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return []\n\n\t\tif (editor.isShapeHidden(onlySelectedShape)) return []\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst minDist =\n\t\t\t((isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom) * 2\n\n\t\tconst vertexHandles = handles.filter((handle) => handle.type === 'vertex')\n\t\tconst vertexHandlesForHitTest: TLHandle[] = []\n\t\tconst otherHandlesForHitTest: TLHandle[] = []\n\n\t\t// Vertex handles come first so they win hit-testing against overlapping\n\t\t// virtual/create handles (e.g., a line's midpoint create handle that\n\t\t// coincides with its endpoint vertices when a segment is very short).\n\t\t// `render` iterates this array in reverse so the painted order puts\n\t\t// vertex handles on top visually, matching the main branch's paint\n\t\t// order where vertex handles were sorted last.\n\t\tfor (const handle of handles) {\n\t\t\tif (\n\t\t\t\thandle.type === 'virtual' &&\n\t\t\t\tvertexHandles.some((vertexHandle) => Vec.Dist(handle, vertexHandle) < minDist)\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (handle.type === 'vertex') {\n\t\t\t\tvertexHandlesForHitTest.push(handle)\n\t\t\t} else {\n\t\t\t\totherHandlesForHitTest.push(handle)\n\t\t\t}\n\t\t}\n\n\t\treturn vertexHandlesForHitTest.concat(otherHandlesForHitTest).map((handle) => ({\n\t\t\tid: `handle:${onlySelectedShape.id}:${handle.id}`,\n\t\t\ttype: 'shape_handle',\n\t\t\tprops: {\n\t\t\t\tshapeId: onlySelectedShape.id,\n\t\t\t\thandle,\n\t\t\t},\n\t\t}))\n\t}\n\n\toverride getGeometry(overlay: TLShapeHandleOverlay): Geometry2d | null {\n\t\tconst editor = this.editor\n\t\tconst { shapeId, handle } = overlay.props\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return null\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst radius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\t// Transform handle position to page space\n\t\tconst pagePoint = Mat.applyToPoint(transform, { x: handle.x, y: handle.y })\n\n\t\treturn new Circle2d({\n\t\t\tx: pagePoint.x - radius,\n\t\t\ty: pagePoint.y - radius,\n\t\t\tradius,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getCursor(_overlay: TLShapeHandleOverlay): TLCursorType | undefined {\n\t\treturn 'grab' as TLCursorType\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, overlays: TLShapeHandleOverlay[]): void {\n\t\tif (overlays.length === 0) return\n\n\t\tconst editor = this.editor\n\t\tconst shapeId = overlays[0].props.shapeId\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\tconst fgColor = themeColors.selectedContrast\n\t\tconst strokeColor = themeColors.selectionStroke\n\t\tconst bgFill = themeColors.selectionFill\n\t\tconst hoveredOverlayId = editor.overlays.getHoveredOverlayId()\n\t\tconst bgRadius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\tctx.save()\n\t\tctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f)\n\n\t\tctx.strokeStyle = strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\t// Iterate in reverse: vertex handles come first in the array (for hit-\n\t\t// test priority) but should paint last so they visually sit on top of\n\t\t// overlapping virtual/create handles.\n\t\tfor (let i = overlays.length - 1; i >= 0; i--) {\n\t\t\tconst overlay = overlays[i]\n\t\t\tconst { handle } = overlay.props\n\t\t\tconst isHovered = overlay.id === hoveredOverlayId\n\n\t\t\t// 'create' handles are invisible on fine pointers and revealed on\n\t\t\t// hover (matches the old .tl-handle__create opacity rules).\n\t\t\tif (handle.type === 'create' && !isCoarse && !isHovered) continue\n\n\t\t\t// Hover halo \u2014 matches the old .tl-handle__bg:hover fill rule.\n\t\t\tif (isHovered) {\n\t\t\t\tctx.fillStyle = bgFill\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.arc(handle.x, handle.y, bgRadius, 0, Math.PI * 2)\n\t\t\t\tctx.fill()\n\t\t\t}\n\n\t\t\tif (handle.type === 'clone') {\n\t\t\t\t// Note clone handles render as a side-facing half circle.\n\t\t\t\tconst fr = 3 / zoom\n\t\t\t\tconst sideIndex = SIDES.indexOf(handle.id as (typeof SIDES)[number])\n\t\t\t\tconst rotation = (-Math.PI / 2) * (1 - sideIndex)\n\n\t\t\t\tctx.save()\n\t\t\t\tctx.translate(handle.x, handle.y)\n\t\t\t\tctx.rotate(rotation)\n\t\t\t\tctx.fillStyle = strokeColor\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.moveTo(0, -fr)\n\t\t\t\tctx.arc(0, 0, fr, -Math.PI / 2, Math.PI / 2)\n\t\t\t\tctx.closePath()\n\t\t\t\tctx.fill()\n\t\t\t\tctx.restore()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Match the old DefaultHandle sizing: create handles on coarse\n\t\t\t// pointers are slightly smaller (3px) since they're always visible;\n\t\t\t// on fine pointers they render at 4px when revealed by hover so\n\t\t\t// they match the vertex handles. Clamp the zoom divisor at 0.25 so\n\t\t\t// the visible circle stops growing past 25% zoom and visually\n\t\t\t// shrinks as the user zooms further out \u2014 the hit-area halo above\n\t\t\t// still tracks the full zoom so handles remain grabbable.\n\t\t\tconst fr = (handle.type === 'create' && isCoarse ? 3 : 4) / Math.max(zoom, 0.25)\n\n\t\t\tctx.fillStyle = fgColor\n\t\t\tctx.beginPath()\n\t\t\tctx.arc(handle.x, handle.y, fr, 0, Math.PI * 2)\n\t\t\tctx.fill()\n\t\t\tctx.stroke()\n\t\t}\n\n\t\tctx.restore()\n\t}\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import {\n\tCircle2d,\n\tGeometry2d,\n\tMat,\n\tOverlayUtil,\n\tSIDES,\n\tTLCursorType,\n\tTLHandle,\n\tTLOverlay,\n\tTLShapeId,\n\tVec,\n} from '@tldraw/editor'\n\n/** @public */\nexport interface TLShapeHandleOverlay extends TLOverlay {\n\tprops: {\n\t\tshapeId: TLShapeId\n\t\thandle: TLHandle\n\t}\n}\n\n/**\n * Overlay util for shape handles (arrow endpoints, line vertices, etc.).\n *\n * @public\n */\nexport class ShapeHandleOverlayUtil extends OverlayUtil<TLShapeHandleOverlay> {\n\tstatic override type = 'shape_handle'\n\toverride options = { zIndex: 200, lineWidth: 1.5 }\n\n\toverride isActive(): boolean {\n\t\tconst editor = this.editor\n\t\tif (editor.getIsReadonly() || editor.getInstanceState().isChangingStyle) return false\n\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return false\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return false\n\n\t\t// Not shown in select.pointing_shape: hiding handles on pointer down\n\t\t// matches the arrow binding hint, which also waits for pointer up.\n\t\tif (editor.isInAny('select.idle', 'select.pointing_handle')) {\n\t\t\treturn true\n\t\t}\n\n\t\tif (editor.isIn('select.editing_shape')) {\n\t\t\treturn editor.isShapeOfType(onlySelectedShape, 'note')\n\t\t}\n\n\t\treturn false\n\t}\n\n\toverride getOverlays(): TLShapeHandleOverlay[] {\n\t\tconst editor = this.editor\n\t\tconst onlySelectedShape = editor.getOnlySelectedShape()\n\t\tif (!onlySelectedShape) return []\n\n\t\tconst handles = editor.getShapeHandles(onlySelectedShape)\n\t\tif (!handles) return []\n\n\t\tif (editor.isShapeHidden(onlySelectedShape)) return []\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst minDist =\n\t\t\t((isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom) * 2\n\n\t\tconst vertexHandles = handles.filter((handle) => handle.type === 'vertex')\n\t\tconst vertexHandlesForHitTest: TLHandle[] = []\n\t\tconst otherHandlesForHitTest: TLHandle[] = []\n\n\t\t// Vertex handles come first so they win hit-testing against overlapping\n\t\t// virtual/create handles (e.g., a line's midpoint create handle that\n\t\t// coincides with its endpoint vertices when a segment is very short).\n\t\t// `render` iterates this array in reverse so the painted order puts\n\t\t// vertex handles on top visually, matching the main branch's paint\n\t\t// order where vertex handles were sorted last.\n\t\tfor (const handle of handles) {\n\t\t\tif (\n\t\t\t\thandle.type === 'virtual' &&\n\t\t\t\tvertexHandles.some((vertexHandle) => Vec.Dist(handle, vertexHandle) < minDist)\n\t\t\t) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif (handle.type === 'vertex') {\n\t\t\t\tvertexHandlesForHitTest.push(handle)\n\t\t\t} else {\n\t\t\t\totherHandlesForHitTest.push(handle)\n\t\t\t}\n\t\t}\n\n\t\treturn vertexHandlesForHitTest.concat(otherHandlesForHitTest).map((handle) => ({\n\t\t\tid: `handle:${onlySelectedShape.id}:${handle.id}`,\n\t\t\ttype: 'shape_handle',\n\t\t\tprops: {\n\t\t\t\tshapeId: onlySelectedShape.id,\n\t\t\t\thandle,\n\t\t\t},\n\t\t}))\n\t}\n\n\toverride getGeometry(overlay: TLShapeHandleOverlay): Geometry2d | null {\n\t\tconst editor = this.editor\n\t\tconst { shapeId, handle } = overlay.props\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return null\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst radius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\t// Transform handle position to page space\n\t\tconst pagePoint = Mat.applyToPoint(transform, { x: handle.x, y: handle.y })\n\n\t\treturn new Circle2d({\n\t\t\tx: pagePoint.x - radius,\n\t\t\ty: pagePoint.y - radius,\n\t\t\tradius,\n\t\t\tisFilled: true,\n\t\t})\n\t}\n\n\toverride getCursor(_overlay: TLShapeHandleOverlay): TLCursorType | undefined {\n\t\treturn 'grab' as TLCursorType\n\t}\n\n\toverride render(ctx: CanvasRenderingContext2D, overlays: TLShapeHandleOverlay[]): void {\n\t\tif (overlays.length === 0) return\n\n\t\tconst editor = this.editor\n\t\tconst shapeId = overlays[0].props.shapeId\n\t\tconst transform = editor.getShapePageTransform(shapeId)\n\t\tif (!transform) return\n\n\t\tconst zoom = editor.getZoomLevel()\n\t\tconst isCoarse = editor.getInstanceState().isCoarsePointer\n\t\tconst themeColors = editor.getCurrentTheme().colors[editor.getColorMode()]\n\t\tconst fgColor = themeColors.selectedContrast\n\t\tconst strokeColor = themeColors.selectionStroke\n\t\tconst bgFill = themeColors.selectionFill\n\t\tconst hoveredOverlayId = editor.overlays.getHoveredOverlayId()\n\t\tconst bgRadius =\n\t\t\t(isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom\n\n\t\tctx.save()\n\t\tctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f)\n\n\t\tctx.strokeStyle = strokeColor\n\t\tctx.lineWidth = this.options.lineWidth / zoom\n\n\t\t// Iterate in reverse: vertex handles come first in the array (for hit-\n\t\t// test priority) but should paint last so they visually sit on top of\n\t\t// overlapping virtual/create handles.\n\t\tfor (let i = overlays.length - 1; i >= 0; i--) {\n\t\t\tconst overlay = overlays[i]\n\t\t\tconst { handle } = overlay.props\n\t\t\tconst isHovered = overlay.id === hoveredOverlayId\n\n\t\t\t// 'create' handles are invisible on fine pointers and revealed on\n\t\t\t// hover (matches the old .tl-handle__create opacity rules).\n\t\t\tif (handle.type === 'create' && !isCoarse && !isHovered) continue\n\n\t\t\t// Hover halo \u2014 matches the old .tl-handle__bg:hover fill rule.\n\t\t\tif (isHovered) {\n\t\t\t\tctx.fillStyle = bgFill\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.arc(handle.x, handle.y, bgRadius, 0, Math.PI * 2)\n\t\t\t\tctx.fill()\n\t\t\t}\n\n\t\t\tif (handle.type === 'clone') {\n\t\t\t\t// Note clone handles render as a side-facing half circle.\n\t\t\t\tconst fr = 3 / zoom\n\t\t\t\tconst sideIndex = SIDES.indexOf(handle.id as (typeof SIDES)[number])\n\t\t\t\tconst rotation = (-Math.PI / 2) * (1 - sideIndex)\n\n\t\t\t\tctx.save()\n\t\t\t\tctx.translate(handle.x, handle.y)\n\t\t\t\tctx.rotate(rotation)\n\t\t\t\tctx.fillStyle = strokeColor\n\t\t\t\tctx.beginPath()\n\t\t\t\tctx.moveTo(0, -fr)\n\t\t\t\tctx.arc(0, 0, fr, -Math.PI / 2, Math.PI / 2)\n\t\t\t\tctx.closePath()\n\t\t\t\tctx.fill()\n\t\t\t\tctx.restore()\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Match the old DefaultHandle sizing: create handles on coarse\n\t\t\t// pointers are slightly smaller (3px) since they're always visible;\n\t\t\t// on fine pointers they render at 4px when revealed by hover so\n\t\t\t// they match the vertex handles. Clamp the zoom divisor at 0.25 so\n\t\t\t// the visible circle stops growing past 25% zoom and visually\n\t\t\t// shrinks as the user zooms further out \u2014 the hit-area halo above\n\t\t\t// still tracks the full zoom so handles remain grabbable.\n\t\t\tconst fr = (handle.type === 'create' && isCoarse ? 3 : 4) / Math.max(zoom, 0.25)\n\n\t\t\tctx.fillStyle = fgColor\n\t\t\tctx.beginPath()\n\t\t\tctx.arc(handle.x, handle.y, fr, 0, Math.PI * 2)\n\t\t\tctx.fill()\n\t\t\tctx.stroke()\n\t\t}\n\n\t\tctx.restore()\n\t}\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["fr"]
7
7
  }