js-draw 1.20.3 → 1.21.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. package/LICENSE +1 -1
  2. package/dist/Editor.css +134 -26
  3. package/dist/bundle.js +2 -2
  4. package/dist/bundledStyles.js +1 -1
  5. package/dist/cjs/Editor.d.ts +27 -6
  6. package/dist/cjs/Editor.js +30 -8
  7. package/dist/cjs/SVGLoader/SVGLoader.js +2 -2
  8. package/dist/cjs/Viewport.d.ts +2 -2
  9. package/dist/cjs/commands/Command.d.ts +5 -0
  10. package/dist/cjs/commands/Command.js +5 -0
  11. package/dist/cjs/commands/SerializableCommand.d.ts +7 -0
  12. package/dist/cjs/commands/SerializableCommand.js +9 -0
  13. package/dist/cjs/dialogs/makeAboutDialog.d.ts +1 -1
  14. package/dist/cjs/dialogs/makeAboutDialog.js +10 -25
  15. package/dist/cjs/dialogs/makeMessageDialog.d.ts +11 -0
  16. package/dist/cjs/dialogs/makeMessageDialog.js +56 -0
  17. package/dist/cjs/image/EditorImage.d.ts +15 -1
  18. package/dist/cjs/image/EditorImage.js +15 -5
  19. package/dist/cjs/inputEvents.d.ts +10 -2
  20. package/dist/cjs/inputEvents.js +1 -0
  21. package/dist/cjs/localizations/es.js +3 -0
  22. package/dist/cjs/rendering/Display.d.ts +1 -0
  23. package/dist/cjs/rendering/Display.js +1 -0
  24. package/dist/cjs/rendering/TextRenderingStyle.d.ts +7 -6
  25. package/dist/cjs/rendering/TextRenderingStyle.js +1 -0
  26. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  27. package/dist/cjs/rendering/renderers/CanvasRenderer.js +15 -2
  28. package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  29. package/dist/cjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  30. package/dist/cjs/testing/firstElementAncestorOfNode.js +1 -1
  31. package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
  32. package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
  33. package/dist/cjs/toolbar/AbstractToolbar.d.ts +6 -1
  34. package/dist/cjs/toolbar/AbstractToolbar.js +6 -1
  35. package/dist/cjs/toolbar/IconProvider.d.ts +1 -1
  36. package/dist/cjs/toolbar/IconProvider.js +6 -1
  37. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  38. package/dist/cjs/toolbar/widgets/BaseWidget.js +8 -0
  39. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  40. package/dist/cjs/toolbar/widgets/HandToolWidget.js +1 -0
  41. package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  42. package/dist/cjs/toolbar/widgets/PenToolWidget.js +5 -0
  43. package/dist/cjs/types.d.ts +5 -0
  44. package/dist/cjs/types.js +1 -0
  45. package/dist/cjs/util/ClipboardHandler.d.ts +9 -1
  46. package/dist/cjs/util/ClipboardHandler.js +82 -24
  47. package/dist/cjs/version.js +1 -1
  48. package/dist/mjs/Editor.d.ts +27 -6
  49. package/dist/mjs/Editor.mjs +31 -9
  50. package/dist/mjs/SVGLoader/SVGLoader.mjs +2 -2
  51. package/dist/mjs/Viewport.d.ts +2 -2
  52. package/dist/mjs/commands/Command.d.ts +5 -0
  53. package/dist/mjs/commands/Command.mjs +5 -0
  54. package/dist/mjs/commands/SerializableCommand.d.ts +7 -0
  55. package/dist/mjs/commands/SerializableCommand.mjs +9 -0
  56. package/dist/mjs/dialogs/makeAboutDialog.d.ts +1 -1
  57. package/dist/mjs/dialogs/makeAboutDialog.mjs +7 -25
  58. package/dist/mjs/dialogs/makeMessageDialog.d.ts +11 -0
  59. package/dist/mjs/dialogs/makeMessageDialog.mjs +51 -0
  60. package/dist/mjs/image/EditorImage.d.ts +15 -1
  61. package/dist/mjs/image/EditorImage.mjs +15 -5
  62. package/dist/mjs/inputEvents.d.ts +10 -2
  63. package/dist/mjs/inputEvents.mjs +1 -0
  64. package/dist/mjs/localizations/es.mjs +3 -0
  65. package/dist/mjs/rendering/Display.d.ts +1 -0
  66. package/dist/mjs/rendering/Display.mjs +1 -0
  67. package/dist/mjs/rendering/TextRenderingStyle.d.ts +7 -6
  68. package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -0
  69. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  70. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +15 -2
  71. package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  72. package/dist/mjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  73. package/dist/mjs/testing/firstElementAncestorOfNode.mjs +1 -1
  74. package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
  75. package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
  76. package/dist/mjs/toolbar/AbstractToolbar.d.ts +6 -1
  77. package/dist/mjs/toolbar/AbstractToolbar.mjs +6 -1
  78. package/dist/mjs/toolbar/IconProvider.d.ts +1 -1
  79. package/dist/mjs/toolbar/IconProvider.mjs +6 -1
  80. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  81. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +8 -0
  82. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  83. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +1 -0
  84. package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  85. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +5 -0
  86. package/dist/mjs/types.d.ts +5 -0
  87. package/dist/mjs/types.mjs +1 -0
  88. package/dist/mjs/util/ClipboardHandler.d.ts +9 -1
  89. package/dist/mjs/util/ClipboardHandler.mjs +82 -24
  90. package/dist/mjs/version.mjs +1 -1
  91. package/package.json +8 -9
  92. package/src/dialogs/dialogs.scss +9 -21
  93. package/src/dialogs/makeAboutDialog.scss +13 -33
  94. package/src/dialogs/makeMessageDialog.scss +46 -0
  95. package/dist/cjs/tools/BaseTool.d.ts +0 -60
  96. package/dist/cjs/tools/BaseTool.js +0 -174
  97. package/dist/cjs/tools/Eraser.d.ts +0 -56
  98. package/dist/cjs/tools/Eraser.js +0 -295
  99. package/dist/cjs/tools/Eraser.test.d.ts +0 -1
  100. package/dist/cjs/tools/FindTool.d.ts +0 -21
  101. package/dist/cjs/tools/FindTool.js +0 -137
  102. package/dist/cjs/tools/FindTool.test.d.ts +0 -1
  103. package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  104. package/dist/cjs/tools/InputFilter/FunctionMapper.js +0 -21
  105. package/dist/cjs/tools/InputFilter/InputMapper.d.ts +0 -23
  106. package/dist/cjs/tools/InputFilter/InputMapper.js +0 -38
  107. package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  108. package/dist/cjs/tools/InputFilter/InputPipeline.js +0 -54
  109. package/dist/cjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  110. package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  111. package/dist/cjs/tools/InputFilter/InputStabilizer.js +0 -181
  112. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  113. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +0 -84
  114. package/dist/cjs/tools/PanZoom.d.ts +0 -119
  115. package/dist/cjs/tools/PanZoom.js +0 -508
  116. package/dist/cjs/tools/PanZoom.test.d.ts +0 -1
  117. package/dist/cjs/tools/PasteHandler.d.ts +0 -23
  118. package/dist/cjs/tools/PasteHandler.js +0 -109
  119. package/dist/cjs/tools/Pen.d.ts +0 -53
  120. package/dist/cjs/tools/Pen.js +0 -318
  121. package/dist/cjs/tools/Pen.test.d.ts +0 -1
  122. package/dist/cjs/tools/PipetteTool.d.ts +0 -28
  123. package/dist/cjs/tools/PipetteTool.js +0 -69
  124. package/dist/cjs/tools/ScrollbarTool.d.ts +0 -18
  125. package/dist/cjs/tools/ScrollbarTool.js +0 -85
  126. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  127. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +0 -32
  128. package/dist/cjs/tools/SelectionTool/Selection.d.ts +0 -71
  129. package/dist/cjs/tools/SelectionTool/Selection.js +0 -620
  130. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  131. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +0 -141
  132. package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  133. package/dist/cjs/tools/SelectionTool/SelectionTool.js +0 -494
  134. package/dist/cjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  135. package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  136. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  137. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +0 -83
  138. package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  139. package/dist/cjs/tools/SelectionTool/TransformMode.js +0 -155
  140. package/dist/cjs/tools/SelectionTool/types.d.ts +0 -28
  141. package/dist/cjs/tools/SelectionTool/types.js +0 -14
  142. package/dist/cjs/tools/SoundUITool.d.ts +0 -26
  143. package/dist/cjs/tools/SoundUITool.js +0 -171
  144. package/dist/cjs/tools/TextTool.d.ts +0 -36
  145. package/dist/cjs/tools/TextTool.js +0 -285
  146. package/dist/cjs/tools/TextTool.test.d.ts +0 -1
  147. package/dist/cjs/tools/ToolController.d.ts +0 -73
  148. package/dist/cjs/tools/ToolController.js +0 -304
  149. package/dist/cjs/tools/ToolController.test.d.ts +0 -1
  150. package/dist/cjs/tools/ToolEnabledGroup.d.ts +0 -6
  151. package/dist/cjs/tools/ToolEnabledGroup.js +0 -13
  152. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  153. package/dist/cjs/tools/ToolSwitcherShortcut.js +0 -40
  154. package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  155. package/dist/cjs/tools/ToolbarShortcutHandler.js +0 -34
  156. package/dist/cjs/tools/UndoRedoShortcut.d.ts +0 -8
  157. package/dist/cjs/tools/UndoRedoShortcut.js +0 -27
  158. package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  159. package/dist/cjs/tools/keybindings.d.ts +0 -18
  160. package/dist/cjs/tools/keybindings.js +0 -49
  161. package/dist/cjs/tools/lib.d.ts +0 -14
  162. package/dist/cjs/tools/lib.js +0 -36
  163. package/dist/cjs/tools/localization.d.ts +0 -34
  164. package/dist/cjs/tools/localization.js +0 -36
  165. package/dist/cjs/tools/util/StationaryPenDetector.d.ts +0 -22
  166. package/dist/cjs/tools/util/StationaryPenDetector.js +0 -95
  167. package/dist/mjs/tools/BaseTool.d.ts +0 -60
  168. package/dist/mjs/tools/BaseTool.mjs +0 -172
  169. package/dist/mjs/tools/Eraser.d.ts +0 -56
  170. package/dist/mjs/tools/Eraser.mjs +0 -288
  171. package/dist/mjs/tools/Eraser.test.d.ts +0 -1
  172. package/dist/mjs/tools/FindTool.d.ts +0 -21
  173. package/dist/mjs/tools/FindTool.mjs +0 -131
  174. package/dist/mjs/tools/FindTool.test.d.ts +0 -1
  175. package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  176. package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +0 -15
  177. package/dist/mjs/tools/InputFilter/InputMapper.d.ts +0 -23
  178. package/dist/mjs/tools/InputFilter/InputMapper.mjs +0 -36
  179. package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  180. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +0 -49
  181. package/dist/mjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  182. package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  183. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +0 -175
  184. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  185. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +0 -78
  186. package/dist/mjs/tools/PanZoom.d.ts +0 -119
  187. package/dist/mjs/tools/PanZoom.mjs +0 -501
  188. package/dist/mjs/tools/PanZoom.test.d.ts +0 -1
  189. package/dist/mjs/tools/PasteHandler.d.ts +0 -23
  190. package/dist/mjs/tools/PasteHandler.mjs +0 -103
  191. package/dist/mjs/tools/Pen.d.ts +0 -53
  192. package/dist/mjs/tools/Pen.mjs +0 -312
  193. package/dist/mjs/tools/Pen.test.d.ts +0 -1
  194. package/dist/mjs/tools/PipetteTool.d.ts +0 -28
  195. package/dist/mjs/tools/PipetteTool.mjs +0 -63
  196. package/dist/mjs/tools/ScrollbarTool.d.ts +0 -18
  197. package/dist/mjs/tools/ScrollbarTool.mjs +0 -79
  198. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  199. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +0 -26
  200. package/dist/mjs/tools/SelectionTool/Selection.d.ts +0 -71
  201. package/dist/mjs/tools/SelectionTool/Selection.mjs +0 -592
  202. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  203. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +0 -137
  204. package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  205. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +0 -488
  206. package/dist/mjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  207. package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  208. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  209. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +0 -77
  210. package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  211. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +0 -146
  212. package/dist/mjs/tools/SelectionTool/types.d.ts +0 -28
  213. package/dist/mjs/tools/SelectionTool/types.mjs +0 -11
  214. package/dist/mjs/tools/SoundUITool.d.ts +0 -26
  215. package/dist/mjs/tools/SoundUITool.mjs +0 -165
  216. package/dist/mjs/tools/TextTool.d.ts +0 -36
  217. package/dist/mjs/tools/TextTool.mjs +0 -279
  218. package/dist/mjs/tools/TextTool.test.d.ts +0 -1
  219. package/dist/mjs/tools/ToolController.d.ts +0 -73
  220. package/dist/mjs/tools/ToolController.mjs +0 -275
  221. package/dist/mjs/tools/ToolController.test.d.ts +0 -1
  222. package/dist/mjs/tools/ToolEnabledGroup.d.ts +0 -6
  223. package/dist/mjs/tools/ToolEnabledGroup.mjs +0 -10
  224. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  225. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +0 -34
  226. package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  227. package/dist/mjs/tools/ToolbarShortcutHandler.mjs +0 -28
  228. package/dist/mjs/tools/UndoRedoShortcut.d.ts +0 -8
  229. package/dist/mjs/tools/UndoRedoShortcut.mjs +0 -21
  230. package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  231. package/dist/mjs/tools/keybindings.d.ts +0 -18
  232. package/dist/mjs/tools/keybindings.mjs +0 -43
  233. package/dist/mjs/tools/lib.d.ts +0 -14
  234. package/dist/mjs/tools/lib.mjs +0 -14
  235. package/dist/mjs/tools/localization.d.ts +0 -34
  236. package/dist/mjs/tools/localization.mjs +0 -33
  237. package/dist/mjs/tools/util/StationaryPenDetector.d.ts +0 -22
  238. package/dist/mjs/tools/util/StationaryPenDetector.mjs +0 -92
  239. package/src/tools/FindTool.css +0 -7
  240. package/src/tools/ScrollbarTool.scss +0 -57
  241. package/src/tools/SelectionTool/SelectionTool.scss +0 -137
  242. package/src/tools/SoundUITool.scss +0 -22
  243. package/src/tools/tools.scss +0 -5
