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