js-draw 1.21.2 → 1.22.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +103 -75
- package/build-config.json +2 -2
- package/dist/Editor.css +29 -16
- package/dist/bundle.js +2 -2
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.js +36 -22
- package/dist/cjs/EventDispatcher.js +1 -1
- package/dist/cjs/Pointer.js +3 -3
- package/dist/cjs/SVGLoader/SVGLoader.js +13 -6
- package/dist/cjs/UndoRedoHistory.js +1 -1
- package/dist/cjs/Viewport.js +4 -2
- package/dist/cjs/commands/Command.js +7 -5
- package/dist/cjs/commands/Duplicate.js +2 -2
- package/dist/cjs/commands/Erase.js +3 -4
- package/dist/cjs/commands/invertCommand.js +4 -4
- package/dist/cjs/commands/lib.d.ts +1 -1
- package/dist/cjs/commands/uniteCommands.js +4 -4
- package/dist/cjs/components/AbstractComponent.d.ts +1 -1
- package/dist/cjs/components/AbstractComponent.js +3 -3
- package/dist/cjs/components/BackgroundComponent.js +8 -6
- package/dist/cjs/components/ImageComponent.js +12 -5
- package/dist/cjs/components/RestylableComponent.js +1 -1
- package/dist/cjs/components/SVGGlobalAttributesObject.js +1 -2
- package/dist/cjs/components/Stroke.js +37 -24
- package/dist/cjs/components/TextComponent.js +13 -10
- package/dist/cjs/components/UnknownSVGObject.js +2 -3
- package/dist/cjs/components/builders/ArrowBuilder.d.ts +6 -0
- package/dist/cjs/components/builders/ArrowBuilder.js +9 -3
- package/dist/cjs/components/builders/CircleBuilder.d.ts +6 -0
- package/dist/cjs/components/builders/CircleBuilder.js +11 -4
- package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +6 -0
- package/dist/cjs/components/builders/FreehandLineBuilder.js +10 -4
- package/dist/cjs/components/builders/LineBuilder.d.ts +6 -0
- package/dist/cjs/components/builders/LineBuilder.js +8 -4
- package/dist/cjs/components/builders/PolylineBuilder.d.ts +4 -1
- package/dist/cjs/components/builders/PolylineBuilder.js +9 -5
- package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +16 -10
- package/dist/cjs/components/builders/RectangleBuilder.d.ts +12 -0
- package/dist/cjs/components/builders/RectangleBuilder.js +17 -3
- package/dist/cjs/components/builders/autocorrect/makeShapeFitAutocorrect.js +5 -8
- package/dist/cjs/components/builders/autocorrect/makeSnapToGridAutocorrect.js +1 -1
- package/dist/cjs/components/builders/lib.d.ts +7 -0
- package/dist/cjs/components/builders/lib.js +18 -0
- package/dist/cjs/components/lib.d.ts +1 -4
- package/dist/cjs/components/lib.js +2 -9
- package/dist/cjs/components/util/StrokeSmoother.js +5 -6
- package/dist/cjs/dialogs/makeAboutDialog.js +1 -1
- package/dist/cjs/dialogs/makeMessageDialog.js +2 -2
- package/dist/cjs/image/EditorImage.js +13 -15
- package/dist/cjs/image/export/editorImageToSVG.js +1 -1
- package/dist/cjs/inputEvents.js +3 -3
- package/dist/cjs/lib.d.ts +2 -2
- package/dist/cjs/localizations/de.js +2 -2
- package/dist/cjs/localizations/es.js +7 -3
- package/dist/cjs/rendering/Display.js +7 -3
- package/dist/cjs/rendering/RenderablePathSpec.js +26 -11
- package/dist/cjs/rendering/RenderingStyle.js +22 -15
- package/dist/cjs/rendering/TextRenderingStyle.js +1 -1
- package/dist/cjs/rendering/caching/CacheRecord.js +1 -1
- package/dist/cjs/rendering/caching/CacheRecordManager.js +1 -1
- package/dist/cjs/rendering/caching/RenderingCache.js +1 -1
- package/dist/cjs/rendering/caching/RenderingCacheNode.js +26 -15
- package/dist/cjs/rendering/caching/testUtils.js +2 -2
- package/dist/cjs/rendering/renderers/AbstractRenderer.js +3 -1
- package/dist/cjs/rendering/renderers/CanvasRenderer.js +4 -3
- package/dist/cjs/rendering/renderers/DummyRenderer.js +1 -1
- package/dist/cjs/rendering/renderers/SVGRenderer.js +37 -19
- package/dist/cjs/rendering/renderers/TextOnlyRenderer.js +13 -15
- package/dist/cjs/shortcuts/KeyBinding.js +6 -12
- package/dist/cjs/shortcuts/KeyboardShortcutManager.js +2 -2
- package/dist/cjs/testing/createEditor.js +6 -1
- package/dist/cjs/testing/findNodeWithText.d.ts +4 -1
- package/dist/cjs/testing/findNodeWithText.js +12 -3
- package/dist/cjs/testing/getUniquePointerId.js +1 -1
- package/dist/cjs/testing/sendHtmlSwipe.js +7 -3
- package/dist/cjs/testing/sendPenEvent.js +1 -3
- package/dist/cjs/testing/sendTouchEvent.js +1 -4
- package/dist/cjs/testing/startPinchGesture.js +3 -1
- package/dist/cjs/toolbar/AbstractToolbar.js +7 -11
- package/dist/cjs/toolbar/EdgeToolbar.js +11 -15
- package/dist/cjs/toolbar/IconProvider.js +5 -3
- package/dist/cjs/toolbar/localization.js +3 -3
- package/dist/cjs/toolbar/utils/HelpDisplay.js +8 -6
- package/dist/cjs/toolbar/utils/makeDraggable.js +4 -7
- package/dist/cjs/toolbar/widgets/BaseToolWidget.js +3 -2
- package/dist/cjs/toolbar/widgets/BaseWidget.js +7 -7
- package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +2 -2
- package/dist/cjs/toolbar/widgets/EraserToolWidget.js +5 -3
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +8 -6
- package/dist/cjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.js +9 -10
- package/dist/cjs/toolbar/widgets/PenToolWidget.js +22 -13
- package/dist/cjs/toolbar/widgets/SelectionToolWidget.js +2 -2
- package/dist/cjs/toolbar/widgets/TextToolWidget.js +5 -5
- package/dist/cjs/toolbar/widgets/components/makeFileInput.js +7 -7
- package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +5 -5
- package/dist/cjs/toolbar/widgets/components/makeSnappedList.js +9 -5
- package/dist/cjs/toolbar/widgets/keybindings.js +2 -2
- package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.js +6 -6
- package/dist/cjs/tools/BaseTool.d.ts +61 -0
- package/dist/cjs/tools/BaseTool.js +181 -0
- package/dist/cjs/tools/Eraser.d.ts +60 -0
- package/dist/cjs/tools/Eraser.js +304 -0
- package/dist/cjs/tools/Eraser.test.d.ts +1 -0
- package/dist/cjs/tools/FindTool.d.ts +21 -0
- package/dist/cjs/tools/FindTool.js +137 -0
- package/dist/cjs/tools/FindTool.test.d.ts +1 -0
- package/dist/cjs/tools/InputFilter/ContextMenuRecognizer.d.ts +17 -0
- package/dist/cjs/tools/InputFilter/ContextMenuRecognizer.js +103 -0
- package/dist/cjs/tools/InputFilter/ContextMenuRecognizer.test.d.ts +1 -0
- 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/InputPipeline.test.d.ts +1 -0
- package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
- package/dist/cjs/tools/InputFilter/InputStabilizer.js +188 -0
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +87 -0
- package/dist/cjs/tools/PanZoom.d.ts +125 -0
- package/dist/cjs/tools/PanZoom.js +522 -0
- package/dist/cjs/tools/PanZoom.test.d.ts +1 -0
- package/dist/cjs/tools/PasteHandler.d.ts +23 -0
- package/dist/cjs/tools/PasteHandler.js +115 -0
- package/dist/cjs/tools/Pen.d.ts +54 -0
- package/dist/cjs/tools/Pen.js +343 -0
- package/dist/cjs/tools/Pen.test.d.ts +1 -0
- package/dist/cjs/tools/PipetteTool.d.ts +28 -0
- package/dist/cjs/tools/PipetteTool.js +69 -0
- package/dist/cjs/tools/ScrollbarTool.d.ts +18 -0
- package/dist/cjs/tools/ScrollbarTool.js +86 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +9 -0
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +32 -0
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +72 -0
- package/dist/cjs/tools/SelectionTool/Selection.js +638 -0
- package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +62 -0
- package/dist/cjs/tools/SelectionTool/SelectionHandle.js +144 -0
- package/dist/cjs/tools/SelectionTool/SelectionMenuShortcut.d.ts +32 -0
- package/dist/cjs/tools/SelectionTool/SelectionMenuShortcut.js +88 -0
- package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +42 -0
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +509 -0
- package/dist/cjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +1 -0
- package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +1 -0
- package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +23 -0
- package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +83 -0
- package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +42 -0
- package/dist/cjs/tools/SelectionTool/TransformMode.js +154 -0
- package/dist/cjs/tools/SelectionTool/keybindings.d.ts +15 -0
- package/dist/cjs/tools/SelectionTool/keybindings.js +38 -0
- package/dist/cjs/tools/SelectionTool/types.d.ts +35 -0
- package/dist/cjs/tools/SelectionTool/types.js +14 -0
- package/dist/cjs/tools/SelectionTool/util/makeClipboardErrorHandlers.d.ts +6 -0
- package/dist/cjs/tools/SelectionTool/util/makeClipboardErrorHandlers.js +71 -0
- package/dist/cjs/tools/SelectionTool/util/showSelectionContextMenu.d.ts +5 -0
- package/dist/cjs/tools/SelectionTool/util/showSelectionContextMenu.js +52 -0
- package/dist/cjs/tools/SoundUITool.d.ts +26 -0
- package/dist/cjs/tools/SoundUITool.js +173 -0
- package/dist/cjs/tools/TextTool.d.ts +36 -0
- package/dist/cjs/tools/TextTool.js +287 -0
- package/dist/cjs/tools/TextTool.test.d.ts +1 -0
- package/dist/cjs/tools/ToolController.d.ts +73 -0
- package/dist/cjs/tools/ToolController.js +310 -0
- package/dist/cjs/tools/ToolController.test.d.ts +1 -0
- package/dist/cjs/tools/ToolEnabledGroup.d.ts +6 -0
- package/dist/cjs/tools/ToolEnabledGroup.js +13 -0
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +16 -0
- package/dist/cjs/tools/ToolSwitcherShortcut.js +40 -0
- package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +12 -0
- package/dist/cjs/tools/ToolbarShortcutHandler.js +34 -0
- package/dist/cjs/tools/UndoRedoShortcut.d.ts +8 -0
- package/dist/cjs/tools/UndoRedoShortcut.js +27 -0
- package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +1 -0
- package/dist/cjs/tools/keybindings.d.ts +16 -0
- package/dist/cjs/tools/keybindings.js +58 -0
- package/dist/cjs/tools/lib.d.ts +14 -0
- package/dist/cjs/tools/lib.js +36 -0
- package/dist/cjs/tools/localization.d.ts +45 -0
- package/dist/cjs/tools/localization.js +47 -0
- package/dist/cjs/tools/util/StationaryPenDetector.d.ts +25 -0
- package/dist/cjs/tools/util/StationaryPenDetector.js +107 -0
- package/dist/cjs/tools/util/createMenuOverlay.d.ts +10 -0
- package/dist/cjs/tools/util/createMenuOverlay.js +126 -0
- package/dist/cjs/tools/util/createMenuOverlay.test.d.ts +1 -0
- package/dist/cjs/util/ClipboardHandler.d.ts +1 -1
- package/dist/cjs/util/ClipboardHandler.js +19 -18
- package/dist/cjs/util/ReactiveValue.js +16 -12
- package/dist/cjs/util/adjustEditorThemeForContrast.js +6 -2
- package/dist/cjs/util/guessKeyCodeFromKey.js +1 -1
- package/dist/cjs/util/listenForKeyboardEventsFrom.js +8 -6
- package/dist/cjs/util/waitForAll.js +3 -3
- package/dist/cjs/util/waitForImageLoaded.js +3 -3
- package/dist/cjs/util/waitForTimeout.js +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.mjs +37 -23
- package/dist/mjs/EventDispatcher.mjs +1 -1
- package/dist/mjs/Pointer.mjs +3 -3
- package/dist/mjs/SVGLoader/SVGLoader.mjs +14 -7
- package/dist/mjs/UndoRedoHistory.mjs +1 -1
- package/dist/mjs/Viewport.mjs +4 -2
- package/dist/mjs/commands/Command.mjs +7 -5
- package/dist/mjs/commands/Duplicate.mjs +2 -2
- package/dist/mjs/commands/Erase.mjs +3 -4
- package/dist/mjs/commands/invertCommand.mjs +4 -4
- package/dist/mjs/commands/lib.d.ts +1 -1
- package/dist/mjs/commands/lib.mjs +1 -1
- package/dist/mjs/commands/uniteCommands.mjs +4 -4
- package/dist/mjs/components/AbstractComponent.d.ts +1 -1
- package/dist/mjs/components/AbstractComponent.mjs +3 -3
- package/dist/mjs/components/BackgroundComponent.mjs +10 -8
- package/dist/mjs/components/ImageComponent.mjs +12 -5
- package/dist/mjs/components/RestylableComponent.mjs +2 -2
- package/dist/mjs/components/SVGGlobalAttributesObject.mjs +1 -2
- package/dist/mjs/components/Stroke.mjs +40 -27
- package/dist/mjs/components/TextComponent.mjs +15 -12
- package/dist/mjs/components/UnknownSVGObject.mjs +2 -3
- package/dist/mjs/components/builders/ArrowBuilder.d.ts +6 -0
- package/dist/mjs/components/builders/ArrowBuilder.mjs +9 -3
- package/dist/mjs/components/builders/CircleBuilder.d.ts +6 -0
- package/dist/mjs/components/builders/CircleBuilder.mjs +11 -4
- package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +6 -0
- package/dist/mjs/components/builders/FreehandLineBuilder.mjs +10 -4
- package/dist/mjs/components/builders/LineBuilder.d.ts +6 -0
- package/dist/mjs/components/builders/LineBuilder.mjs +8 -4
- package/dist/mjs/components/builders/PolylineBuilder.d.ts +4 -1
- package/dist/mjs/components/builders/PolylineBuilder.mjs +10 -6
- package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +17 -11
- package/dist/mjs/components/builders/RectangleBuilder.d.ts +12 -0
- package/dist/mjs/components/builders/RectangleBuilder.mjs +17 -3
- package/dist/mjs/components/builders/autocorrect/makeShapeFitAutocorrect.mjs +5 -8
- package/dist/mjs/components/builders/autocorrect/makeSnapToGridAutocorrect.mjs +1 -1
- package/dist/mjs/components/builders/lib.d.ts +7 -0
- package/dist/mjs/components/builders/lib.mjs +7 -0
- package/dist/mjs/components/lib.d.ts +1 -4
- package/dist/mjs/components/lib.mjs +2 -5
- package/dist/mjs/components/util/StrokeSmoother.mjs +5 -6
- package/dist/mjs/dialogs/makeAboutDialog.mjs +1 -1
- package/dist/mjs/dialogs/makeMessageDialog.mjs +2 -2
- package/dist/mjs/image/EditorImage.mjs +13 -15
- package/dist/mjs/image/export/editorImageToSVG.mjs +1 -1
- package/dist/mjs/inputEvents.mjs +3 -3
- package/dist/mjs/lib.d.ts +2 -2
- package/dist/mjs/lib.mjs +2 -2
- package/dist/mjs/localization.mjs +2 -2
- package/dist/mjs/localizations/de.mjs +2 -2
- package/dist/mjs/localizations/es.mjs +7 -3
- package/dist/mjs/rendering/Display.mjs +7 -3
- package/dist/mjs/rendering/RenderablePathSpec.mjs +26 -11
- package/dist/mjs/rendering/RenderingStyle.mjs +22 -15
- package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -1
- package/dist/mjs/rendering/caching/CacheRecord.mjs +1 -1
- package/dist/mjs/rendering/caching/CacheRecordManager.mjs +1 -1
- package/dist/mjs/rendering/caching/RenderingCache.mjs +1 -1
- package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +26 -15
- package/dist/mjs/rendering/caching/testUtils.mjs +2 -2
- package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +3 -1
- package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +4 -3
- package/dist/mjs/rendering/renderers/DummyRenderer.mjs +1 -1
- package/dist/mjs/rendering/renderers/SVGRenderer.mjs +38 -20
- package/dist/mjs/rendering/renderers/TextOnlyRenderer.mjs +13 -15
- package/dist/mjs/shortcuts/KeyBinding.mjs +6 -12
- package/dist/mjs/shortcuts/KeyboardShortcutManager.mjs +2 -2
- package/dist/mjs/testing/createEditor.mjs +6 -1
- package/dist/mjs/testing/findNodeWithText.d.ts +4 -1
- package/dist/mjs/testing/findNodeWithText.mjs +12 -3
- package/dist/mjs/testing/getUniquePointerId.mjs +1 -1
- package/dist/mjs/testing/sendHtmlSwipe.mjs +7 -3
- package/dist/mjs/testing/sendPenEvent.mjs +1 -3
- package/dist/mjs/testing/sendTouchEvent.mjs +1 -4
- package/dist/mjs/testing/startPinchGesture.mjs +3 -1
- package/dist/mjs/toolbar/AbstractToolbar.mjs +7 -11
- package/dist/mjs/toolbar/EdgeToolbar.mjs +11 -15
- package/dist/mjs/toolbar/IconProvider.mjs +5 -3
- package/dist/mjs/toolbar/localization.mjs +3 -3
- package/dist/mjs/toolbar/utils/HelpDisplay.mjs +8 -6
- package/dist/mjs/toolbar/utils/makeDraggable.mjs +4 -7
- package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +3 -2
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +8 -8
- package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +2 -2
- package/dist/mjs/toolbar/widgets/EraserToolWidget.mjs +5 -3
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +8 -6
- package/dist/mjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.mjs +9 -10
- package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +23 -14
- package/dist/mjs/toolbar/widgets/SelectionToolWidget.mjs +2 -2
- package/dist/mjs/toolbar/widgets/TextToolWidget.mjs +5 -5
- package/dist/mjs/toolbar/widgets/components/makeFileInput.mjs +7 -7
- package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +5 -5
- package/dist/mjs/toolbar/widgets/components/makeSnappedList.mjs +9 -5
- package/dist/mjs/toolbar/widgets/keybindings.mjs +2 -2
- package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.mjs +6 -6
- package/dist/mjs/tools/BaseTool.d.ts +61 -0
- package/dist/mjs/tools/BaseTool.mjs +179 -0
- package/dist/mjs/tools/Eraser.d.ts +60 -0
- package/dist/mjs/tools/Eraser.mjs +297 -0
- package/dist/mjs/tools/Eraser.test.d.ts +1 -0
- package/dist/mjs/tools/FindTool.d.ts +21 -0
- package/dist/mjs/tools/FindTool.mjs +131 -0
- package/dist/mjs/tools/FindTool.test.d.ts +1 -0
- package/dist/mjs/tools/InputFilter/ContextMenuRecognizer.d.ts +17 -0
- package/dist/mjs/tools/InputFilter/ContextMenuRecognizer.mjs +74 -0
- package/dist/mjs/tools/InputFilter/ContextMenuRecognizer.test.d.ts +1 -0
- 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/InputPipeline.test.d.ts +1 -0
- package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
- package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +182 -0
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +81 -0
- package/dist/mjs/tools/PanZoom.d.ts +125 -0
- package/dist/mjs/tools/PanZoom.mjs +515 -0
- package/dist/mjs/tools/PanZoom.test.d.ts +1 -0
- package/dist/mjs/tools/PasteHandler.d.ts +23 -0
- package/dist/mjs/tools/PasteHandler.mjs +109 -0
- package/dist/mjs/tools/Pen.d.ts +54 -0
- package/dist/mjs/tools/Pen.mjs +314 -0
- package/dist/mjs/tools/Pen.test.d.ts +1 -0
- package/dist/mjs/tools/PipetteTool.d.ts +28 -0
- package/dist/mjs/tools/PipetteTool.mjs +63 -0
- package/dist/mjs/tools/ScrollbarTool.d.ts +18 -0
- package/dist/mjs/tools/ScrollbarTool.mjs +80 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +9 -0
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +26 -0
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +72 -0
- package/dist/mjs/tools/SelectionTool/Selection.mjs +610 -0
- package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +62 -0
- package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +140 -0
- package/dist/mjs/tools/SelectionTool/SelectionMenuShortcut.d.ts +32 -0
- package/dist/mjs/tools/SelectionTool/SelectionMenuShortcut.mjs +85 -0
- package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +42 -0
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +502 -0
- package/dist/mjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +1 -0
- package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +1 -0
- package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +23 -0
- package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +77 -0
- package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +42 -0
- package/dist/mjs/tools/SelectionTool/TransformMode.mjs +145 -0
- package/dist/mjs/tools/SelectionTool/keybindings.d.ts +15 -0
- package/dist/mjs/tools/SelectionTool/keybindings.mjs +32 -0
- package/dist/mjs/tools/SelectionTool/types.d.ts +35 -0
- package/dist/mjs/tools/SelectionTool/types.mjs +11 -0
- package/dist/mjs/tools/SelectionTool/util/makeClipboardErrorHandlers.d.ts +6 -0
- package/dist/mjs/tools/SelectionTool/util/makeClipboardErrorHandlers.mjs +66 -0
- package/dist/mjs/tools/SelectionTool/util/showSelectionContextMenu.d.ts +5 -0
- package/dist/mjs/tools/SelectionTool/util/showSelectionContextMenu.mjs +47 -0
- package/dist/mjs/tools/SoundUITool.d.ts +26 -0
- package/dist/mjs/tools/SoundUITool.mjs +167 -0
- package/dist/mjs/tools/TextTool.d.ts +36 -0
- package/dist/mjs/tools/TextTool.mjs +281 -0
- package/dist/mjs/tools/TextTool.test.d.ts +1 -0
- package/dist/mjs/tools/ToolController.d.ts +73 -0
- package/dist/mjs/tools/ToolController.mjs +281 -0
- package/dist/mjs/tools/ToolController.test.d.ts +1 -0
- package/dist/mjs/tools/ToolEnabledGroup.d.ts +6 -0
- package/dist/mjs/tools/ToolEnabledGroup.mjs +10 -0
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +16 -0
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +34 -0
- package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +12 -0
- package/dist/mjs/tools/ToolbarShortcutHandler.mjs +28 -0
- package/dist/mjs/tools/UndoRedoShortcut.d.ts +8 -0
- package/dist/mjs/tools/UndoRedoShortcut.mjs +21 -0
- package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +1 -0
- package/dist/mjs/tools/keybindings.d.ts +16 -0
- package/dist/mjs/tools/keybindings.mjs +38 -0
- package/dist/mjs/tools/lib.d.ts +14 -0
- package/dist/mjs/tools/lib.mjs +14 -0
- package/dist/mjs/tools/localization.d.ts +45 -0
- package/dist/mjs/tools/localization.mjs +44 -0
- package/dist/mjs/tools/util/StationaryPenDetector.d.ts +25 -0
- package/dist/mjs/tools/util/StationaryPenDetector.mjs +103 -0
- package/dist/mjs/tools/util/createMenuOverlay.d.ts +10 -0
- package/dist/mjs/tools/util/createMenuOverlay.mjs +121 -0
- package/dist/mjs/tools/util/createMenuOverlay.test.d.ts +1 -0
- package/dist/mjs/util/ClipboardHandler.d.ts +1 -1
- package/dist/mjs/util/ClipboardHandler.mjs +19 -18
- package/dist/mjs/util/ReactiveValue.mjs +16 -12
- package/dist/mjs/util/adjustEditorThemeForContrast.mjs +6 -2
- package/dist/mjs/util/guessKeyCodeFromKey.mjs +1 -1
- package/dist/mjs/util/listenForKeyboardEventsFrom.mjs +8 -6
- package/dist/mjs/util/waitForAll.mjs +3 -3
- package/dist/mjs/util/waitForImageLoaded.mjs +3 -3
- package/dist/mjs/util/waitForTimeout.mjs +1 -1
- package/dist/mjs/version.mjs +1 -1
- package/package.json +88 -88
- package/src/Coloris.css +6 -6
- package/src/Editor.scss +7 -5
- package/src/dialogs/dialogs.scss +3 -4
- package/src/dialogs/makeAboutDialog.scss +2 -2
- package/src/dialogs/makeMessageDialog.scss +11 -7
- package/src/styles.js +1 -1
- package/src/toolbar/AbstractToolbar.scss +20 -12
- package/src/toolbar/DropdownToolbar.scss +5 -4
- package/src/toolbar/EdgeToolbar.scss +65 -31
- package/src/toolbar/toolbar.scss +5 -5
- package/src/toolbar/utils/HelpDisplay.scss +48 -25
- package/src/toolbar/utils/labelVisibleOnHover.scss +39 -16
- package/src/toolbar/widgets/DocumentPropertiesWidget.scss +0 -1
- package/src/toolbar/widgets/HandToolWidget.scss +0 -1
- package/src/toolbar/widgets/InsertImageWidget/InsertImageWidget.scss +2 -3
- package/src/toolbar/widgets/OverflowWidget.css +1 -2
- package/src/toolbar/widgets/PenToolWidget.scss +0 -2
- package/src/toolbar/widgets/SelectionToolWidget.scss +1 -2
- package/src/toolbar/widgets/components/components.scss +6 -6
- package/src/toolbar/widgets/components/makeColorInput.scss +0 -2
- package/src/toolbar/widgets/components/makeFileInput.scss +5 -7
- package/src/toolbar/widgets/components/makeGridSelector.scss +6 -9
- package/src/toolbar/widgets/components/makeSnappedList.scss +3 -4
- package/src/toolbar/widgets/components/makeThicknessSlider.scss +1 -2
- package/src/toolbar/widgets/widgets.scss +7 -7
- package/src/tools/FindTool.css +6 -0
- package/src/tools/ScrollbarTool.scss +61 -0
- package/src/tools/SelectionTool/SelectionTool.scss +173 -0
- package/src/tools/SelectionTool/util/makeClipboardErrorHandlers.scss +14 -0
- package/src/tools/SoundUITool.scss +22 -0
- package/src/tools/tools.scss +5 -0
- package/src/tools/util/createMenuOverlay.scss +73 -0
- package/tsconfig.json +1 -3
- package/typedoc.json +1 -1
@@ -51,7 +51,7 @@ class Erase extends SerializableCommand_1.default {
|
|
51
51
|
constructor(toRemove) {
|
52
52
|
super('erase');
|
53
53
|
// Clone the list
|
54
|
-
this.toRemove = toRemove.map(elem => elem);
|
54
|
+
this.toRemove = toRemove.map((elem) => elem);
|
55
55
|
this.applied = false;
|
56
56
|
}
|
57
57
|
apply(editor) {
|
@@ -91,7 +91,7 @@ class Erase extends SerializableCommand_1.default {
|
|
91
91
|
serializeToJSON() {
|
92
92
|
// If applied, the elements can't be fetched from the image because they're
|
93
93
|
// erased. Serialize and return the elements themselves.
|
94
|
-
const elems = this.toRemove.map(elem => elem.serialize());
|
94
|
+
const elems = this.toRemove.map((elem) => elem.serialize());
|
95
95
|
return elems;
|
96
96
|
}
|
97
97
|
}
|
@@ -100,8 +100,7 @@ class Erase extends SerializableCommand_1.default {
|
|
100
100
|
if (!Array.isArray(json)) {
|
101
101
|
throw new Error('seralized erase data must be an array');
|
102
102
|
}
|
103
|
-
const elems = json
|
104
|
-
.map((elemData) => {
|
103
|
+
const elems = json.map((elemData) => {
|
105
104
|
const componentId = typeof elemData === 'string' ? elemData : `${elemData.id}`;
|
106
105
|
const component = editor.image.lookupElement(componentId) ?? AbstractComponent_1.default.deserialize(elemData);
|
107
106
|
return component;
|
@@ -10,7 +10,7 @@ const SerializableCommand_1 = __importDefault(require("./SerializableCommand"));
|
|
10
10
|
const invertCommand = (command) => {
|
11
11
|
if (command instanceof SerializableCommand_1.default) {
|
12
12
|
// SerializableCommand that does the inverse of [command]
|
13
|
-
return new class extends SerializableCommand_1.default {
|
13
|
+
return new (class extends SerializableCommand_1.default {
|
14
14
|
constructor() {
|
15
15
|
super(...arguments);
|
16
16
|
// For debugging
|
@@ -31,11 +31,11 @@ const invertCommand = (command) => {
|
|
31
31
|
description(editor, localizationTable) {
|
32
32
|
return localizationTable.inverseOf(command.description(editor, localizationTable));
|
33
33
|
}
|
34
|
-
}('inverse');
|
34
|
+
})('inverse');
|
35
35
|
}
|
36
36
|
else {
|
37
37
|
// Command that does the inverse of [command].
|
38
|
-
const result = new class extends Command_1.default {
|
38
|
+
const result = new (class extends Command_1.default {
|
39
39
|
apply(editor) {
|
40
40
|
command.unapply(editor);
|
41
41
|
}
|
@@ -48,7 +48,7 @@ const invertCommand = (command) => {
|
|
48
48
|
description(editor, localizationTable) {
|
49
49
|
return localizationTable.inverseOf(command.description(editor, localizationTable));
|
50
50
|
}
|
51
|
-
};
|
51
|
+
})();
|
52
52
|
// We know that T does not extend SerializableCommand, and thus returning a Command
|
53
53
|
// is appropriate.
|
54
54
|
return result;
|
@@ -4,4 +4,4 @@ import Erase from './Erase';
|
|
4
4
|
import invertCommand from './invertCommand';
|
5
5
|
import SerializableCommand from './SerializableCommand';
|
6
6
|
import uniteCommands from './uniteCommands';
|
7
|
-
export { Command, Duplicate, Erase, SerializableCommand, invertCommand, uniteCommands
|
7
|
+
export { Command, Duplicate, Erase, SerializableCommand, invertCommand, uniteCommands };
|
@@ -15,7 +15,7 @@ class NonSerializableUnion extends Command_1.default {
|
|
15
15
|
}
|
16
16
|
apply(editor) {
|
17
17
|
if (this.applyChunkSize === undefined) {
|
18
|
-
const results = this.commands.map(cmd => cmd.apply(editor));
|
18
|
+
const results = this.commands.map((cmd) => cmd.apply(editor));
|
19
19
|
return (0, waitForAll_1.default)(results);
|
20
20
|
}
|
21
21
|
else {
|
@@ -26,7 +26,7 @@ class NonSerializableUnion extends Command_1.default {
|
|
26
26
|
const commands = [...this.commands];
|
27
27
|
commands.reverse();
|
28
28
|
if (this.applyChunkSize === undefined) {
|
29
|
-
const results = commands.map(cmd => cmd.unapply(editor));
|
29
|
+
const results = commands.map((cmd) => cmd.unapply(editor));
|
30
30
|
return (0, waitForAll_1.default)(results);
|
31
31
|
}
|
32
32
|
else {
|
@@ -34,7 +34,7 @@ class NonSerializableUnion extends Command_1.default {
|
|
34
34
|
}
|
35
35
|
}
|
36
36
|
onDrop(editor) {
|
37
|
-
this.commands.forEach(command => command.onDrop(editor));
|
37
|
+
this.commands.forEach((command) => command.onDrop(editor));
|
38
38
|
}
|
39
39
|
description(editor, localizationTable) {
|
40
40
|
if (this.descriptionOverride) {
|
@@ -86,7 +86,7 @@ class SerializableUnion extends SerializableCommand_1.default {
|
|
86
86
|
}
|
87
87
|
return {
|
88
88
|
applyChunkSize: this.applyChunkSize,
|
89
|
-
data: this.commands.map(command => command.serialize()),
|
89
|
+
data: this.commands.map((command) => command.serialize()),
|
90
90
|
description: this.descriptionOverride,
|
91
91
|
};
|
92
92
|
}
|
@@ -4,7 +4,7 @@ import { LineSegment2, Mat33, Path, Rect2 } from '@js-draw/math';
|
|
4
4
|
import AbstractRenderer from '../rendering/renderers/AbstractRenderer';
|
5
5
|
import { ImageComponentLocalization } from './localization';
|
6
6
|
import Viewport from '../Viewport';
|
7
|
-
export type LoadSaveData =
|
7
|
+
export type LoadSaveData = string[] | Record<symbol, string | number>;
|
8
8
|
export type LoadSaveDataTable = Record<string, Array<LoadSaveData>>;
|
9
9
|
export type DeserializeCallback = (data: string) => AbstractComponent;
|
10
10
|
export declare enum ComponentSizingMode {
|
@@ -42,7 +42,7 @@ class AbstractComponent {
|
|
42
42
|
this.componentKind = componentKind;
|
43
43
|
// Stores data attached by a loader.
|
44
44
|
this.loadSaveData = {};
|
45
|
-
this.lastChangedTime =
|
45
|
+
this.lastChangedTime = new Date().getTime();
|
46
46
|
if (initialZIndex !== undefined) {
|
47
47
|
this.zIndex = initialZIndex;
|
48
48
|
}
|
@@ -140,7 +140,7 @@ class AbstractComponent {
|
|
140
140
|
}
|
141
141
|
// Otherwise check if it intersects one of the rectangle's edges.
|
142
142
|
const testLines = rect.getEdges();
|
143
|
-
return testLines.some(edge => this.intersects(edge));
|
143
|
+
return testLines.some((edge) => this.intersects(edge));
|
144
144
|
}
|
145
145
|
// @returns true iff this component can be selected (e.g. by the selection tool.)
|
146
146
|
isSelectable() {
|
@@ -290,7 +290,7 @@ AbstractComponent.TransformElementCommand = (_a = class extends UnresolvedComman
|
|
290
290
|
}
|
291
291
|
this.component.applyTransformation(newTransfm);
|
292
292
|
this.component.zIndex = targetZIndex;
|
293
|
-
this.component.lastChangedTime =
|
293
|
+
this.component.lastChangedTime = new Date().getTime();
|
294
294
|
// Ensure that new components are automatically drawn above the current component.
|
295
295
|
if (targetZIndex >= AbstractComponent.zIndexCounter) {
|
296
296
|
AbstractComponent.zIndexCounter = targetZIndex + 1;
|
@@ -207,7 +207,7 @@ class BackgroundComponent extends AbstractComponent_1.default {
|
|
207
207
|
});
|
208
208
|
result.push({
|
209
209
|
kind: math_1.PathCommandType.LineTo,
|
210
|
-
point: math_1.Vec2.of(x, targetRect.y + targetRect.h)
|
210
|
+
point: math_1.Vec2.of(x, targetRect.y + targetRect.h),
|
211
211
|
});
|
212
212
|
}
|
213
213
|
return new math_1.Path(startPoint, result);
|
@@ -235,7 +235,8 @@ class BackgroundComponent extends AbstractComponent_1.default {
|
|
235
235
|
const clip = this.backgroundType === BackgroundType.Grid;
|
236
236
|
const contentBBox = this.getFullBoundingBox(visibleRect);
|
237
237
|
canvas.startObject(contentBBox, clip);
|
238
|
-
if (this.backgroundType === BackgroundType.SolidColor ||
|
238
|
+
if (this.backgroundType === BackgroundType.SolidColor ||
|
239
|
+
this.backgroundType === BackgroundType.Grid) {
|
239
240
|
// If the rectangle for this region contains the visible rect,
|
240
241
|
// we can fill the entire visible rectangle (which may be more efficient than
|
241
242
|
// filling the entire region for this.)
|
@@ -257,7 +258,7 @@ class BackgroundComponent extends AbstractComponent_1.default {
|
|
257
258
|
}
|
258
259
|
const style = {
|
259
260
|
fill: math_1.Color4.transparent,
|
260
|
-
stroke: { width: this.gridStrokeWidth, color: gridColor }
|
261
|
+
stroke: { width: this.gridStrokeWidth, color: gridColor },
|
261
262
|
};
|
262
263
|
canvas.drawPath((0, RenderablePathSpec_1.pathToRenderable)(this.generateGridPath(visibleRect), style));
|
263
264
|
}
|
@@ -274,7 +275,7 @@ class BackgroundComponent extends AbstractComponent_1.default {
|
|
274
275
|
canvas.endObject(this.getLoadSaveData(), classNames);
|
275
276
|
}
|
276
277
|
intersects(lineSegment) {
|
277
|
-
return this.contentBBox.getEdges().some(edge => edge.intersects(lineSegment));
|
278
|
+
return this.contentBBox.getEdges().some((edge) => edge.intersects(lineSegment));
|
278
279
|
}
|
279
280
|
isSelectable() {
|
280
281
|
return false;
|
@@ -325,8 +326,9 @@ class BackgroundComponent extends AbstractComponent_1.default {
|
|
325
326
|
}
|
326
327
|
let backgroundType;
|
327
328
|
const jsonBackgroundType = json.backgroundType;
|
328
|
-
if (jsonBackgroundType === BackgroundType.None ||
|
329
|
-
|
329
|
+
if (jsonBackgroundType === BackgroundType.None ||
|
330
|
+
jsonBackgroundType === BackgroundType.Grid ||
|
331
|
+
jsonBackgroundType === BackgroundType.SolidColor) {
|
330
332
|
backgroundType = jsonBackgroundType;
|
331
333
|
}
|
332
334
|
else {
|
@@ -18,7 +18,10 @@ class ImageComponent extends AbstractComponent_1.default {
|
|
18
18
|
super('image-component');
|
19
19
|
this.image = {
|
20
20
|
...image,
|
21
|
-
label: image.label ??
|
21
|
+
label: image.label ??
|
22
|
+
image.image.getAttribute('alt') ??
|
23
|
+
image.image.getAttribute('aria-label') ??
|
24
|
+
undefined,
|
22
25
|
};
|
23
26
|
const isHTMLImageElem = (elem) => {
|
24
27
|
return elem.getAttribute('src') !== undefined;
|
@@ -44,8 +47,10 @@ class ImageComponent extends AbstractComponent_1.default {
|
|
44
47
|
static async fromImage(elem, transform) {
|
45
48
|
await (0, waitForImageLoaded_1.default)(elem);
|
46
49
|
let width, height;
|
47
|
-
if (typeof elem.width === 'number' &&
|
48
|
-
|
50
|
+
if (typeof elem.width === 'number' &&
|
51
|
+
typeof elem.height === 'number' &&
|
52
|
+
elem.width !== 0 &&
|
53
|
+
elem.height !== 0) {
|
49
54
|
width = elem.width;
|
50
55
|
height = elem.height;
|
51
56
|
}
|
@@ -91,7 +96,7 @@ class ImageComponent extends AbstractComponent_1.default {
|
|
91
96
|
}
|
92
97
|
intersects(lineSegment) {
|
93
98
|
const rect = this.getImageRect();
|
94
|
-
const edges = rect.getEdges().map(edge => edge.transformedBy(this.image.transform));
|
99
|
+
const edges = rect.getEdges().map((edge) => edge.transformedBy(this.image.transform));
|
95
100
|
for (const edge of edges) {
|
96
101
|
if (edge.intersects(lineSegment)) {
|
97
102
|
return true;
|
@@ -104,7 +109,9 @@ class ImageComponent extends AbstractComponent_1.default {
|
|
104
109
|
this.recomputeBBox();
|
105
110
|
}
|
106
111
|
description(localizationTable) {
|
107
|
-
return this.image.label
|
112
|
+
return this.image.label
|
113
|
+
? localizationTable.imageNode(this.image.label)
|
114
|
+
: localizationTable.unlabeledImageNode;
|
108
115
|
}
|
109
116
|
getAltText() {
|
110
117
|
return this.image.label;
|
@@ -81,7 +81,7 @@ class DefaultRestyleComponentCommand extends UnresolvedCommand_1.default {
|
|
81
81
|
const newStyle = deserializeComponentStyle(json.newStyle);
|
82
82
|
const id = json.id;
|
83
83
|
if (typeof json.id !== 'string') {
|
84
|
-
throw new Error(`json.id is of type ${
|
84
|
+
throw new Error(`json.id is of type ${typeof json.id}, not string.`);
|
85
85
|
}
|
86
86
|
return new DefaultRestyleComponentCommand(origStyle, newStyle, id);
|
87
87
|
});
|
@@ -79,8 +79,7 @@ class Stroke extends AbstractComponent_1.default {
|
|
79
79
|
return {};
|
80
80
|
}
|
81
81
|
const firstPart = this.parts[0];
|
82
|
-
if (firstPart.style.stroke === undefined
|
83
|
-
|| firstPart.style.stroke.width === 0) {
|
82
|
+
if (firstPart.style.stroke === undefined || firstPart.style.stroke.width === 0) {
|
84
83
|
return {
|
85
84
|
color: firstPart.style.fill,
|
86
85
|
};
|
@@ -99,9 +98,11 @@ class Stroke extends AbstractComponent_1.default {
|
|
99
98
|
this.parts = this.parts.map((part) => {
|
100
99
|
const newStyle = {
|
101
100
|
...part.style,
|
102
|
-
stroke: part.style.stroke
|
103
|
-
|
104
|
-
|
101
|
+
stroke: part.style.stroke
|
102
|
+
? {
|
103
|
+
...part.style.stroke,
|
104
|
+
}
|
105
|
+
: undefined,
|
105
106
|
};
|
106
107
|
// Change the stroke color if a stroked shape. Else,
|
107
108
|
// change the fill.
|
@@ -136,7 +137,8 @@ class Stroke extends AbstractComponent_1.default {
|
|
136
137
|
const makeStroke = (path) => {
|
137
138
|
if (part.style.fill.a > 0) {
|
138
139
|
// Remove visually empty paths.
|
139
|
-
if (path.parts.length < 1 ||
|
140
|
+
if (path.parts.length < 1 ||
|
141
|
+
(path.parts.length === 1 && path.parts[0].kind === math_1.PathCommandType.LineTo)) {
|
140
142
|
// TODO: If this isn't present, a very large number of strokes are created while erasing.
|
141
143
|
return null;
|
142
144
|
}
|
@@ -169,10 +171,10 @@ class Stroke extends AbstractComponent_1.default {
|
|
169
171
|
// 2. If zoomed in significantly, it's unlikely that the user wants to erase a large
|
170
172
|
// part of the stroke.
|
171
173
|
let isErasingFromEdge = false;
|
172
|
-
if (intersectionPoints.length === 0
|
173
|
-
|
174
|
-
|
175
|
-
|
174
|
+
if (intersectionPoints.length === 0 &&
|
175
|
+
part.style.stroke &&
|
176
|
+
part.style.stroke.width > eraserPath.bbox.minDimension * 0.3 &&
|
177
|
+
part.style.stroke.width < eraserPath.bbox.maxDimension * 30) {
|
176
178
|
for (const segment of polyline) {
|
177
179
|
intersectionPoints.push(...path.intersection(segment, part.style.stroke.width / 2));
|
178
180
|
}
|
@@ -186,7 +188,7 @@ class Stroke extends AbstractComponent_1.default {
|
|
186
188
|
}
|
187
189
|
// The eraser may not be near the center of the curve -- approximate.
|
188
190
|
if (isErasingFromEdge) {
|
189
|
-
return intersectionPoints[0].curveIndex === 0 && intersectionPoints[0].parameterValue <= 0;
|
191
|
+
return (intersectionPoints[0].curveIndex === 0 && intersectionPoints[0].parameterValue <= 0);
|
190
192
|
}
|
191
193
|
const justBeforeFirstIntersection = (0, math_1.stepPathIndexBy)(intersectionPoints[0], -1e-10);
|
192
194
|
return isPointInsideEraser(path.at(justBeforeFirstIntersection));
|
@@ -203,24 +205,30 @@ class Stroke extends AbstractComponent_1.default {
|
|
203
205
|
// (including https://github.com/Pomax/bezierjs/issues/179).
|
204
206
|
// Even if not all intersections are returned correctly, we still want
|
205
207
|
// isInside to be roughly correct.
|
206
|
-
if (knownToBeInside === undefined &&
|
208
|
+
if (knownToBeInside === undefined &&
|
209
|
+
!isInside &&
|
210
|
+
eraserPath.closedContainsPoint(path.getExactBBox().center)) {
|
207
211
|
isInside = !isInside;
|
208
212
|
}
|
209
213
|
if (!component) {
|
210
214
|
return;
|
211
215
|
}
|
212
216
|
// Assertion: Avoid deleting sections that are much larger than the eraser.
|
213
|
-
failedAssertions ||=
|
217
|
+
failedAssertions ||=
|
218
|
+
isInside && path.getExactBBox().maxDimension > eraserPath.getExactBBox().maxDimension * 2;
|
214
219
|
if (!isInside) {
|
215
220
|
newStrokes.push(component);
|
216
221
|
}
|
217
222
|
};
|
218
|
-
if (part.style.fill.a === 0) {
|
223
|
+
if (part.style.fill.a === 0) {
|
224
|
+
// Not filled?
|
219
225
|
// An additional case where we erase completely -- without the padding of the stroke,
|
220
226
|
// the path is smaller than the eraser (allows us to erase dots completely).
|
221
227
|
const shouldEraseCompletely = eraserPath.getExactBBox().maxDimension / 10 > path.getExactBBox().maxDimension;
|
222
228
|
if (!shouldEraseCompletely) {
|
223
|
-
const split = path.splitAt(intersectionPoints, {
|
229
|
+
const split = path.splitAt(intersectionPoints, {
|
230
|
+
mapNewPoint: (p) => viewport.roundPoint(p),
|
231
|
+
});
|
224
232
|
for (const splitPart of split) {
|
225
233
|
addNewPath(splitPart);
|
226
234
|
}
|
@@ -262,7 +270,9 @@ class Stroke extends AbstractComponent_1.default {
|
|
262
270
|
//
|
263
271
|
// The difficulty here is correctly pairing edges to create the the output
|
264
272
|
// strokes, particularly because we don't know the order of intersection points.
|
265
|
-
const parts = path.splitAt(intersectionPoints, {
|
273
|
+
const parts = path.splitAt(intersectionPoints, {
|
274
|
+
mapNewPoint: (p) => viewport.roundPoint(p),
|
275
|
+
});
|
266
276
|
for (let i = 0; i < Math.floor(parts.length / 2); i++) {
|
267
277
|
addNewPath(parts[i].union(parts[parts.length - i - 1]).asClosed());
|
268
278
|
}
|
@@ -338,12 +348,12 @@ class Stroke extends AbstractComponent_1.default {
|
|
338
348
|
let occludes = false;
|
339
349
|
let skipSimplification = false;
|
340
350
|
for (const part of this.parts) {
|
341
|
-
if (skipSimplification
|
351
|
+
if (skipSimplification ||
|
342
352
|
// Simplification currently only works for stroked paths
|
343
|
-
|
353
|
+
!part.style.stroke ||
|
344
354
|
// One of the main purposes of this is to check for occlusion.
|
345
355
|
// We can't occlude things if the stroke is partially transparent.
|
346
|
-
|
356
|
+
part.style.stroke.color.a < 0.99) {
|
347
357
|
simplifiedParts.push(part);
|
348
358
|
continue;
|
349
359
|
}
|
@@ -393,7 +403,8 @@ class Stroke extends AbstractComponent_1.default {
|
|
393
403
|
continue;
|
394
404
|
}
|
395
405
|
const muchBiggerThanVisible = bbox.size.x > visibleRect.size.x * 3 || bbox.size.y > visibleRect.size.y * 3;
|
396
|
-
if (muchBiggerThanVisible &&
|
406
|
+
if (muchBiggerThanVisible &&
|
407
|
+
!part.path.roughlyIntersects(visibleRect, part.style.stroke?.width ?? 0)) {
|
397
408
|
continue;
|
398
409
|
}
|
399
410
|
}
|
@@ -429,9 +440,11 @@ class Stroke extends AbstractComponent_1.default {
|
|
429
440
|
const newPath = part.path.transformedBy(affineTransfm);
|
430
441
|
const newStyle = {
|
431
442
|
...part.style,
|
432
|
-
stroke: part.style.stroke
|
433
|
-
|
434
|
-
|
443
|
+
stroke: part.style.stroke
|
444
|
+
? {
|
445
|
+
...part.style.stroke,
|
446
|
+
}
|
447
|
+
: undefined,
|
435
448
|
};
|
436
449
|
// Approximate the scale factor.
|
437
450
|
if (newStyle.stroke) {
|
@@ -489,7 +502,7 @@ class Stroke extends AbstractComponent_1.default {
|
|
489
502
|
return new Stroke(this.parts);
|
490
503
|
}
|
491
504
|
serializeToJSON() {
|
492
|
-
return this.parts.map(part => {
|
505
|
+
return this.parts.map((part) => {
|
493
506
|
return {
|
494
507
|
style: (0, RenderingStyle_1.styleToJSON)(part.style),
|
495
508
|
path: part.path.serialize(),
|
@@ -21,7 +21,9 @@ var TextTransformMode;
|
|
21
21
|
TextTransformMode[TextTransformMode["RELATIVE_Y_ABSOLUTE_X"] = 3] = "RELATIVE_Y_ABSOLUTE_X";
|
22
22
|
})(TextTransformMode || (exports.TextTransformMode = TextTransformMode = {}));
|
23
23
|
const defaultTextStyle = {
|
24
|
-
fontFamily: 'sans',
|
24
|
+
fontFamily: 'sans',
|
25
|
+
size: 12,
|
26
|
+
renderingStyle: { fill: math_1.Color4.purple },
|
25
27
|
};
|
26
28
|
/**
|
27
29
|
* Displays text.
|
@@ -82,7 +84,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
82
84
|
this.recomputeBBox();
|
83
85
|
// If this has no direct children, choose a style representative of this' content
|
84
86
|
// (useful for estimating the style of the TextComponent).
|
85
|
-
const hasDirectContent = textObjects.some(obj => typeof obj === 'string');
|
87
|
+
const hasDirectContent = textObjects.some((obj) => typeof obj === 'string');
|
86
88
|
if (!hasDirectContent && textObjects.length > 0) {
|
87
89
|
this.style = textObjects[0].getTextStyle();
|
88
90
|
}
|
@@ -96,7 +98,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
96
98
|
style.fontStyle ?? '',
|
97
99
|
style.fontWeight ?? '',
|
98
100
|
(style.size ?? 12) + 'px',
|
99
|
-
`${fontFamily}
|
101
|
+
`${fontFamily}`,
|
100
102
|
].join(' ');
|
101
103
|
// TODO: Support RTL
|
102
104
|
ctx.textAlign = 'left';
|
@@ -107,7 +109,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
107
109
|
const heightEst = style.size;
|
108
110
|
// Text is drawn with (0, 0) as its baseline. As such, the majority of the text's height should
|
109
111
|
// be above (0, 0).
|
110
|
-
return new math_1.Rect2(0, -heightEst * 2 / 3, widthEst, heightEst);
|
112
|
+
return new math_1.Rect2(0, (-heightEst * 2) / 3, widthEst, heightEst);
|
111
113
|
}
|
112
114
|
// Returns a set of TextMetrics for the given text, if a canvas is available.
|
113
115
|
static getTextMetrics(text, style) {
|
@@ -187,7 +189,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
187
189
|
const textBBox = TextComponent.getTextDimens(subObject, this.style);
|
188
190
|
// TODO: Use a better intersection check. Perhaps draw the text onto a CanvasElement and
|
189
191
|
// use pixel-testing to check for intersection with its contour.
|
190
|
-
if (textBBox.getEdges().some(edge => transformedLine.intersection(edge) !== null)) {
|
192
|
+
if (textBBox.getEdges().some((edge) => transformedLine.intersection(edge) !== null)) {
|
191
193
|
return true;
|
192
194
|
}
|
193
195
|
}
|
@@ -255,7 +257,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
255
257
|
this.recomputeBBox();
|
256
258
|
}
|
257
259
|
createClone() {
|
258
|
-
const clonedTextObjects = this.textObjects.map(obj => {
|
260
|
+
const clonedTextObjects = this.textObjects.map((obj) => {
|
259
261
|
if (typeof obj === 'string') {
|
260
262
|
return obj;
|
261
263
|
}
|
@@ -283,7 +285,7 @@ class TextComponent extends AbstractComponent_1.default {
|
|
283
285
|
// Do not rely on the output of `serializeToJSON` taking any particular format.
|
284
286
|
serializeToJSON() {
|
285
287
|
const serializableStyle = (0, TextRenderingStyle_1.textStyleToJSON)(this.style);
|
286
|
-
const serializedTextObjects = this.textObjects.map(text => {
|
288
|
+
const serializedTextObjects = this.textObjects.map((text) => {
|
287
289
|
if (typeof text === 'string') {
|
288
290
|
return {
|
289
291
|
text,
|
@@ -369,7 +371,7 @@ TextComponent.TextCursor = class {
|
|
369
371
|
let elementTransform = math_1.Mat33.identity;
|
370
372
|
let elemInternalTransform = math_1.Mat33.identity;
|
371
373
|
let textSize;
|
372
|
-
if (typeof
|
374
|
+
if (typeof elem === 'string') {
|
373
375
|
textSize = TextComponent.getTextDimens(elem, this.parentStyle);
|
374
376
|
}
|
375
377
|
else {
|
@@ -378,12 +380,13 @@ TextComponent.TextCursor = class {
|
|
378
380
|
elemInternalTransform = elem.transform;
|
379
381
|
textSize = elem.getBBox();
|
380
382
|
}
|
381
|
-
const positioning = typeof
|
383
|
+
const positioning = typeof elem === 'string' ? TextTransformMode.RELATIVE_XY : elem.transformMode;
|
382
384
|
if (positioning === TextTransformMode.RELATIVE_XY) {
|
383
385
|
// Position relative to the previous element's transform.
|
384
386
|
elementTransform = this.transform.rightMul(elementTransform);
|
385
387
|
}
|
386
|
-
else if (positioning === TextTransformMode.RELATIVE_X_ABSOLUTE_Y ||
|
388
|
+
else if (positioning === TextTransformMode.RELATIVE_X_ABSOLUTE_Y ||
|
389
|
+
positioning === TextTransformMode.RELATIVE_Y_ABSOLUTE_X) {
|
387
390
|
// Zero the absolute component of this.transform's translation
|
388
391
|
const transform = this.transform.mapEntries((component, [row, col]) => {
|
389
392
|
if (positioning === TextTransformMode.RELATIVE_X_ABSOLUTE_Y) {
|
@@ -51,10 +51,9 @@ class UnknownSVGObject extends AbstractComponent_1.default {
|
|
51
51
|
canvas.endObject(this.getLoadSaveData());
|
52
52
|
}
|
53
53
|
intersects(lineSegment) {
|
54
|
-
return this.contentBBox.getEdges().some(edge => edge.intersection(lineSegment) !== null);
|
55
|
-
}
|
56
|
-
applyTransformation(_affineTransfm) {
|
54
|
+
return this.contentBBox.getEdges().some((edge) => edge.intersection(lineSegment) !== null);
|
57
55
|
}
|
56
|
+
applyTransformation(_affineTransfm) { }
|
58
57
|
isSelectable() {
|
59
58
|
return false;
|
60
59
|
}
|
@@ -4,6 +4,12 @@ import { StrokeDataPoint } from '../../types';
|
|
4
4
|
import Viewport from '../../Viewport';
|
5
5
|
import AbstractComponent from '../AbstractComponent';
|
6
6
|
import { ComponentBuilder, ComponentBuilderFactory } from './types';
|
7
|
+
/**
|
8
|
+
* Creates a stroke builder that generates arrows circles.
|
9
|
+
*
|
10
|
+
* Example:
|
11
|
+
* [[include:doc-pages/inline-examples/changing-pen-types.md]]
|
12
|
+
*/
|
7
13
|
export declare const makeArrowBuilder: ComponentBuilderFactory;
|
8
14
|
export default class ArrowBuilder implements ComponentBuilder {
|
9
15
|
private readonly startPoint;
|
@@ -7,6 +7,12 @@ exports.makeArrowBuilder = void 0;
|
|
7
7
|
const math_1 = require("@js-draw/math");
|
8
8
|
const Stroke_1 = __importDefault(require("../Stroke"));
|
9
9
|
const makeSnapToGridAutocorrect_1 = __importDefault(require("./autocorrect/makeSnapToGridAutocorrect"));
|
10
|
+
/**
|
11
|
+
* Creates a stroke builder that generates arrows circles.
|
12
|
+
*
|
13
|
+
* Example:
|
14
|
+
* [[include:doc-pages/inline-examples/changing-pen-types.md]]
|
15
|
+
*/
|
10
16
|
exports.makeArrowBuilder = (0, makeSnapToGridAutocorrect_1.default)((initialPoint, viewport) => {
|
11
17
|
return new ArrowBuilder(initialPoint, viewport);
|
12
18
|
});
|
@@ -69,15 +75,15 @@ class ArrowBuilder {
|
|
69
75
|
point: arrowTipBase.minus(scaledBaseNormal),
|
70
76
|
},
|
71
77
|
// Round all points in the arrow (to remove unnecessary decimal places)
|
72
|
-
]).mapPoints(point => this.viewport.roundPoint(point));
|
78
|
+
]).mapPoints((point) => this.viewport.roundPoint(point));
|
73
79
|
const preview = new Stroke_1.default([
|
74
80
|
{
|
75
81
|
startPoint: path.startPoint,
|
76
82
|
commands: path.parts,
|
77
83
|
style: {
|
78
84
|
fill: this.startPoint.color,
|
79
|
-
}
|
80
|
-
}
|
85
|
+
},
|
86
|
+
},
|
81
87
|
]);
|
82
88
|
return preview;
|
83
89
|
}
|
@@ -1,2 +1,8 @@
|
|
1
1
|
import { ComponentBuilderFactory } from './types';
|
2
|
+
/**
|
3
|
+
* Creates a stroke builder that generates outlined circles.
|
4
|
+
*
|
5
|
+
* Example:
|
6
|
+
* [[include:doc-pages/inline-examples/changing-pen-types.md]]
|
7
|
+
*/
|
2
8
|
export declare const makeOutlinedCircleBuilder: ComponentBuilderFactory;
|
@@ -9,6 +9,12 @@ const RenderablePathSpec_1 = require("../../rendering/RenderablePathSpec");
|
|
9
9
|
const Viewport_1 = __importDefault(require("../../Viewport"));
|
10
10
|
const Stroke_1 = __importDefault(require("../Stroke"));
|
11
11
|
const makeSnapToGridAutocorrect_1 = __importDefault(require("./autocorrect/makeSnapToGridAutocorrect"));
|
12
|
+
/**
|
13
|
+
* Creates a stroke builder that generates outlined circles.
|
14
|
+
*
|
15
|
+
* Example:
|
16
|
+
* [[include:doc-pages/inline-examples/changing-pen-types.md]]
|
17
|
+
*/
|
12
18
|
exports.makeOutlinedCircleBuilder = (0, makeSnapToGridAutocorrect_1.default)((initialPoint, viewport) => {
|
13
19
|
return new CircleBuilder(initialPoint, viewport);
|
14
20
|
});
|
@@ -26,7 +32,7 @@ class CircleBuilder {
|
|
26
32
|
buildPreview() {
|
27
33
|
const pathCommands = [];
|
28
34
|
const numDivisions = 6;
|
29
|
-
const stepSize = Math.PI * 2 / numDivisions;
|
35
|
+
const stepSize = (Math.PI * 2) / numDivisions;
|
30
36
|
// Round the stroke width so that when exported it doesn't have unnecessary trailing decimals.
|
31
37
|
const strokeWidth = Viewport_1.default.roundPoint(this.endPoint.width, 5 / this.viewport.getScaleFactor());
|
32
38
|
const center = this.startPoint.pos.lerp(this.endPoint.pos, 0.5);
|
@@ -38,7 +44,9 @@ class CircleBuilder {
|
|
38
44
|
// controlPointRadiusScale is selected to make the circles appear circular and
|
39
45
|
// **does** depend on stepSize.
|
40
46
|
const controlPointRadiusScale = 1.141;
|
41
|
-
const controlPoint = math_1.Vec2.of(Math.cos(t - stepSize / 2), -Math.sin(t - stepSize / 2))
|
47
|
+
const controlPoint = math_1.Vec2.of(Math.cos(t - stepSize / 2), -Math.sin(t - stepSize / 2))
|
48
|
+
.times(radius * controlPointRadiusScale)
|
49
|
+
.plus(center);
|
42
50
|
pathCommands.push({
|
43
51
|
kind: math_1.PathCommandType.QuadraticBezierTo,
|
44
52
|
controlPoint,
|
@@ -49,8 +57,7 @@ class CircleBuilder {
|
|
49
57
|
kind: math_1.PathCommandType.LineTo,
|
50
58
|
point: startPoint,
|
51
59
|
});
|
52
|
-
const path = new math_1.Path(startPoint, pathCommands)
|
53
|
-
.mapPoints(point => this.viewport.roundPoint(point));
|
60
|
+
const path = new math_1.Path(startPoint, pathCommands).mapPoints((point) => this.viewport.roundPoint(point));
|
54
61
|
const preview = new Stroke_1.default([
|
55
62
|
(0, RenderablePathSpec_1.pathToRenderable)(path, {
|
56
63
|
fill: math_1.Color4.transparent,
|
@@ -6,6 +6,12 @@ import Viewport from '../../Viewport';
|
|
6
6
|
import { StrokeDataPoint } from '../../types';
|
7
7
|
import { ComponentBuilder, ComponentBuilderFactory } from './types';
|
8
8
|
import RenderingStyle from '../../rendering/RenderingStyle';
|
9
|
+
/**
|
10
|
+
* Creates a stroke builder that draws freehand lines.
|
11
|
+
*
|
12
|
+
* Example:
|
13
|
+
* [[include:doc-pages/inline-examples/changing-pen-types.md]]
|
14
|
+
*/
|
9
15
|
export declare const makeFreehandLineBuilder: ComponentBuilderFactory;
|
10
16
|
export default class FreehandLineBuilder implements ComponentBuilder {
|
11
17
|
private startPoint;
|