js-draw 0.25.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -20
- package/build-config.json +22 -21
- package/dist/Editor.css +1281 -0
- package/dist/bundle.js +3 -3
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +91 -12
- package/dist/cjs/Editor.js +619 -590
- package/dist/cjs/EditorImage.d.ts +5 -2
- package/dist/cjs/EditorImage.js +258 -297
- package/dist/cjs/EventDispatcher.js +17 -19
- package/dist/cjs/Pointer.d.ts +3 -1
- package/dist/cjs/Pointer.js +41 -44
- package/dist/cjs/SVGLoader.d.ts +7 -1
- package/dist/cjs/SVGLoader.js +373 -474
- package/dist/cjs/UndoRedoHistory.js +28 -40
- package/dist/cjs/Viewport.d.ts +1 -4
- package/dist/cjs/Viewport.js +150 -193
- package/dist/cjs/bundle/bundled.js +4 -1
- package/dist/cjs/commands/Command.js +22 -49
- package/dist/cjs/commands/Duplicate.js +28 -44
- package/dist/cjs/commands/Erase.js +36 -54
- package/dist/cjs/commands/SerializableCommand.js +20 -35
- package/dist/cjs/commands/UnresolvedCommand.js +14 -29
- package/dist/cjs/commands/invertCommand.js +29 -51
- package/dist/cjs/commands/lib.js +9 -6
- package/dist/cjs/commands/localization.d.ts +1 -1
- package/dist/cjs/commands/localization.js +9 -9
- package/dist/cjs/commands/uniteCommands.js +57 -87
- package/dist/cjs/components/AbstractComponent.d.ts +11 -3
- package/dist/cjs/components/AbstractComponent.js +141 -169
- package/dist/cjs/components/BackgroundComponent.d.ts +3 -6
- package/dist/cjs/components/BackgroundComponent.js +124 -149
- package/dist/cjs/components/ImageComponent.d.ts +3 -5
- package/dist/cjs/components/ImageComponent.js +95 -175
- package/dist/cjs/components/RestylableComponent.d.ts +1 -1
- package/dist/cjs/components/RestylableComponent.js +41 -56
- package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +1 -3
- package/dist/cjs/components/SVGGlobalAttributesObject.js +34 -51
- package/dist/cjs/components/Stroke.d.ts +4 -6
- package/dist/cjs/components/Stroke.js +95 -121
- package/dist/cjs/components/TextComponent.d.ts +2 -4
- package/dist/cjs/components/TextComponent.js +189 -234
- package/dist/cjs/components/UnknownSVGObject.d.ts +1 -3
- package/dist/cjs/components/UnknownSVGObject.js +30 -43
- package/dist/cjs/components/builders/ArrowBuilder.d.ts +1 -1
- package/dist/cjs/components/builders/ArrowBuilder.js +43 -42
- package/dist/cjs/components/builders/CircleBuilder.js +43 -43
- package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +3 -2
- package/dist/cjs/components/builders/FreehandLineBuilder.js +73 -86
- package/dist/cjs/components/builders/LineBuilder.d.ts +1 -1
- package/dist/cjs/components/builders/LineBuilder.js +38 -36
- package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
- package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +131 -139
- package/dist/cjs/components/builders/RectangleBuilder.d.ts +1 -1
- package/dist/cjs/components/builders/RectangleBuilder.js +31 -31
- package/dist/cjs/components/builders/types.d.ts +1 -1
- package/dist/cjs/components/lib.d.ts +3 -1
- package/dist/cjs/components/lib.js +10 -7
- package/dist/cjs/components/localization.js +4 -4
- package/dist/cjs/components/util/StrokeSmoother.d.ts +1 -2
- package/dist/cjs/components/util/StrokeSmoother.js +67 -72
- package/dist/cjs/components/util/describeComponentList.d.ts +1 -1
- package/dist/cjs/components/util/describeComponentList.js +4 -5
- package/dist/cjs/dialogs/makeAboutDialog.d.ts +15 -0
- package/dist/cjs/dialogs/makeAboutDialog.js +54 -0
- package/dist/cjs/inputEvents.d.ts +84 -0
- package/dist/cjs/inputEvents.js +40 -0
- package/dist/cjs/lib.d.ts +29 -13
- package/dist/cjs/lib.js +38 -23
- package/dist/cjs/localization.js +19 -18
- package/dist/cjs/localizations/de.js +117 -13
- package/dist/cjs/localizations/en.js +4 -13
- package/dist/cjs/localizations/es.js +62 -23
- package/dist/cjs/localizations/getLocalizationTable.js +15 -13
- package/dist/cjs/rendering/Display.d.ts +1 -2
- package/dist/cjs/rendering/Display.js +70 -83
- package/dist/cjs/rendering/RenderablePathSpec.d.ts +15 -0
- package/dist/cjs/rendering/RenderablePathSpec.js +70 -0
- package/dist/cjs/rendering/RenderingStyle.d.ts +4 -4
- package/dist/cjs/rendering/RenderingStyle.js +18 -28
- package/dist/cjs/rendering/TextRenderingStyle.d.ts +10 -10
- package/dist/cjs/rendering/TextRenderingStyle.js +13 -18
- package/dist/cjs/rendering/caching/CacheRecord.d.ts +1 -2
- package/dist/cjs/rendering/caching/CacheRecord.js +20 -22
- package/dist/cjs/rendering/caching/CacheRecordManager.d.ts +1 -1
- package/dist/cjs/rendering/caching/CacheRecordManager.js +17 -15
- package/dist/cjs/rendering/caching/RenderingCache.js +19 -19
- package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.js +98 -118
- package/dist/cjs/rendering/caching/testUtils.js +24 -23
- package/dist/cjs/rendering/caching/types.d.ts +3 -3
- package/dist/cjs/rendering/lib.js +8 -5
- package/dist/cjs/rendering/localization.js +5 -5
- package/dist/cjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
- package/dist/cjs/rendering/renderers/AbstractRenderer.js +53 -57
- package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
- package/dist/cjs/rendering/renderers/CanvasRenderer.js +91 -106
- package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -4
- package/dist/cjs/rendering/renderers/DummyRenderer.js +56 -76
- package/dist/cjs/rendering/renderers/SVGRenderer.d.ts +5 -5
- package/dist/cjs/rendering/renderers/SVGRenderer.js +194 -176
- package/dist/cjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
- package/dist/cjs/rendering/renderers/TextOnlyRenderer.js +47 -72
- package/dist/cjs/shortcuts/KeyBinding.d.ts +5 -0
- package/dist/cjs/shortcuts/KeyBinding.js +94 -70
- package/dist/cjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
- package/dist/cjs/shortcuts/KeyboardShortcutManager.js +36 -45
- package/dist/cjs/shortcuts/lib.js +5 -2
- package/dist/cjs/testing/createEditor.js +7 -4
- package/dist/cjs/testing/getUniquePointerId.js +4 -5
- package/dist/cjs/testing/lib.js +5 -2
- package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
- package/dist/cjs/testing/sendPenEvent.js +10 -7
- package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
- package/dist/cjs/testing/sendTouchEvent.js +34 -16
- package/dist/cjs/toolbar/AbstractToolbar.d.ts +166 -0
- package/dist/cjs/toolbar/AbstractToolbar.js +410 -0
- package/dist/cjs/toolbar/DropdownToolbar.d.ts +43 -0
- package/dist/cjs/toolbar/DropdownToolbar.js +176 -0
- package/dist/cjs/toolbar/EdgeToolbar.d.ts +47 -0
- package/dist/cjs/toolbar/EdgeToolbar.js +422 -0
- package/dist/cjs/toolbar/IconProvider.d.ts +54 -30
- package/dist/cjs/toolbar/IconProvider.js +652 -224
- package/dist/cjs/toolbar/constants.d.ts +1 -0
- package/dist/cjs/toolbar/constants.js +4 -0
- package/dist/cjs/toolbar/lib.d.ts +4 -2
- package/dist/cjs/toolbar/lib.js +10 -3
- package/dist/cjs/toolbar/localization.d.ts +9 -2
- package/dist/cjs/toolbar/localization.js +26 -19
- package/dist/cjs/toolbar/types.d.ts +7 -0
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
- package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +23 -39
- package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
- package/dist/cjs/toolbar/widgets/BaseToolWidget.js +35 -37
- package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +60 -5
- package/dist/cjs/toolbar/widgets/BaseWidget.js +232 -177
- package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +130 -117
- package/dist/cjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
- package/dist/cjs/toolbar/widgets/EraserToolWidget.js +45 -73
- package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +126 -141
- package/dist/cjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
- package/dist/cjs/toolbar/widgets/InsertImageWidget.js +147 -212
- package/dist/cjs/toolbar/widgets/OverflowWidget.js +33 -61
- package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
- package/dist/cjs/toolbar/widgets/PenToolWidget.js +162 -234
- package/dist/cjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
- package/dist/cjs/toolbar/widgets/SelectionToolWidget.js +105 -177
- package/dist/cjs/toolbar/widgets/TextToolWidget.js +64 -87
- package/dist/cjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
- package/dist/cjs/toolbar/{makeColorInput.js → widgets/components/makeColorInput.js} +57 -34
- package/dist/cjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
- package/dist/cjs/toolbar/widgets/components/makeFileInput.js +111 -0
- package/dist/cjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
- package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +127 -0
- package/dist/cjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
- package/dist/cjs/toolbar/widgets/components/makeSeparator.js +16 -0
- package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
- package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.js +47 -0
- package/dist/cjs/toolbar/widgets/keybindings.js +8 -5
- package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
- package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.js +199 -0
- package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
- package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.js +60 -0
- package/dist/cjs/toolbar/widgets/layout/types.d.ts +63 -0
- package/dist/cjs/toolbar/widgets/layout/types.js +2 -0
- package/dist/cjs/toolbar/widgets/lib.d.ts +1 -1
- package/dist/cjs/toolbar/widgets/lib.js +15 -11
- package/dist/cjs/tools/BaseTool.d.ts +28 -9
- package/dist/cjs/tools/BaseTool.js +128 -51
- package/dist/cjs/tools/Eraser.d.ts +8 -1
- package/dist/cjs/tools/Eraser.js +82 -92
- package/dist/cjs/tools/FindTool.d.ts +1 -1
- package/dist/cjs/tools/FindTool.js +61 -77
- package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
- package/dist/cjs/tools/InputFilter/FunctionMapper.js +21 -0
- package/dist/cjs/tools/InputFilter/InputMapper.d.ts +23 -0
- package/dist/cjs/tools/InputFilter/InputMapper.js +38 -0
- package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +15 -0
- package/dist/cjs/tools/InputFilter/InputPipeline.js +54 -0
- package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
- package/dist/cjs/tools/InputFilter/InputStabilizer.js +181 -0
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +84 -0
- package/dist/cjs/tools/PanZoom.d.ts +4 -2
- package/dist/cjs/tools/PanZoom.js +186 -248
- package/dist/cjs/tools/PasteHandler.d.ts +1 -1
- package/dist/cjs/tools/PasteHandler.js +49 -148
- package/dist/cjs/tools/Pen.d.ts +12 -11
- package/dist/cjs/tools/Pen.js +123 -158
- package/dist/cjs/tools/PipetteTool.d.ts +11 -2
- package/dist/cjs/tools/PipetteTool.js +51 -48
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +15 -30
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +5 -5
- package/dist/cjs/tools/SelectionTool/Selection.js +308 -415
- package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
- package/dist/cjs/tools/SelectionTool/SelectionHandle.js +63 -37
- package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +164 -187
- package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +1 -1
- package/dist/cjs/tools/SelectionTool/TransformMode.js +65 -66
- package/dist/cjs/tools/SoundUITool.d.ts +2 -1
- package/dist/cjs/tools/SoundUITool.js +70 -84
- package/dist/cjs/tools/TextTool.d.ts +5 -3
- package/dist/cjs/tools/TextTool.js +169 -173
- package/dist/cjs/tools/ToolController.d.ts +16 -2
- package/dist/cjs/tools/ToolController.js +124 -100
- package/dist/cjs/tools/ToolEnabledGroup.js +6 -9
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -1
- package/dist/cjs/tools/ToolSwitcherShortcut.js +16 -32
- package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +1 -1
- package/dist/cjs/tools/ToolbarShortcutHandler.js +17 -33
- package/dist/cjs/tools/UndoRedoShortcut.d.ts +1 -1
- package/dist/cjs/tools/UndoRedoShortcut.js +12 -27
- package/dist/cjs/tools/keybindings.js +21 -18
- package/dist/cjs/tools/lib.js +17 -14
- package/dist/cjs/tools/localization.d.ts +2 -1
- package/dist/cjs/tools/localization.js +8 -7
- package/dist/cjs/types.d.ts +22 -80
- package/dist/cjs/types.js +8 -16
- package/dist/cjs/util/ReactiveValue.d.ts +65 -0
- package/dist/cjs/util/ReactiveValue.js +166 -0
- package/dist/cjs/util/assertions.js +5 -8
- package/dist/cjs/util/fileToBase64.js +6 -6
- package/dist/cjs/util/guessKeyCodeFromKey.d.ts +9 -0
- package/dist/cjs/util/guessKeyCodeFromKey.js +32 -0
- package/dist/cjs/util/listPrefixMatch.d.ts +6 -0
- package/dist/cjs/util/listPrefixMatch.js +17 -0
- package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
- package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.js +17 -0
- package/dist/cjs/util/untilNextAnimationFrame.js +3 -3
- package/dist/cjs/util/waitForAll.js +3 -3
- package/dist/cjs/util/waitForTimeout.js +3 -3
- package/dist/cjs/version.d.ts +4 -0
- package/dist/cjs/version.js +5 -0
- package/dist/mjs/Editor.d.ts +91 -12
- package/dist/mjs/Editor.mjs +565 -563
- package/dist/mjs/EditorImage.d.ts +5 -2
- package/dist/mjs/EditorImage.mjs +248 -291
- package/dist/mjs/EventDispatcher.mjs +17 -20
- package/dist/mjs/Pointer.d.ts +3 -1
- package/dist/mjs/Pointer.mjs +40 -44
- package/dist/mjs/SVGLoader.d.ts +7 -1
- package/dist/mjs/SVGLoader.mjs +338 -466
- package/dist/mjs/UndoRedoHistory.mjs +27 -39
- package/dist/mjs/Viewport.d.ts +1 -4
- package/dist/mjs/Viewport.mjs +139 -187
- package/dist/mjs/commands/Command.mjs +21 -49
- package/dist/mjs/commands/Duplicate.mjs +22 -41
- package/dist/mjs/commands/Erase.mjs +30 -51
- package/dist/mjs/commands/SerializableCommand.mjs +16 -34
- package/dist/mjs/commands/UnresolvedCommand.mjs +10 -29
- package/dist/mjs/commands/invertCommand.mjs +24 -49
- package/dist/mjs/commands/localization.d.ts +1 -1
- package/dist/mjs/commands/localization.mjs +10 -10
- package/dist/mjs/commands/uniteCommands.mjs +52 -85
- package/dist/mjs/components/AbstractComponent.d.ts +11 -3
- package/dist/mjs/components/AbstractComponent.mjs +135 -166
- package/dist/mjs/components/BackgroundComponent.d.ts +3 -6
- package/dist/mjs/components/BackgroundComponent.mjs +107 -136
- package/dist/mjs/components/ImageComponent.d.ts +3 -5
- package/dist/mjs/components/ImageComponent.mjs +90 -174
- package/dist/mjs/components/RestylableComponent.d.ts +1 -1
- package/dist/mjs/components/RestylableComponent.mjs +35 -53
- package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +1 -3
- package/dist/mjs/components/SVGGlobalAttributesObject.mjs +29 -50
- package/dist/mjs/components/Stroke.d.ts +4 -6
- package/dist/mjs/components/Stroke.mjs +89 -119
- package/dist/mjs/components/TextComponent.d.ts +2 -4
- package/dist/mjs/components/TextComponent.mjs +180 -228
- package/dist/mjs/components/UnknownSVGObject.d.ts +1 -3
- package/dist/mjs/components/UnknownSVGObject.mjs +26 -43
- package/dist/mjs/components/builders/ArrowBuilder.d.ts +1 -1
- package/dist/mjs/components/builders/ArrowBuilder.mjs +32 -35
- package/dist/mjs/components/builders/CircleBuilder.mjs +35 -38
- package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +3 -2
- package/dist/mjs/components/builders/FreehandLineBuilder.mjs +52 -69
- package/dist/mjs/components/builders/LineBuilder.d.ts +1 -1
- package/dist/mjs/components/builders/LineBuilder.mjs +30 -32
- package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
- package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +103 -115
- package/dist/mjs/components/builders/RectangleBuilder.d.ts +1 -1
- package/dist/mjs/components/builders/RectangleBuilder.mjs +27 -31
- package/dist/mjs/components/builders/types.d.ts +1 -1
- package/dist/mjs/components/lib.d.ts +3 -1
- package/dist/mjs/components/lib.mjs +1 -1
- package/dist/mjs/components/localization.mjs +5 -5
- package/dist/mjs/components/util/StrokeSmoother.d.ts +1 -2
- package/dist/mjs/components/util/StrokeSmoother.mjs +63 -69
- package/dist/mjs/components/util/describeComponentList.d.ts +1 -1
- package/dist/mjs/components/util/describeComponentList.mjs +4 -5
- package/dist/mjs/dialogs/makeAboutDialog.d.ts +15 -0
- package/dist/mjs/dialogs/makeAboutDialog.mjs +52 -0
- package/dist/mjs/inputEvents.d.ts +84 -0
- package/dist/mjs/inputEvents.mjs +34 -0
- package/dist/mjs/lib.d.ts +29 -13
- package/dist/mjs/lib.mjs +30 -13
- package/dist/mjs/localization.mjs +14 -13
- package/dist/mjs/localizations/de.mjs +116 -12
- package/dist/mjs/localizations/en.mjs +3 -12
- package/dist/mjs/localizations/es.mjs +61 -22
- package/dist/mjs/localizations/getLocalizationTable.mjs +12 -13
- package/dist/mjs/rendering/Display.d.ts +1 -2
- package/dist/mjs/rendering/Display.mjs +62 -79
- package/dist/mjs/rendering/RenderablePathSpec.d.ts +15 -0
- package/dist/mjs/rendering/RenderablePathSpec.mjs +64 -0
- package/dist/mjs/rendering/RenderingStyle.d.ts +4 -4
- package/dist/mjs/rendering/RenderingStyle.mjs +16 -26
- package/dist/mjs/rendering/TextRenderingStyle.d.ts +10 -10
- package/dist/mjs/rendering/TextRenderingStyle.mjs +12 -17
- package/dist/mjs/rendering/caching/CacheRecord.d.ts +1 -2
- package/dist/mjs/rendering/caching/CacheRecord.mjs +20 -23
- package/dist/mjs/rendering/caching/CacheRecordManager.d.ts +1 -1
- package/dist/mjs/rendering/caching/CacheRecordManager.mjs +13 -15
- package/dist/mjs/rendering/caching/RenderingCache.mjs +13 -17
- package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +94 -115
- package/dist/mjs/rendering/caching/testUtils.mjs +19 -21
- package/dist/mjs/rendering/caching/types.d.ts +3 -3
- package/dist/mjs/rendering/localization.mjs +6 -6
- package/dist/mjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
- package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +47 -52
- package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
- package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +84 -103
- package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -4
- package/dist/mjs/rendering/renderers/DummyRenderer.mjs +51 -75
- package/dist/mjs/rendering/renderers/SVGRenderer.d.ts +5 -5
- package/dist/mjs/rendering/renderers/SVGRenderer.mjs +185 -171
- package/dist/mjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
- package/dist/mjs/rendering/renderers/TextOnlyRenderer.mjs +43 -72
- package/dist/mjs/shortcuts/KeyBinding.d.ts +5 -0
- package/dist/mjs/shortcuts/KeyBinding.mjs +94 -71
- package/dist/mjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
- package/dist/mjs/shortcuts/KeyboardShortcutManager.mjs +32 -44
- package/dist/mjs/testing/createEditor.mjs +2 -2
- package/dist/mjs/testing/getUniquePointerId.mjs +4 -5
- package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
- package/dist/mjs/testing/sendPenEvent.mjs +5 -5
- package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
- package/dist/mjs/testing/sendTouchEvent.mjs +8 -16
- package/dist/mjs/toolbar/AbstractToolbar.d.ts +166 -0
- package/dist/mjs/toolbar/AbstractToolbar.mjs +405 -0
- package/dist/mjs/toolbar/DropdownToolbar.d.ts +43 -0
- package/dist/mjs/toolbar/DropdownToolbar.mjs +168 -0
- package/dist/mjs/toolbar/EdgeToolbar.d.ts +47 -0
- package/dist/mjs/toolbar/EdgeToolbar.mjs +414 -0
- package/dist/mjs/toolbar/IconProvider.d.ts +54 -30
- package/dist/mjs/toolbar/IconProvider.mjs +644 -219
- package/dist/mjs/toolbar/constants.d.ts +1 -0
- package/dist/mjs/toolbar/constants.mjs +1 -0
- package/dist/mjs/toolbar/lib.d.ts +4 -2
- package/dist/mjs/toolbar/lib.mjs +3 -1
- package/dist/mjs/toolbar/localization.d.ts +9 -2
- package/dist/mjs/toolbar/localization.mjs +27 -20
- package/dist/mjs/toolbar/types.d.ts +7 -0
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
- package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +19 -39
- package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
- package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +30 -36
- package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +60 -5
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +227 -176
- package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +98 -111
- package/dist/mjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
- package/dist/mjs/toolbar/widgets/EraserToolWidget.mjs +41 -73
- package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +94 -136
- package/dist/mjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
- package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +140 -208
- package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +30 -62
- package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
- package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +150 -225
- package/dist/mjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
- package/dist/mjs/toolbar/widgets/SelectionToolWidget.mjs +97 -173
- package/dist/mjs/toolbar/widgets/TextToolWidget.mjs +59 -85
- package/dist/mjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
- package/dist/mjs/toolbar/{makeColorInput.mjs → widgets/components/makeColorInput.mjs} +53 -33
- package/dist/mjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
- package/dist/mjs/toolbar/widgets/components/makeFileInput.mjs +106 -0
- package/dist/mjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
- package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +122 -0
- package/dist/mjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
- package/dist/mjs/toolbar/widgets/components/makeSeparator.mjs +14 -0
- package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
- package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.mjs +45 -0
- package/dist/mjs/toolbar/widgets/keybindings.mjs +5 -5
- package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
- package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.mjs +193 -0
- package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
- package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.mjs +57 -0
- package/dist/mjs/toolbar/widgets/layout/types.d.ts +63 -0
- package/dist/mjs/toolbar/widgets/lib.d.ts +1 -1
- package/dist/mjs/toolbar/widgets/lib.mjs +1 -1
- package/dist/mjs/tools/BaseTool.d.ts +28 -9
- package/dist/mjs/tools/BaseTool.mjs +127 -50
- package/dist/mjs/tools/Eraser.d.ts +8 -1
- package/dist/mjs/tools/Eraser.mjs +72 -86
- package/dist/mjs/tools/FindTool.d.ts +1 -1
- package/dist/mjs/tools/FindTool.mjs +55 -75
- package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
- package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +15 -0
- package/dist/mjs/tools/InputFilter/InputMapper.d.ts +23 -0
- package/dist/mjs/tools/InputFilter/InputMapper.mjs +36 -0
- package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +15 -0
- package/dist/mjs/tools/InputFilter/InputPipeline.mjs +49 -0
- package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
- package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +175 -0
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +78 -0
- package/dist/mjs/tools/PanZoom.d.ts +4 -2
- package/dist/mjs/tools/PanZoom.mjs +169 -235
- package/dist/mjs/tools/PasteHandler.d.ts +1 -1
- package/dist/mjs/tools/PasteHandler.mjs +42 -145
- package/dist/mjs/tools/Pen.d.ts +12 -11
- package/dist/mjs/tools/Pen.mjs +115 -154
- package/dist/mjs/tools/PipetteTool.d.ts +11 -2
- package/dist/mjs/tools/PipetteTool.mjs +47 -48
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +9 -28
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +5 -5
- package/dist/mjs/tools/SelectionTool/Selection.mjs +268 -401
- package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
- package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +62 -37
- package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +153 -179
- package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +1 -1
- package/dist/mjs/tools/SelectionTool/TransformMode.mjs +52 -59
- package/dist/mjs/tools/SoundUITool.d.ts +2 -1
- package/dist/mjs/tools/SoundUITool.mjs +66 -84
- package/dist/mjs/tools/TextTool.d.ts +5 -3
- package/dist/mjs/tools/TextTool.mjs +155 -163
- package/dist/mjs/tools/ToolController.d.ts +16 -2
- package/dist/mjs/tools/ToolController.mjs +81 -84
- package/dist/mjs/tools/ToolEnabledGroup.mjs +6 -10
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -1
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +12 -32
- package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +1 -1
- package/dist/mjs/tools/ToolbarShortcutHandler.mjs +13 -33
- package/dist/mjs/tools/UndoRedoShortcut.d.ts +1 -1
- package/dist/mjs/tools/UndoRedoShortcut.mjs +7 -26
- package/dist/mjs/tools/keybindings.mjs +34 -34
- package/dist/mjs/tools/localization.d.ts +2 -1
- package/dist/mjs/tools/localization.mjs +9 -8
- package/dist/mjs/types.d.ts +22 -80
- package/dist/mjs/types.mjs +7 -15
- package/dist/mjs/util/ReactiveValue.d.ts +65 -0
- package/dist/mjs/util/ReactiveValue.mjs +161 -0
- package/dist/mjs/util/assertions.mjs +5 -8
- package/dist/mjs/util/fileToBase64.mjs +6 -6
- package/dist/mjs/util/guessKeyCodeFromKey.d.ts +9 -0
- package/dist/mjs/util/guessKeyCodeFromKey.mjs +30 -0
- package/dist/mjs/util/listPrefixMatch.d.ts +6 -0
- package/dist/mjs/util/listPrefixMatch.mjs +15 -0
- package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
- package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.mjs +15 -0
- package/dist/mjs/util/untilNextAnimationFrame.mjs +3 -3
- package/dist/mjs/util/waitForAll.mjs +3 -3
- package/dist/mjs/util/waitForTimeout.mjs +3 -3
- package/dist/mjs/version.d.ts +4 -0
- package/dist/mjs/version.mjs +3 -0
- package/package.json +11 -22
- package/src/Coloris.css +8 -8
- package/src/Editor.scss +148 -0
- package/src/dialogs/dialogs.scss +36 -0
- package/src/dialogs/makeAboutDialog.scss +41 -0
- package/src/styles.js +1 -1
- package/src/toolbar/{toolbar.css → AbstractToolbar.scss} +47 -85
- package/src/toolbar/DropdownToolbar.scss +46 -0
- package/src/toolbar/EdgeToolbar.scss +511 -0
- package/src/toolbar/toolbar.scss +11 -0
- package/src/toolbar/widgets/DocumentPropertiesWidget.scss +7 -0
- package/src/toolbar/widgets/HandToolWidget.scss +14 -0
- package/src/toolbar/widgets/InsertImageWidget.scss +41 -0
- package/src/toolbar/widgets/PenToolWidget.css +0 -51
- package/src/toolbar/widgets/SelectionToolWidget.scss +6 -0
- package/src/toolbar/widgets/components/components.scss +5 -0
- package/src/toolbar/widgets/components/makeColorInput.scss +82 -0
- package/src/toolbar/widgets/components/makeFileInput.scss +77 -0
- package/src/toolbar/widgets/components/makeGridSelector.scss +60 -0
- package/src/toolbar/widgets/components/makeSeparator.scss +14 -0
- package/src/toolbar/widgets/components/makeThicknessSlider.scss +9 -0
- package/src/tools/FindTool.css +3 -3
- package/src/tools/SelectionTool/SelectionTool.css +23 -11
- package/src/tools/tools.scss +4 -0
- package/tsconfig.json +1 -1
- package/typedoc.json +4 -0
- package/dist/cjs/Color4.d.ts +0 -69
- package/dist/cjs/Color4.js +0 -263
- package/dist/cjs/Editor.loadFrom.test.d.ts +0 -1
- package/dist/cjs/Editor.toSVG.test.d.ts +0 -1
- package/dist/cjs/EditorImage.test.d.ts +0 -1
- package/dist/cjs/EventDispatcher.test.d.ts +0 -1
- package/dist/cjs/SVGLoader.test.d.ts +0 -1
- package/dist/cjs/UndoRedoHistory.test.d.ts +0 -1
- package/dist/cjs/commands/uniteCommands.test.d.ts +0 -1
- package/dist/cjs/components/AbstractComponent.transformBy.test.d.ts +0 -1
- package/dist/cjs/components/BackgroundComponent.test.d.ts +0 -1
- package/dist/cjs/components/Stroke.test.d.ts +0 -1
- package/dist/cjs/components/TextComponent.test.d.ts +0 -1
- package/dist/cjs/components/UnknownSVGObject.test.d.ts +0 -1
- package/dist/cjs/components/builders/FreehandLineBuilder.test.d.ts +0 -1
- package/dist/cjs/localizations/getLocalizationTable.test.d.ts +0 -1
- package/dist/cjs/math/Mat33.d.ts +0 -123
- package/dist/cjs/math/Mat33.js +0 -340
- package/dist/cjs/math/Mat33.test.d.ts +0 -1
- package/dist/cjs/math/Vec2.d.ts +0 -33
- package/dist/cjs/math/Vec2.js +0 -37
- package/dist/cjs/math/Vec2.test.d.ts +0 -1
- package/dist/cjs/math/Vec3.d.ts +0 -106
- package/dist/cjs/math/Vec3.js +0 -183
- package/dist/cjs/math/Vec3.test.d.ts +0 -1
- package/dist/cjs/math/lib.d.ts +0 -7
- package/dist/cjs/math/lib.js +0 -15
- package/dist/cjs/math/polynomial/solveQuadratic.d.ts +0 -9
- package/dist/cjs/math/polynomial/solveQuadratic.js +0 -39
- package/dist/cjs/math/polynomial/solveQuadratic.test.d.ts +0 -1
- package/dist/cjs/math/rounding.d.ts +0 -4
- package/dist/cjs/math/rounding.js +0 -140
- package/dist/cjs/math/rounding.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Abstract2DShape.d.ts +0 -49
- package/dist/cjs/math/shapes/Abstract2DShape.js +0 -42
- package/dist/cjs/math/shapes/BezierJSWrapper.d.ts +0 -36
- package/dist/cjs/math/shapes/BezierJSWrapper.js +0 -109
- package/dist/cjs/math/shapes/CubicBezier.d.ts +0 -17
- package/dist/cjs/math/shapes/CubicBezier.js +0 -50
- package/dist/cjs/math/shapes/LineSegment2.d.ts +0 -70
- package/dist/cjs/math/shapes/LineSegment2.js +0 -204
- package/dist/cjs/math/shapes/LineSegment2.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Path.d.ts +0 -93
- package/dist/cjs/math/shapes/Path.fromString.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Path.js +0 -865
- package/dist/cjs/math/shapes/Path.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Path.toString.test.d.ts +0 -1
- package/dist/cjs/math/shapes/PointShape2D.d.ts +0 -18
- package/dist/cjs/math/shapes/PointShape2D.js +0 -46
- package/dist/cjs/math/shapes/QuadraticBezier.d.ts +0 -34
- package/dist/cjs/math/shapes/QuadraticBezier.js +0 -133
- package/dist/cjs/math/shapes/QuadraticBezier.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Rect2.d.ts +0 -57
- package/dist/cjs/math/shapes/Rect2.js +0 -311
- package/dist/cjs/math/shapes/Rect2.test.d.ts +0 -1
- package/dist/cjs/math/shapes/Triangle.d.ts +0 -46
- package/dist/cjs/math/shapes/Triangle.js +0 -148
- package/dist/cjs/math/shapes/Triangle.test.d.ts +0 -1
- package/dist/cjs/rendering/RenderingStyle.test.d.ts +0 -1
- package/dist/cjs/rendering/caching/CacheRecord.test.d.ts +0 -1
- package/dist/cjs/rendering/caching/RenderingCache.test.d.ts +0 -1
- package/dist/cjs/rendering/renderers/DummyRenderer.test.d.ts +0 -1
- package/dist/cjs/rendering/renderers/TextOnlyRenderer.test.d.ts +0 -1
- package/dist/cjs/shortcuts/KeyBinding.test.d.ts +0 -1
- package/dist/cjs/shortcuts/KeyboardShortcutManager.test.d.ts +0 -1
- package/dist/cjs/toolbar/HTMLToolbar.d.ts +0 -105
- package/dist/cjs/toolbar/HTMLToolbar.js +0 -465
- package/dist/cjs/toolbar/makeColorInput.d.ts +0 -6
- package/dist/cjs/tools/Eraser.test.d.ts +0 -1
- package/dist/cjs/tools/PanZoom.test.d.ts +0 -1
- package/dist/cjs/tools/Pen.test.d.ts +0 -1
- package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
- package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +0 -1
- package/dist/mjs/Color4.d.ts +0 -69
- package/dist/mjs/Color4.mjs +0 -260
- package/dist/mjs/Color4.test.d.ts +0 -1
- package/dist/mjs/Editor.loadFrom.test.d.ts +0 -1
- package/dist/mjs/Editor.toSVG.test.d.ts +0 -1
- package/dist/mjs/EditorImage.test.d.ts +0 -1
- package/dist/mjs/EventDispatcher.test.d.ts +0 -1
- package/dist/mjs/SVGLoader.test.d.ts +0 -1
- package/dist/mjs/UndoRedoHistory.test.d.ts +0 -1
- package/dist/mjs/commands/uniteCommands.test.d.ts +0 -1
- package/dist/mjs/components/AbstractComponent.transformBy.test.d.ts +0 -1
- package/dist/mjs/components/BackgroundComponent.test.d.ts +0 -1
- package/dist/mjs/components/Stroke.test.d.ts +0 -1
- package/dist/mjs/components/TextComponent.test.d.ts +0 -1
- package/dist/mjs/components/UnknownSVGObject.test.d.ts +0 -1
- package/dist/mjs/components/builders/FreehandLineBuilder.test.d.ts +0 -1
- package/dist/mjs/localizations/getLocalizationTable.test.d.ts +0 -1
- package/dist/mjs/math/Mat33.d.ts +0 -123
- package/dist/mjs/math/Mat33.mjs +0 -338
- package/dist/mjs/math/Mat33.test.d.ts +0 -1
- package/dist/mjs/math/Vec2.d.ts +0 -33
- package/dist/mjs/math/Vec2.mjs +0 -34
- package/dist/mjs/math/Vec2.test.d.ts +0 -1
- package/dist/mjs/math/Vec3.d.ts +0 -106
- package/dist/mjs/math/Vec3.mjs +0 -181
- package/dist/mjs/math/Vec3.test.d.ts +0 -1
- package/dist/mjs/math/lib.d.ts +0 -7
- package/dist/mjs/math/lib.mjs +0 -7
- package/dist/mjs/math/polynomial/solveQuadratic.d.ts +0 -9
- package/dist/mjs/math/polynomial/solveQuadratic.mjs +0 -37
- package/dist/mjs/math/polynomial/solveQuadratic.test.d.ts +0 -1
- package/dist/mjs/math/rounding.d.ts +0 -4
- package/dist/mjs/math/rounding.mjs +0 -133
- package/dist/mjs/math/rounding.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Abstract2DShape.d.ts +0 -49
- package/dist/mjs/math/shapes/Abstract2DShape.mjs +0 -40
- package/dist/mjs/math/shapes/BezierJSWrapper.d.ts +0 -36
- package/dist/mjs/math/shapes/BezierJSWrapper.mjs +0 -107
- package/dist/mjs/math/shapes/CubicBezier.d.ts +0 -17
- package/dist/mjs/math/shapes/CubicBezier.mjs +0 -48
- package/dist/mjs/math/shapes/LineSegment2.d.ts +0 -70
- package/dist/mjs/math/shapes/LineSegment2.mjs +0 -202
- package/dist/mjs/math/shapes/LineSegment2.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Path.d.ts +0 -93
- package/dist/mjs/math/shapes/Path.fromString.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Path.mjs +0 -862
- package/dist/mjs/math/shapes/Path.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Path.toString.test.d.ts +0 -1
- package/dist/mjs/math/shapes/PointShape2D.d.ts +0 -18
- package/dist/mjs/math/shapes/PointShape2D.mjs +0 -44
- package/dist/mjs/math/shapes/QuadraticBezier.d.ts +0 -34
- package/dist/mjs/math/shapes/QuadraticBezier.mjs +0 -131
- package/dist/mjs/math/shapes/QuadraticBezier.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Rect2.d.ts +0 -57
- package/dist/mjs/math/shapes/Rect2.mjs +0 -309
- package/dist/mjs/math/shapes/Rect2.test.d.ts +0 -1
- package/dist/mjs/math/shapes/Triangle.d.ts +0 -46
- package/dist/mjs/math/shapes/Triangle.mjs +0 -146
- package/dist/mjs/math/shapes/Triangle.test.d.ts +0 -1
- package/dist/mjs/rendering/RenderingStyle.test.d.ts +0 -1
- package/dist/mjs/rendering/caching/CacheRecord.test.d.ts +0 -1
- package/dist/mjs/rendering/caching/RenderingCache.test.d.ts +0 -1
- package/dist/mjs/rendering/renderers/DummyRenderer.test.d.ts +0 -1
- package/dist/mjs/rendering/renderers/TextOnlyRenderer.test.d.ts +0 -1
- package/dist/mjs/shortcuts/KeyBinding.test.d.ts +0 -1
- package/dist/mjs/shortcuts/KeyboardShortcutManager.test.d.ts +0 -1
- package/dist/mjs/toolbar/HTMLToolbar.d.ts +0 -105
- package/dist/mjs/toolbar/HTMLToolbar.mjs +0 -462
- package/dist/mjs/toolbar/makeColorInput.d.ts +0 -6
- package/dist/mjs/tools/Eraser.test.d.ts +0 -1
- package/dist/mjs/tools/PanZoom.test.d.ts +0 -1
- package/dist/mjs/tools/Pen.test.d.ts +0 -1
- package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
- package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +0 -1
- package/dist-test/test_imports/package-lock.json +0 -13
- package/dist-test/test_imports/package.json +0 -12
- package/dist-test/test_imports/test-imports.js +0 -17
- package/dist-test/test_imports/test-require.cjs +0 -19
- package/src/Color4.test.ts +0 -47
- package/src/Color4.ts +0 -304
- package/src/Editor.css +0 -98
- package/src/Editor.loadFrom.test.ts +0 -24
- package/src/Editor.toSVG.test.ts +0 -111
- package/src/Editor.ts +0 -1171
- 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 -72
- package/src/Pointer.ts +0 -170
- package/src/SVGLoader.test.ts +0 -114
- package/src/SVGLoader.ts +0 -610
- package/src/UndoRedoHistory.test.ts +0 -33
- package/src/UndoRedoHistory.ts +0 -102
- package/src/Viewport.ts +0 -325
- package/src/bundle/bundled.ts +0 -7
- package/src/commands/Command.ts +0 -45
- package/src/commands/Duplicate.ts +0 -75
- package/src/commands/Erase.ts +0 -94
- package/src/commands/SerializableCommand.ts +0 -49
- package/src/commands/UnresolvedCommand.ts +0 -37
- package/src/commands/invertCommand.ts +0 -58
- 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 -140
- package/src/components/AbstractComponent.transformBy.test.ts +0 -22
- package/src/components/AbstractComponent.ts +0 -374
- package/src/components/BackgroundComponent.test.ts +0 -45
- package/src/components/BackgroundComponent.ts +0 -353
- package/src/components/ImageComponent.ts +0 -178
- package/src/components/RestylableComponent.ts +0 -161
- package/src/components/SVGGlobalAttributesObject.ts +0 -81
- package/src/components/Stroke.test.ts +0 -139
- package/src/components/Stroke.ts +0 -296
- package/src/components/TextComponent.test.ts +0 -204
- package/src/components/TextComponent.ts +0 -432
- 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/CircleBuilder.ts +0 -102
- package/src/components/builders/FreehandLineBuilder.test.ts +0 -25
- 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 -31
- package/src/components/localization.ts +0 -24
- package/src/components/util/StrokeSmoother.ts +0 -302
- package/src/components/util/describeComponentList.ts +0 -18
- package/src/lib.ts +0 -69
- package/src/localization.ts +0 -34
- package/src/localizations/de.ts +0 -146
- 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 -74
- package/src/math/Mat33.test.ts +0 -244
- package/src/math/Mat33.ts +0 -442
- package/src/math/Vec2.test.ts +0 -30
- package/src/math/Vec2.ts +0 -40
- 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/polynomial/solveQuadratic.test.ts +0 -39
- package/src/math/polynomial/solveQuadratic.ts +0 -43
- package/src/math/rounding.test.ts +0 -65
- package/src/math/rounding.ts +0 -156
- package/src/math/shapes/Abstract2DShape.ts +0 -63
- package/src/math/shapes/BezierJSWrapper.ts +0 -93
- package/src/math/shapes/CubicBezier.ts +0 -35
- package/src/math/shapes/LineSegment2.test.ts +0 -99
- package/src/math/shapes/LineSegment2.ts +0 -231
- package/src/math/shapes/Path.fromString.test.ts +0 -223
- package/src/math/shapes/Path.test.ts +0 -309
- package/src/math/shapes/Path.toString.test.ts +0 -77
- package/src/math/shapes/Path.ts +0 -1027
- package/src/math/shapes/PointShape2D.ts +0 -33
- package/src/math/shapes/QuadraticBezier.test.ts +0 -31
- package/src/math/shapes/QuadraticBezier.ts +0 -141
- package/src/math/shapes/Rect2.test.ts +0 -209
- package/src/math/shapes/Rect2.ts +0 -344
- package/src/math/shapes/Triangle.test.ts +0 -61
- package/src/math/shapes/Triangle.ts +0 -139
- package/src/rendering/Display.ts +0 -248
- package/src/rendering/RenderingStyle.test.ts +0 -68
- package/src/rendering/RenderingStyle.ts +0 -55
- package/src/rendering/TextRenderingStyle.ts +0 -55
- 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 -8
- package/src/rendering/localization.ts +0 -20
- package/src/rendering/renderers/AbstractRenderer.ts +0 -242
- package/src/rendering/renderers/CanvasRenderer.ts +0 -307
- package/src/rendering/renderers/DummyRenderer.test.ts +0 -42
- package/src/rendering/renderers/DummyRenderer.ts +0 -145
- package/src/rendering/renderers/SVGRenderer.ts +0 -377
- package/src/rendering/renderers/TextOnlyRenderer.test.ts +0 -34
- package/src/rendering/renderers/TextOnlyRenderer.ts +0 -71
- package/src/shortcuts/KeyBinding.test.ts +0 -51
- package/src/shortcuts/KeyBinding.ts +0 -218
- package/src/shortcuts/KeyboardShortcutManager.test.ts +0 -95
- package/src/shortcuts/KeyboardShortcutManager.ts +0 -163
- package/src/shortcuts/lib.ts +0 -3
- package/src/testing/createEditor.ts +0 -11
- package/src/testing/getUniquePointerId.ts +0 -18
- package/src/testing/lib.ts +0 -3
- package/src/testing/sendPenEvent.ts +0 -36
- package/src/testing/sendTouchEvent.ts +0 -71
- package/src/toolbar/HTMLToolbar.ts +0 -567
- package/src/toolbar/IconProvider.ts +0 -805
- package/src/toolbar/lib.ts +0 -4
- package/src/toolbar/localization.ts +0 -114
- package/src/toolbar/makeColorInput.ts +0 -159
- package/src/toolbar/types.ts +0 -5
- package/src/toolbar/widgets/ActionButtonWidget.ts +0 -39
- package/src/toolbar/widgets/BaseToolWidget.ts +0 -65
- package/src/toolbar/widgets/BaseWidget.ts +0 -428
- package/src/toolbar/widgets/DocumentPropertiesWidget.ts +0 -234
- 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.ts +0 -92
- package/src/toolbar/widgets/PenToolWidget.ts +0 -409
- package/src/toolbar/widgets/SelectionToolWidget.ts +0 -197
- package/src/toolbar/widgets/TextToolWidget.ts +0 -145
- package/src/toolbar/widgets/keybindings.ts +0 -21
- package/src/toolbar/widgets/lib.ts +0 -13
- package/src/tools/BaseTool.ts +0 -97
- package/src/tools/Eraser.test.ts +0 -103
- package/src/tools/Eraser.ts +0 -160
- package/src/tools/FindTool.ts +0 -153
- package/src/tools/PanZoom.test.ts +0 -349
- package/src/tools/PanZoom.ts +0 -502
- package/src/tools/PasteHandler.ts +0 -95
- package/src/tools/Pen.test.ts +0 -262
- package/src/tools/Pen.ts +0 -300
- package/src/tools/PipetteTool.ts +0 -55
- package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +0 -29
- package/src/tools/SelectionTool/Selection.ts +0 -611
- package/src/tools/SelectionTool/SelectionHandle.ts +0 -108
- package/src/tools/SelectionTool/SelectionTool.test.ts +0 -261
- package/src/tools/SelectionTool/SelectionTool.ts +0 -496
- package/src/tools/SelectionTool/TransformMode.ts +0 -114
- package/src/tools/SelectionTool/types.ts +0 -11
- package/src/tools/SoundUITool.ts +0 -212
- package/src/tools/TextTool.ts +0 -340
- package/src/tools/ToolController.ts +0 -200
- package/src/tools/ToolEnabledGroup.ts +0 -14
- package/src/tools/ToolSwitcherShortcut.ts +0 -39
- package/src/tools/ToolbarShortcutHandler.ts +0 -39
- package/src/tools/UndoRedoShortcut.test.ts +0 -56
- package/src/tools/UndoRedoShortcut.ts +0 -24
- package/src/tools/keybindings.ts +0 -85
- package/src/tools/lib.ts +0 -22
- package/src/tools/localization.ts +0 -74
- package/src/tools/tools.css +0 -4
- package/src/types.ts +0 -239
- package/src/util/assertions.ts +0 -55
- package/src/util/fileToBase64.ts +0 -18
- package/src/util/untilNextAnimationFrame.ts +0 -9
- package/src/util/waitForAll.ts +0 -18
- package/src/util/waitForTimeout.ts +0 -9
- /package/dist/{cjs/Color4.test.d.ts → mjs/toolbar/widgets/layout/types.mjs} +0 -0
package/dist/mjs/Editor.mjs
CHANGED
@@ -1,77 +1,17 @@
|
|
1
|
-
var __assign = (this && this.__assign) || function () {
|
2
|
-
__assign = Object.assign || function(t) {
|
3
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4
|
-
s = arguments[i];
|
5
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6
|
-
t[p] = s[p];
|
7
|
-
}
|
8
|
-
return t;
|
9
|
-
};
|
10
|
-
return __assign.apply(this, arguments);
|
11
|
-
};
|
12
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
13
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
14
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
15
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
16
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
17
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
18
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
19
|
-
});
|
20
|
-
};
|
21
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
22
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
23
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
24
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
25
|
-
function step(op) {
|
26
|
-
if (f) throw new TypeError("Generator is already executing.");
|
27
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
28
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
29
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
30
|
-
switch (op[0]) {
|
31
|
-
case 0: case 1: t = op; break;
|
32
|
-
case 4: _.label++; return { value: op[1], done: false };
|
33
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
34
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
35
|
-
default:
|
36
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
37
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
38
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
39
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
40
|
-
if (t[2]) _.ops.pop();
|
41
|
-
_.trys.pop(); continue;
|
42
|
-
}
|
43
|
-
op = body.call(thisArg, _);
|
44
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
45
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
46
|
-
}
|
47
|
-
};
|
48
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
49
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
50
|
-
if (ar || !(i in from)) {
|
51
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
52
|
-
ar[i] = from[i];
|
53
|
-
}
|
54
|
-
}
|
55
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
56
|
-
};
|
57
1
|
import EditorImage from './EditorImage.mjs';
|
58
2
|
import ToolController from './tools/ToolController.mjs';
|
59
|
-
import {
|
3
|
+
import { EditorEventType } from './types.mjs';
|
4
|
+
import { InputEvtType, keyUpEventFromHTMLEvent, keyPressEventFromHTMLEvent } from './inputEvents.mjs';
|
60
5
|
import UndoRedoHistory from './UndoRedoHistory.mjs';
|
61
6
|
import Viewport from './Viewport.mjs';
|
62
7
|
import EventDispatcher from './EventDispatcher.mjs';
|
63
|
-
import
|
64
|
-
import Vec3 from './math/Vec3.mjs';
|
65
|
-
import HTMLToolbar from './toolbar/HTMLToolbar.mjs';
|
8
|
+
import { Vec2, Vec3, Color4, Mat33, toRoundedString } from '@js-draw/math';
|
66
9
|
import Display, { RenderingMode } from './rendering/Display.mjs';
|
67
10
|
import SVGRenderer from './rendering/renderers/SVGRenderer.mjs';
|
68
|
-
import Color4 from './Color4.mjs';
|
69
11
|
import SVGLoader from './SVGLoader.mjs';
|
70
12
|
import Pointer from './Pointer.mjs';
|
71
|
-
import Mat33 from './math/Mat33.mjs';
|
72
13
|
import getLocalizationTable from './localizations/getLocalizationTable.mjs';
|
73
14
|
import IconProvider from './toolbar/IconProvider.mjs';
|
74
|
-
import { toRoundedString } from './math/rounding.mjs';
|
75
15
|
import CanvasRenderer from './rendering/renderers/CanvasRenderer.mjs';
|
76
16
|
import untilNextAnimationFrame from './util/untilNextAnimationFrame.mjs';
|
77
17
|
import fileToBase64 from './util/fileToBase64.mjs';
|
@@ -81,6 +21,11 @@ import Erase from './commands/Erase.mjs';
|
|
81
21
|
import BackgroundComponent, { BackgroundType } from './components/BackgroundComponent.mjs';
|
82
22
|
import sendPenEvent from './testing/sendPenEvent.mjs';
|
83
23
|
import KeyboardShortcutManager from './shortcuts/KeyboardShortcutManager.mjs';
|
24
|
+
import EdgeToolbar from './toolbar/EdgeToolbar.mjs';
|
25
|
+
import StrokeKeyboardControl from './tools/InputFilter/StrokeKeyboardControl.mjs';
|
26
|
+
import guessKeyCodeFromKey from './util/guessKeyCodeFromKey.mjs';
|
27
|
+
import makeAboutDialog from './dialogs/makeAboutDialog.mjs';
|
28
|
+
import version from './version.mjs';
|
84
29
|
/**
|
85
30
|
* The main entrypoint for the full editor.
|
86
31
|
*
|
@@ -99,7 +44,7 @@ import KeyboardShortcutManager from './shortcuts/KeyboardShortcutManager.mjs';
|
|
99
44
|
* See also
|
100
45
|
* [`docs/example/example.ts`](https://github.com/personalizedrefrigerator/js-draw/blob/main/docs/demo/example.ts#L15).
|
101
46
|
*/
|
102
|
-
|
47
|
+
export class Editor {
|
103
48
|
/**
|
104
49
|
* @example
|
105
50
|
* ```
|
@@ -125,39 +70,41 @@ var Editor = /** @class */ (function () {
|
|
125
70
|
* });
|
126
71
|
* ```
|
127
72
|
*/
|
128
|
-
|
129
|
-
if (settings === void 0) { settings = {}; }
|
130
|
-
var _this = this;
|
131
|
-
var _a, _b, _c, _d, _e, _f;
|
73
|
+
constructor(parent, settings = {}) {
|
132
74
|
this.eventListenerTargets = [];
|
133
75
|
this.previousAccessibilityAnnouncement = '';
|
134
76
|
this.pointers = {};
|
135
|
-
this.announceUndoCallback =
|
136
|
-
|
77
|
+
this.announceUndoCallback = (command) => {
|
78
|
+
this.announceForAccessibility(this.localization.undoAnnouncement(command.description(this, this.localization)));
|
137
79
|
};
|
138
|
-
this.announceRedoCallback =
|
139
|
-
|
80
|
+
this.announceRedoCallback = (command) => {
|
81
|
+
this.announceForAccessibility(this.localization.redoAnnouncement(command.description(this, this.localization)));
|
140
82
|
};
|
141
83
|
// Listeners to be called once at the end of the next re-render.
|
142
84
|
this.nextRerenderListeners = [];
|
143
85
|
this.rerenderQueued = false;
|
144
|
-
this.
|
86
|
+
this.closeAboutDialog = null;
|
87
|
+
this.localization = {
|
88
|
+
...getLocalizationTable(),
|
89
|
+
...settings.localization,
|
90
|
+
};
|
145
91
|
// Fill default settings.
|
146
92
|
this.settings = {
|
147
|
-
wheelEventsEnabled:
|
148
|
-
renderingMode:
|
93
|
+
wheelEventsEnabled: settings.wheelEventsEnabled ?? true,
|
94
|
+
renderingMode: settings.renderingMode ?? RenderingMode.CanvasRenderer,
|
149
95
|
localization: this.localization,
|
150
|
-
minZoom:
|
151
|
-
maxZoom:
|
152
|
-
keyboardShortcutOverrides:
|
153
|
-
iconProvider:
|
96
|
+
minZoom: settings.minZoom ?? 2e-10,
|
97
|
+
maxZoom: settings.maxZoom ?? 1e12,
|
98
|
+
keyboardShortcutOverrides: settings.keyboardShortcutOverrides ?? {},
|
99
|
+
iconProvider: settings.iconProvider ?? new IconProvider(),
|
100
|
+
notices: [],
|
154
101
|
};
|
155
102
|
this.icons = this.settings.iconProvider;
|
156
103
|
this.shortcuts = new KeyboardShortcutManager(this.settings.keyboardShortcutOverrides);
|
157
104
|
this.container = document.createElement('div');
|
158
105
|
this.renderingRegion = document.createElement('div');
|
159
106
|
this.container.appendChild(this.renderingRegion);
|
160
|
-
this.container.
|
107
|
+
this.container.classList.add('imageEditorContainer', 'js-draw');
|
161
108
|
this.loadingWarning = document.createElement('div');
|
162
109
|
this.loadingWarning.classList.add('loadingMessage');
|
163
110
|
this.loadingWarning.ariaLive = 'polite';
|
@@ -178,33 +125,35 @@ var Editor = /** @class */ (function () {
|
|
178
125
|
this.renderingRegion.setAttribute('tabIndex', '0');
|
179
126
|
this.renderingRegion.setAttribute('alt', '');
|
180
127
|
this.notifier = new EventDispatcher();
|
181
|
-
this.viewport = new Viewport(
|
182
|
-
|
128
|
+
this.viewport = new Viewport((oldTransform, newTransform) => {
|
129
|
+
this.notifier.dispatch(EditorEventType.ViewportChanged, {
|
183
130
|
kind: EditorEventType.ViewportChanged,
|
184
|
-
newTransform
|
185
|
-
oldTransform
|
131
|
+
newTransform,
|
132
|
+
oldTransform,
|
186
133
|
});
|
187
134
|
});
|
188
135
|
this.display = new Display(this, this.settings.renderingMode, this.renderingRegion);
|
189
136
|
this.image = new EditorImage();
|
190
137
|
this.history = new UndoRedoHistory(this, this.announceRedoCallback, this.announceUndoCallback);
|
191
138
|
this.toolController = new ToolController(this, this.localization);
|
139
|
+
// TODO: Make this pipeline configurable (e.g. allow users to add global input stabilization)
|
140
|
+
this.toolController.addInputMapper(StrokeKeyboardControl.fromEditor(this));
|
192
141
|
parent.appendChild(this.container);
|
193
142
|
this.viewport.updateScreenSize(Vec2.of(this.display.width, this.display.height));
|
194
143
|
this.registerListeners();
|
195
144
|
this.queueRerender();
|
196
145
|
this.hideLoadingWarning();
|
197
146
|
// Enforce zoom limits.
|
198
|
-
this.notifier.on(EditorEventType.ViewportChanged,
|
147
|
+
this.notifier.on(EditorEventType.ViewportChanged, evt => {
|
199
148
|
if (evt.kind === EditorEventType.ViewportChanged) {
|
200
|
-
|
201
|
-
if (zoom >
|
202
|
-
|
203
|
-
|
204
|
-
if (oldZoom <=
|
149
|
+
const zoom = evt.newTransform.transformVec3(Vec2.unitX).length();
|
150
|
+
if (zoom > this.settings.maxZoom || zoom < this.settings.minZoom) {
|
151
|
+
const oldZoom = evt.oldTransform.transformVec3(Vec2.unitX).length();
|
152
|
+
let resetTransform = Mat33.identity;
|
153
|
+
if (oldZoom <= this.settings.maxZoom && oldZoom >= this.settings.minZoom) {
|
205
154
|
resetTransform = evt.oldTransform;
|
206
155
|
}
|
207
|
-
|
156
|
+
this.viewport.resetTransform(resetTransform);
|
208
157
|
}
|
209
158
|
}
|
210
159
|
});
|
@@ -218,57 +167,55 @@ var Editor = /** @class */ (function () {
|
|
218
167
|
* editor.getRootElement().style.height = '500px';
|
219
168
|
* ```
|
220
169
|
*/
|
221
|
-
|
170
|
+
getRootElement() {
|
222
171
|
return this.container;
|
223
|
-
}
|
172
|
+
}
|
224
173
|
/** @param fractionLoaded - should be a number from 0 to 1, where 1 represents completely loaded. */
|
225
|
-
|
226
|
-
|
174
|
+
showLoadingWarning(fractionLoaded) {
|
175
|
+
const loadingPercent = Math.round(fractionLoaded * 100);
|
227
176
|
this.loadingWarning.innerText = this.localization.loading(loadingPercent);
|
228
177
|
this.loadingWarning.style.display = 'block';
|
229
|
-
}
|
230
|
-
|
178
|
+
}
|
179
|
+
hideLoadingWarning() {
|
231
180
|
this.loadingWarning.style.display = 'none';
|
232
181
|
this.announceForAccessibility(this.localization.doneLoading);
|
233
|
-
}
|
182
|
+
}
|
234
183
|
/**
|
235
184
|
* Announce `message` for screen readers. If `message` is the same as the previous
|
236
185
|
* message, it is re-announced.
|
237
186
|
*/
|
238
|
-
|
187
|
+
announceForAccessibility(message) {
|
239
188
|
// Force re-announcing an announcement if announced again.
|
240
189
|
if (message === this.previousAccessibilityAnnouncement) {
|
241
190
|
message = message + '. ';
|
242
191
|
}
|
243
192
|
this.accessibilityAnnounceArea.innerText = message;
|
244
193
|
this.previousAccessibilityAnnouncement = message;
|
245
|
-
}
|
194
|
+
}
|
246
195
|
/**
|
247
196
|
* Creates a toolbar. If `defaultLayout` is true, default buttons are used.
|
248
197
|
* @returns a reference to the toolbar.
|
249
198
|
*/
|
250
|
-
|
251
|
-
|
252
|
-
var toolbar = new HTMLToolbar(this, this.container, this.localization);
|
199
|
+
addToolbar(defaultLayout = true) {
|
200
|
+
const toolbar = new EdgeToolbar(this, this.container, this.localization);
|
253
201
|
if (defaultLayout) {
|
254
202
|
toolbar.addDefaults();
|
255
203
|
}
|
256
204
|
return toolbar;
|
257
|
-
}
|
258
|
-
|
259
|
-
var _this = this;
|
205
|
+
}
|
206
|
+
registerListeners() {
|
260
207
|
this.handlePointerEventsFrom(this.renderingRegion);
|
261
208
|
this.handleKeyEventsFrom(this.renderingRegion);
|
262
|
-
this.container.addEventListener('wheel',
|
263
|
-
|
209
|
+
this.container.addEventListener('wheel', evt => {
|
210
|
+
let delta = Vec3.of(evt.deltaX, evt.deltaY, evt.deltaZ);
|
264
211
|
// Process wheel events if the ctrl key is down, even if disabled -- we do want to handle
|
265
212
|
// pinch-zooming.
|
266
213
|
if (!evt.ctrlKey && !evt.metaKey) {
|
267
|
-
if (!
|
214
|
+
if (!this.settings.wheelEventsEnabled) {
|
268
215
|
return;
|
269
216
|
}
|
270
|
-
else if (
|
271
|
-
|
217
|
+
else if (this.settings.wheelEventsEnabled === 'only-if-focused') {
|
218
|
+
const focusedChild = this.container.querySelector(':focus');
|
272
219
|
if (!focusedChild) {
|
273
220
|
return;
|
274
221
|
}
|
@@ -284,11 +231,11 @@ var Editor = /** @class */ (function () {
|
|
284
231
|
delta = Vec3.of(0, 0, evt.deltaY);
|
285
232
|
}
|
286
233
|
// Ensure that `pos` is relative to `this.renderingRegion`
|
287
|
-
|
288
|
-
|
289
|
-
if (
|
234
|
+
const bbox = this.renderingRegion.getBoundingClientRect();
|
235
|
+
const pos = Vec2.of(evt.clientX, evt.clientY).minus(Vec2.of(bbox.left, bbox.top));
|
236
|
+
if (this.toolController.dispatchInputEvent({
|
290
237
|
kind: InputEvtType.WheelEvt,
|
291
|
-
delta
|
238
|
+
delta,
|
292
239
|
screenPos: pos,
|
293
240
|
})) {
|
294
241
|
evt.preventDefault();
|
@@ -296,81 +243,82 @@ var Editor = /** @class */ (function () {
|
|
296
243
|
}
|
297
244
|
return false;
|
298
245
|
});
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
var handleResize = function () {
|
304
|
-
_this.notifier.dispatch(EditorEventType.DisplayResized, {
|
305
|
-
kind: EditorEventType.DisplayResized,
|
306
|
-
newSize: Vec2.of(_this.display.width, _this.display.height),
|
307
|
-
});
|
246
|
+
const handleResize = () => {
|
247
|
+
this.viewport.updateScreenSize(Vec2.of(this.display.width, this.display.height));
|
248
|
+
this.rerender();
|
249
|
+
this.updateEditorSizeVariables();
|
308
250
|
};
|
309
251
|
if ('ResizeObserver' in window) {
|
310
|
-
|
252
|
+
const resizeObserver = new ResizeObserver(handleResize);
|
253
|
+
resizeObserver.observe(this.renderingRegion);
|
311
254
|
resizeObserver.observe(this.container);
|
312
255
|
}
|
313
256
|
else {
|
314
257
|
addEventListener('resize', handleResize);
|
315
258
|
}
|
316
|
-
this.accessibilityControlArea.addEventListener('input',
|
317
|
-
|
259
|
+
this.accessibilityControlArea.addEventListener('input', () => {
|
260
|
+
this.accessibilityControlArea.value = '';
|
318
261
|
});
|
319
|
-
document.addEventListener('copy',
|
320
|
-
if (!
|
262
|
+
document.addEventListener('copy', evt => {
|
263
|
+
if (!this.isEventSink(document.querySelector(':focus'))) {
|
321
264
|
return;
|
322
265
|
}
|
323
|
-
|
324
|
-
if (
|
266
|
+
const clipboardData = evt.clipboardData;
|
267
|
+
if (this.toolController.dispatchInputEvent({
|
325
268
|
kind: InputEvtType.CopyEvent,
|
326
|
-
setData:
|
327
|
-
clipboardData
|
269
|
+
setData: (mime, data) => {
|
270
|
+
clipboardData?.setData(mime, data);
|
328
271
|
},
|
329
272
|
})) {
|
330
273
|
evt.preventDefault();
|
331
274
|
}
|
332
275
|
});
|
333
|
-
document.addEventListener('paste',
|
334
|
-
|
276
|
+
document.addEventListener('paste', evt => {
|
277
|
+
this.handlePaste(evt);
|
335
278
|
});
|
336
|
-
}
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
279
|
+
}
|
280
|
+
updateEditorSizeVariables() {
|
281
|
+
// Add CSS variables so that absolutely-positioned children of the editor can
|
282
|
+
// still fill the screen.
|
283
|
+
this.container.style.setProperty('--editor-current-width-px', `${this.container.clientWidth}px`);
|
284
|
+
this.container.style.setProperty('--editor-current-height-px', `${this.container.clientHeight}px`);
|
285
|
+
}
|
286
|
+
getPointerList() {
|
287
|
+
const nowTime = performance.now();
|
288
|
+
const res = [];
|
289
|
+
for (const id in this.pointers) {
|
290
|
+
const maxUnupdatedTime = 2000; // Maximum time without a pointer update (ms)
|
342
291
|
if (this.pointers[id] && (nowTime - this.pointers[id].timeStamp) < maxUnupdatedTime) {
|
343
292
|
res.push(this.pointers[id]);
|
344
293
|
}
|
345
294
|
}
|
346
295
|
return res;
|
347
|
-
}
|
296
|
+
}
|
348
297
|
/**
|
349
298
|
* Dispatches a `PointerEvent` to the editor. The target element for `evt` must have the same top left
|
350
299
|
* as the content of the editor.
|
351
300
|
*/
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
var eventTarget = (_a = evt.target) !== null && _a !== void 0 ? _a : this.renderingRegion;
|
301
|
+
handleHTMLPointerEvent(eventType, evt) {
|
302
|
+
const eventsRelativeTo = this.renderingRegion;
|
303
|
+
const eventTarget = evt.target ?? this.renderingRegion;
|
356
304
|
if (eventType === 'pointerdown') {
|
357
|
-
|
305
|
+
const pointer = Pointer.ofEvent(evt, true, this.viewport, eventsRelativeTo);
|
358
306
|
this.pointers[pointer.id] = pointer;
|
359
307
|
eventTarget.setPointerCapture(pointer.id);
|
360
|
-
|
308
|
+
const event = {
|
361
309
|
kind: InputEvtType.PointerDownEvt,
|
362
310
|
current: pointer,
|
363
311
|
allPointers: this.getPointerList(),
|
364
312
|
};
|
365
|
-
this.toolController.dispatchInputEvent(
|
313
|
+
this.toolController.dispatchInputEvent(event);
|
366
314
|
return true;
|
367
315
|
}
|
368
316
|
else if (eventType === 'pointermove') {
|
369
|
-
|
317
|
+
const pointer = Pointer.ofEvent(evt, this.pointers[evt.pointerId]?.down ?? false, this.viewport, eventsRelativeTo);
|
370
318
|
if (pointer.down) {
|
371
|
-
|
319
|
+
const prevData = this.pointers[pointer.id];
|
372
320
|
if (prevData) {
|
373
|
-
|
321
|
+
const distanceMoved = pointer.screenPos.minus(prevData.screenPos).magnitude();
|
374
322
|
// If the pointer moved less than two pixels, don't send a new event.
|
375
323
|
if (distanceMoved < 2) {
|
376
324
|
return false;
|
@@ -388,7 +336,7 @@ var Editor = /** @class */ (function () {
|
|
388
336
|
return true;
|
389
337
|
}
|
390
338
|
else if (eventType === 'pointercancel' || eventType === 'pointerup') {
|
391
|
-
|
339
|
+
const pointer = Pointer.ofEvent(evt, false, this.viewport, eventsRelativeTo);
|
392
340
|
if (!this.pointers[pointer.id]) {
|
393
341
|
return false;
|
394
342
|
}
|
@@ -405,12 +353,11 @@ var Editor = /** @class */ (function () {
|
|
405
353
|
return true;
|
406
354
|
}
|
407
355
|
return eventType;
|
408
|
-
}
|
409
|
-
|
410
|
-
|
356
|
+
}
|
357
|
+
isEventSink(evtTarget) {
|
358
|
+
let currentElem = evtTarget;
|
411
359
|
while (currentElem !== null) {
|
412
|
-
for (
|
413
|
-
var elem = _a[_i];
|
360
|
+
for (const elem of this.eventListenerTargets) {
|
414
361
|
if (elem === currentElem) {
|
415
362
|
return true;
|
416
363
|
}
|
@@ -418,108 +365,84 @@ var Editor = /** @class */ (function () {
|
|
418
365
|
currentElem = currentElem.parentElement;
|
419
366
|
}
|
420
367
|
return false;
|
421
|
-
}
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
_g.label = 5;
|
462
|
-
case 5:
|
463
|
-
if (!(_d < _e.length)) return [3 /*break*/, 11];
|
464
|
-
file = _e[_d];
|
465
|
-
fileType = file.type.toLowerCase();
|
466
|
-
if (!(fileType === 'image/png' || fileType === 'image/jpg')) return [3 /*break*/, 10];
|
467
|
-
this.showLoadingWarning(0);
|
468
|
-
onprogress_1 = function (evt) {
|
469
|
-
_this.showLoadingWarning(evt.loaded / evt.total);
|
470
|
-
};
|
471
|
-
_g.label = 6;
|
472
|
-
case 6:
|
473
|
-
_g.trys.push([6, 8, , 9]);
|
474
|
-
return [4 /*yield*/, fileToBase64(file, onprogress_1)];
|
475
|
-
case 7:
|
476
|
-
data = _g.sent();
|
477
|
-
if (data && this.toolController.dispatchInputEvent({
|
478
|
-
kind: InputEvtType.PasteEvent,
|
479
|
-
mime: fileType,
|
480
|
-
data: data,
|
481
|
-
})) {
|
482
|
-
evt.preventDefault();
|
483
|
-
this.hideLoadingWarning();
|
484
|
-
return [2 /*return*/];
|
485
|
-
}
|
486
|
-
return [3 /*break*/, 9];
|
487
|
-
case 8:
|
488
|
-
e_1 = _g.sent();
|
489
|
-
console.error('Error reading image:', e_1);
|
490
|
-
return [3 /*break*/, 9];
|
491
|
-
case 9:
|
368
|
+
}
|
369
|
+
async handlePaste(evt) {
|
370
|
+
const target = document.querySelector(':focus') ?? evt.target;
|
371
|
+
if (!this.isEventSink(target)) {
|
372
|
+
return;
|
373
|
+
}
|
374
|
+
const clipboardData = evt.dataTransfer ?? evt.clipboardData;
|
375
|
+
if (!clipboardData) {
|
376
|
+
return;
|
377
|
+
}
|
378
|
+
// Handle SVG files (prefer to PNG/JPEG)
|
379
|
+
for (const file of clipboardData.files) {
|
380
|
+
if (file.type.toLowerCase() === 'image/svg+xml') {
|
381
|
+
const text = await file.text();
|
382
|
+
if (this.toolController.dispatchInputEvent({
|
383
|
+
kind: InputEvtType.PasteEvent,
|
384
|
+
mime: file.type,
|
385
|
+
data: text,
|
386
|
+
})) {
|
387
|
+
evt.preventDefault();
|
388
|
+
return;
|
389
|
+
}
|
390
|
+
}
|
391
|
+
}
|
392
|
+
// Handle image files.
|
393
|
+
for (const file of clipboardData.files) {
|
394
|
+
const fileType = file.type.toLowerCase();
|
395
|
+
if (fileType === 'image/png' || fileType === 'image/jpg') {
|
396
|
+
this.showLoadingWarning(0);
|
397
|
+
const onprogress = (evt) => {
|
398
|
+
this.showLoadingWarning(evt.loaded / evt.total);
|
399
|
+
};
|
400
|
+
try {
|
401
|
+
const data = await fileToBase64(file, onprogress);
|
402
|
+
if (data && this.toolController.dispatchInputEvent({
|
403
|
+
kind: InputEvtType.PasteEvent,
|
404
|
+
mime: fileType,
|
405
|
+
data: data,
|
406
|
+
})) {
|
407
|
+
evt.preventDefault();
|
492
408
|
this.hideLoadingWarning();
|
493
|
-
|
494
|
-
|
495
|
-
_d++;
|
496
|
-
return [3 /*break*/, 5];
|
497
|
-
case 11:
|
498
|
-
supportedMIMEs = [
|
499
|
-
'image/svg+xml',
|
500
|
-
'text/plain',
|
501
|
-
];
|
502
|
-
for (_f = 0, supportedMIMEs_1 = supportedMIMEs; _f < supportedMIMEs_1.length; _f++) {
|
503
|
-
mime = supportedMIMEs_1[_f];
|
504
|
-
data = clipboardData.getData(mime);
|
505
|
-
if (data && this.toolController.dispatchInputEvent({
|
506
|
-
kind: InputEvtType.PasteEvent,
|
507
|
-
mime: mime,
|
508
|
-
data: data,
|
509
|
-
})) {
|
510
|
-
evt.preventDefault();
|
511
|
-
return [2 /*return*/];
|
512
|
-
}
|
513
|
-
}
|
514
|
-
return [2 /*return*/];
|
409
|
+
return;
|
410
|
+
}
|
515
411
|
}
|
516
|
-
|
517
|
-
|
518
|
-
|
412
|
+
catch (e) {
|
413
|
+
console.error('Error reading image:', e);
|
414
|
+
}
|
415
|
+
this.hideLoadingWarning();
|
416
|
+
}
|
417
|
+
}
|
418
|
+
// Supported MIMEs for text data, in order of preference
|
419
|
+
const supportedMIMEs = [
|
420
|
+
'image/svg+xml',
|
421
|
+
'text/plain',
|
422
|
+
];
|
423
|
+
for (const mime of supportedMIMEs) {
|
424
|
+
const data = clipboardData.getData(mime);
|
425
|
+
if (data && this.toolController.dispatchInputEvent({
|
426
|
+
kind: InputEvtType.PasteEvent,
|
427
|
+
mime,
|
428
|
+
data,
|
429
|
+
})) {
|
430
|
+
evt.preventDefault();
|
431
|
+
return;
|
432
|
+
}
|
433
|
+
}
|
434
|
+
}
|
519
435
|
/**
|
520
436
|
* Forward pointer events from `elem` to this editor. Such that right-click/right-click drag
|
521
437
|
* events are also forwarded, `elem`'s contextmenu is disabled.
|
522
438
|
*
|
439
|
+
* `filter` is called once per pointer event, before doing any other processing. If `filter` returns `true` the event is
|
440
|
+
* forwarded to the editor.
|
441
|
+
*
|
442
|
+
* **Note**: `otherEventsFilter` is like `filter`, but is called for other pointer-related
|
443
|
+
* events that could also be forwarded to the editor. To forward just pointer events,
|
444
|
+
* for example, `otherEventsFilter` could be given as `()=>false`.
|
445
|
+
*
|
523
446
|
* @example
|
524
447
|
* ```ts
|
525
448
|
* const overlay = document.createElement('div');
|
@@ -535,94 +458,196 @@ var Editor = /** @class */ (function () {
|
|
535
458
|
* });
|
536
459
|
* ```
|
537
460
|
*/
|
538
|
-
|
539
|
-
var _this = this;
|
461
|
+
handlePointerEventsFrom(elem, filter, otherEventsFilter) {
|
540
462
|
// May be required to prevent text selection on iOS/Safari:
|
541
463
|
// See https://stackoverflow.com/a/70992717/17055750
|
542
|
-
|
543
|
-
|
464
|
+
const touchstartListener = (evt) => {
|
465
|
+
if (otherEventsFilter && !otherEventsFilter('touchstart', evt)) {
|
466
|
+
return;
|
467
|
+
}
|
468
|
+
evt.preventDefault();
|
469
|
+
};
|
470
|
+
const contextmenuListener = (evt) => {
|
471
|
+
if (otherEventsFilter && !otherEventsFilter('contextmenu', evt)) {
|
472
|
+
return;
|
473
|
+
}
|
544
474
|
// Don't show a context menu
|
545
475
|
evt.preventDefault();
|
546
476
|
};
|
547
|
-
|
477
|
+
const listeners = {
|
548
478
|
'touchstart': touchstartListener,
|
549
479
|
'contextmenu': contextmenuListener,
|
550
480
|
};
|
551
|
-
|
552
|
-
|
553
|
-
listeners[eventName] =
|
481
|
+
const eventNames = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'];
|
482
|
+
for (const eventName of eventNames) {
|
483
|
+
listeners[eventName] = (evt) => {
|
554
484
|
// This listener will only be called in the context of PointerEvents.
|
555
|
-
|
485
|
+
const event = evt;
|
556
486
|
if (filter && !filter(eventName, event)) {
|
557
|
-
return
|
487
|
+
return undefined;
|
558
488
|
}
|
559
|
-
return
|
489
|
+
return this.handleHTMLPointerEvent(eventName, event);
|
560
490
|
};
|
561
|
-
};
|
562
|
-
for (var _i = 0, eventNames_1 = eventNames; _i < eventNames_1.length; _i++) {
|
563
|
-
var eventName = eventNames_1[_i];
|
564
|
-
_loop_1(eventName);
|
565
491
|
}
|
566
492
|
// Add all listeners.
|
567
|
-
for (
|
493
|
+
for (const eventName in listeners) {
|
568
494
|
elem.addEventListener(eventName, listeners[eventName]);
|
569
495
|
}
|
570
496
|
return {
|
571
497
|
/** Remove all event listeners registered by this function. */
|
572
|
-
remove:
|
573
|
-
for (
|
498
|
+
remove: () => {
|
499
|
+
for (const eventName in listeners) {
|
574
500
|
elem.removeEventListener(eventName, listeners[eventName]);
|
575
501
|
}
|
576
502
|
},
|
577
503
|
};
|
578
|
-
}
|
579
|
-
/**
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
504
|
+
}
|
505
|
+
/**
|
506
|
+
* Like {@link handlePointerEventsFrom} except ignores short input gestures like clicks.
|
507
|
+
*
|
508
|
+
* `filter` is called once per event, before doing any other processing. If `filter` returns `true` the event is
|
509
|
+
* forwarded to the editor.
|
510
|
+
*
|
511
|
+
* `otherEventsFilter` is passed unmodified to `handlePointerEventsFrom`.
|
512
|
+
*/
|
513
|
+
handlePointerEventsExceptClicksFrom(elem, filter, otherEventsFilter) {
|
514
|
+
// Maps pointer IDs to gesture start points
|
515
|
+
const gestureData = Object.create(null);
|
516
|
+
return this.handlePointerEventsFrom(elem, (eventName, event) => {
|
517
|
+
if (filter && !filter(eventName, event)) {
|
518
|
+
return false;
|
586
519
|
}
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
520
|
+
// Position of the current event.
|
521
|
+
const currentPos = Vec2.of(event.pageX, event.pageY);
|
522
|
+
const pointerId = event.pointerId ?? 0;
|
523
|
+
// Whether to send the current event to the editor
|
524
|
+
let sendToEditor = true;
|
525
|
+
if (eventName === 'pointerdown') {
|
526
|
+
// Buffer the event, but don't send it to the editor yet.
|
527
|
+
// We don't want to send single-click events, but we do want to send full strokes.
|
528
|
+
gestureData[pointerId] = {
|
529
|
+
eventBuffer: [[eventName, event]],
|
530
|
+
startPoint: currentPos,
|
531
|
+
};
|
532
|
+
// Capture the pointer so we receive future events even if the overlay is hidden.
|
533
|
+
elem.setPointerCapture(event.pointerId);
|
534
|
+
// Don't send to the editor.
|
535
|
+
sendToEditor = false;
|
536
|
+
}
|
537
|
+
else if (eventName === 'pointermove' && gestureData[pointerId]) {
|
538
|
+
const gestureStartPos = gestureData[pointerId].startPoint;
|
539
|
+
const eventBuffer = gestureData[pointerId].eventBuffer;
|
540
|
+
// Skip if the pointer hasn't moved enough to not be a "click".
|
541
|
+
const strokeStartThreshold = 10;
|
542
|
+
const isWithinClickThreshold = gestureStartPos && currentPos.minus(gestureStartPos).magnitude() < strokeStartThreshold;
|
543
|
+
if (isWithinClickThreshold) {
|
544
|
+
eventBuffer.push([eventName, event]);
|
545
|
+
sendToEditor = false;
|
546
|
+
}
|
547
|
+
else {
|
548
|
+
// Send all buffered events to the editor -- start the stroke.
|
549
|
+
for (const [eventName, event] of eventBuffer) {
|
550
|
+
this.handleHTMLPointerEvent(eventName, event);
|
551
|
+
}
|
552
|
+
gestureData[pointerId].eventBuffer = [];
|
553
|
+
sendToEditor = true;
|
554
|
+
}
|
555
|
+
}
|
556
|
+
// Pointers that aren't down -- send to the editor.
|
557
|
+
else if (eventName === 'pointermove') {
|
558
|
+
sendToEditor = true;
|
559
|
+
}
|
560
|
+
// Otherwise, if we received a pointerup/pointercancel without flushing all pointerevents from the
|
561
|
+
// buffer, the gesture wasn't recognised as a stroke. Thus, the editor isn't expecting a pointerup/
|
562
|
+
// pointercancel event.
|
563
|
+
else if ((eventName === 'pointerup' || eventName === 'pointercancel')
|
564
|
+
&& gestureData[pointerId] && gestureData[pointerId].eventBuffer.length > 0) {
|
565
|
+
elem.releasePointerCapture(event.pointerId);
|
566
|
+
// Don't send to the editor.
|
567
|
+
sendToEditor = false;
|
568
|
+
delete gestureData[pointerId];
|
569
|
+
}
|
570
|
+
// Forward all other events to the editor.
|
571
|
+
return sendToEditor;
|
572
|
+
}, otherEventsFilter);
|
573
|
+
}
|
574
|
+
/**
|
575
|
+
* Adds event listners for keypresses (and drop events) on `elem` and forwards those
|
576
|
+
* events to the editor.
|
577
|
+
*
|
578
|
+
* If the given `filter` returns `false` for an event, the event is ignored and not
|
579
|
+
* passed to the editor.
|
580
|
+
*/
|
581
|
+
handleKeyEventsFrom(elem, filter = () => true) {
|
582
|
+
// Track which keys are down so we can release them when the element
|
583
|
+
// loses focus. This is particularly important for keys like Control
|
584
|
+
// that can trigger shortcuts that cause the editor to lose focus before
|
585
|
+
// the keyup event is triggered.
|
586
|
+
let keysDown = [];
|
587
|
+
// Return whether two objects that are similar to keyboard events represent the
|
588
|
+
// same key.
|
589
|
+
const keyEventsMatch = (a, b) => {
|
590
|
+
return a.key === b.key && a.code === b.code;
|
591
|
+
};
|
592
|
+
elem.addEventListener('keydown', htmlEvent => {
|
593
|
+
if (!filter(htmlEvent)) {
|
594
|
+
return;
|
595
|
+
}
|
596
|
+
const event = keyPressEventFromHTMLEvent(htmlEvent);
|
597
|
+
// Add event to the list of keys that are down (so long as it
|
598
|
+
// isn't a duplicate).
|
599
|
+
if (!keysDown.some(other => keyEventsMatch(other, event))) {
|
600
|
+
keysDown.push(event);
|
594
601
|
}
|
595
|
-
|
596
|
-
|
602
|
+
if (event.key === 't' || event.key === 'T') {
|
603
|
+
htmlEvent.preventDefault();
|
604
|
+
this.display.rerenderAsText();
|
605
|
+
}
|
606
|
+
else if (this.toolController.dispatchInputEvent(event)) {
|
607
|
+
htmlEvent.preventDefault();
|
608
|
+
}
|
609
|
+
else if (event.key === 'Escape') {
|
610
|
+
this.renderingRegion.blur();
|
597
611
|
}
|
598
612
|
});
|
599
|
-
elem.addEventListener('keyup',
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
613
|
+
elem.addEventListener('keyup', htmlEvent => {
|
614
|
+
// Remove the key from keysDown -- it's no longer down.
|
615
|
+
keysDown = keysDown.filter(event => {
|
616
|
+
const matches = keyEventsMatch(event, htmlEvent);
|
617
|
+
return !matches;
|
618
|
+
});
|
619
|
+
if (!filter(htmlEvent)) {
|
620
|
+
return;
|
621
|
+
}
|
622
|
+
const event = keyUpEventFromHTMLEvent(htmlEvent);
|
623
|
+
if (this.toolController.dispatchInputEvent(event)) {
|
624
|
+
htmlEvent.preventDefault();
|
625
|
+
}
|
626
|
+
});
|
627
|
+
elem.addEventListener('blur', () => {
|
628
|
+
for (const event of keysDown) {
|
629
|
+
this.toolController.dispatchInputEvent({
|
630
|
+
...event,
|
631
|
+
kind: InputEvtType.KeyUpEvent,
|
632
|
+
});
|
607
633
|
}
|
608
634
|
});
|
609
635
|
// Allow drop.
|
610
|
-
elem.ondragover =
|
636
|
+
elem.ondragover = evt => {
|
611
637
|
evt.preventDefault();
|
612
638
|
};
|
613
|
-
elem.ondrop =
|
639
|
+
elem.ondrop = evt => {
|
614
640
|
evt.preventDefault();
|
615
|
-
|
641
|
+
this.handlePaste(evt);
|
616
642
|
};
|
617
643
|
this.eventListenerTargets.push(elem);
|
618
|
-
}
|
644
|
+
}
|
619
645
|
/** `apply` a command. `command` will be announced for accessibility. */
|
620
|
-
|
621
|
-
|
622
|
-
var dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
|
646
|
+
dispatch(command, addToHistory = true) {
|
647
|
+
const dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
|
623
648
|
this.announceForAccessibility(command.description(this, this.localization));
|
624
649
|
return dispatchResult;
|
625
|
-
}
|
650
|
+
}
|
626
651
|
/**
|
627
652
|
* Dispatches a command without announcing it. By default, does not add to history.
|
628
653
|
* Use this to show finalized commands that don't need to have `announceForAccessibility`
|
@@ -638,158 +663,132 @@ var Editor = /** @class */ (function () {
|
|
638
663
|
* editor.dispatchNoAnnounce(editor.viewport.zoomTo(someRectangle), addToHistory);
|
639
664
|
* ```
|
640
665
|
*/
|
641
|
-
|
642
|
-
|
643
|
-
var result = command.apply(this);
|
666
|
+
dispatchNoAnnounce(command, addToHistory = false) {
|
667
|
+
const result = command.apply(this);
|
644
668
|
if (addToHistory) {
|
645
|
-
|
669
|
+
const apply = false; // Don't double-apply
|
646
670
|
this.history.push(command, apply);
|
647
671
|
}
|
648
672
|
return result;
|
649
|
-
}
|
673
|
+
}
|
650
674
|
/**
|
651
675
|
* Apply a large transformation in chunks.
|
652
676
|
* If `apply` is `false`, the commands are unapplied.
|
653
677
|
* Triggers a re-render after each `updateChunkSize`-sized group of commands
|
654
678
|
* has been applied.
|
655
679
|
*/
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
i = 0;
|
666
|
-
_a.label = 1;
|
667
|
-
case 1:
|
668
|
-
if (!(i < commands.length)) return [3 /*break*/, 4];
|
669
|
-
this.showLoadingWarning(i / commands.length);
|
670
|
-
for (j = i; j < commands.length && j < i + updateChunkSize; j++) {
|
671
|
-
cmd = commands[j];
|
672
|
-
if (apply) {
|
673
|
-
cmd.apply(this);
|
674
|
-
}
|
675
|
-
else {
|
676
|
-
cmd.unapply(this);
|
677
|
-
}
|
678
|
-
}
|
679
|
-
if (!(i + updateChunkSize < commands.length)) return [3 /*break*/, 3];
|
680
|
-
return [4 /*yield*/, new Promise(function (resolve) {
|
681
|
-
_this.rerender();
|
682
|
-
requestAnimationFrame(resolve);
|
683
|
-
})];
|
684
|
-
case 2:
|
685
|
-
_a.sent();
|
686
|
-
_a.label = 3;
|
687
|
-
case 3:
|
688
|
-
i += updateChunkSize;
|
689
|
-
return [3 /*break*/, 1];
|
690
|
-
case 4:
|
691
|
-
this.display.setDraftMode(false);
|
692
|
-
this.hideLoadingWarning();
|
693
|
-
return [2 /*return*/];
|
680
|
+
async asyncApplyOrUnapplyCommands(commands, apply, updateChunkSize) {
|
681
|
+
console.assert(updateChunkSize > 0);
|
682
|
+
this.display.setDraftMode(true);
|
683
|
+
for (let i = 0; i < commands.length; i += updateChunkSize) {
|
684
|
+
this.showLoadingWarning(i / commands.length);
|
685
|
+
for (let j = i; j < commands.length && j < i + updateChunkSize; j++) {
|
686
|
+
const cmd = commands[j];
|
687
|
+
if (apply) {
|
688
|
+
cmd.apply(this);
|
694
689
|
}
|
695
|
-
|
696
|
-
|
697
|
-
|
690
|
+
else {
|
691
|
+
cmd.unapply(this);
|
692
|
+
}
|
693
|
+
}
|
694
|
+
// Re-render to show progress, but only if we're not done.
|
695
|
+
if (i + updateChunkSize < commands.length) {
|
696
|
+
await new Promise(resolve => {
|
697
|
+
this.rerender();
|
698
|
+
requestAnimationFrame(resolve);
|
699
|
+
});
|
700
|
+
}
|
701
|
+
}
|
702
|
+
this.display.setDraftMode(false);
|
703
|
+
this.hideLoadingWarning();
|
704
|
+
}
|
698
705
|
// @see {@link #asyncApplyOrUnapplyCommands }
|
699
|
-
|
706
|
+
asyncApplyCommands(commands, chunkSize) {
|
700
707
|
return this.asyncApplyOrUnapplyCommands(commands, true, chunkSize);
|
701
|
-
}
|
708
|
+
}
|
702
709
|
// If `unapplyInReverseOrder`, commands are reversed before unapplying.
|
703
710
|
// @see {@link #asyncApplyOrUnapplyCommands }
|
704
|
-
|
705
|
-
if (unapplyInReverseOrder === void 0) { unapplyInReverseOrder = false; }
|
711
|
+
asyncUnapplyCommands(commands, chunkSize, unapplyInReverseOrder = false) {
|
706
712
|
if (unapplyInReverseOrder) {
|
707
|
-
commands =
|
713
|
+
commands = [...commands]; // copy
|
708
714
|
commands.reverse();
|
709
715
|
}
|
710
716
|
return this.asyncApplyOrUnapplyCommands(commands, false, chunkSize);
|
711
|
-
}
|
717
|
+
}
|
712
718
|
/**
|
713
719
|
* Schedule a re-render for some time in the near future. Does not schedule an additional
|
714
720
|
* re-render if a re-render is already queued.
|
715
721
|
*
|
716
722
|
* @returns a promise that resolves when re-rendering has completed.
|
717
723
|
*/
|
718
|
-
|
719
|
-
var _this = this;
|
724
|
+
queueRerender() {
|
720
725
|
if (!this.rerenderQueued) {
|
721
726
|
this.rerenderQueued = true;
|
722
|
-
requestAnimationFrame(
|
727
|
+
requestAnimationFrame(() => {
|
723
728
|
// If .rerender was called manually, we might not need to
|
724
729
|
// re-render.
|
725
|
-
if (
|
726
|
-
|
727
|
-
|
730
|
+
if (this.rerenderQueued) {
|
731
|
+
this.rerender();
|
732
|
+
this.rerenderQueued = false;
|
728
733
|
}
|
729
734
|
});
|
730
735
|
}
|
731
|
-
return new Promise(
|
732
|
-
|
736
|
+
return new Promise(resolve => {
|
737
|
+
this.nextRerenderListeners.push(() => resolve());
|
733
738
|
});
|
734
|
-
}
|
739
|
+
}
|
735
740
|
// @internal
|
736
|
-
|
741
|
+
isRerenderQueued() {
|
737
742
|
return this.rerenderQueued;
|
738
|
-
}
|
743
|
+
}
|
739
744
|
/**
|
740
745
|
* Re-renders the entire image.
|
741
746
|
*
|
742
747
|
* @see {@link Editor.queueRerender}
|
743
748
|
*/
|
744
|
-
|
745
|
-
if (showImageBounds === void 0) { showImageBounds = true; }
|
749
|
+
rerender(showImageBounds = true) {
|
746
750
|
this.display.startRerender();
|
747
751
|
// Don't render if the display has zero size.
|
748
752
|
if (this.display.width === 0 || this.display.height === 0) {
|
749
753
|
return;
|
750
754
|
}
|
751
|
-
|
752
|
-
var renderer = this.display.getDryInkRenderer();
|
755
|
+
const renderer = this.display.getDryInkRenderer();
|
753
756
|
this.image.renderWithCache(renderer, this.display.getCache(), this.viewport);
|
754
757
|
if (showImageBounds) {
|
755
|
-
|
756
|
-
|
758
|
+
// Draw a rectangle around the region that will be visible on save
|
759
|
+
const exportRectFill = { fill: Color4.fromHex('#44444455') };
|
760
|
+
const exportRectStrokeWidth = 5 * this.viewport.getSizeOfPixelOnCanvas();
|
757
761
|
renderer.drawRect(this.getImportExportRect(), exportRectStrokeWidth, exportRectFill);
|
758
762
|
}
|
759
763
|
this.rerenderQueued = false;
|
760
|
-
this.nextRerenderListeners.forEach(
|
764
|
+
this.nextRerenderListeners.forEach(listener => listener());
|
761
765
|
this.nextRerenderListeners = [];
|
762
|
-
}
|
766
|
+
}
|
763
767
|
/**
|
764
768
|
* Draws the given path onto the wet ink renderer. The given path will
|
765
769
|
* be displayed on top of the main image.
|
766
770
|
*
|
767
771
|
* @see {@link Display.getWetInkRenderer} {@link Display.flatten}
|
768
772
|
*/
|
769
|
-
|
770
|
-
|
771
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
772
|
-
path[_i] = arguments[_i];
|
773
|
-
}
|
774
|
-
for (var _a = 0, path_1 = path; _a < path_1.length; _a++) {
|
775
|
-
var part = path_1[_a];
|
773
|
+
drawWetInk(...path) {
|
774
|
+
for (const part of path) {
|
776
775
|
this.display.getWetInkRenderer().drawPath(part);
|
777
776
|
}
|
778
|
-
}
|
777
|
+
}
|
779
778
|
/**
|
780
779
|
* Clears the wet ink display.
|
781
780
|
*
|
782
781
|
* @see {@link Display.getWetInkRenderer}
|
783
782
|
*/
|
784
|
-
|
783
|
+
clearWetInk() {
|
785
784
|
this.display.getWetInkRenderer().clear();
|
786
|
-
}
|
785
|
+
}
|
787
786
|
/**
|
788
787
|
* Focuses the region used for text input/key commands.
|
789
788
|
*/
|
790
|
-
|
789
|
+
focus() {
|
791
790
|
this.renderingRegion.focus();
|
792
|
-
}
|
791
|
+
}
|
793
792
|
/**
|
794
793
|
* Creates an element that will be positioned on top of the dry/wet ink
|
795
794
|
* renderers.
|
@@ -797,31 +796,42 @@ var Editor = /** @class */ (function () {
|
|
797
796
|
* This is useful for displaying content on top of the rendered content
|
798
797
|
* (e.g. a selection box).
|
799
798
|
*/
|
800
|
-
|
799
|
+
createHTMLOverlay(overlay) {
|
801
800
|
overlay.classList.add('overlay');
|
802
801
|
this.container.appendChild(overlay);
|
803
802
|
return {
|
804
|
-
remove:
|
803
|
+
remove: () => overlay.remove(),
|
805
804
|
};
|
806
|
-
}
|
807
|
-
|
808
|
-
|
805
|
+
}
|
806
|
+
addStyleSheet(content) {
|
807
|
+
const styleSheet = document.createElement('style');
|
809
808
|
styleSheet.innerText = content;
|
810
809
|
this.container.appendChild(styleSheet);
|
811
810
|
return styleSheet;
|
812
|
-
}
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
811
|
+
}
|
812
|
+
/**
|
813
|
+
* Dispatch a keyboard event to the currently selected tool.
|
814
|
+
* Intended for unit testing.
|
815
|
+
*
|
816
|
+
* If `shiftKey` is undefined, it is guessed from `key`.
|
817
|
+
*
|
818
|
+
* At present, the **key code** dispatched is guessed from the given key and,
|
819
|
+
* while this works for ASCII alphanumeric characters, this does not work for
|
820
|
+
* most non-alphanumeric keys.
|
821
|
+
*
|
822
|
+
* Because guessing the key code from `key` is problematic, **only use this for testing**.
|
823
|
+
*/
|
824
|
+
sendKeyboardEvent(eventType, key, ctrlKey = false, altKey = false, shiftKey = undefined) {
|
825
|
+
shiftKey ??= key.toUpperCase() === key && key.toLowerCase() !== key;
|
818
826
|
this.toolController.dispatchInputEvent({
|
819
827
|
kind: eventType,
|
820
|
-
key
|
821
|
-
|
822
|
-
|
828
|
+
key,
|
829
|
+
code: guessKeyCodeFromKey(key),
|
830
|
+
ctrlKey,
|
831
|
+
altKey,
|
832
|
+
shiftKey,
|
823
833
|
});
|
824
|
-
}
|
834
|
+
}
|
825
835
|
/**
|
826
836
|
* Dispatch a pen event to the currently selected tool.
|
827
837
|
* Intended primarially for unit tests.
|
@@ -829,227 +839,219 @@ var Editor = /** @class */ (function () {
|
|
829
839
|
* @deprecated
|
830
840
|
* @see {@link sendPenEvent} {@link sendTouchEvent}
|
831
841
|
*/
|
832
|
-
|
842
|
+
sendPenEvent(eventType, point,
|
833
843
|
// @deprecated
|
834
844
|
allPointers) {
|
835
845
|
sendPenEvent(this, eventType, point, allPointers);
|
836
|
-
}
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
case 1:
|
877
|
-
_d.sent();
|
878
|
-
if (selectComponents) {
|
879
|
-
for (_b = 0, _c = this.toolController.getMatchingTools(SelectionTool); _b < _c.length; _b++) {
|
880
|
-
selectionTool = _c[_b];
|
881
|
-
selectionTool.setEnabled(true);
|
882
|
-
selectionTool.setSelection(components);
|
883
|
-
}
|
884
|
-
}
|
885
|
-
return [2 /*return*/];
|
886
|
-
}
|
887
|
-
});
|
888
|
-
});
|
889
|
-
};
|
846
|
+
}
|
847
|
+
async addAndCenterComponents(components, selectComponents = true) {
|
848
|
+
let bbox = null;
|
849
|
+
for (const component of components) {
|
850
|
+
if (bbox) {
|
851
|
+
bbox = bbox.union(component.getBBox());
|
852
|
+
}
|
853
|
+
else {
|
854
|
+
bbox = component.getBBox();
|
855
|
+
}
|
856
|
+
}
|
857
|
+
if (!bbox) {
|
858
|
+
return;
|
859
|
+
}
|
860
|
+
// Find a transform that scales/moves bbox onto the screen.
|
861
|
+
const visibleRect = this.viewport.visibleRect;
|
862
|
+
const scaleRatioX = visibleRect.width / bbox.width;
|
863
|
+
const scaleRatioY = visibleRect.height / bbox.height;
|
864
|
+
let scaleRatio = scaleRatioX;
|
865
|
+
if (bbox.width * scaleRatio > visibleRect.width || bbox.height * scaleRatio > visibleRect.height) {
|
866
|
+
scaleRatio = scaleRatioY;
|
867
|
+
}
|
868
|
+
scaleRatio *= 2 / 3;
|
869
|
+
scaleRatio = Viewport.roundScaleRatio(scaleRatio);
|
870
|
+
const transfm = Mat33.translation(visibleRect.center.minus(bbox.center)).rightMul(Mat33.scaling2D(scaleRatio, bbox.center));
|
871
|
+
const commands = [];
|
872
|
+
for (const component of components) {
|
873
|
+
// To allow deserialization, we need to add first, then transform.
|
874
|
+
commands.push(EditorImage.addElement(component));
|
875
|
+
commands.push(component.transformBy(transfm));
|
876
|
+
}
|
877
|
+
const applyChunkSize = 100;
|
878
|
+
await this.dispatch(uniteCommands(commands, applyChunkSize), true);
|
879
|
+
if (selectComponents) {
|
880
|
+
for (const selectionTool of this.toolController.getMatchingTools(SelectionTool)) {
|
881
|
+
selectionTool.setEnabled(true);
|
882
|
+
selectionTool.setSelection(components);
|
883
|
+
}
|
884
|
+
}
|
885
|
+
}
|
890
886
|
// Get a data URL (e.g. as produced by `HTMLCanvasElement::toDataURL`).
|
891
887
|
// If `format` is not `image/png`, a PNG image URL may still be returned (as in the
|
892
888
|
// case of `HTMLCanvasElement::toDataURL`).
|
893
889
|
//
|
894
890
|
// The export resolution is the same as the size of the drawing canvas.
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
var resolution = outputSize !== null && outputSize !== void 0 ? outputSize : exportRectSize;
|
891
|
+
toDataURL(format = 'image/png', outputSize) {
|
892
|
+
const canvas = document.createElement('canvas');
|
893
|
+
const importExportViewport = this.image.getImportExportViewport();
|
894
|
+
const exportRectSize = importExportViewport.getScreenRectSize();
|
895
|
+
const resolution = outputSize ?? exportRectSize;
|
901
896
|
canvas.width = resolution.x;
|
902
897
|
canvas.height = resolution.y;
|
903
|
-
|
898
|
+
const ctx = canvas.getContext('2d');
|
904
899
|
// Scale to ensure that the entire output is visible.
|
905
|
-
|
900
|
+
const scaleFactor = Math.min(resolution.x / exportRectSize.x, resolution.y / exportRectSize.y);
|
906
901
|
ctx.scale(scaleFactor, scaleFactor);
|
907
|
-
|
902
|
+
const renderer = new CanvasRenderer(ctx, importExportViewport);
|
908
903
|
this.image.renderAll(renderer);
|
909
|
-
|
904
|
+
const dataURL = canvas.toDataURL(format);
|
910
905
|
return dataURL;
|
911
|
-
}
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
906
|
+
}
|
907
|
+
toSVG() {
|
908
|
+
const importExportViewport = this.image.getImportExportViewport().getTemporaryClone();
|
909
|
+
const sanitize = false;
|
910
|
+
const { element: result, renderer } = SVGRenderer.fromViewport(importExportViewport, sanitize);
|
911
|
+
const origTransform = importExportViewport.canvasToScreenTransform;
|
917
912
|
// Render with (0,0) at (0,0) — we'll handle translation with
|
918
913
|
// the viewBox property.
|
919
914
|
importExportViewport.resetTransform(Mat33.identity);
|
920
915
|
this.image.renderAll(renderer);
|
921
916
|
importExportViewport.resetTransform(origTransform);
|
922
917
|
// Just show the main region
|
923
|
-
|
924
|
-
result.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(
|
918
|
+
const rect = importExportViewport.visibleRect;
|
919
|
+
result.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(part => toRoundedString(part)).join(' '));
|
925
920
|
result.setAttribute('width', toRoundedString(rect.w));
|
926
921
|
result.setAttribute('height', toRoundedString(rect.h));
|
927
922
|
return result;
|
928
|
-
}
|
923
|
+
}
|
929
924
|
/**
|
930
925
|
* Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
|
931
926
|
*
|
932
927
|
* @see loadFromSVG
|
933
928
|
*/
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
return [2 /*return*/];
|
952
|
-
}
|
953
|
-
});
|
954
|
-
}); }, function (countProcessed, totalToProcess) {
|
955
|
-
if (countProcessed % 500 === 0) {
|
956
|
-
_this.showLoadingWarning(countProcessed / totalToProcess);
|
957
|
-
_this.rerender();
|
958
|
-
return untilNextAnimationFrame();
|
959
|
-
}
|
960
|
-
return null;
|
961
|
-
}, function (importExportRect) {
|
962
|
-
_this.dispatchNoAnnounce(_this.setImportExportRect(importExportRect), false);
|
963
|
-
_this.dispatchNoAnnounce(_this.viewport.zoomTo(importExportRect), false);
|
964
|
-
})];
|
965
|
-
case 1:
|
966
|
-
_a.sent();
|
967
|
-
if (!(this.image.getBackgroundComponents().length !== originalBackgrounds.length)) return [3 /*break*/, 3];
|
968
|
-
return [4 /*yield*/, this.dispatchNoAnnounce(eraseBackgroundCommand)];
|
969
|
-
case 2:
|
970
|
-
_a.sent();
|
971
|
-
_a.label = 3;
|
972
|
-
case 3:
|
973
|
-
this.hideLoadingWarning();
|
974
|
-
this.display.setDraftMode(false);
|
975
|
-
this.queueRerender();
|
976
|
-
return [2 /*return*/];
|
977
|
-
}
|
978
|
-
});
|
929
|
+
async loadFrom(loader) {
|
930
|
+
this.showLoadingWarning(0);
|
931
|
+
this.display.setDraftMode(true);
|
932
|
+
const originalBackgrounds = this.image.getBackgroundComponents();
|
933
|
+
const eraseBackgroundCommand = new Erase(originalBackgrounds);
|
934
|
+
await loader.start(async (component) => {
|
935
|
+
await this.dispatchNoAnnounce(EditorImage.addElement(component));
|
936
|
+
}, (countProcessed, totalToProcess) => {
|
937
|
+
if (countProcessed % 500 === 0) {
|
938
|
+
this.showLoadingWarning(countProcessed / totalToProcess);
|
939
|
+
this.rerender();
|
940
|
+
return untilNextAnimationFrame();
|
941
|
+
}
|
942
|
+
return null;
|
943
|
+
}, (importExportRect) => {
|
944
|
+
this.dispatchNoAnnounce(this.setImportExportRect(importExportRect), false);
|
945
|
+
this.dispatchNoAnnounce(this.viewport.zoomTo(importExportRect), false);
|
979
946
|
});
|
980
|
-
|
981
|
-
|
982
|
-
|
947
|
+
// Ensure that we don't have multiple overlapping BackgroundComponents. Remove
|
948
|
+
// old BackgroundComponents.
|
949
|
+
// Overlapping BackgroundComponents may cause changing the background color to
|
950
|
+
// not work properly.
|
951
|
+
if (this.image.getBackgroundComponents().length !== originalBackgrounds.length) {
|
952
|
+
await this.dispatchNoAnnounce(eraseBackgroundCommand);
|
953
|
+
}
|
954
|
+
this.hideLoadingWarning();
|
955
|
+
this.display.setDraftMode(false);
|
956
|
+
this.queueRerender();
|
957
|
+
}
|
958
|
+
getTopmostBackgroundComponent() {
|
959
|
+
let background = null;
|
983
960
|
// Find a background component, if one exists.
|
984
961
|
// Use the last (topmost) background component if there are multiple.
|
985
|
-
for (
|
986
|
-
var component = _a[_i];
|
962
|
+
for (const component of this.image.getBackgroundComponents()) {
|
987
963
|
if (component instanceof BackgroundComponent) {
|
988
964
|
background = component;
|
989
965
|
}
|
990
966
|
}
|
991
967
|
return background;
|
992
|
-
}
|
968
|
+
}
|
993
969
|
/**
|
994
970
|
* Set the background color of the image.
|
995
971
|
*/
|
996
|
-
|
997
|
-
|
972
|
+
setBackgroundColor(color) {
|
973
|
+
let background = this.getTopmostBackgroundComponent();
|
998
974
|
if (!background) {
|
999
|
-
|
975
|
+
const backgroundType = color.eq(Color4.transparent) ? BackgroundType.None : BackgroundType.SolidColor;
|
1000
976
|
background = new BackgroundComponent(backgroundType, color);
|
1001
977
|
return this.image.addElement(background);
|
1002
978
|
}
|
1003
979
|
else {
|
1004
|
-
return background.updateStyle({ color
|
980
|
+
return background.updateStyle({ color });
|
1005
981
|
}
|
1006
|
-
}
|
982
|
+
}
|
1007
983
|
/**
|
1008
984
|
* @returns the average of the colors of all background components. Use this to get the current background
|
1009
985
|
* color.
|
1010
986
|
*/
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
for (var _i = 0, _b = this.image.getBackgroundComponents(); _i < _b.length; _i++) {
|
1015
|
-
var component = _b[_i];
|
987
|
+
estimateBackgroundColor() {
|
988
|
+
const backgroundColors = [];
|
989
|
+
for (const component of this.image.getBackgroundComponents()) {
|
1016
990
|
if (component instanceof BackgroundComponent) {
|
1017
|
-
backgroundColors.push(
|
991
|
+
backgroundColors.push(component.getStyle().color ?? Color4.transparent);
|
1018
992
|
}
|
1019
993
|
}
|
1020
994
|
return Color4.average(backgroundColors);
|
1021
|
-
}
|
995
|
+
}
|
1022
996
|
// Returns the size of the visible region of the output SVG
|
1023
|
-
|
997
|
+
getImportExportRect() {
|
1024
998
|
return this.image.getImportExportViewport().visibleRect;
|
1025
|
-
}
|
999
|
+
}
|
1026
1000
|
// Resize the output SVG to match `imageRect`.
|
1027
|
-
|
1001
|
+
setImportExportRect(imageRect) {
|
1028
1002
|
return this.image.setImportExportRect(imageRect);
|
1029
|
-
}
|
1003
|
+
}
|
1030
1004
|
/**
|
1031
|
-
* Alias for loadFrom(SVGLoader.fromString)
|
1005
|
+
* Alias for `loadFrom(SVGLoader.fromString)`.
|
1032
1006
|
*
|
1033
1007
|
* This is particularly useful when accessing a bundled version of the editor,
|
1034
1008
|
* where `SVGLoader.fromString` is unavailable.
|
1035
1009
|
*/
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1010
|
+
async loadFromSVG(svgData, sanitize = false) {
|
1011
|
+
const loader = SVGLoader.fromString(svgData, sanitize);
|
1012
|
+
await this.loadFrom(loader);
|
1013
|
+
}
|
1014
|
+
/**
|
1015
|
+
* Shows an information dialog with legal notices.
|
1016
|
+
*/
|
1017
|
+
showAboutDialog() {
|
1018
|
+
const iconLicenseText = this.icons.licenseInfo();
|
1019
|
+
const notices = [];
|
1020
|
+
notices.push({
|
1021
|
+
heading: { kind: 'link', text: 'js-draw', href: 'https://github.com/personalizedrefrigerator/js-draw' },
|
1022
|
+
text: [
|
1023
|
+
`v${version.number}`,
|
1024
|
+
'',
|
1025
|
+
'Image debug information (from when this dialog was opened):',
|
1026
|
+
` ${this.viewport.getScaleFactor()}x zoom, ${180 / Math.PI * this.viewport.getRotationAngle()} rotation`,
|
1027
|
+
` ${this.image.estimateNumElements()} components`,
|
1028
|
+
` ${this.getImportExportRect().w}x${this.getImportExportRect().h} size`,
|
1029
|
+
].join('\n'),
|
1030
|
+
});
|
1031
|
+
notices.push({
|
1032
|
+
heading: 'Libraries',
|
1033
|
+
text: [
|
1034
|
+
'js-draw uses several libraries at runtime. Particularly noteworthy are:',
|
1035
|
+
' - The Coloris color picker: https://github.com/mdbassit/Coloris',
|
1036
|
+
' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs'
|
1037
|
+
].join('\n'),
|
1038
|
+
minimized: true,
|
1050
1039
|
});
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1040
|
+
if (iconLicenseText) {
|
1041
|
+
notices.push({
|
1042
|
+
heading: 'Icon Pack',
|
1043
|
+
text: iconLicenseText,
|
1044
|
+
minimized: true,
|
1045
|
+
});
|
1046
|
+
}
|
1047
|
+
notices.push(...this.settings.notices);
|
1048
|
+
this.closeAboutDialog?.();
|
1049
|
+
this.closeAboutDialog = makeAboutDialog(this, notices).close;
|
1050
|
+
}
|
1051
|
+
/** Removes and destroys the editor */
|
1052
|
+
remove() {
|
1053
|
+
this.container.remove();
|
1054
|
+
// TODO: Is additional cleanup necessary here?
|
1055
|
+
}
|
1056
|
+
}
|
1055
1057
|
export default Editor;
|