@@ -1,494 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.cssPrefix = void 0;
7
- const math_1 = require("@js-draw/math");
8
- const types_1 = require("../../types");
9
- const Viewport_1 = __importDefault(require("../../Viewport"));
10
- const BaseTool_1 = __importDefault(require("../BaseTool"));
11
- const CanvasRenderer_1 = __importDefault(require("../../rendering/renderers/CanvasRenderer"));
12
- const SVGRenderer_1 = __importDefault(require("../../rendering/renderers/SVGRenderer"));
13
- const Selection_1 = __importDefault(require("./Selection"));
14
- const TextComponent_1 = __importDefault(require("../../components/TextComponent"));
15
- const keybindings_1 = require("../keybindings");
16
- const ToPointerAutoscroller_1 = __importDefault(require("./ToPointerAutoscroller"));
17
- exports.cssPrefix = 'selection-tool-';
18
- // Allows users to select/transform portions of the `EditorImage`.
19
- // With respect to `extend`ing, `SelectionTool` is not stable.
20
- class SelectionTool extends BaseTool_1.default {
21
- constructor(editor, description) {
22
- super(editor.notifier, description);
23
- this.editor = editor;
24
- this.startPoint = null; // canvas position
25
- this.expandingSelectionBox = false;
26
- this.shiftKeyPressed = false;
27
- this.snapToGrid = false;
28
- this.lastPointer = null;
29
- this.selectionBoxHandlingEvt = false;
30
- this.lastSelectedObjects = [];
31
- // Whether the last keypress corresponded to an action that didn't transform the
32
- // selection (and thus does not need to be finalized on onKeyUp).
33
- this.hasUnfinalizedTransformFromKeyPress = false;
34
- this.autoscroller = new ToPointerAutoscroller_1.default(editor.viewport, (scrollBy) => {
35
- editor.dispatch(Viewport_1.default.transformBy(math_1.Mat33.translation(scrollBy)), false);
36
- // Update the selection box/content to match the new viewport.
37
- if (this.lastPointer) {
38
- // The viewport has changed -- ensure that the screen and canvas positions
39
- // of the pointer are both correct
40
- const updatedPointer = this.lastPointer.withScreenPosition(this.lastPointer.screenPos, editor.viewport);
41
- this.onMainPointerUpdated(updatedPointer);
42
- }
43
- });
44
- this.handleOverlay = document.createElement('div');
45
- editor.createHTMLOverlay(this.handleOverlay);
46
- this.handleOverlay.style.display = 'none';
47
- this.handleOverlay.classList.add('handleOverlay');
48
- editor.notifier.on(types_1.EditorEventType.ViewportChanged, _data => {
49
- // The selection box could be using the wet ink display if its transformation
50
- // hasn't been finalized yet. Clear before updating the UI.
51
- this.editor.clearWetInk();
52
- // If not currently selecting, ensure that the selection box
53
- // is large enough.
54
- if (!this.expandingSelectionBox) {
55
- this.selectionBox?.padRegion();
56
- }
57
- this.selectionBox?.updateUI();
58
- });
59
- this.editor.handleKeyEventsFrom(this.handleOverlay);
60
- this.editor.handlePointerEventsFrom(this.handleOverlay);
61
- }
62
- makeSelectionBox(selectionStartPos) {
63
- this.prevSelectionBox = this.selectionBox;
64
- this.selectionBox = new Selection_1.default(selectionStartPos, this.editor);
65
- if (!this.expandingSelectionBox) {
66
- // Remove any previous selection rects
67
- this.prevSelectionBox?.cancelSelection();
68
- }
69
- this.selectionBox.addTo(this.handleOverlay);
70
- }
71
- snapSelectionToGrid() {
72
- if (!this.selectionBox)
73
- throw new Error('No selection to snap!');
74
- // Snap the top left corner of what we have selected.
75
- const topLeftOfBBox = this.selectionBox.computeTightBoundingBox().topLeft;
76
- const snappedTopLeft = this.editor.viewport.snapToGrid(topLeftOfBBox);
77
- const snapDelta = snappedTopLeft.minus(topLeftOfBBox);
78
- const oldTransform = this.selectionBox.getTransform();
79
- this.selectionBox.setTransform(oldTransform.rightMul(math_1.Mat33.translation(snapDelta)));
80
- this.selectionBox.finalizeTransform();
81
- }
82
- onPointerDown({ allPointers, current }) {
83
- const snapToGrid = this.snapToGrid;
84
- if (snapToGrid) {
85
- current = current.snappedToGrid(this.editor.viewport);
86
- }
87
- if (allPointers.length === 1 && current.isPrimary) {
88
- this.startPoint = current.canvasPos;
89
- let transforming = false;
90
- if (this.selectionBox) {
91
- if (snapToGrid) {
92
- this.snapSelectionToGrid();
93
- }
94
- const dragStartResult = this.selectionBox.onDragStart(current);
95
- if (dragStartResult) {
96
- transforming = true;
97
- this.selectionBoxHandlingEvt = true;
98
- this.expandingSelectionBox = false;
99
- }
100
- }
101
- if (!transforming) {
102
- // Shift key: Combine the new and old selection boxes at the end of the gesture.
103
- this.expandingSelectionBox = this.shiftKeyPressed;
104
- this.makeSelectionBox(current.canvasPos);
105
- }
106
- else {
107
- // Only autoscroll if we're transforming an existing selection
108
- this.autoscroller.start();
109
- }
110
- return true;
111
- }
112
- return false;
113
- }
114
- onPointerMove(event) {
115
- this.onMainPointerUpdated(event.current);
116
- }
117
- onMainPointerUpdated(currentPointer) {
118
- this.lastPointer = currentPointer;
119
- if (!this.selectionBox)
120
- return;
121
- this.autoscroller.onPointerMove(currentPointer.screenPos);
122
- if (!this.expandingSelectionBox && this.shiftKeyPressed && this.startPoint) {
123
- const screenPos = this.editor.viewport.canvasToScreen(this.startPoint);
124
- currentPointer = currentPointer.lockedToXYAxesScreen(screenPos, this.editor.viewport);
125
- }
126
- if (this.snapToGrid) {
127
- currentPointer = currentPointer.snappedToGrid(this.editor.viewport);
128
- }
129
- if (this.selectionBoxHandlingEvt) {
130
- this.selectionBox.onDragUpdate(currentPointer);
131
- }
132
- else {
133
- this.selectionBox.setToPoint(currentPointer.canvasPos);
134
- }
135
- }
136
- onPointerUp(event) {
137
- this.autoscroller.stop();
138
- if (!this.selectionBox)
139
- return;
140
- let currentPointer = event.current;
141
- if (this.snapToGrid) {
142
- currentPointer = currentPointer.snappedToGrid(this.editor.viewport);
143
- }
144
- this.selectionBox.setToPoint(currentPointer.canvasPos);
145
- // Were we expanding the previous selection?
146
- if (this.expandingSelectionBox && this.prevSelectionBox) {
147
- // If so, finish expanding.
148
- this.expandingSelectionBox = false;
149
- this.selectionBox.resolveToObjects();
150
- this.setSelection([
151
- ...this.selectionBox.getSelectedObjects(),
152
- ...this.prevSelectionBox.getSelectedObjects(),
153
- ]);
154
- }
155
- else {
156
- if (!this.selectionBoxHandlingEvt) {
157
- // Expand/shrink the selection rectangle, if applicable
158
- this.selectionBox.resolveToObjects();
159
- this.onSelectionUpdated();
160
- }
161
- else {
162
- this.selectionBox.onDragEnd();
163
- }
164
- this.selectionBoxHandlingEvt = false;
165
- this.lastPointer = null;
166
- }
167
- }
168
- onGestureCancel() {
169
- this.autoscroller.stop();
170
- if (this.selectionBoxHandlingEvt) {
171
- this.selectionBox?.onDragCancel();
172
- }
173
- else {
174
- // Revert to the previous selection, if any.
175
- this.selectionBox?.cancelSelection();
176
- this.selectionBox = this.prevSelectionBox;
177
- this.selectionBox?.addTo(this.handleOverlay);
178
- this.selectionBox?.recomputeRegion();
179
- this.prevSelectionBox = null;
180
- }
181
- this.expandingSelectionBox = false;
182
- this.lastPointer = null;
183
- this.selectionBoxHandlingEvt = false;
184
- }
185
- onSelectionUpdated() {
186
- const selectedItemCount = this.selectionBox?.getSelectedItemCount() ?? 0;
187
- const selectedObjects = this.selectionBox?.getSelectedObjects() ?? [];
188
- const hasDifferentSelection = this.lastSelectedObjects.length !== selectedItemCount
189
- || selectedObjects.some((obj, i) => this.lastSelectedObjects[i] !== obj);
190
- if (hasDifferentSelection) {
191
- this.lastSelectedObjects = selectedObjects;
192
- // Note that the selection has changed
193
- this.editor.notifier.dispatch(types_1.EditorEventType.ToolUpdated, {
194
- kind: types_1.EditorEventType.ToolUpdated,
195
- tool: this,
196
- });
197
- // Only fire the SelectionUpdated event if the selection really updated.
198
- this.editor.notifier.dispatch(types_1.EditorEventType.SelectionUpdated, {
199
- kind: types_1.EditorEventType.SelectionUpdated,
200
- selectedComponents: selectedObjects,
201
- tool: this,
202
- });
203
- if (selectedItemCount > 0) {
204
- this.editor.announceForAccessibility(this.editor.localization.selectedElements(selectedItemCount));
205
- this.zoomToSelection();
206
- }
207
- }
208
- if (selectedItemCount === 0 && this.selectionBox) {
209
- this.selectionBox.cancelSelection();
210
- this.prevSelectionBox = this.selectionBox;
211
- this.selectionBox = null;
212
- }
213
- }
214
- zoomToSelection() {
215
- if (this.selectionBox) {
216
- const selectionRect = this.selectionBox.region;
217
- this.editor.dispatchNoAnnounce(this.editor.viewport.zoomTo(selectionRect, false), false);
218
- }
219
- }
220
- onKeyPress(event) {
221
- const shortcucts = this.editor.shortcuts;
222
- if (shortcucts.matchesShortcut(keybindings_1.snapToGridKeyboardShortcutId, event)) {
223
- this.snapToGrid = true;
224
- return true;
225
- }
226
- if (this.selectionBox && (shortcucts.matchesShortcut(keybindings_1.duplicateSelectionShortcut, event)
227
- || shortcucts.matchesShortcut(keybindings_1.sendToBackSelectionShortcut, event))) {
228
- // Handle duplication on key up — we don't want to accidentally duplicate
229
- // many times.
230
- return true;
231
- }
232
- else if (shortcucts.matchesShortcut(keybindings_1.selectAllKeyboardShortcut, event)) {
233
- this.setSelection(this.editor.image.getAllElements());
234
- return true;
235
- }
236
- else if (event.ctrlKey) {
237
- // Don't transform the selection with, for example, ctrl+i.
238
- // Pass it to another tool, if apliccable.
239
- return false;
240
- }
241
- else if (event.shiftKey || event.key === 'Shift') {
242
- this.shiftKeyPressed = true;
243
- if (event.key === 'Shift') {
244
- return true;
245
- }
246
- }
247
- let rotationSteps = 0;
248
- let xTranslateSteps = 0;
249
- let yTranslateSteps = 0;
250
- let xScaleSteps = 0;
251
- let yScaleSteps = 0;
252
- switch (event.key) {
253
- case 'a':
254
- case 'h':
255
- case 'ArrowLeft':
256
- xTranslateSteps -= 1;
257
- break;
258
- case 'd':
259
- case 'l':
260
- case 'ArrowRight':
261
- xTranslateSteps += 1;
262
- break;
263
- case 'q':
264
- case 'k':
265
- case 'ArrowUp':
266
- yTranslateSteps -= 1;
267
- break;
268
- case 'e':
269
- case 'j':
270
- case 'ArrowDown':
271
- yTranslateSteps += 1;
272
- break;
273
- case 'r':
274
- rotationSteps += 1;
275
- break;
276
- case 'R':
277
- rotationSteps -= 1;
278
- break;
279
- case 'i':
280
- xScaleSteps -= 1;
281
- break;
282
- case 'I':
283
- xScaleSteps += 1;
284
- break;
285
- case 'o':
286
- yScaleSteps -= 1;
287
- break;
288
- case 'O':
289
- yScaleSteps += 1;
290
- break;
291
- }
292
- let handled = xTranslateSteps !== 0
293
- || yTranslateSteps !== 0
294
- || rotationSteps !== 0
295
- || xScaleSteps !== 0
296
- || yScaleSteps !== 0;
297
- if (!this.selectionBox) {
298
- handled = false;
299
- }
300
- else if (handled) {
301
- const translateStepSize = 10 * this.editor.viewport.getSizeOfPixelOnCanvas();
302
- const rotateStepSize = Math.PI / 8;
303
- const scaleStepSize = 5 / 4;
304
- const region = this.selectionBox.region;
305
- const scaleFactor = math_1.Vec2.of(scaleStepSize ** xScaleSteps, scaleStepSize ** yScaleSteps);
306
- const rotationMat = math_1.Mat33.zRotation(rotationSteps * rotateStepSize);
307
- const roundedRotationMatrix = rotationMat.mapEntries(component => Viewport_1.default.roundScaleRatio(component));
308
- const regionCenter = this.editor.viewport.roundPoint(region.center);
309
- const transform = math_1.Mat33.scaling2D(scaleFactor, this.editor.viewport.roundPoint(region.topLeft)).rightMul(math_1.Mat33.translation(regionCenter).rightMul(roundedRotationMatrix).rightMul(math_1.Mat33.translation(regionCenter.times(-1)))).rightMul(math_1.Mat33.translation(this.editor.viewport.roundPoint(math_1.Vec2.of(xTranslateSteps, yTranslateSteps).times(translateStepSize))));
310
- const oldTransform = this.selectionBox.getTransform();
311
- this.selectionBox.setTransform(oldTransform.rightMul(transform));
312
- this.selectionBox.scrollTo();
313
- // The transformation needs to be finalized at some point (on key up)
314
- this.hasUnfinalizedTransformFromKeyPress = true;
315
- }
316
- if (this.selectionBox && !handled && (event.key === 'Delete' || event.key === 'Backspace')) {
317
- this.editor.dispatch(this.selectionBox.deleteSelectedObjects());
318
- this.clearSelection();
319
- handled = true;
320
- }
321
- return handled;
322
- }
323
- onKeyUp(evt) {
324
- const shortcucts = this.editor.shortcuts;
325
- if (shortcucts.matchesShortcut(keybindings_1.snapToGridKeyboardShortcutId, evt)) {
326
- this.snapToGrid = false;
327
- return true;
328
- }
329
- if (shortcucts.matchesShortcut(keybindings_1.selectAllKeyboardShortcut, evt)) {
330
- // Selected all in onKeyDown. Don't finalizeTransform.
331
- return true;
332
- }
333
- if (this.selectionBox && shortcucts.matchesShortcut(keybindings_1.duplicateSelectionShortcut, evt)) {
334
- // Finalize duplicating the selection
335
- this.selectionBox.duplicateSelectedObjects().then(command => {
336
- this.editor.dispatch(command);
337
- });
338
- return true;
339
- }
340
- if (this.selectionBox && shortcucts.matchesShortcut(keybindings_1.sendToBackSelectionShortcut, evt)) {
341
- const sendToBackCommand = this.selectionBox.sendToBack();
342
- if (sendToBackCommand) {
343
- this.editor.dispatch(sendToBackCommand);
344
- }
345
- return true;
346
- }
347
- // Here, we check if shiftKey === false because, as of this writing,
348
- // evt.shiftKey is an optional property. Being falsey could just mean
349
- // that it wasn't set.
350
- if (evt.shiftKey === false) {
351
- this.shiftKeyPressed = false;
352
- // Don't return immediately -- event may be otherwise handled
353
- }
354
- // Also check for key === 'Shift' (for the case where shiftKey is undefined)
355
- if (evt.key === 'Shift') {
356
- this.shiftKeyPressed = false;
357
- return true;
358
- }
359
- // If we don't need to finalize the transform
360
- if (!this.hasUnfinalizedTransformFromKeyPress) {
361
- return true;
362
- }
363
- if (this.selectionBox && SelectionTool.handleableKeys.some(key => key === evt.key)) {
364
- this.selectionBox.finalizeTransform();
365
- this.hasUnfinalizedTransformFromKeyPress = false;
366
- return true;
367
- }
368
- return false;
369
- }
370
- onCopy(event) {
371
- if (!this.selectionBox) {
372
- return false;
373
- }
374
- const selectedElems = this.selectionBox.getSelectedObjects();
375
- const bbox = this.selectionBox.region;
376
- if (selectedElems.length === 0) {
377
- return false;
378
- }
379
- const exportViewport = new Viewport_1.default(() => { });
380
- const selectionScreenSize = this.selectionBox.getScreenRegion().size.times(this.editor.display.getDevicePixelRatio());
381
- // Update the viewport to have screen size roughly equal to the size of the selection box
382
- let scaleFactor = selectionScreenSize.maximumEntryMagnitude() / (bbox.size.maximumEntryMagnitude() || 1);
383
- // Round to a nearby power of two
384
- scaleFactor = Math.pow(2, Math.ceil(Math.log2(scaleFactor)));
385
- exportViewport.updateScreenSize(bbox.size.times(scaleFactor));
386
- exportViewport.resetTransform(math_1.Mat33.scaling2D(scaleFactor)
387
- // Move the selection onto the screen
388
- .rightMul(math_1.Mat33.translation(bbox.topLeft.times(-1))));
389
- const { element: svgExportElem, renderer: svgRenderer } = SVGRenderer_1.default.fromViewport(exportViewport, { sanitize: true, useViewBoxForPositioning: true });
390
- const { element: canvas, renderer: canvasRenderer } = CanvasRenderer_1.default.fromViewport(exportViewport, { maxCanvasDimen: 4096 });
391
- const text = [];
392
- for (const elem of selectedElems) {
393
- elem.render(svgRenderer);
394
- elem.render(canvasRenderer);
395
- if (elem instanceof TextComponent_1.default) {
396
- text.push(elem.getText());
397
- }
398
- }
399
- event.setData('image/svg+xml', svgExportElem.outerHTML);
400
- event.setData('text/html', svgExportElem.outerHTML);
401
- event.setData('image/png', new Promise((resolve, reject) => {
402
- canvas.toBlob((blob) => {
403
- if (blob) {
404
- resolve(blob);
405
- }
406
- else {
407
- reject(new Error('Failed to convert canvas to blob.'));
408
- }
409
- }, 'image/png');
410
- }));
411
- if (text.length > 0) {
412
- event.setData('text/plain', text.join('\n'));
413
- }
414
- return true;
415
- }
416
- setEnabled(enabled) {
417
- const wasEnabled = this.isEnabled();
418
- super.setEnabled(enabled);
419
- if (wasEnabled === enabled) {
420
- return;
421
- }
422
- // Clear the selection
423
- this.selectionBox?.cancelSelection();
424
- this.onSelectionUpdated();
425
- this.handleOverlay.replaceChildren();
426
- this.selectionBox = null;
427
- this.shiftKeyPressed = false;
428
- this.snapToGrid = false;
429
- this.handleOverlay.style.display = enabled ? 'block' : 'none';
430
- if (enabled) {
431
- this.handleOverlay.tabIndex = 0;
432
- this.handleOverlay.setAttribute('aria-label', this.editor.localization.selectionToolKeyboardShortcuts);
433
- }
434
- else {
435
- this.handleOverlay.tabIndex = -1;
436
- }
437
- }
438
- // Get the object responsible for displaying this' selection.
439
- // @internal
440
- getSelection() {
441
- return this.selectionBox;
442
- }
443
- getSelectedObjects() {
444
- return this.selectionBox?.getSelectedObjects() ?? [];
445
- }
446
- // Select the given `objects`. Any non-selectable objects in `objects` are ignored.
447
- setSelection(objects) {
448
- // Only select selectable objects.
449
- objects = objects.filter(obj => obj.isSelectable());
450
- // Sort by z-index
451
- objects.sort((a, b) => a.getZIndex() - b.getZIndex());
452
- // Remove duplicates
453
- objects = objects.filter((current, idx) => {
454
- if (idx > 0) {
455
- return current !== objects[idx - 1];
456
- }
457
- return true;
458
- });
459
- let bbox = null;
460
- for (const object of objects) {
461
- if (bbox) {
462
- bbox = bbox.union(object.getBBox());
463
- }
464
- else {
465
- bbox = object.getBBox();
466
- }
467
- }
468
- if (!bbox) {
469
- return;
470
- }
471
- this.clearSelection();
472
- if (!this.selectionBox) {
473
- this.makeSelectionBox(bbox.topLeft);
474
- }
475
- this.selectionBox.setSelectedObjects(objects, bbox);
476
- this.onSelectionUpdated();
477
- }
478
- clearSelection() {
479
- this.handleOverlay.replaceChildren();
480
- this.prevSelectionBox = this.selectionBox;
481
- this.selectionBox = null;
482
- this.onSelectionUpdated();
483
- }
484
- }
485
- SelectionTool.handleableKeys = [
486
- 'a', 'h', 'ArrowLeft',
487
- 'd', 'l', 'ArrowRight',
488
- 'q', 'k', 'ArrowUp',
489
- 'e', 'j', 'ArrowDown',
490
- 'r', 'R',
491
- 'i', 'I', 'o', 'O',
492
- 'Control', 'Meta',
493
- ];
494
- exports.default = SelectionTool;
@@ -1 +0,0 @@
1
- export {};
@@ -1,23 +0,0 @@
1
- import { Point2, Vec2 } from '@js-draw/math';
2
- import Viewport from '../../Viewport';
3
- type ScrollByCallback = (delta: Vec2) => void;
4
- /**
5
- * Automatically scrolls the viewport such that the user's pointer is visible.
6
- */
7
- export default class ToPointerAutoscroller {
8
- private viewport;
9
- private scrollByCanvasDelta;
10
- private started;
11
- private updateLoopId;
12
- private updateLoopRunning;
13
- private targetPoint;
14
- private scrollRate;
15
- constructor(viewport: Viewport, scrollByCanvasDelta: ScrollByCallback);
16
- private getScrollForPoint;
17
- start(): void;
18
- onPointerMove(pointerScreenPosition: Point2): void;
19
- stop(): void;
20
- private startUpdateLoop;
21
- private stopUpdateLoop;
22
- }
23
- export {};
@@ -1,83 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const math_1 = require("@js-draw/math");
7
- const untilNextAnimationFrame_1 = __importDefault(require("../../util/untilNextAnimationFrame"));
8
- /**
9
- * Automatically scrolls the viewport such that the user's pointer is visible.
10
- */
11
- class ToPointerAutoscroller {
12
- constructor(viewport, scrollByCanvasDelta) {
13
- this.viewport = viewport;
14
- this.scrollByCanvasDelta = scrollByCanvasDelta;
15
- this.started = false;
16
- this.updateLoopId = 0;
17
- this.updateLoopRunning = false;
18
- this.targetPoint = null;
19
- this.scrollRate = 1000; // px/s
20
- }
21
- getScrollForPoint(screenPoint) {
22
- const screenSize = this.viewport.getScreenRectSize();
23
- const screenRect = new math_1.Rect2(0, 0, screenSize.x, screenSize.y);
24
- // Starts autoscrolling when the cursor is **outside of** this region
25
- const marginSize = 44;
26
- const autoscrollBoundary = screenRect.grownBy(-marginSize);
27
- if (autoscrollBoundary.containsPoint(screenPoint)) {
28
- return math_1.Vec2.zero;
29
- }
30
- const closestEdgePoint = autoscrollBoundary.getClosestPointOnBoundaryTo(screenPoint);
31
- const distToEdge = closestEdgePoint.distanceTo(screenPoint);
32
- const toEdge = closestEdgePoint.minus(screenPoint);
33
- // Go faster for points further away from the boundary.
34
- const maximumScaleFactor = 1.25;
35
- const scaleFactor = Math.min(distToEdge / marginSize, maximumScaleFactor);
36
- return toEdge.normalizedOrZero().times(scaleFactor);
37
- }
38
- start() {
39
- this.started = true;
40
- }
41
- onPointerMove(pointerScreenPosition) {
42
- if (!this.started) {
43
- return;
44
- }
45
- if (this.getScrollForPoint(pointerScreenPosition) === math_1.Vec2.zero) {
46
- this.stopUpdateLoop();
47
- }
48
- else {
49
- this.targetPoint = pointerScreenPosition;
50
- this.startUpdateLoop();
51
- }
52
- }
53
- stop() {
54
- this.targetPoint = null;
55
- this.started = false;
56
- this.stopUpdateLoop();
57
- }
58
- startUpdateLoop() {
59
- if (this.updateLoopRunning) {
60
- return;
61
- }
62
- (async () => {
63
- this.updateLoopId++;
64
- const currentUpdateLoopId = this.updateLoopId;
65
- let lastUpdateTime = performance.now();
66
- while (this.updateLoopId === currentUpdateLoopId && this.targetPoint) {
67
- this.updateLoopRunning = true;
68
- const currentTime = performance.now();
69
- const deltaTimeMs = currentTime - lastUpdateTime;
70
- const scrollDirection = this.getScrollForPoint(this.targetPoint);
71
- const screenScrollAmount = scrollDirection.times(this.scrollRate * deltaTimeMs / 1000);
72
- this.scrollByCanvasDelta(this.viewport.screenToCanvasTransform.transformVec3(screenScrollAmount));
73
- lastUpdateTime = currentTime;
74
- await (0, untilNextAnimationFrame_1.default)();
75
- }
76
- this.updateLoopRunning = false;
77
- })();
78
- }
79
- stopUpdateLoop() {
80
- this.updateLoopId++;
81
- }
82
- }
83
- exports.default = ToPointerAutoscroller;
@@ -1,42 +0,0 @@
1
- import Editor from '../../Editor';
2
- import { Vec3 } from '@js-draw/math';
3
- import Selection from './Selection';
4
- import { ResizeMode } from './types';
5
- export declare class DragTransformer {
6
- private readonly editor;
7
- private selection;
8
- private dragStartPoint;
9
- constructor(editor: Editor, selection: Selection);
10
- onDragStart(startPoint: Vec3): void;
11
- onDragUpdate(canvasPos: Vec3): void;
12
- onDragEnd(): void | Promise<void>;
13
- }
14
- export declare class ResizeTransformer {
15
- private readonly editor;
16
- private selection;
17
- private mode;
18
- private dragStartPoint;
19
- private transformOrigin;
20
- private scaleRate;
21
- constructor(editor: Editor, selection: Selection);
22
- onDragStart(startPoint: Vec3, mode: ResizeMode): void;
23
- private computeOriginAndScaleRate;
24
- onDragUpdate(canvasPos: Vec3): void;
25
- onDragEnd(): void | Promise<void>;
26
- }
27
- export declare class RotateTransformer {
28
- private readonly editor;
29
- private selection;
30
- private startAngle;
31
- private targetRotation;
32
- private maximumDistFromStart;
33
- private startPoint;
34
- private startTime;
35
- constructor(editor: Editor, selection: Selection);
36
- private getAngle;
37
- private roundAngle;
38
- onDragStart(startPoint: Vec3): void;
39
- private setRotationTo;
40
- onDragUpdate(canvasPos: Vec3): void;
41
- onDragEnd(): void | Promise<void>;
42
- }