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,312 +0,0 @@
1
- import { Color4 } from '@js-draw/math';
2
- import EditorImage from '../image/EditorImage.mjs';
3
- import { PointerDevice } from '../Pointer.mjs';
4
- import { makeFreehandLineBuilder } from '../components/builders/FreehandLineBuilder.mjs';
5
- import { EditorEventType } from '../types.mjs';
6
- import BaseTool from './BaseTool.mjs';
7
- import { undoKeyboardShortcutId } from './keybindings.mjs';
8
- import { decreaseSizeKeyboardShortcutId, increaseSizeKeyboardShortcutId } from './keybindings.mjs';
9
- import InputStabilizer from './InputFilter/InputStabilizer.mjs';
10
- import { ReactiveValue } from '../util/ReactiveValue.mjs';
11
- import StationaryPenDetector from './util/StationaryPenDetector.mjs';
12
- export default class Pen extends BaseTool {
13
- constructor(editor, description, style) {
14
- super(editor.notifier, description);
15
- this.editor = editor;
16
- this.builder = null;
17
- this.lastPoint = null;
18
- this.startPoint = null;
19
- this.currentDeviceType = null;
20
- this.shapeAutocompletionEnabled = false;
21
- this.autocorrectedShape = null;
22
- this.lastAutocorrectedShape = null;
23
- this.removedAutocorrectedShapeTime = 0;
24
- this.stationaryDetector = null;
25
- this.styleValue = ReactiveValue.fromInitialValue({
26
- factory: makeFreehandLineBuilder,
27
- color: Color4.blue,
28
- thickness: 4,
29
- ...style,
30
- });
31
- this.styleValue.onUpdateAndNow(newValue => {
32
- this.style = newValue;
33
- this.noteUpdated();
34
- });
35
- }
36
- getPressureMultiplier() {
37
- const thickness = this.style.thickness;
38
- return 1 / this.editor.viewport.getScaleFactor() * thickness;
39
- }
40
- // Converts a `pointer` to a `StrokeDataPoint`.
41
- toStrokePoint(pointer) {
42
- const minPressure = 0.3;
43
- let pressure = Math.max(pointer.pressure ?? 1.0, minPressure);
44
- if (!isFinite(pressure)) {
45
- console.warn('Non-finite pressure!', pointer);
46
- pressure = minPressure;
47
- }
48
- console.assert(isFinite(pointer.canvasPos.length()), 'Non-finite canvas position!');
49
- console.assert(isFinite(pointer.screenPos.length()), 'Non-finite screen position!');
50
- console.assert(isFinite(pointer.timeStamp), 'Non-finite timeStamp on pointer!');
51
- const pos = pointer.canvasPos;
52
- return {
53
- pos,
54
- width: pressure * this.getPressureMultiplier(),
55
- color: this.style.color,
56
- time: pointer.timeStamp,
57
- };
58
- }
59
- // Displays the stroke that is currently being built with the display's `wetInkRenderer`.
60
- previewStroke() {
61
- this.editor.clearWetInk();
62
- const wetInkRenderer = this.editor.display.getWetInkRenderer();
63
- if (this.autocorrectedShape) {
64
- const visibleRect = this.editor.viewport.visibleRect;
65
- this.autocorrectedShape.render(wetInkRenderer, visibleRect);
66
- }
67
- else {
68
- this.builder?.preview(wetInkRenderer);
69
- }
70
- }
71
- // Throws if no stroke builder exists.
72
- addPointToStroke(point) {
73
- if (!this.builder) {
74
- throw new Error('No stroke is currently being generated.');
75
- }
76
- this.builder.addPoint(point);
77
- this.lastPoint = point;
78
- this.previewStroke();
79
- }
80
- onPointerDown(event) {
81
- const { current, allPointers } = event;
82
- const isEraser = current.device === PointerDevice.Eraser;
83
- let anyDeviceIsStylus = false;
84
- for (const pointer of allPointers) {
85
- if (pointer.device === PointerDevice.Pen) {
86
- anyDeviceIsStylus = true;
87
- break;
88
- }
89
- }
90
- // Avoid canceling an existing stroke
91
- if (this.builder && !this.eventCanCancelStroke(event)) {
92
- return true;
93
- }
94
- if ((allPointers.length === 1 && !isEraser) || anyDeviceIsStylus) {
95
- this.startPoint = this.toStrokePoint(current);
96
- this.builder = this.style.factory(this.startPoint, this.editor.viewport);
97
- this.currentDeviceType = current.device;
98
- if (this.shapeAutocompletionEnabled) {
99
- const stationaryDetectionConfig = {
100
- maxSpeed: 8.5, // screenPx/s
101
- maxRadius: 11, // screenPx
102
- minTimeSeconds: 0.5, // s
103
- };
104
- this.stationaryDetector = new StationaryPenDetector(current, stationaryDetectionConfig, pointer => this.autocorrectShape(pointer));
105
- }
106
- else {
107
- this.stationaryDetector = null;
108
- }
109
- this.lastAutocorrectedShape = null;
110
- this.removedAutocorrectedShapeTime = 0;
111
- return true;
112
- }
113
- return false;
114
- }
115
- eventCanCancelStroke(event) {
116
- // If there has been a delay since the last input event,
117
- // it's always okay to cancel
118
- const lastInputTime = this.lastPoint?.time ?? 0;
119
- if (event.current.timeStamp - lastInputTime > 1000) {
120
- return true;
121
- }
122
- const isPenStroke = this.currentDeviceType === PointerDevice.Pen;
123
- const isTouchEvent = event.current.device === PointerDevice.Touch;
124
- // Don't allow pen strokes to be cancelled by touch events.
125
- if (isPenStroke && isTouchEvent) {
126
- return false;
127
- }
128
- return true;
129
- }
130
- eventCanBeDeliveredToNonActiveTool(event) {
131
- return this.eventCanCancelStroke(event);
132
- }
133
- onPointerMove({ current }) {
134
- if (!this.builder)
135
- return;
136
- if (current.device !== this.currentDeviceType)
137
- return;
138
- const isStationary = this.stationaryDetector?.onPointerMove(current);
139
- if (!isStationary) {
140
- this.addPointToStroke(this.toStrokePoint(current));
141
- if (this.autocorrectedShape) {
142
- this.removedAutocorrectedShapeTime = performance.now();
143
- this.autocorrectedShape = null;
144
- this.editor.announceForAccessibility(this.editor.localization.autocorrectionCanceled);
145
- }
146
- }
147
- }
148
- onPointerUp({ current }) {
149
- if (!this.builder)
150
- return false;
151
- if (current.device !== this.currentDeviceType) {
152
- // this.builder still exists, so we're handling events from another
153
- // device type.
154
- return true;
155
- }
156
- this.stationaryDetector?.onPointerUp(current);
157
- // onPointerUp events can have zero pressure. Use the last pressure instead.
158
- const currentPoint = this.toStrokePoint(current);
159
- const strokePoint = {
160
- ...currentPoint,
161
- width: this.lastPoint?.width ?? currentPoint.width,
162
- };
163
- this.addPointToStroke(strokePoint);
164
- if (current.isPrimary) {
165
- this.finalizeStroke();
166
- }
167
- return false;
168
- }
169
- onGestureCancel() {
170
- this.builder = null;
171
- this.editor.clearWetInk();
172
- this.stationaryDetector?.destroy();
173
- this.stationaryDetector = null;
174
- }
175
- removedAutocorrectedShapeRecently() {
176
- return this.removedAutocorrectedShapeTime > performance.now() - 320;
177
- }
178
- async autocorrectShape(_lastPointer) {
179
- if (!this.builder || !this.builder.autocorrectShape)
180
- return;
181
- if (!this.shapeAutocompletionEnabled)
182
- return;
183
- // If already corrected, do nothing
184
- if (this.autocorrectedShape)
185
- return;
186
- // Activate stroke fitting
187
- const correctedShape = await this.builder.autocorrectShape();
188
- if (!this.builder || !correctedShape) {
189
- return;
190
- }
191
- // Don't complete to empty shapes.
192
- const bboxArea = correctedShape.getBBox().area;
193
- if (bboxArea === 0 || !isFinite(bboxArea)) {
194
- return;
195
- }
196
- const shapeDescription = correctedShape.description(this.editor.localization);
197
- this.editor.announceForAccessibility(this.editor.localization.autocorrectedTo(shapeDescription));
198
- this.autocorrectedShape = correctedShape;
199
- this.lastAutocorrectedShape = correctedShape;
200
- this.previewStroke();
201
- }
202
- finalizeStroke() {
203
- if (this.builder) {
204
- // If autocorrectedShape was cleared recently enough, it was
205
- // probably by mistake. Reset it.
206
- if (this.lastAutocorrectedShape && this.removedAutocorrectedShapeRecently()) {
207
- this.autocorrectedShape = this.lastAutocorrectedShape;
208
- }
209
- const stroke = this.autocorrectedShape ?? this.builder.build();
210
- this.previewStroke();
211
- if (stroke.getBBox().area > 0) {
212
- if (stroke === this.autocorrectedShape) {
213
- this.editor.announceForAccessibility(this.editor.localization.autocorrectedTo(stroke.description(this.editor.localization)));
214
- }
215
- const canFlatten = true;
216
- const action = EditorImage.addElement(stroke, canFlatten);
217
- this.editor.dispatch(action);
218
- }
219
- else {
220
- console.warn('Pen: Not adding empty stroke', stroke, 'to the canvas.');
221
- }
222
- }
223
- this.builder = null;
224
- this.lastPoint = null;
225
- this.autocorrectedShape = null;
226
- this.lastAutocorrectedShape = null;
227
- this.editor.clearWetInk();
228
- this.stationaryDetector?.destroy();
229
- this.stationaryDetector = null;
230
- }
231
- noteUpdated() {
232
- this.editor.notifier.dispatch(EditorEventType.ToolUpdated, {
233
- kind: EditorEventType.ToolUpdated,
234
- tool: this,
235
- });
236
- }
237
- setColor(color) {
238
- if (color.toHexString() !== this.style.color.toHexString()) {
239
- this.styleValue.set({
240
- ...this.style,
241
- color,
242
- });
243
- }
244
- }
245
- setThickness(thickness) {
246
- if (thickness !== this.style.thickness) {
247
- this.styleValue.set({
248
- ...this.style,
249
- thickness,
250
- });
251
- }
252
- }
253
- setStrokeFactory(factory) {
254
- if (factory !== this.style.factory) {
255
- this.styleValue.set({
256
- ...this.style,
257
- factory,
258
- });
259
- }
260
- }
261
- setHasStabilization(hasStabilization) {
262
- const hasInputMapper = !!this.getInputMapper();
263
- // TODO: Currently, this assumes that there is no other input mapper.
264
- if (hasStabilization === hasInputMapper) {
265
- return;
266
- }
267
- if (hasInputMapper) {
268
- this.setInputMapper(null);
269
- }
270
- else {
271
- this.setInputMapper(new InputStabilizer(this.editor.viewport));
272
- }
273
- this.noteUpdated();
274
- }
275
- setStrokeAutocorrectEnabled(enabled) {
276
- if (enabled !== this.shapeAutocompletionEnabled) {
277
- this.shapeAutocompletionEnabled = enabled;
278
- this.noteUpdated();
279
- }
280
- }
281
- getStrokeAutocorrectionEnabled() {
282
- return this.shapeAutocompletionEnabled;
283
- }
284
- getThickness() { return this.style.thickness; }
285
- getColor() { return this.style.color; }
286
- getStrokeFactory() { return this.style.factory; }
287
- getStyleValue() { return this.styleValue; }
288
- onKeyPress(event) {
289
- const shortcuts = this.editor.shortcuts;
290
- // Ctrl+Z: End the stroke so that it can be undone/redone.
291
- const isCtrlZ = shortcuts.matchesShortcut(undoKeyboardShortcutId, event);
292
- if (this.builder && isCtrlZ) {
293
- this.finalizeStroke();
294
- // Return false: Allow other listeners to handle the event (e.g.
295
- // undo/redo).
296
- return false;
297
- }
298
- let newThickness;
299
- if (shortcuts.matchesShortcut(decreaseSizeKeyboardShortcutId, event)) {
300
- newThickness = this.getThickness() * 2 / 3;
301
- }
302
- else if (shortcuts.matchesShortcut(increaseSizeKeyboardShortcutId, event)) {
303
- newThickness = this.getThickness() * 3 / 2;
304
- }
305
- if (newThickness !== undefined) {
306
- newThickness = Math.min(Math.max(1, newThickness), 256);
307
- this.setThickness(newThickness);
308
- return true;
309
- }
310
- return false;
311
- }
312
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,28 +0,0 @@
1
- import { Color4 } from '@js-draw/math';
2
- import Editor from '../Editor';
3
- import { PointerEvt } from '../inputEvents';
4
- import BaseTool from './BaseTool';
5
- type ColorListener = (color: Color4 | null) => void;
6
- /**
7
- * A tool used internally to pick colors from the canvas.
8
- *
9
- * When color selection is in progress, the `pipette--color-selection-in-progress` class
10
- * is added to the root element. This can be used by themes.
11
- *
12
- * @internal
13
- */
14
- export default class PipetteTool extends BaseTool {
15
- private editor;
16
- private colorPreviewListener;
17
- private colorSelectListener;
18
- constructor(editor: Editor, description: string);
19
- canReceiveInputInReadOnlyEditor(): boolean;
20
- private updateSelectingStatus;
21
- setColorListener(colorPreviewListener: ColorListener, colorSelectListener: ColorListener): void;
22
- clearColorListener(): void;
23
- onPointerDown({ current, allPointers }: PointerEvt): boolean;
24
- onPointerMove({ current }: PointerEvt): void;
25
- onPointerUp({ current }: PointerEvt): void;
26
- onGestureCancel(): void;
27
- }
28
- export {};
@@ -1,63 +0,0 @@
1
- // @internal @packageDocumentation
2
- import BaseTool from './BaseTool.mjs';
3
- /**
4
- * A tool used internally to pick colors from the canvas.
5
- *
6
- * When color selection is in progress, the `pipette--color-selection-in-progress` class
7
- * is added to the root element. This can be used by themes.
8
- *
9
- * @internal
10
- */
11
- export default class PipetteTool extends BaseTool {
12
- constructor(editor, description) {
13
- super(editor.notifier, description);
14
- this.editor = editor;
15
- this.colorPreviewListener = null;
16
- this.colorSelectListener = null;
17
- this.enabledValue().onUpdateAndNow(() => {
18
- this.updateSelectingStatus();
19
- });
20
- }
21
- canReceiveInputInReadOnlyEditor() {
22
- return true;
23
- }
24
- // Ensures that the root editor element correctly reflects whether color selection
25
- // is in progress.
26
- updateSelectingStatus() {
27
- const className = 'pipette--color-selection-in-progress';
28
- if (this.isEnabled() && this.colorSelectListener && this.colorPreviewListener) {
29
- this.editor.getRootElement().classList.add(className);
30
- }
31
- else {
32
- this.editor.getRootElement().classList.remove(className);
33
- }
34
- }
35
- setColorListener(colorPreviewListener,
36
- // Called when the gesture ends -- when the user has selected a color.
37
- colorSelectListener) {
38
- this.colorPreviewListener = colorPreviewListener;
39
- this.colorSelectListener = colorSelectListener;
40
- this.updateSelectingStatus();
41
- }
42
- clearColorListener() {
43
- this.colorPreviewListener = null;
44
- this.colorSelectListener = null;
45
- this.updateSelectingStatus();
46
- }
47
- onPointerDown({ current, allPointers }) {
48
- if (this.colorPreviewListener && allPointers.length === 1) {
49
- this.colorPreviewListener(this.editor.display.getColorAt(current.screenPos));
50
- return true;
51
- }
52
- return false;
53
- }
54
- onPointerMove({ current }) {
55
- this.colorPreviewListener?.(this.editor.display.getColorAt(current.screenPos));
56
- }
57
- onPointerUp({ current }) {
58
- this.colorSelectListener?.(this.editor.display.getColorAt(current.screenPos));
59
- }
60
- onGestureCancel() {
61
- this.colorSelectListener?.(null);
62
- }
63
- }
@@ -1,18 +0,0 @@
1
- import Editor from '../Editor';
2
- import BaseTool from './BaseTool';
3
- /**
4
- * This tool, when enabled, renders scrollbars reflecting the current position
5
- * of the view relative to the import/export area of the image.
6
- *
7
- * **Note**: These scrollbars are currently not draggable. This may change in
8
- * a future release.
9
- */
10
- export default class ScrollbarTool extends BaseTool {
11
- private editor;
12
- private scrollbarOverlay;
13
- private verticalScrollbar;
14
- private horizontalScrollbar;
15
- constructor(editor: Editor);
16
- private fadeOutTimeout;
17
- private updateScrollbars;
18
- }
@@ -1,79 +0,0 @@
1
- import { Rect2 } from '@js-draw/math';
2
- import { EditorEventType } from '../types.mjs';
3
- import BaseTool from './BaseTool.mjs';
4
- /**
5
- * This tool, when enabled, renders scrollbars reflecting the current position
6
- * of the view relative to the import/export area of the image.
7
- *
8
- * **Note**: These scrollbars are currently not draggable. This may change in
9
- * a future release.
10
- */
11
- export default class ScrollbarTool extends BaseTool {
12
- constructor(editor) {
13
- super(editor.notifier, 'scrollbar');
14
- this.editor = editor;
15
- this.fadeOutTimeout = null;
16
- this.scrollbarOverlay = document.createElement('div');
17
- this.scrollbarOverlay.classList.add('ScrollbarTool-overlay');
18
- this.verticalScrollbar = document.createElement('div');
19
- this.verticalScrollbar.classList.add('vertical-scrollbar');
20
- this.horizontalScrollbar = document.createElement('div');
21
- this.horizontalScrollbar.classList.add('horizontal-scrollbar');
22
- this.scrollbarOverlay.replaceChildren(this.verticalScrollbar, this.horizontalScrollbar);
23
- let overlay = null;
24
- let viewportListener = null;
25
- this.enabledValue().onUpdateAndNow(enabled => {
26
- overlay?.remove();
27
- viewportListener?.remove();
28
- viewportListener = null;
29
- overlay = null;
30
- if (enabled) {
31
- viewportListener = editor.notifier.on(EditorEventType.ViewportChanged, _event => {
32
- this.updateScrollbars();
33
- });
34
- this.updateScrollbars();
35
- overlay = editor.createHTMLOverlay(this.scrollbarOverlay);
36
- }
37
- });
38
- }
39
- updateScrollbars() {
40
- const viewport = this.editor.viewport;
41
- const screenSize = viewport.getScreenRectSize();
42
- const screenRect = new Rect2(0, 0, screenSize.x, screenSize.y);
43
- const imageRect = this.editor.getImportExportRect()
44
- // The scrollbars are positioned in screen coordinates, so the exportRect also needs
45
- // to be in screen coordinates
46
- .transformedBoundingBox(viewport.canvasToScreenTransform)
47
- // If the screenRect is outside of the exportRect, expand the image rectangle
48
- .union(screenRect);
49
- const scrollbarWidth = screenRect.width / imageRect.width * screenSize.x;
50
- const scrollbarHeight = screenRect.height / imageRect.height * screenSize.y;
51
- const scrollbarX = (screenRect.x - imageRect.x) / imageRect.width * (screenSize.x);
52
- const scrollbarY = (screenRect.y - imageRect.y) / imageRect.height * (screenSize.y);
53
- this.horizontalScrollbar.style.width = `${scrollbarWidth}px`;
54
- this.verticalScrollbar.style.height = `${scrollbarHeight}px`;
55
- this.horizontalScrollbar.style.marginLeft = `${scrollbarX}px`;
56
- this.verticalScrollbar.style.marginTop = `${scrollbarY}px`;
57
- // Style the scrollbars differently when there's no scroll (all content visible)
58
- const handleNoScrollStyling = (scrollbar, size, fillSize) => {
59
- const fillsWindowClass = 'represents-no-scroll';
60
- if (Math.abs(size - fillSize) < 1e-8) {
61
- scrollbar.classList.add(fillsWindowClass);
62
- }
63
- else {
64
- scrollbar.classList.remove(fillsWindowClass);
65
- }
66
- };
67
- handleNoScrollStyling(this.horizontalScrollbar, scrollbarWidth, screenSize.x);
68
- handleNoScrollStyling(this.verticalScrollbar, scrollbarHeight, screenSize.y);
69
- // Fade out after a delay.
70
- if (this.fadeOutTimeout !== null) {
71
- clearTimeout(this.fadeOutTimeout);
72
- }
73
- const fadeOutDelay = 3000;
74
- this.fadeOutTimeout = setTimeout(() => {
75
- this.scrollbarOverlay.classList.remove('just-updated');
76
- }, fadeOutDelay);
77
- this.scrollbarOverlay.classList.add('just-updated');
78
- }
79
- }
@@ -1,9 +0,0 @@
1
- import Editor from '../../Editor';
2
- import { KeyPressEvent } from '../../inputEvents';
3
- import BaseTool from '../BaseTool';
4
- export default class SelectAllShortcutHandler extends BaseTool {
5
- private editor;
6
- constructor(editor: Editor);
7
- canReceiveInputInReadOnlyEditor(): boolean;
8
- onKeyPress(event: KeyPressEvent): boolean;
9
- }
@@ -1,26 +0,0 @@
1
- import BaseTool from '../BaseTool.mjs';
2
- import { selectAllKeyboardShortcut } from '../keybindings.mjs';
3
- import SelectionTool from './SelectionTool.mjs';
4
- // Handles ctrl+a: Select all
5
- export default class SelectAllShortcutHandler extends BaseTool {
6
- constructor(editor) {
7
- super(editor.notifier, editor.localization.selectAllTool);
8
- this.editor = editor;
9
- }
10
- canReceiveInputInReadOnlyEditor() {
11
- return true;
12
- }
13
- // @internal
14
- onKeyPress(event) {
15
- if (this.editor.shortcuts.matchesShortcut(selectAllKeyboardShortcut, event)) {
16
- const selectionTools = this.editor.toolController.getMatchingTools(SelectionTool);
17
- if (selectionTools.length > 0) {
18
- const selectionTool = selectionTools[0];
19
- selectionTool.setEnabled(true);
20
- selectionTool.setSelection(this.editor.image.getAllElements());
21
- return true;
22
- }
23
- }
24
- return false;
25
- }
26
- }
@@ -1,71 +0,0 @@
1
- /**
2
- * @internal
3
- * @packageDocumentation
4
- */
5
- import SerializableCommand from '../../commands/SerializableCommand';
6
- import Editor from '../../Editor';
7
- import { Mat33, Rect2, Point2 } from '@js-draw/math';
8
- import Pointer from '../../Pointer';
9
- import AbstractComponent from '../../components/AbstractComponent';
10
- import Command from '../../commands/Command';
11
- export default class Selection {
12
- private editor;
13
- private childwidgets;
14
- private originalRegion;
15
- private selectionTightBoundingBox;
16
- private transformers;
17
- private transform;
18
- private selectedElems;
19
- private outerContainer;
20
- private innerContainer;
21
- private backgroundElem;
22
- private hasParent;
23
- constructor(startPoint: Point2, editor: Editor);
24
- getBackgroundElem(): HTMLElement;
25
- getTransform(): Mat33;
26
- get preTransformRegion(): Rect2;
27
- get region(): Rect2;
28
- /**
29
- * Computes and returns the bounding box of the selection without
30
- * any additional padding. Computes directly from the elements that are selected.
31
- * @internal
32
- */
33
- computeTightBoundingBox(): Rect2;
34
- get regionRotation(): number;
35
- get preTransformedScreenRegion(): Rect2;
36
- get preTransformedScreenRegionRotation(): number;
37
- getScreenRegion(): Rect2;
38
- get screenRegionRotation(): number;
39
- setTransform(transform: Mat33, preview?: boolean): void;
40
- private getDeltaZIndexToMoveSelectionToTop;
41
- finalizeTransform(): void | Promise<void>;
42
- /** Sends all selected elements to the bottom of the visible image. */
43
- sendToBack(): SerializableCommand | null;
44
- private static ApplyTransformationCommand;
45
- private previewTransformCmds;
46
- resolveToObjects(): boolean;
47
- recomputeRegion(): boolean;
48
- padRegion(): void;
49
- getMinCanvasSize(): number;
50
- getSelectedItemCount(): number;
51
- updateUI(): void;
52
- private removedFromImage;
53
- private addRemoveSelectionFromImage;
54
- private removeDeletedElemsFromSelection;
55
- private activeHandle;
56
- private backgroundDragging;
57
- onDragStart(pointer: Pointer): boolean;
58
- onDragUpdate(pointer: Pointer): void;
59
- onDragEnd(): void;
60
- onDragCancel(): void;
61
- scrollTo(): boolean;
62
- deleteSelectedObjects(): Command;
63
- private selectionDuplicatedAnimationTimeout;
64
- private runSelectionDuplicatedAnimation;
65
- duplicateSelectedObjects(): Promise<Command>;
66
- addTo(elem: HTMLElement): void;
67
- setToPoint(point: Point2): void;
68
- cancelSelection(): void;
69
- setSelectedObjects(objects: AbstractComponent[], bbox: Rect2): void;
70
- getSelectedObjects(): AbstractComponent[];
71
- }