js-draw 0.17.4 → 0.18.1
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.
- package/CHANGELOG.md +8 -0
- package/dist/bundle.js +9 -1
- package/package.json +35 -33
- package/tsconfig.json +3 -2
- package/tsconfig.mjs.json +9 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -34
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/.github/ISSUE_TEMPLATE/translation.yml +0 -902
- package/.github/pull_request_template.md +0 -15
- package/.github/workflows/firebase-hosting-merge.yml +0 -32
- package/.github/workflows/firebase-hosting-pull-request.yml +0 -32
- package/.github/workflows/github-pages.yml +0 -56
- package/.husky/pre-commit +0 -4
- package/build_tools/BundledFile.ts +0 -167
- package/build_tools/buildTranslationTemplate.ts +0 -121
- package/build_tools/bundle.ts +0 -11
- package/dist/build_tools/BundledFile.d.ts +0 -13
- package/dist/build_tools/BundledFile.js +0 -157
- package/dist/build_tools/buildTranslationTemplate.d.ts +0 -1
- package/dist/build_tools/buildTranslationTemplate.js +0 -94
- package/dist/build_tools/bundle.d.ts +0 -1
- package/dist/build_tools/bundle.js +0 -5
- package/dist/src/Color4.d.ts +0 -60
- package/dist/src/Color4.js +0 -192
- package/dist/src/Editor.d.ts +0 -308
- package/dist/src/Editor.js +0 -874
- package/dist/src/EditorImage.d.ts +0 -97
- package/dist/src/EditorImage.js +0 -477
- package/dist/src/EventDispatcher.d.ts +0 -30
- package/dist/src/EventDispatcher.js +0 -54
- package/dist/src/Pointer.d.ts +0 -24
- package/dist/src/Pointer.js +0 -80
- package/dist/src/SVGLoader.d.ts +0 -48
- package/dist/src/SVGLoader.js +0 -442
- package/dist/src/UndoRedoHistory.d.ts +0 -19
- package/dist/src/UndoRedoHistory.js +0 -91
- package/dist/src/Viewport.d.ts +0 -71
- package/dist/src/Viewport.js +0 -256
- package/dist/src/bundle/bundled.d.ts +0 -4
- package/dist/src/bundle/bundled.js +0 -5
- package/dist/src/commands/Command.d.ts +0 -16
- package/dist/src/commands/Command.js +0 -30
- package/dist/src/commands/Duplicate.d.ts +0 -14
- package/dist/src/commands/Duplicate.js +0 -33
- package/dist/src/commands/Erase.d.ts +0 -14
- package/dist/src/commands/Erase.js +0 -57
- package/dist/src/commands/SerializableCommand.d.ts +0 -12
- package/dist/src/commands/SerializableCommand.js +0 -36
- package/dist/src/commands/UnresolvedCommand.d.ts +0 -14
- package/dist/src/commands/UnresolvedCommand.js +0 -22
- package/dist/src/commands/invertCommand.d.ts +0 -4
- package/dist/src/commands/invertCommand.js +0 -44
- package/dist/src/commands/lib.d.ts +0 -7
- package/dist/src/commands/lib.js +0 -7
- package/dist/src/commands/localization.d.ts +0 -23
- package/dist/src/commands/localization.js +0 -21
- package/dist/src/commands/uniteCommands.d.ts +0 -4
- package/dist/src/commands/uniteCommands.js +0 -116
- package/dist/src/components/AbstractComponent.d.ts +0 -73
- package/dist/src/components/AbstractComponent.js +0 -252
- package/dist/src/components/ImageBackground.d.ts +0 -42
- package/dist/src/components/ImageBackground.js +0 -139
- package/dist/src/components/ImageComponent.d.ts +0 -31
- package/dist/src/components/ImageComponent.js +0 -146
- package/dist/src/components/RestylableComponent.d.ts +0 -24
- package/dist/src/components/RestylableComponent.js +0 -80
- package/dist/src/components/SVGGlobalAttributesObject.d.ts +0 -21
- package/dist/src/components/SVGGlobalAttributesObject.js +0 -59
- package/dist/src/components/Stroke.d.ts +0 -40
- package/dist/src/components/Stroke.js +0 -185
- package/dist/src/components/TextComponent.d.ts +0 -53
- package/dist/src/components/TextComponent.js +0 -252
- package/dist/src/components/UnknownSVGObject.d.ts +0 -18
- package/dist/src/components/UnknownSVGObject.js +0 -44
- package/dist/src/components/builders/ArrowBuilder.d.ts +0 -19
- package/dist/src/components/builders/ArrowBuilder.js +0 -86
- package/dist/src/components/builders/FreehandLineBuilder.d.ts +0 -33
- package/dist/src/components/builders/FreehandLineBuilder.js +0 -165
- package/dist/src/components/builders/LineBuilder.d.ts +0 -18
- package/dist/src/components/builders/LineBuilder.js +0 -58
- package/dist/src/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +0 -36
- package/dist/src/components/builders/PressureSensitiveFreehandLineBuilder.js +0 -339
- package/dist/src/components/builders/RectangleBuilder.d.ts +0 -20
- package/dist/src/components/builders/RectangleBuilder.js +0 -50
- package/dist/src/components/builders/types.d.ts +0 -12
- package/dist/src/components/builders/types.js +0 -1
- package/dist/src/components/lib.d.ts +0 -12
- package/dist/src/components/lib.js +0 -12
- package/dist/src/components/localization.d.ts +0 -11
- package/dist/src/components/localization.js +0 -10
- package/dist/src/components/util/StrokeSmoother.d.ts +0 -35
- package/dist/src/components/util/StrokeSmoother.js +0 -210
- package/dist/src/components/util/describeComponentList.d.ts +0 -4
- package/dist/src/components/util/describeComponentList.js +0 -14
- package/dist/src/lib.d.ts +0 -34
- package/dist/src/lib.js +0 -34
- package/dist/src/localization.d.ts +0 -14
- package/dist/src/localization.js +0 -10
- package/dist/src/localizations/de.d.ts +0 -3
- package/dist/src/localizations/de.js +0 -4
- package/dist/src/localizations/en.d.ts +0 -3
- package/dist/src/localizations/en.js +0 -4
- package/dist/src/localizations/es.d.ts +0 -3
- package/dist/src/localizations/es.js +0 -18
- package/dist/src/localizations/getLocalizationTable.d.ts +0 -3
- package/dist/src/localizations/getLocalizationTable.js +0 -45
- package/dist/src/math/LineSegment2.d.ts +0 -24
- package/dist/src/math/LineSegment2.js +0 -125
- package/dist/src/math/Mat33.d.ts +0 -118
- package/dist/src/math/Mat33.js +0 -326
- package/dist/src/math/Path.d.ts +0 -71
- package/dist/src/math/Path.js +0 -648
- package/dist/src/math/Rect2.d.ts +0 -52
- package/dist/src/math/Rect2.js +0 -228
- package/dist/src/math/Triangle.d.ts +0 -11
- package/dist/src/math/Triangle.js +0 -19
- package/dist/src/math/Vec2.d.ts +0 -13
- package/dist/src/math/Vec2.js +0 -13
- package/dist/src/math/Vec3.d.ts +0 -106
- package/dist/src/math/Vec3.js +0 -174
- package/dist/src/math/lib.d.ts +0 -7
- package/dist/src/math/lib.js +0 -7
- package/dist/src/math/rounding.d.ts +0 -4
- package/dist/src/math/rounding.js +0 -128
- package/dist/src/rendering/Display.d.ts +0 -75
- package/dist/src/rendering/Display.js +0 -207
- package/dist/src/rendering/RenderingStyle.d.ts +0 -31
- package/dist/src/rendering/RenderingStyle.js +0 -38
- package/dist/src/rendering/TextRenderingStyle.d.ts +0 -36
- package/dist/src/rendering/TextRenderingStyle.js +0 -23
- package/dist/src/rendering/caching/CacheRecord.d.ts +0 -20
- package/dist/src/rendering/caching/CacheRecord.js +0 -55
- package/dist/src/rendering/caching/CacheRecordManager.d.ts +0 -12
- package/dist/src/rendering/caching/CacheRecordManager.js +0 -43
- package/dist/src/rendering/caching/RenderingCache.d.ts +0 -11
- package/dist/src/rendering/caching/RenderingCache.js +0 -45
- package/dist/src/rendering/caching/RenderingCacheNode.d.ts +0 -29
- package/dist/src/rendering/caching/RenderingCacheNode.js +0 -320
- package/dist/src/rendering/caching/testUtils.d.ts +0 -9
- package/dist/src/rendering/caching/testUtils.js +0 -20
- package/dist/src/rendering/caching/types.d.ts +0 -19
- package/dist/src/rendering/caching/types.js +0 -1
- package/dist/src/rendering/lib.d.ts +0 -5
- package/dist/src/rendering/lib.js +0 -5
- package/dist/src/rendering/localization.d.ts +0 -10
- package/dist/src/rendering/localization.js +0 -9
- package/dist/src/rendering/renderers/AbstractRenderer.d.ts +0 -68
- package/dist/src/rendering/renderers/AbstractRenderer.js +0 -144
- package/dist/src/rendering/renderers/CanvasRenderer.d.ts +0 -63
- package/dist/src/rendering/renderers/CanvasRenderer.js +0 -230
- package/dist/src/rendering/renderers/DummyRenderer.d.ts +0 -35
- package/dist/src/rendering/renderers/DummyRenderer.js +0 -106
- package/dist/src/rendering/renderers/SVGRenderer.d.ts +0 -57
- package/dist/src/rendering/renderers/SVGRenderer.js +0 -304
- package/dist/src/rendering/renderers/TextOnlyRenderer.d.ts +0 -29
- package/dist/src/rendering/renderers/TextOnlyRenderer.js +0 -57
- package/dist/src/testing/beforeEachFile.d.ts +0 -1
- package/dist/src/testing/beforeEachFile.js +0 -7
- package/dist/src/testing/createEditor.d.ts +0 -4
- package/dist/src/testing/createEditor.js +0 -9
- package/dist/src/testing/lib.d.ts +0 -2
- package/dist/src/testing/lib.js +0 -2
- package/dist/src/testing/loadExpectExtensions.d.ts +0 -2
- package/dist/src/testing/loadExpectExtensions.js +0 -24
- package/dist/src/testing/sendPenEvent.d.ts +0 -12
- package/dist/src/testing/sendPenEvent.js +0 -19
- package/dist/src/testing/sendTouchEvent.d.ts +0 -42
- package/dist/src/testing/sendTouchEvent.js +0 -62
- package/dist/src/toolbar/HTMLToolbar.d.ts +0 -103
- package/dist/src/toolbar/HTMLToolbar.js +0 -376
- package/dist/src/toolbar/IconProvider.d.ts +0 -62
- package/dist/src/toolbar/IconProvider.js +0 -654
- package/dist/src/toolbar/lib.d.ts +0 -3
- package/dist/src/toolbar/lib.js +0 -3
- package/dist/src/toolbar/localization.d.ts +0 -49
- package/dist/src/toolbar/localization.js +0 -48
- package/dist/src/toolbar/makeColorInput.d.ts +0 -6
- package/dist/src/toolbar/makeColorInput.js +0 -113
- package/dist/src/toolbar/types.d.ts +0 -4
- package/dist/src/toolbar/types.js +0 -1
- package/dist/src/toolbar/widgets/ActionButtonWidget.d.ts +0 -15
- package/dist/src/toolbar/widgets/ActionButtonWidget.js +0 -25
- package/dist/src/toolbar/widgets/BaseToolWidget.d.ts +0 -11
- package/dist/src/toolbar/widgets/BaseToolWidget.js +0 -44
- package/dist/src/toolbar/widgets/BaseWidget.d.ts +0 -72
- package/dist/src/toolbar/widgets/BaseWidget.js +0 -307
- package/dist/src/toolbar/widgets/DocumentPropertiesWidget.d.ts +0 -18
- package/dist/src/toolbar/widgets/DocumentPropertiesWidget.js +0 -120
- package/dist/src/toolbar/widgets/EraserToolWidget.d.ts +0 -17
- package/dist/src/toolbar/widgets/EraserToolWidget.js +0 -57
- package/dist/src/toolbar/widgets/HandToolWidget.d.ts +0 -17
- package/dist/src/toolbar/widgets/HandToolWidget.js +0 -172
- package/dist/src/toolbar/widgets/InsertImageWidget.d.ts +0 -19
- package/dist/src/toolbar/widgets/InsertImageWidget.js +0 -170
- package/dist/src/toolbar/widgets/OverflowWidget.d.ts +0 -25
- package/dist/src/toolbar/widgets/OverflowWidget.js +0 -71
- package/dist/src/toolbar/widgets/PenToolWidget.d.ts +0 -27
- package/dist/src/toolbar/widgets/PenToolWidget.js +0 -220
- package/dist/src/toolbar/widgets/SelectionToolWidget.d.ts +0 -13
- package/dist/src/toolbar/widgets/SelectionToolWidget.js +0 -147
- package/dist/src/toolbar/widgets/TextToolWidget.d.ts +0 -16
- package/dist/src/toolbar/widgets/TextToolWidget.js +0 -109
- package/dist/src/toolbar/widgets/lib.d.ts +0 -10
- package/dist/src/toolbar/widgets/lib.js +0 -10
- package/dist/src/tools/BaseTool.d.ts +0 -22
- package/dist/src/tools/BaseTool.js +0 -63
- package/dist/src/tools/Eraser.d.ts +0 -23
- package/dist/src/tools/Eraser.js +0 -106
- package/dist/src/tools/FindTool.d.ts +0 -21
- package/dist/src/tools/FindTool.js +0 -114
- package/dist/src/tools/PanZoom.d.ts +0 -52
- package/dist/src/tools/PanZoom.js +0 -414
- package/dist/src/tools/PasteHandler.d.ts +0 -23
- package/dist/src/tools/PasteHandler.js +0 -93
- package/dist/src/tools/Pen.d.ts +0 -39
- package/dist/src/tools/Pen.js +0 -173
- package/dist/src/tools/PipetteTool.d.ts +0 -18
- package/dist/src/tools/PipetteTool.js +0 -39
- package/dist/src/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -8
- package/dist/src/tools/SelectionTool/SelectAllShortcutHandler.js +0 -22
- package/dist/src/tools/SelectionTool/Selection.d.ts +0 -64
- package/dist/src/tools/SelectionTool/Selection.js +0 -459
- package/dist/src/tools/SelectionTool/SelectionHandle.d.ts +0 -38
- package/dist/src/tools/SelectionTool/SelectionHandle.js +0 -81
- package/dist/src/tools/SelectionTool/SelectionTool.d.ts +0 -36
- package/dist/src/tools/SelectionTool/SelectionTool.js +0 -398
- package/dist/src/tools/SelectionTool/TransformMode.d.ts +0 -34
- package/dist/src/tools/SelectionTool/TransformMode.js +0 -98
- package/dist/src/tools/SelectionTool/types.d.ts +0 -9
- package/dist/src/tools/SelectionTool/types.js +0 -11
- package/dist/src/tools/TextTool.d.ts +0 -33
- package/dist/src/tools/TextTool.js +0 -256
- package/dist/src/tools/ToolController.d.ts +0 -18
- package/dist/src/tools/ToolController.js +0 -158
- package/dist/src/tools/ToolEnabledGroup.d.ts +0 -6
- package/dist/src/tools/ToolEnabledGroup.js +0 -11
- package/dist/src/tools/ToolSwitcherShortcut.d.ts +0 -16
- package/dist/src/tools/ToolSwitcherShortcut.js +0 -32
- package/dist/src/tools/ToolbarShortcutHandler.d.ts +0 -12
- package/dist/src/tools/ToolbarShortcutHandler.js +0 -23
- package/dist/src/tools/UndoRedoShortcut.d.ts +0 -8
- package/dist/src/tools/UndoRedoShortcut.js +0 -22
- package/dist/src/tools/lib.d.ts +0 -16
- package/dist/src/tools/lib.js +0 -16
- package/dist/src/tools/localization.d.ts +0 -28
- package/dist/src/tools/localization.js +0 -27
- package/dist/src/types.d.ts +0 -151
- package/dist/src/types.js +0 -35
- package/dist/src/util/assertions.d.ts +0 -23
- package/dist/src/util/assertions.js +0 -45
- package/dist/src/util/fileToBase64.d.ts +0 -3
- package/dist/src/util/fileToBase64.js +0 -13
- package/dist/src/util/untilNextAnimationFrame.d.ts +0 -3
- package/dist/src/util/untilNextAnimationFrame.js +0 -7
- package/dist/src/util/waitForTimeout.d.ts +0 -2
- package/dist/src/util/waitForTimeout.js +0 -7
- package/src/Color4.test.ts +0 -40
- package/src/Color4.ts +0 -234
- package/src/Editor.css +0 -86
- package/src/Editor.loadFrom.test.ts +0 -24
- package/src/Editor.toSVG.test.ts +0 -111
- package/src/Editor.ts +0 -1122
- package/src/EditorImage.test.ts +0 -120
- package/src/EditorImage.ts +0 -603
- package/src/EventDispatcher.test.ts +0 -123
- package/src/EventDispatcher.ts +0 -71
- package/src/Pointer.ts +0 -127
- package/src/SVGLoader.test.ts +0 -114
- package/src/SVGLoader.ts +0 -511
- package/src/UndoRedoHistory.test.ts +0 -33
- package/src/UndoRedoHistory.ts +0 -102
- package/src/Viewport.ts +0 -319
- package/src/bundle/bundled.ts +0 -7
- package/src/commands/Command.ts +0 -45
- package/src/commands/Duplicate.ts +0 -48
- package/src/commands/Erase.ts +0 -74
- package/src/commands/SerializableCommand.ts +0 -49
- package/src/commands/UnresolvedCommand.ts +0 -37
- package/src/commands/invertCommand.ts +0 -51
- package/src/commands/lib.ts +0 -16
- package/src/commands/localization.ts +0 -47
- package/src/commands/uniteCommands.test.ts +0 -23
- package/src/commands/uniteCommands.ts +0 -135
- package/src/components/AbstractComponent.transformBy.test.ts +0 -22
- package/src/components/AbstractComponent.ts +0 -364
- package/src/components/ImageBackground.test.ts +0 -35
- package/src/components/ImageBackground.ts +0 -176
- package/src/components/ImageComponent.ts +0 -171
- package/src/components/RestylableComponent.ts +0 -142
- package/src/components/SVGGlobalAttributesObject.ts +0 -81
- package/src/components/Stroke.test.ts +0 -139
- package/src/components/Stroke.ts +0 -245
- package/src/components/TextComponent.test.ts +0 -99
- package/src/components/TextComponent.ts +0 -315
- package/src/components/UnknownSVGObject.test.ts +0 -10
- package/src/components/UnknownSVGObject.ts +0 -60
- package/src/components/builders/ArrowBuilder.ts +0 -107
- package/src/components/builders/FreehandLineBuilder.ts +0 -212
- package/src/components/builders/LineBuilder.ts +0 -77
- package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +0 -454
- package/src/components/builders/RectangleBuilder.ts +0 -74
- package/src/components/builders/types.ts +0 -15
- package/src/components/lib.ts +0 -25
- package/src/components/localization.ts +0 -22
- package/src/components/util/StrokeSmoother.ts +0 -293
- package/src/components/util/describeComponentList.ts +0 -18
- package/src/lib.ts +0 -37
- package/src/localization.ts +0 -34
- package/src/localizations/de.ts +0 -98
- package/src/localizations/en.ts +0 -8
- package/src/localizations/es.ts +0 -74
- package/src/localizations/getLocalizationTable.test.ts +0 -27
- package/src/localizations/getLocalizationTable.ts +0 -55
- package/src/math/LineSegment2.test.ts +0 -99
- package/src/math/LineSegment2.ts +0 -160
- package/src/math/Mat33.test.ts +0 -244
- package/src/math/Mat33.ts +0 -437
- package/src/math/Path.fromString.test.ts +0 -223
- package/src/math/Path.test.ts +0 -198
- package/src/math/Path.toString.test.ts +0 -77
- package/src/math/Path.ts +0 -790
- package/src/math/Rect2.test.ts +0 -204
- package/src/math/Rect2.ts +0 -315
- package/src/math/Triangle.ts +0 -29
- package/src/math/Vec2.test.ts +0 -30
- package/src/math/Vec2.ts +0 -18
- package/src/math/Vec3.test.ts +0 -44
- package/src/math/Vec3.ts +0 -218
- package/src/math/lib.ts +0 -15
- package/src/math/rounding.test.ts +0 -65
- package/src/math/rounding.ts +0 -156
- package/src/rendering/Display.ts +0 -249
- package/src/rendering/RenderingStyle.test.ts +0 -68
- package/src/rendering/RenderingStyle.ts +0 -55
- package/src/rendering/TextRenderingStyle.ts +0 -45
- package/src/rendering/caching/CacheRecord.test.ts +0 -49
- package/src/rendering/caching/CacheRecord.ts +0 -77
- package/src/rendering/caching/CacheRecordManager.ts +0 -71
- package/src/rendering/caching/RenderingCache.test.ts +0 -44
- package/src/rendering/caching/RenderingCache.ts +0 -66
- package/src/rendering/caching/RenderingCacheNode.ts +0 -405
- package/src/rendering/caching/testUtils.ts +0 -35
- package/src/rendering/caching/types.ts +0 -34
- package/src/rendering/lib.ts +0 -6
- package/src/rendering/localization.ts +0 -20
- package/src/rendering/renderers/AbstractRenderer.ts +0 -222
- package/src/rendering/renderers/CanvasRenderer.ts +0 -296
- package/src/rendering/renderers/DummyRenderer.test.ts +0 -42
- package/src/rendering/renderers/DummyRenderer.ts +0 -136
- package/src/rendering/renderers/SVGRenderer.ts +0 -354
- package/src/rendering/renderers/TextOnlyRenderer.ts +0 -70
- package/src/styles.js +0 -7
- package/src/testing/beforeEachFile.ts +0 -8
- package/src/testing/createEditor.ts +0 -11
- package/src/testing/global.d.ts +0 -17
- package/src/testing/lib.ts +0 -3
- package/src/testing/loadExpectExtensions.ts +0 -25
- package/src/testing/sendPenEvent.ts +0 -31
- package/src/testing/sendTouchEvent.ts +0 -78
- package/src/toolbar/HTMLToolbar.ts +0 -492
- package/src/toolbar/IconProvider.ts +0 -736
- package/src/toolbar/lib.ts +0 -4
- package/src/toolbar/localization.ts +0 -106
- package/src/toolbar/makeColorInput.ts +0 -145
- package/src/toolbar/toolbar.css +0 -213
- package/src/toolbar/types.ts +0 -5
- package/src/toolbar/widgets/ActionButtonWidget.ts +0 -39
- package/src/toolbar/widgets/BaseToolWidget.ts +0 -56
- package/src/toolbar/widgets/BaseWidget.ts +0 -377
- package/src/toolbar/widgets/DocumentPropertiesWidget.ts +0 -167
- package/src/toolbar/widgets/EraserToolWidget.ts +0 -85
- package/src/toolbar/widgets/HandToolWidget.ts +0 -250
- package/src/toolbar/widgets/InsertImageWidget.css +0 -44
- package/src/toolbar/widgets/InsertImageWidget.ts +0 -223
- package/src/toolbar/widgets/OverflowWidget.css +0 -27
- package/src/toolbar/widgets/OverflowWidget.ts +0 -92
- package/src/toolbar/widgets/PenToolWidget.ts +0 -288
- package/src/toolbar/widgets/SelectionToolWidget.ts +0 -190
- package/src/toolbar/widgets/TextToolWidget.ts +0 -145
- package/src/toolbar/widgets/lib.ts +0 -13
- package/src/tools/BaseTool.ts +0 -76
- package/src/tools/Eraser.test.ts +0 -103
- package/src/tools/Eraser.ts +0 -139
- package/src/tools/FindTool.css +0 -7
- package/src/tools/FindTool.ts +0 -152
- package/src/tools/PanZoom.test.ts +0 -310
- package/src/tools/PanZoom.ts +0 -520
- package/src/tools/PasteHandler.ts +0 -95
- package/src/tools/Pen.test.ts +0 -194
- package/src/tools/Pen.ts +0 -226
- package/src/tools/PipetteTool.ts +0 -55
- package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +0 -28
- package/src/tools/SelectionTool/Selection.ts +0 -607
- package/src/tools/SelectionTool/SelectionHandle.ts +0 -108
- package/src/tools/SelectionTool/SelectionTool.css +0 -23
- package/src/tools/SelectionTool/SelectionTool.test.ts +0 -261
- package/src/tools/SelectionTool/SelectionTool.ts +0 -480
- package/src/tools/SelectionTool/TransformMode.ts +0 -114
- package/src/tools/SelectionTool/types.ts +0 -11
- package/src/tools/TextTool.ts +0 -326
- package/src/tools/ToolController.ts +0 -178
- package/src/tools/ToolEnabledGroup.ts +0 -14
- package/src/tools/ToolSwitcherShortcut.ts +0 -39
- package/src/tools/ToolbarShortcutHandler.ts +0 -34
- package/src/tools/UndoRedoShortcut.test.ts +0 -56
- package/src/tools/UndoRedoShortcut.ts +0 -25
- package/src/tools/lib.ts +0 -21
- package/src/tools/localization.ts +0 -66
- package/src/types.ts +0 -234
- package/src/util/assertions.ts +0 -55
- package/src/util/fileToBase64.ts +0 -18
- package/src/util/untilNextAnimationFrame.ts +0 -9
- package/src/util/waitForTimeout.ts +0 -9
@@ -1,607 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @internal
|
3
|
-
* @packageDocumentation
|
4
|
-
*/
|
5
|
-
|
6
|
-
import SerializableCommand from '../../commands/SerializableCommand';
|
7
|
-
import Editor from '../../Editor';
|
8
|
-
import Mat33 from '../../math/Mat33';
|
9
|
-
import Rect2 from '../../math/Rect2';
|
10
|
-
import { Point2, Vec2 } from '../../math/Vec2';
|
11
|
-
import Pointer from '../../Pointer';
|
12
|
-
import SelectionHandle, { HandleShape, handleSize } from './SelectionHandle';
|
13
|
-
import { cssPrefix } from './SelectionTool';
|
14
|
-
import AbstractComponent from '../../components/AbstractComponent';
|
15
|
-
import { Mat33Array } from '../../math/Mat33';
|
16
|
-
import { EditorLocalization } from '../../localization';
|
17
|
-
import Viewport from '../../Viewport';
|
18
|
-
import Erase from '../../commands/Erase';
|
19
|
-
import Duplicate from '../../commands/Duplicate';
|
20
|
-
import Command from '../../commands/Command';
|
21
|
-
import { DragTransformer, ResizeTransformer, RotateTransformer } from './TransformMode';
|
22
|
-
import { ResizeMode } from './types';
|
23
|
-
import EditorImage from '../../EditorImage';
|
24
|
-
|
25
|
-
const updateChunkSize = 100;
|
26
|
-
const maxPreviewElemCount = 500;
|
27
|
-
|
28
|
-
// @internal
|
29
|
-
export default class Selection {
|
30
|
-
private handles: SelectionHandle[];
|
31
|
-
private originalRegion: Rect2;
|
32
|
-
|
33
|
-
private transformers;
|
34
|
-
private transform: Mat33 = Mat33.identity;
|
35
|
-
|
36
|
-
private selectedElems: AbstractComponent[] = [];
|
37
|
-
|
38
|
-
private container: HTMLElement;
|
39
|
-
private backgroundElem: HTMLElement;
|
40
|
-
|
41
|
-
private hasParent: boolean = true;
|
42
|
-
|
43
|
-
public constructor(startPoint: Point2, private editor: Editor) {
|
44
|
-
this.originalRegion = new Rect2(startPoint.x, startPoint.y, 0, 0);
|
45
|
-
this.transformers = {
|
46
|
-
drag: new DragTransformer(editor, this),
|
47
|
-
resize: new ResizeTransformer(editor, this),
|
48
|
-
rotate: new RotateTransformer(editor, this),
|
49
|
-
};
|
50
|
-
|
51
|
-
this.container = document.createElement('div');
|
52
|
-
this.backgroundElem = document.createElement('div');
|
53
|
-
this.backgroundElem.classList.add(`${cssPrefix}selection-background`);
|
54
|
-
this.container.appendChild(this.backgroundElem);
|
55
|
-
|
56
|
-
const resizeHorizontalHandle = new SelectionHandle(
|
57
|
-
HandleShape.Square,
|
58
|
-
Vec2.of(1, 0.5),
|
59
|
-
this,
|
60
|
-
(startPoint) => this.transformers.resize.onDragStart(startPoint, ResizeMode.HorizontalOnly),
|
61
|
-
(currentPoint) => this.transformers.resize.onDragUpdate(currentPoint),
|
62
|
-
() => this.transformers.resize.onDragEnd(),
|
63
|
-
);
|
64
|
-
|
65
|
-
const resizeVerticalHandle = new SelectionHandle(
|
66
|
-
HandleShape.Square,
|
67
|
-
Vec2.of(0.5, 1),
|
68
|
-
this,
|
69
|
-
(startPoint) => this.transformers.resize.onDragStart(startPoint, ResizeMode.VerticalOnly),
|
70
|
-
(currentPoint) => this.transformers.resize.onDragUpdate(currentPoint),
|
71
|
-
() => this.transformers.resize.onDragEnd(),
|
72
|
-
);
|
73
|
-
|
74
|
-
const resizeBothHandle = new SelectionHandle(
|
75
|
-
HandleShape.Square,
|
76
|
-
Vec2.of(1, 1),
|
77
|
-
this,
|
78
|
-
(startPoint) => this.transformers.resize.onDragStart(startPoint, ResizeMode.Both),
|
79
|
-
(currentPoint) => this.transformers.resize.onDragUpdate(currentPoint),
|
80
|
-
() => this.transformers.resize.onDragEnd(),
|
81
|
-
);
|
82
|
-
|
83
|
-
const rotationHandle = new SelectionHandle(
|
84
|
-
HandleShape.Circle,
|
85
|
-
Vec2.of(0.5, 0),
|
86
|
-
this,
|
87
|
-
(startPoint) => this.transformers.rotate.onDragStart(startPoint),
|
88
|
-
(currentPoint) => this.transformers.rotate.onDragUpdate(currentPoint),
|
89
|
-
() => this.transformers.rotate.onDragEnd(),
|
90
|
-
);
|
91
|
-
|
92
|
-
this.handles = [
|
93
|
-
resizeBothHandle,
|
94
|
-
resizeHorizontalHandle,
|
95
|
-
resizeVerticalHandle,
|
96
|
-
rotationHandle,
|
97
|
-
];
|
98
|
-
|
99
|
-
for (const handle of this.handles) {
|
100
|
-
handle.addTo(this.backgroundElem);
|
101
|
-
}
|
102
|
-
}
|
103
|
-
|
104
|
-
// @internal Intended for unit tests
|
105
|
-
public getBackgroundElem(): HTMLElement {
|
106
|
-
return this.backgroundElem;
|
107
|
-
}
|
108
|
-
|
109
|
-
public getTransform(): Mat33 {
|
110
|
-
return this.transform;
|
111
|
-
}
|
112
|
-
|
113
|
-
public get preTransformRegion(): Rect2 {
|
114
|
-
return this.originalRegion;
|
115
|
-
}
|
116
|
-
|
117
|
-
public get region(): Rect2 {
|
118
|
-
// TODO: This currently assumes that the region rotates about its center.
|
119
|
-
// This may not be true.
|
120
|
-
const rotationMatrix = Mat33.zRotation(this.regionRotation, this.originalRegion.center);
|
121
|
-
const scaleAndTranslateMat = this.transform.rightMul(rotationMatrix.inverse());
|
122
|
-
return this.originalRegion.transformedBoundingBox(scaleAndTranslateMat);
|
123
|
-
}
|
124
|
-
|
125
|
-
/**
|
126
|
-
* Computes and returns the bounding box of the selection without
|
127
|
-
* any additional padding. Computes directly from the elements that are selected.
|
128
|
-
* @internal
|
129
|
-
*/
|
130
|
-
public computeTightBoundingBox() {
|
131
|
-
const bbox = this.selectedElems.reduce((
|
132
|
-
accumulator: Rect2|null, elem: AbstractComponent
|
133
|
-
): Rect2 => {
|
134
|
-
return (accumulator ?? elem.getBBox()).union(elem.getBBox());
|
135
|
-
}, null);
|
136
|
-
|
137
|
-
return bbox ?? Rect2.empty;
|
138
|
-
}
|
139
|
-
|
140
|
-
public get regionRotation(): number {
|
141
|
-
return this.transform.transformVec3(Vec2.unitX).angle();
|
142
|
-
}
|
143
|
-
|
144
|
-
public get preTransformedScreenRegion(): Rect2 {
|
145
|
-
const toScreen = (vec: Point2) => this.editor.viewport.canvasToScreen(vec);
|
146
|
-
return Rect2.fromCorners(
|
147
|
-
toScreen(this.preTransformRegion.topLeft),
|
148
|
-
toScreen(this.preTransformRegion.bottomRight)
|
149
|
-
);
|
150
|
-
}
|
151
|
-
|
152
|
-
public get preTransformedScreenRegionRotation(): number {
|
153
|
-
return this.editor.viewport.getRotationAngle();
|
154
|
-
}
|
155
|
-
|
156
|
-
public get screenRegion(): Rect2 {
|
157
|
-
const toScreen = this.editor.viewport.canvasToScreenTransform;
|
158
|
-
const scaleFactor = this.editor.viewport.getScaleFactor();
|
159
|
-
|
160
|
-
const screenCenter = toScreen.transformVec2(this.region.center);
|
161
|
-
|
162
|
-
return new Rect2(
|
163
|
-
screenCenter.x, screenCenter.y, scaleFactor * this.region.width, scaleFactor * this.region.height
|
164
|
-
).translatedBy(this.region.size.times(-scaleFactor/2));
|
165
|
-
}
|
166
|
-
|
167
|
-
public get screenRegionRotation(): number {
|
168
|
-
return this.regionRotation + this.editor.viewport.getRotationAngle();
|
169
|
-
}
|
170
|
-
|
171
|
-
// Applies, previews, but doesn't finalize the given transformation.
|
172
|
-
public setTransform(transform: Mat33, preview: boolean = true) {
|
173
|
-
this.transform = transform;
|
174
|
-
|
175
|
-
if (preview && this.hasParent) {
|
176
|
-
this.scrollTo();
|
177
|
-
this.previewTransformCmds();
|
178
|
-
}
|
179
|
-
}
|
180
|
-
|
181
|
-
// Applies the current transformation to the selection
|
182
|
-
public finalizeTransform() {
|
183
|
-
const fullTransform = this.transform;
|
184
|
-
const selectedElems = this.selectedElems;
|
185
|
-
|
186
|
-
// Reset for the next drag
|
187
|
-
this.originalRegion = this.originalRegion.transformedBoundingBox(this.transform);
|
188
|
-
this.transform = Mat33.identity;
|
189
|
-
|
190
|
-
// Make the commands undo-able
|
191
|
-
this.editor.dispatch(new Selection.ApplyTransformationCommand(
|
192
|
-
this, selectedElems, fullTransform
|
193
|
-
));
|
194
|
-
}
|
195
|
-
|
196
|
-
static {
|
197
|
-
SerializableCommand.register('selection-tool-transform', (json: any, _editor) => {
|
198
|
-
// The selection box is lost when serializing/deserializing. No need to store box rotation
|
199
|
-
const fullTransform: Mat33 = new Mat33(...(json.transform as Mat33Array));
|
200
|
-
const elemIds: string[] = (json.elems as any[] ?? []);
|
201
|
-
|
202
|
-
return new this.ApplyTransformationCommand(null, elemIds, fullTransform);
|
203
|
-
});
|
204
|
-
}
|
205
|
-
|
206
|
-
private static ApplyTransformationCommand = class extends SerializableCommand {
|
207
|
-
private transformCommands: Command[];
|
208
|
-
private selectedElemIds: string[];
|
209
|
-
|
210
|
-
public constructor(
|
211
|
-
private selection: Selection|null,
|
212
|
-
|
213
|
-
// If a `string[]`, selectedElems is a list of element IDs.
|
214
|
-
selectedElems: AbstractComponent[]|string[],
|
215
|
-
|
216
|
-
// Full transformation used to transform elements.
|
217
|
-
private fullTransform: Mat33,
|
218
|
-
) {
|
219
|
-
super('selection-tool-transform');
|
220
|
-
|
221
|
-
const isIDList = (arr: AbstractComponent[]|string[]): arr is string[] => {
|
222
|
-
return typeof arr[0] === 'string';
|
223
|
-
};
|
224
|
-
|
225
|
-
// If a list of element IDs,
|
226
|
-
if (isIDList(selectedElems)) {
|
227
|
-
this.selectedElemIds = selectedElems as string[];
|
228
|
-
} else {
|
229
|
-
this.selectedElemIds = (selectedElems as AbstractComponent[]).map(elem => elem.getId());
|
230
|
-
this.transformCommands = selectedElems.map(elem => {
|
231
|
-
return elem.transformBy(this.fullTransform);
|
232
|
-
});
|
233
|
-
}
|
234
|
-
}
|
235
|
-
|
236
|
-
private resolveToElems(editor: Editor) {
|
237
|
-
if (this.transformCommands) {
|
238
|
-
return;
|
239
|
-
}
|
240
|
-
|
241
|
-
this.transformCommands = this.selectedElemIds.map(id => {
|
242
|
-
const elem = editor.image.lookupElement(id);
|
243
|
-
|
244
|
-
if (!elem) {
|
245
|
-
throw new Error(`Unable to find element with ID, ${id}.`);
|
246
|
-
}
|
247
|
-
|
248
|
-
return elem.transformBy(this.fullTransform);
|
249
|
-
});
|
250
|
-
}
|
251
|
-
|
252
|
-
public async apply(editor: Editor) {
|
253
|
-
this.resolveToElems(editor);
|
254
|
-
|
255
|
-
this.selection?.setTransform(this.fullTransform, false);
|
256
|
-
this.selection?.updateUI();
|
257
|
-
await editor.asyncApplyCommands(this.transformCommands, updateChunkSize);
|
258
|
-
this.selection?.setTransform(Mat33.identity, false);
|
259
|
-
this.selection?.recomputeRegion();
|
260
|
-
this.selection?.updateUI();
|
261
|
-
}
|
262
|
-
|
263
|
-
public async unapply(editor: Editor) {
|
264
|
-
this.resolveToElems(editor);
|
265
|
-
|
266
|
-
this.selection?.setTransform(this.fullTransform.inverse(), false);
|
267
|
-
this.selection?.updateUI();
|
268
|
-
|
269
|
-
await editor.asyncUnapplyCommands(this.transformCommands, updateChunkSize, true);
|
270
|
-
this.selection?.setTransform(Mat33.identity);
|
271
|
-
this.selection?.recomputeRegion();
|
272
|
-
this.selection?.updateUI();
|
273
|
-
}
|
274
|
-
|
275
|
-
protected serializeToJSON() {
|
276
|
-
return {
|
277
|
-
elems: this.selectedElemIds,
|
278
|
-
transform: this.fullTransform.toArray(),
|
279
|
-
};
|
280
|
-
}
|
281
|
-
|
282
|
-
public description(_editor: Editor, localizationTable: EditorLocalization) {
|
283
|
-
return localizationTable.transformedElements(this.selectedElemIds.length);
|
284
|
-
}
|
285
|
-
};
|
286
|
-
|
287
|
-
// Preview the effects of the current transformation on the selection
|
288
|
-
private previewTransformCmds() {
|
289
|
-
// Don't render what we're moving if it's likely to be slow.
|
290
|
-
if (this.selectedElems.length > maxPreviewElemCount) {
|
291
|
-
this.updateUI();
|
292
|
-
return;
|
293
|
-
}
|
294
|
-
|
295
|
-
const wetInkRenderer = this.editor.display.getWetInkRenderer();
|
296
|
-
wetInkRenderer.clear();
|
297
|
-
wetInkRenderer.pushTransform(this.transform);
|
298
|
-
|
299
|
-
const viewportVisibleRect = this.editor.viewport.visibleRect;
|
300
|
-
const visibleRect = viewportVisibleRect.transformedBoundingBox(this.transform.inverse());
|
301
|
-
|
302
|
-
for (const elem of this.selectedElems) {
|
303
|
-
elem.render(wetInkRenderer, visibleRect);
|
304
|
-
}
|
305
|
-
|
306
|
-
wetInkRenderer.popTransform();
|
307
|
-
|
308
|
-
this.updateUI();
|
309
|
-
}
|
310
|
-
|
311
|
-
// Find the objects corresponding to this in the document,
|
312
|
-
// select them.
|
313
|
-
// Returns false iff nothing was selected.
|
314
|
-
public resolveToObjects(): boolean {
|
315
|
-
let singleItemSelectionMode = false;
|
316
|
-
this.transform = Mat33.identity;
|
317
|
-
|
318
|
-
// Grow the rectangle, if necessary
|
319
|
-
if (this.region.w === 0 || this.region.h === 0) {
|
320
|
-
const padding = this.editor.viewport.visibleRect.maxDimension / 200;
|
321
|
-
this.originalRegion = Rect2.bboxOf(this.region.corners, padding);
|
322
|
-
|
323
|
-
// Only select one item if the rectangle was very small.
|
324
|
-
singleItemSelectionMode = true;
|
325
|
-
}
|
326
|
-
|
327
|
-
this.selectedElems = this.editor.image.getElementsIntersectingRegion(this.region).filter(elem => {
|
328
|
-
return elem.intersectsRect(this.region) && elem.isSelectable();
|
329
|
-
});
|
330
|
-
|
331
|
-
if (singleItemSelectionMode && this.selectedElems.length > 0) {
|
332
|
-
this.selectedElems = [ this.selectedElems[this.selectedElems.length - 1] ];
|
333
|
-
}
|
334
|
-
|
335
|
-
// Find the bounding box of all selected elements.
|
336
|
-
if (!this.recomputeRegion()) {
|
337
|
-
return false;
|
338
|
-
}
|
339
|
-
this.updateUI();
|
340
|
-
|
341
|
-
return true;
|
342
|
-
}
|
343
|
-
|
344
|
-
// Recompute this' region from the selected elements.
|
345
|
-
// Returns false if the selection is empty.
|
346
|
-
public recomputeRegion(): boolean {
|
347
|
-
const newRegion = this.computeTightBoundingBox();
|
348
|
-
|
349
|
-
if (!newRegion) {
|
350
|
-
this.cancelSelection();
|
351
|
-
return false;
|
352
|
-
}
|
353
|
-
|
354
|
-
this.originalRegion = newRegion;
|
355
|
-
|
356
|
-
const minSize = this.getMinCanvasSize();
|
357
|
-
if (this.originalRegion.w < minSize || this.originalRegion.h < minSize) {
|
358
|
-
// Add padding
|
359
|
-
const padding = minSize / 2;
|
360
|
-
this.originalRegion = Rect2.bboxOf(
|
361
|
-
this.originalRegion.corners, padding
|
362
|
-
);
|
363
|
-
}
|
364
|
-
|
365
|
-
return true;
|
366
|
-
}
|
367
|
-
|
368
|
-
public getMinCanvasSize(): number {
|
369
|
-
const canvasHandleSize = handleSize / this.editor.viewport.getScaleFactor();
|
370
|
-
return canvasHandleSize * 2;
|
371
|
-
}
|
372
|
-
|
373
|
-
public getSelectedItemCount() {
|
374
|
-
return this.selectedElems.length;
|
375
|
-
}
|
376
|
-
|
377
|
-
// @internal
|
378
|
-
public updateUI() {
|
379
|
-
// Don't update old selections.
|
380
|
-
if (!this.hasParent) {
|
381
|
-
return;
|
382
|
-
}
|
383
|
-
|
384
|
-
// marginLeft, marginTop: Display relative to the top left of the selection overlay.
|
385
|
-
// left, top don't work for this.
|
386
|
-
this.backgroundElem.style.marginLeft = `${this.screenRegion.topLeft.x}px`;
|
387
|
-
this.backgroundElem.style.marginTop = `${this.screenRegion.topLeft.y}px`;
|
388
|
-
|
389
|
-
this.backgroundElem.style.width = `${this.screenRegion.width}px`;
|
390
|
-
this.backgroundElem.style.height = `${this.screenRegion.height}px`;
|
391
|
-
|
392
|
-
const rotationDeg = this.screenRegionRotation * 180 / Math.PI;
|
393
|
-
this.backgroundElem.style.transform = `rotate(${rotationDeg}deg)`;
|
394
|
-
this.backgroundElem.style.transformOrigin = 'center';
|
395
|
-
|
396
|
-
for (const handle of this.handles) {
|
397
|
-
handle.updatePosition();
|
398
|
-
}
|
399
|
-
}
|
400
|
-
|
401
|
-
// Maps IDs to whether we removed the component from the image
|
402
|
-
private removedFromImage: Record<string, boolean> = {};
|
403
|
-
|
404
|
-
// Add/remove the contents of this' seleciton from the editor.
|
405
|
-
// Used to prevent previewed content from looking like duplicate content
|
406
|
-
// while dragging.
|
407
|
-
//
|
408
|
-
// Does nothing if a large number of elements are selected (and so modifying
|
409
|
-
// the editor image is likely to be slow.)
|
410
|
-
//
|
411
|
-
// If removed from the image, selected elements are drawn as wet ink.
|
412
|
-
private addRemoveSelectionFromImage(inImage: boolean) {
|
413
|
-
// Don't hide elements if doing so will be slow.
|
414
|
-
if (!inImage && this.selectedElems.length > maxPreviewElemCount) {
|
415
|
-
return;
|
416
|
-
}
|
417
|
-
|
418
|
-
for (const elem of this.selectedElems) {
|
419
|
-
const parent = this.editor.image.findParent(elem);
|
420
|
-
|
421
|
-
if (!inImage && parent) {
|
422
|
-
this.removedFromImage[elem.getId()] = true;
|
423
|
-
parent.remove();
|
424
|
-
}
|
425
|
-
// If we're making things visible and the selected object wasn't previously
|
426
|
-
// visible,
|
427
|
-
else if (!parent && this.removedFromImage[elem.getId()]) {
|
428
|
-
EditorImage.addElement(elem).apply(this.editor);
|
429
|
-
|
430
|
-
this.removedFromImage[elem.getId()] = false;
|
431
|
-
delete this.removedFromImage[elem.getId()];
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
// Don't await queueRerender. If we're running in a test, the re-render might never
|
436
|
-
// happen.
|
437
|
-
this.editor.queueRerender().then(() => {
|
438
|
-
if (!inImage) {
|
439
|
-
this.previewTransformCmds();
|
440
|
-
}
|
441
|
-
});
|
442
|
-
}
|
443
|
-
|
444
|
-
private removeDeletedElemsFromSelection() {
|
445
|
-
// Remove any deleted elements from the selection.
|
446
|
-
this.selectedElems = this.selectedElems.filter(elem => {
|
447
|
-
const hasParent = !!this.editor.image.findParent(elem);
|
448
|
-
|
449
|
-
// If we removed the element and haven't added it back yet, don't remove it
|
450
|
-
// from the selection.
|
451
|
-
const weRemoved = this.removedFromImage[elem.getId()];
|
452
|
-
return hasParent || weRemoved;
|
453
|
-
});
|
454
|
-
}
|
455
|
-
|
456
|
-
private targetHandle: SelectionHandle|null = null;
|
457
|
-
private backgroundDragging: boolean = false;
|
458
|
-
public onDragStart(pointer: Pointer, target: EventTarget): boolean {
|
459
|
-
this.removeDeletedElemsFromSelection();
|
460
|
-
this.addRemoveSelectionFromImage(false);
|
461
|
-
|
462
|
-
for (const handle of this.handles) {
|
463
|
-
if (handle.isTarget(target)) {
|
464
|
-
handle.handleDragStart(pointer);
|
465
|
-
this.targetHandle = handle;
|
466
|
-
return true;
|
467
|
-
}
|
468
|
-
}
|
469
|
-
|
470
|
-
if (this.backgroundElem === target) {
|
471
|
-
this.backgroundDragging = true;
|
472
|
-
this.transformers.drag.onDragStart(pointer.canvasPos);
|
473
|
-
return true;
|
474
|
-
}
|
475
|
-
|
476
|
-
return false;
|
477
|
-
}
|
478
|
-
|
479
|
-
public onDragUpdate(pointer: Pointer) {
|
480
|
-
if (this.backgroundDragging) {
|
481
|
-
this.transformers.drag.onDragUpdate(pointer.canvasPos);
|
482
|
-
}
|
483
|
-
|
484
|
-
if (this.targetHandle) {
|
485
|
-
this.targetHandle.handleDragUpdate(pointer);
|
486
|
-
}
|
487
|
-
}
|
488
|
-
|
489
|
-
public onDragEnd() {
|
490
|
-
if (this.backgroundDragging) {
|
491
|
-
this.transformers.drag.onDragEnd();
|
492
|
-
}
|
493
|
-
else if (this.targetHandle) {
|
494
|
-
this.targetHandle.handleDragEnd();
|
495
|
-
}
|
496
|
-
|
497
|
-
this.addRemoveSelectionFromImage(true);
|
498
|
-
|
499
|
-
this.backgroundDragging = false;
|
500
|
-
this.targetHandle = null;
|
501
|
-
this.updateUI();
|
502
|
-
}
|
503
|
-
|
504
|
-
public onDragCancel() {
|
505
|
-
this.backgroundDragging = false;
|
506
|
-
this.targetHandle = null;
|
507
|
-
this.setTransform(Mat33.identity);
|
508
|
-
|
509
|
-
this.addRemoveSelectionFromImage(true);
|
510
|
-
}
|
511
|
-
|
512
|
-
// Scroll the viewport to this. Does not zoom
|
513
|
-
public async scrollTo() {
|
514
|
-
if (this.selectedElems.length === 0) {
|
515
|
-
return;
|
516
|
-
}
|
517
|
-
|
518
|
-
const screenRect = new Rect2(0, 0, this.editor.display.width, this.editor.display.height);
|
519
|
-
if (!screenRect.containsPoint(this.screenRegion.center)) {
|
520
|
-
const closestPoint = screenRect.getClosestPointOnBoundaryTo(this.screenRegion.center);
|
521
|
-
const screenDelta = this.screenRegion.center.minus(closestPoint);
|
522
|
-
const delta = this.editor.viewport.screenToCanvasTransform.transformVec3(screenDelta);
|
523
|
-
await this.editor.dispatchNoAnnounce(
|
524
|
-
Viewport.transformBy(Mat33.translation(delta.times(-1))), false
|
525
|
-
);
|
526
|
-
|
527
|
-
// Re-renders clear wet ink, so we need to re-draw the preview
|
528
|
-
// after the full re-render.
|
529
|
-
await this.editor.queueRerender();
|
530
|
-
this.previewTransformCmds();
|
531
|
-
}
|
532
|
-
}
|
533
|
-
|
534
|
-
public deleteSelectedObjects(): Command {
|
535
|
-
if (this.backgroundDragging || this.targetHandle) {
|
536
|
-
this.onDragEnd();
|
537
|
-
}
|
538
|
-
|
539
|
-
return new Erase(this.selectedElems);
|
540
|
-
}
|
541
|
-
|
542
|
-
public async duplicateSelectedObjects(): Promise<Command> {
|
543
|
-
const wasTransforming = this.backgroundDragging || this.targetHandle;
|
544
|
-
let tmpApplyCommand: Command|null = null;
|
545
|
-
|
546
|
-
if (wasTransforming) {
|
547
|
-
// Don't update the selection's focus when redoing/undoing
|
548
|
-
const selectionToUpdate: Selection|null = null;
|
549
|
-
tmpApplyCommand = new Selection.ApplyTransformationCommand(
|
550
|
-
selectionToUpdate, this.selectedElems, this.transform
|
551
|
-
);
|
552
|
-
|
553
|
-
// Transform to ensure that the duplicates are in the correct location
|
554
|
-
await tmpApplyCommand.apply(this.editor);
|
555
|
-
|
556
|
-
// Show items again
|
557
|
-
this.addRemoveSelectionFromImage(true);
|
558
|
-
}
|
559
|
-
|
560
|
-
const duplicateCommand = new Duplicate(this.selectedElems);
|
561
|
-
|
562
|
-
if (wasTransforming) {
|
563
|
-
// Move the selected objects back to the correct location.
|
564
|
-
await tmpApplyCommand?.unapply(this.editor);
|
565
|
-
this.addRemoveSelectionFromImage(false);
|
566
|
-
|
567
|
-
this.previewTransformCmds();
|
568
|
-
this.updateUI();
|
569
|
-
}
|
570
|
-
|
571
|
-
return duplicateCommand;
|
572
|
-
}
|
573
|
-
|
574
|
-
public addTo(elem: HTMLElement) {
|
575
|
-
if (this.container.parentElement) {
|
576
|
-
this.container.remove();
|
577
|
-
}
|
578
|
-
|
579
|
-
elem.appendChild(this.container);
|
580
|
-
this.hasParent = true;
|
581
|
-
}
|
582
|
-
|
583
|
-
public setToPoint(point: Point2) {
|
584
|
-
this.originalRegion = this.originalRegion.grownToPoint(point);
|
585
|
-
this.updateUI();
|
586
|
-
}
|
587
|
-
|
588
|
-
public cancelSelection() {
|
589
|
-
if (this.container.parentElement) {
|
590
|
-
this.container.remove();
|
591
|
-
}
|
592
|
-
this.originalRegion = Rect2.empty;
|
593
|
-
this.hasParent = false;
|
594
|
-
}
|
595
|
-
|
596
|
-
public setSelectedObjects(objects: AbstractComponent[], bbox: Rect2) {
|
597
|
-
this.addRemoveSelectionFromImage(true);
|
598
|
-
this.originalRegion = bbox;
|
599
|
-
this.selectedElems = objects.filter(object => object.isSelectable());
|
600
|
-
this.updateUI();
|
601
|
-
}
|
602
|
-
|
603
|
-
public getSelectedObjects(): AbstractComponent[] {
|
604
|
-
return this.selectedElems;
|
605
|
-
}
|
606
|
-
}
|
607
|
-
|
@@ -1,108 +0,0 @@
|
|
1
|
-
import { assertUnreachable } from '../../util/assertions';
|
2
|
-
import { Point2, Vec2 } from '../../math/Vec2';
|
3
|
-
import { cssPrefix } from './SelectionTool';
|
4
|
-
import Selection from './Selection';
|
5
|
-
import Pointer from '../../Pointer';
|
6
|
-
|
7
|
-
export enum HandleShape {
|
8
|
-
Circle,
|
9
|
-
Square,
|
10
|
-
}
|
11
|
-
|
12
|
-
export const handleSize = 30;
|
13
|
-
|
14
|
-
// `startPoint` is in screen coordinates
|
15
|
-
export type DragStartCallback = (startPoint: Point2)=>void;
|
16
|
-
export type DragUpdateCallback = (canvasPoint: Point2)=> void;
|
17
|
-
export type DragEndCallback = ()=> void;
|
18
|
-
|
19
|
-
export default class SelectionHandle {
|
20
|
-
private element: HTMLElement;
|
21
|
-
private snapToGrid: boolean;
|
22
|
-
|
23
|
-
// Bounding box in screen coordinates.
|
24
|
-
|
25
|
-
public constructor(
|
26
|
-
readonly shape: HandleShape,
|
27
|
-
private readonly parentSide: Vec2,
|
28
|
-
private readonly parent: Selection,
|
29
|
-
|
30
|
-
private readonly onDragStart: DragStartCallback,
|
31
|
-
private readonly onDragUpdate: DragUpdateCallback,
|
32
|
-
private readonly onDragEnd: DragEndCallback,
|
33
|
-
) {
|
34
|
-
this.element = document.createElement('div');
|
35
|
-
this.element.classList.add(`${cssPrefix}handle`);
|
36
|
-
|
37
|
-
switch (shape) {
|
38
|
-
case HandleShape.Circle:
|
39
|
-
this.element.classList.add(`${cssPrefix}circle`);
|
40
|
-
break;
|
41
|
-
case HandleShape.Square:
|
42
|
-
this.element.classList.add(`${cssPrefix}square`);
|
43
|
-
break;
|
44
|
-
default:
|
45
|
-
assertUnreachable(shape);
|
46
|
-
}
|
47
|
-
|
48
|
-
this.updatePosition();
|
49
|
-
}
|
50
|
-
|
51
|
-
/**
|
52
|
-
* Adds this to `container`, where `conatiner` should be the background/selection
|
53
|
-
* element visible on the screen.
|
54
|
-
*/
|
55
|
-
public addTo(container: HTMLElement) {
|
56
|
-
container.appendChild(this.element);
|
57
|
-
}
|
58
|
-
|
59
|
-
public updatePosition() {
|
60
|
-
const parentRect = this.parent.screenRegion;
|
61
|
-
const size = Vec2.of(handleSize, handleSize);
|
62
|
-
const topLeft = parentRect.size.scale(this.parentSide)
|
63
|
-
// Center
|
64
|
-
.minus(size.times(1/2));
|
65
|
-
|
66
|
-
// Position within the selection box.
|
67
|
-
this.element.style.marginLeft = `${topLeft.x}px`;
|
68
|
-
this.element.style.marginTop = `${topLeft.y}px`;
|
69
|
-
this.element.style.width = `${size.x}px`;
|
70
|
-
this.element.style.height = `${size.y}px`;
|
71
|
-
}
|
72
|
-
|
73
|
-
/**
|
74
|
-
* @returns `true` if the given `EventTarget` matches this.
|
75
|
-
*/
|
76
|
-
public isTarget(target: EventTarget): boolean {
|
77
|
-
return target === this.element;
|
78
|
-
}
|
79
|
-
|
80
|
-
private dragLastPos: Vec2|null = null;
|
81
|
-
public handleDragStart(pointer: Pointer) {
|
82
|
-
this.onDragStart(pointer.canvasPos);
|
83
|
-
this.dragLastPos = pointer.canvasPos;
|
84
|
-
}
|
85
|
-
|
86
|
-
public handleDragUpdate(pointer: Pointer) {
|
87
|
-
if (!this.dragLastPos) {
|
88
|
-
return;
|
89
|
-
}
|
90
|
-
|
91
|
-
this.onDragUpdate(pointer.canvasPos);
|
92
|
-
}
|
93
|
-
|
94
|
-
public handleDragEnd() {
|
95
|
-
if (!this.dragLastPos) {
|
96
|
-
return;
|
97
|
-
}
|
98
|
-
this.onDragEnd();
|
99
|
-
}
|
100
|
-
|
101
|
-
public setSnapToGrid(snap: boolean) {
|
102
|
-
this.snapToGrid = snap;
|
103
|
-
}
|
104
|
-
|
105
|
-
public isSnappingToGrid() {
|
106
|
-
return this.snapToGrid;
|
107
|
-
}
|
108
|
-
}
|