@kritzel/engine 0.4.31
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/LICENSE.md +50 -0
- package/dist/cjs/app-globals-V2Kpy_OQ.js +5 -0
- package/dist/cjs/engine.constants-CakmdKMW.js +28206 -0
- package/dist/cjs/index-BbbWU2aN.js +1742 -0
- package/dist/cjs/index.cjs.js +4232 -0
- package/dist/cjs/kritzel-awareness-cursors_5.cjs.entry.js +28004 -0
- package/dist/cjs/loader.cjs.js +13 -0
- package/dist/cjs/stencil.cjs.js +25 -0
- package/dist/collection/classes/core/core.class.js +1389 -0
- package/dist/collection/classes/core/reviver.class.js +124 -0
- package/dist/collection/classes/core/store.class.js +337 -0
- package/dist/collection/classes/core/viewport.class.js +794 -0
- package/dist/collection/classes/core/workspace.class.js +112 -0
- package/dist/collection/classes/handlers/base.handler.js +20 -0
- package/dist/collection/classes/handlers/context-menu.handler.js +170 -0
- package/dist/collection/classes/handlers/hover.handler.js +35 -0
- package/dist/collection/classes/handlers/key.handler.js +162 -0
- package/dist/collection/classes/handlers/line-handle.handler.js +475 -0
- package/dist/collection/classes/handlers/move.handler.js +295 -0
- package/dist/collection/classes/handlers/resize.handler.js +327 -0
- package/dist/collection/classes/handlers/rotation.handler.js +174 -0
- package/dist/collection/classes/handlers/selection.handler.js +526 -0
- package/dist/collection/classes/managers/anchor.manager.js +1476 -0
- package/dist/collection/classes/managers/browser-permission.manager.js +64 -0
- package/dist/collection/classes/managers/clipboard.manager.js +346 -0
- package/dist/collection/classes/managers/clipboard.types.js +1 -0
- package/dist/collection/classes/managers/cursor.manager.js +139 -0
- package/dist/collection/classes/managers/license.manager.js +341 -0
- package/dist/collection/classes/managers/localization.manager.js +227 -0
- package/dist/collection/classes/managers/theme.manager.js +206 -0
- package/dist/collection/classes/objects/base-object.class.js +462 -0
- package/dist/collection/classes/objects/dynamic-object.class.js +437 -0
- package/dist/collection/classes/objects/group.class.js +590 -0
- package/dist/collection/classes/objects/image.class.js +500 -0
- package/dist/collection/classes/objects/line.class.js +789 -0
- package/dist/collection/classes/objects/path.class.js +578 -0
- package/dist/collection/classes/objects/selection-box.class.js +32 -0
- package/dist/collection/classes/objects/selection-group.class.js +752 -0
- package/dist/collection/classes/objects/shape.class.js +628 -0
- package/dist/collection/classes/objects/text.class.js +461 -0
- package/dist/collection/classes/providers/assets/asset-resolver.class.js +536 -0
- package/dist/collection/classes/providers/assets/http-asset-provider.class.js +111 -0
- package/dist/collection/classes/providers/assets/indexeddb-asset-provider.class.js +241 -0
- package/dist/collection/classes/providers/assets/presigned-asset-provider.class.js +86 -0
- package/dist/collection/classes/providers/paste-intent/event-paste-intent.provider.js +48 -0
- package/dist/collection/classes/providers/paste-intent/ios-paste-intent.provider.js +16 -0
- package/dist/collection/classes/providers/paste-intent/navigator-paste-intent.provider.js +86 -0
- package/dist/collection/classes/providers/sync/broadcast-sync-provider.class.js +100 -0
- package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +333 -0
- package/dist/collection/classes/providers/sync/in-memory-sync-provider.class.js +69 -0
- package/dist/collection/classes/providers/sync/indexeddb-sync-provider.class.js +39 -0
- package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +110 -0
- package/dist/collection/classes/registries/dynamic-object-renderer.registry.js +52 -0
- package/dist/collection/classes/registries/font-registry.class.js +161 -0
- package/dist/collection/classes/registries/icon-registry.class.js +118 -0
- package/dist/collection/classes/registries/paste-intent-provider.registry.js +26 -0
- package/dist/collection/classes/registries/tool.registry.js +69 -0
- package/dist/collection/classes/structures/app-state-map.structure.js +461 -0
- package/dist/collection/classes/structures/object-map.structure.js +1103 -0
- package/dist/collection/classes/structures/quadtree.structure.js +251 -0
- package/dist/collection/classes/tools/base-tool.class.js +88 -0
- package/dist/collection/classes/tools/brush-tool.class.js +236 -0
- package/dist/collection/classes/tools/eraser-tool.class.js +133 -0
- package/dist/collection/classes/tools/image-tool.class.js +152 -0
- package/dist/collection/classes/tools/line-tool.class.js +249 -0
- package/dist/collection/classes/tools/selection-tool.class.js +611 -0
- package/dist/collection/classes/tools/shape-tool.class.js +251 -0
- package/dist/collection/classes/tools/text-tool.class.js +179 -0
- package/dist/collection/collection-manifest.json +17 -0
- package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -0
- package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.js +380 -0
- package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -0
- package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.js +153 -0
- package/dist/collection/components/kritzel-engine/kritzel-engine.css +81 -0
- package/dist/collection/components/kritzel-engine/kritzel-engine.js +6345 -0
- package/dist/collection/components/kritzel-icon/kritzel-icon.css +18 -0
- package/dist/collection/components/kritzel-icon/kritzel-icon.js +93 -0
- package/dist/collection/components/kritzel-watermark/kritzel-watermark.css +29 -0
- package/dist/collection/components/kritzel-watermark/kritzel-watermark.js +83 -0
- package/dist/collection/configs/default-asset-storage.config.js +9 -0
- package/dist/collection/configs/default-brush-tool.config.js +9 -0
- package/dist/collection/configs/default-engine-config.js +73 -0
- package/dist/collection/configs/default-line-tool.config.js +12 -0
- package/dist/collection/configs/default-shape-tool.config.js +15 -0
- package/dist/collection/configs/default-sync.config.js +6 -0
- package/dist/collection/configs/default-text-tool.config.js +12 -0
- package/dist/collection/constants/color-palette.constants.js +40 -0
- package/dist/collection/constants/core.constants.js +1 -0
- package/dist/collection/constants/engine.constants.js +4 -0
- package/dist/collection/constants/license.constants.js +25 -0
- package/dist/collection/constants/schema.constants.js +4 -0
- package/dist/collection/constants/storage.constants.js +1 -0
- package/dist/collection/constants/stroke-size.constants.js +2 -0
- package/dist/collection/constants/text-tool-fonts.constants.js +18 -0
- package/dist/collection/constants/version.js +6 -0
- package/dist/collection/enums/alignment.enum.js +9 -0
- package/dist/collection/enums/event-button.enum.js +6 -0
- package/dist/collection/enums/handle-type.enum.js +7 -0
- package/dist/collection/enums/shape-type.enum.js +6 -0
- package/dist/collection/events/active-workspace-change.event.js +1 -0
- package/dist/collection/events/editor-is-ready.event.js +1 -0
- package/dist/collection/events/login.event.js +1 -0
- package/dist/collection/helpers/alignment.helper.js +73 -0
- package/dist/collection/helpers/class.helper.js +5 -0
- package/dist/collection/helpers/color.helper.js +106 -0
- package/dist/collection/helpers/cursor.helper.js +57 -0
- package/dist/collection/helpers/devices.helper.js +28 -0
- package/dist/collection/helpers/event.helper.js +58 -0
- package/dist/collection/helpers/geometry.helper.js +149 -0
- package/dist/collection/helpers/html.helper.js +116 -0
- package/dist/collection/helpers/image-file.helper.js +6 -0
- package/dist/collection/helpers/keyboard.helper.js +55 -0
- package/dist/collection/helpers/localization.helper.js +25 -0
- package/dist/collection/helpers/math.helper.js +8 -0
- package/dist/collection/helpers/migration.helper.js +45 -0
- package/dist/collection/helpers/object.helper.js +29 -0
- package/dist/collection/helpers/svg-export.helper.js +655 -0
- package/dist/collection/helpers/theme.helper.js +77 -0
- package/dist/collection/helpers/tool-config.helper.js +63 -0
- package/dist/collection/helpers/wheel.helper.js +113 -0
- package/dist/collection/index.js +107 -0
- package/dist/collection/interfaces/anchor.interface.js +1 -0
- package/dist/collection/interfaces/arrow-head.interface.js +1 -0
- package/dist/collection/interfaces/asset-provider.interface.js +1 -0
- package/dist/collection/interfaces/asset-storage-config.interface.js +1 -0
- package/dist/collection/interfaces/asset.interface.js +1 -0
- package/dist/collection/interfaces/bounding-box.interface.js +1 -0
- package/dist/collection/interfaces/clonable.interface.js +1 -0
- package/dist/collection/interfaces/context-menu-item.interface.js +1 -0
- package/dist/collection/interfaces/context-menu-state.interface.js +1 -0
- package/dist/collection/interfaces/debug-info.interface.js +1 -0
- package/dist/collection/interfaces/dialog.interface.js +1 -0
- package/dist/collection/interfaces/document-metadata.interface.js +1 -0
- package/dist/collection/interfaces/dynamic-object-renderer.interface.js +1 -0
- package/dist/collection/interfaces/engine-state.interface.js +1 -0
- package/dist/collection/interfaces/font.interface.js +1 -0
- package/dist/collection/interfaces/localization.interface.js +1 -0
- package/dist/collection/interfaces/login-config.interface.js +1 -0
- package/dist/collection/interfaces/master-detail.interface.js +1 -0
- package/dist/collection/interfaces/menu-item.interface.js +1 -0
- package/dist/collection/interfaces/migration.interface.js +1 -0
- package/dist/collection/interfaces/notification.interface.js +1 -0
- package/dist/collection/interfaces/object-change-event.interface.js +1 -0
- package/dist/collection/interfaces/object-export.interface.js +1 -0
- package/dist/collection/interfaces/object.interface.js +1 -0
- package/dist/collection/interfaces/paste-intent-provider.interface.js +1 -0
- package/dist/collection/interfaces/point.interface.js +1 -0
- package/dist/collection/interfaces/polygon.interface.js +1 -0
- package/dist/collection/interfaces/remote-cursor.interface.js +1 -0
- package/dist/collection/interfaces/selection-state.interface.js +1 -0
- package/dist/collection/interfaces/serializable.interface.js +1 -0
- package/dist/collection/interfaces/settings.interface.js +1 -0
- package/dist/collection/interfaces/share.interface.js +1 -0
- package/dist/collection/interfaces/shortcut.interface.js +1 -0
- package/dist/collection/interfaces/sync-config.interface.js +21 -0
- package/dist/collection/interfaces/sync-provider.interface.js +1 -0
- package/dist/collection/interfaces/theme.interface.js +1 -0
- package/dist/collection/interfaces/tool-config.interface.js +1 -0
- package/dist/collection/interfaces/tool-type.interface.js +1 -0
- package/dist/collection/interfaces/tool.interface.js +1 -0
- package/dist/collection/interfaces/toolbar-item.interface.js +1 -0
- package/dist/collection/interfaces/undo-state.interface.js +1 -0
- package/dist/collection/interfaces/user.interface.js +1 -0
- package/dist/collection/interfaces/viewport-state.interface.js +1 -0
- package/dist/collection/locales/de-locale.js +119 -0
- package/dist/collection/locales/en-locale.js +120 -0
- package/dist/collection/locales/fr-locale.js +119 -0
- package/dist/collection/migrations/app-state.migrations.js +47 -0
- package/dist/collection/migrations/workspace.migrations.js +67 -0
- package/dist/collection/themes/dark-theme.js +340 -0
- package/dist/collection/themes/light-theme.js +346 -0
- package/dist/collection/types/deep-readonly.type.js +1 -0
- package/dist/collection/types/state.types.js +1 -0
- package/dist/components/index.d.ts +47 -0
- package/dist/components/index.js +4143 -0
- package/dist/components/kritzel-awareness-cursors.d.ts +11 -0
- package/dist/components/kritzel-awareness-cursors.js +6 -0
- package/dist/components/kritzel-cursor-trail.d.ts +11 -0
- package/dist/components/kritzel-cursor-trail.js +6 -0
- package/dist/components/kritzel-engine.d.ts +11 -0
- package/dist/components/kritzel-engine.js +52641 -0
- package/dist/components/kritzel-icon.d.ts +11 -0
- package/dist/components/kritzel-icon.js +6 -0
- package/dist/components/kritzel-watermark.d.ts +11 -0
- package/dist/components/kritzel-watermark.js +6 -0
- package/dist/components/p-B2Htv9ou.js +49 -0
- package/dist/components/p-BvRGQvVI.js +3456 -0
- package/dist/components/p-CfSx6HU_.js +1469 -0
- package/dist/components/p-YP8wAcF4.js +122 -0
- package/dist/components/p-fx6msYHJ.js +167 -0
- package/dist/esm/app-globals-DQuL1Twl.js +3 -0
- package/dist/esm/engine.constants-Bl5-pbq-.js +28143 -0
- package/dist/esm/index-BU9Mv7y0.js +1715 -0
- package/dist/esm/index.js +4134 -0
- package/dist/esm/kritzel-awareness-cursors_5.entry.js +27978 -0
- package/dist/esm/loader.js +11 -0
- package/dist/esm/stencil.js +21 -0
- package/dist/index.cjs.js +1 -0
- package/dist/index.js +1 -0
- package/dist/stencil/index.esm.js +4134 -0
- package/dist/stencil/p-BU9Mv7y0.js +1702 -0
- package/dist/stencil/p-Bl5-pbq-.js +28143 -0
- package/dist/stencil/p-DQuL1Twl.js +3 -0
- package/dist/stencil/p-f0a8b7af.entry.js +27978 -0
- package/dist/stencil/stencil.esm.js +21 -0
- package/dist/types/classes/core/core.class.d.ts +532 -0
- package/dist/types/classes/core/reviver.class.d.ts +32 -0
- package/dist/types/classes/core/store.class.d.ts +198 -0
- package/dist/types/classes/core/viewport.class.d.ts +256 -0
- package/dist/types/classes/core/workspace.class.d.ts +95 -0
- package/dist/types/classes/handlers/base.handler.d.ts +18 -0
- package/dist/types/classes/handlers/context-menu.handler.d.ts +67 -0
- package/dist/types/classes/handlers/hover.handler.d.ts +23 -0
- package/dist/types/classes/handlers/key.handler.d.ts +44 -0
- package/dist/types/classes/handlers/line-handle.handler.d.ts +115 -0
- package/dist/types/classes/handlers/move.handler.d.ts +94 -0
- package/dist/types/classes/handlers/resize.handler.d.ts +95 -0
- package/dist/types/classes/handlers/rotation.handler.d.ts +50 -0
- package/dist/types/classes/handlers/selection.handler.d.ts +153 -0
- package/dist/types/classes/managers/anchor.manager.d.ts +513 -0
- package/dist/types/classes/managers/browser-permission.manager.d.ts +41 -0
- package/dist/types/classes/managers/clipboard.manager.d.ts +71 -0
- package/dist/types/classes/managers/clipboard.types.d.ts +23 -0
- package/dist/types/classes/managers/cursor.manager.d.ts +66 -0
- package/dist/types/classes/managers/license.manager.d.ts +147 -0
- package/dist/types/classes/managers/localization.manager.d.ts +145 -0
- package/dist/types/classes/managers/theme.manager.d.ts +112 -0
- package/dist/types/classes/objects/base-object.class.d.ts +266 -0
- package/dist/types/classes/objects/dynamic-object.class.d.ts +148 -0
- package/dist/types/classes/objects/group.class.d.ts +231 -0
- package/dist/types/classes/objects/image.class.d.ts +246 -0
- package/dist/types/classes/objects/line.class.d.ts +285 -0
- package/dist/types/classes/objects/path.class.d.ts +220 -0
- package/dist/types/classes/objects/selection-box.class.d.ts +19 -0
- package/dist/types/classes/objects/selection-group.class.d.ts +267 -0
- package/dist/types/classes/objects/shape.class.d.ts +322 -0
- package/dist/types/classes/objects/text.class.d.ts +197 -0
- package/dist/types/classes/providers/assets/asset-resolver.class.d.ts +141 -0
- package/dist/types/classes/providers/assets/http-asset-provider.class.d.ts +79 -0
- package/dist/types/classes/providers/assets/indexeddb-asset-provider.class.d.ts +69 -0
- package/dist/types/classes/providers/assets/presigned-asset-provider.class.d.ts +69 -0
- package/dist/types/classes/providers/paste-intent/event-paste-intent.provider.d.ts +8 -0
- package/dist/types/classes/providers/paste-intent/ios-paste-intent.provider.d.ts +6 -0
- package/dist/types/classes/providers/paste-intent/navigator-paste-intent.provider.d.ts +9 -0
- package/dist/types/classes/providers/sync/broadcast-sync-provider.class.d.ts +23 -0
- package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +163 -0
- package/dist/types/classes/providers/sync/in-memory-sync-provider.class.d.ts +39 -0
- package/dist/types/classes/providers/sync/indexeddb-sync-provider.class.d.ts +25 -0
- package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +63 -0
- package/dist/types/classes/registries/dynamic-object-renderer.registry.d.ts +32 -0
- package/dist/types/classes/registries/font-registry.class.d.ts +19 -0
- package/dist/types/classes/registries/icon-registry.class.d.ts +39 -0
- package/dist/types/classes/registries/paste-intent-provider.registry.d.ts +10 -0
- package/dist/types/classes/registries/tool.registry.d.ts +53 -0
- package/dist/types/classes/structures/app-state-map.structure.d.ts +171 -0
- package/dist/types/classes/structures/object-map.structure.d.ts +403 -0
- package/dist/types/classes/structures/quadtree.structure.d.ts +128 -0
- package/dist/types/classes/tools/base-tool.class.d.ts +72 -0
- package/dist/types/classes/tools/brush-tool.class.d.ts +68 -0
- package/dist/types/classes/tools/eraser-tool.class.d.ts +38 -0
- package/dist/types/classes/tools/image-tool.class.d.ts +74 -0
- package/dist/types/classes/tools/line-tool.class.d.ts +63 -0
- package/dist/types/classes/tools/selection-tool.class.d.ts +188 -0
- package/dist/types/classes/tools/shape-tool.class.d.ts +90 -0
- package/dist/types/classes/tools/text-tool.class.d.ts +66 -0
- package/dist/types/components/kritzel-awareness-cursors/kritzel-awareness-cursors.d.ts +29 -0
- package/dist/types/components/kritzel-cursor-trail/kritzel-cursor-trail.d.ts +19 -0
- package/dist/types/components/kritzel-engine/kritzel-engine.d.ts +695 -0
- package/dist/types/components/kritzel-icon/kritzel-icon.d.ts +6 -0
- package/dist/types/components/kritzel-watermark/kritzel-watermark.d.ts +20 -0
- package/dist/types/components.d.ts +981 -0
- package/dist/types/configs/default-asset-storage.config.d.ts +8 -0
- package/dist/types/configs/default-brush-tool.config.d.ts +2 -0
- package/dist/types/configs/default-engine-config.d.ts +2 -0
- package/dist/types/configs/default-line-tool.config.d.ts +2 -0
- package/dist/types/configs/default-shape-tool.config.d.ts +2 -0
- package/dist/types/configs/default-sync.config.d.ts +5 -0
- package/dist/types/configs/default-text-tool.config.d.ts +2 -0
- package/dist/types/constants/color-palette.constants.d.ts +31 -0
- package/dist/types/constants/core.constants.d.ts +0 -0
- package/dist/types/constants/engine.constants.d.ts +4 -0
- package/dist/types/constants/license.constants.d.ts +25 -0
- package/dist/types/constants/schema.constants.d.ts +4 -0
- package/dist/types/constants/storage.constants.d.ts +1 -0
- package/dist/types/constants/stroke-size.constants.d.ts +2 -0
- package/dist/types/constants/text-tool-fonts.constants.d.ts +3 -0
- package/dist/types/constants/version.d.ts +6 -0
- package/dist/types/enums/alignment.enum.d.ts +8 -0
- package/dist/types/enums/event-button.enum.d.ts +5 -0
- package/dist/types/enums/handle-type.enum.d.ts +6 -0
- package/dist/types/enums/shape-type.enum.d.ts +5 -0
- package/dist/types/events/active-workspace-change.event.d.ts +7 -0
- package/dist/types/events/editor-is-ready.event.d.ts +18 -0
- package/dist/types/events/login.event.d.ts +3 -0
- package/dist/types/helpers/alignment.helper.d.ts +21 -0
- package/dist/types/helpers/class.helper.d.ts +3 -0
- package/dist/types/helpers/color.helper.d.ts +34 -0
- package/dist/types/helpers/cursor.helper.d.ts +22 -0
- package/dist/types/helpers/devices.helper.d.ts +8 -0
- package/dist/types/helpers/event.helper.d.ts +6 -0
- package/dist/types/helpers/geometry.helper.d.ts +38 -0
- package/dist/types/helpers/html.helper.d.ts +8 -0
- package/dist/types/helpers/image-file.helper.d.ts +3 -0
- package/dist/types/helpers/keyboard.helper.d.ts +6 -0
- package/dist/types/helpers/localization.helper.d.ts +18 -0
- package/dist/types/helpers/math.helper.d.ts +4 -0
- package/dist/types/helpers/migration.helper.d.ts +30 -0
- package/dist/types/helpers/object.helper.d.ts +9 -0
- package/dist/types/helpers/svg-export.helper.d.ts +231 -0
- package/dist/types/helpers/theme.helper.d.ts +42 -0
- package/dist/types/helpers/tool-config.helper.d.ts +4 -0
- package/dist/types/helpers/wheel.helper.d.ts +9 -0
- package/dist/types/index.d.ts +109 -0
- package/dist/types/interfaces/anchor.interface.d.ts +147 -0
- package/dist/types/interfaces/arrow-head.interface.d.ts +27 -0
- package/dist/types/interfaces/asset-provider.interface.d.ts +88 -0
- package/dist/types/interfaces/asset-storage-config.interface.d.ts +40 -0
- package/dist/types/interfaces/asset.interface.d.ts +43 -0
- package/dist/types/interfaces/bounding-box.interface.d.ts +8 -0
- package/dist/types/interfaces/clonable.interface.d.ts +3 -0
- package/dist/types/interfaces/context-menu-item.interface.d.ts +25 -0
- package/dist/types/interfaces/context-menu-state.interface.d.ts +16 -0
- package/dist/types/interfaces/debug-info.interface.d.ts +7 -0
- package/dist/types/interfaces/dialog.interface.d.ts +4 -0
- package/dist/types/interfaces/document-metadata.interface.d.ts +6 -0
- package/dist/types/interfaces/dynamic-object-renderer.interface.d.ts +40 -0
- package/dist/types/interfaces/engine-state.interface.d.ts +82 -0
- package/dist/types/interfaces/font.interface.d.ts +15 -0
- package/dist/types/interfaces/localization.interface.d.ts +143 -0
- package/dist/types/interfaces/login-config.interface.d.ts +24 -0
- package/dist/types/interfaces/master-detail.interface.d.ts +14 -0
- package/dist/types/interfaces/menu-item.interface.d.ts +27 -0
- package/dist/types/interfaces/migration.interface.d.ts +16 -0
- package/dist/types/interfaces/notification.interface.d.ts +10 -0
- package/dist/types/interfaces/object-change-event.interface.d.ts +31 -0
- package/dist/types/interfaces/object-export.interface.d.ts +20 -0
- package/dist/types/interfaces/object.interface.d.ts +53 -0
- package/dist/types/interfaces/paste-intent-provider.interface.d.ts +10 -0
- package/dist/types/interfaces/point.interface.d.ts +4 -0
- package/dist/types/interfaces/polygon.interface.d.ts +7 -0
- package/dist/types/interfaces/remote-cursor.interface.d.ts +18 -0
- package/dist/types/interfaces/selection-state.interface.d.ts +7 -0
- package/dist/types/interfaces/serializable.interface.d.ts +5 -0
- package/dist/types/interfaces/settings.interface.d.ts +25 -0
- package/dist/types/interfaces/share.interface.d.ts +9 -0
- package/dist/types/interfaces/shortcut.interface.d.ts +10 -0
- package/dist/types/interfaces/sync-config.interface.d.ts +41 -0
- package/dist/types/interfaces/sync-provider.interface.d.ts +66 -0
- package/dist/types/interfaces/theme.interface.d.ts +553 -0
- package/dist/types/interfaces/tool-config.interface.d.ts +24 -0
- package/dist/types/interfaces/tool-type.interface.d.ts +1 -0
- package/dist/types/interfaces/tool.interface.d.ts +8 -0
- package/dist/types/interfaces/toolbar-item.interface.d.ts +66 -0
- package/dist/types/interfaces/undo-state.interface.d.ts +6 -0
- package/dist/types/interfaces/user.interface.d.ts +22 -0
- package/dist/types/interfaces/viewport-state.interface.d.ts +7 -0
- package/dist/types/locales/de-locale.d.ts +5 -0
- package/dist/types/locales/en-locale.d.ts +6 -0
- package/dist/types/locales/fr-locale.d.ts +5 -0
- package/dist/types/migrations/app-state.migrations.d.ts +11 -0
- package/dist/types/migrations/workspace.migrations.d.ts +11 -0
- package/dist/types/stencil-public-runtime.d.ts +1873 -0
- package/dist/types/themes/dark-theme.d.ts +5 -0
- package/dist/types/themes/light-theme.d.ts +5 -0
- package/dist/types/types/deep-readonly.type.d.ts +7 -0
- package/dist/types/types/state.types.d.ts +3 -0
- package/loader/cdn.js +1 -0
- package/loader/index.cjs.js +1 -0
- package/loader/index.d.ts +24 -0
- package/loader/index.es2017.js +1 -0
- package/loader/index.js +2 -0
- package/package.json +101 -0
- package/readme.md +11 -0
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
import { KritzelBaseObject } from "./base-object.class";
|
|
2
|
+
import { KritzelGeometryHelper } from "../../helpers/geometry.helper";
|
|
3
|
+
import { KritzelColorHelper } from "../../helpers/color.helper";
|
|
4
|
+
import { KritzelMathHelper } from "../../helpers/math.helper";
|
|
5
|
+
export class KritzelLine extends KritzelBaseObject {
|
|
6
|
+
__class__ = 'KritzelLine';
|
|
7
|
+
startX;
|
|
8
|
+
startY;
|
|
9
|
+
endX;
|
|
10
|
+
endY;
|
|
11
|
+
controlX;
|
|
12
|
+
controlY;
|
|
13
|
+
stroke;
|
|
14
|
+
strokeWidth;
|
|
15
|
+
scale = 1;
|
|
16
|
+
options;
|
|
17
|
+
/** Anchor connection for the start point of the line */
|
|
18
|
+
startAnchor;
|
|
19
|
+
/** Anchor connection for the end point of the line */
|
|
20
|
+
endAnchor;
|
|
21
|
+
/** Arrow head configuration for start and end of line */
|
|
22
|
+
arrows;
|
|
23
|
+
isVisible = true;
|
|
24
|
+
isDebugInfoVisible = true;
|
|
25
|
+
isCompleted = false;
|
|
26
|
+
/** Cached adjusted points for hit testing, accounting for rotation and translation */
|
|
27
|
+
_adjustedPoints = null;
|
|
28
|
+
/** Cached clip information for anchored line endpoints */
|
|
29
|
+
_clipInfo = null;
|
|
30
|
+
/**
|
|
31
|
+
* Generates the SVG path data string for the line.
|
|
32
|
+
* Returns a quadratic Bezier curve path if control point exists, otherwise a straight line.
|
|
33
|
+
* @returns SVG path data string in the format "M x y Q cx cy ex ey" or "M x y L ex ey"
|
|
34
|
+
*/
|
|
35
|
+
get d() {
|
|
36
|
+
if (this.controlX !== undefined && this.controlY !== undefined) {
|
|
37
|
+
return `M ${this.startX} ${this.startY} Q ${this.controlX} ${this.controlY} ${this.endX} ${this.endY}`;
|
|
38
|
+
}
|
|
39
|
+
return `M ${this.startX} ${this.startY} L ${this.endX} ${this.endY}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generates the SVG viewBox attribute string for rendering the line.
|
|
43
|
+
* @returns ViewBox string in the format "x y width height"
|
|
44
|
+
*/
|
|
45
|
+
get viewBox() {
|
|
46
|
+
return `${this.x} ${this.y} ${this.width} ${this.height}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new KritzelLine instance.
|
|
50
|
+
* @param config - Optional configuration options for the line including start/end points,
|
|
51
|
+
* control point for curves, stroke settings, anchors, and arrow configuration
|
|
52
|
+
*/
|
|
53
|
+
constructor(config) {
|
|
54
|
+
super();
|
|
55
|
+
this.options = config;
|
|
56
|
+
this.startX = config?.startX ?? 0;
|
|
57
|
+
this.startY = config?.startY ?? 0;
|
|
58
|
+
this.endX = config?.endX ?? 0;
|
|
59
|
+
this.endY = config?.endY ?? 0;
|
|
60
|
+
this.controlX = config?.controlX;
|
|
61
|
+
this.controlY = config?.controlY;
|
|
62
|
+
this.translateX = config?.translateX ?? 0;
|
|
63
|
+
this.translateY = config?.translateY ?? 0;
|
|
64
|
+
this.rotation = KritzelMathHelper.degreesToRadians(config?.rotation ?? 0);
|
|
65
|
+
this.scale = config?.scale ?? 1;
|
|
66
|
+
this.strokeWidth = config?.strokeWidth ?? 4;
|
|
67
|
+
this.stroke = config?.stroke ?? { light: '#000000', dark: '#ffffff' };
|
|
68
|
+
this.startAnchor = config?.startAnchor;
|
|
69
|
+
this.endAnchor = config?.endAnchor;
|
|
70
|
+
this.arrows = config?.arrows;
|
|
71
|
+
this.updateDimensions();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Factory method to create a new KritzelLine with a core reference and unique ID.
|
|
75
|
+
* This is the preferred way to create lines that will be managed by the core.
|
|
76
|
+
* @param core - The KritzelCore instance that will manage this line
|
|
77
|
+
* @param options - Optional configuration options for the line
|
|
78
|
+
* @returns A fully initialized KritzelLine instance with generated ID and workspace assignment
|
|
79
|
+
*/
|
|
80
|
+
static create(core, options) {
|
|
81
|
+
const object = new KritzelLine();
|
|
82
|
+
object._core = core;
|
|
83
|
+
object.id = object.generateId();
|
|
84
|
+
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
85
|
+
object.userId = core.user?.id;
|
|
86
|
+
object.options = options;
|
|
87
|
+
object.startX = options?.startX ?? 0;
|
|
88
|
+
object.startY = options?.startY ?? 0;
|
|
89
|
+
object.endX = options?.endX ?? 0;
|
|
90
|
+
object.endY = options?.endY ?? 0;
|
|
91
|
+
object.controlX = options?.controlX;
|
|
92
|
+
object.controlY = options?.controlY;
|
|
93
|
+
object.translateX = options?.translateX ?? 0;
|
|
94
|
+
object.translateY = options?.translateY ?? 0;
|
|
95
|
+
object.rotation = KritzelMathHelper.degreesToRadians(options?.rotation ?? 0);
|
|
96
|
+
object.scale = options?.scale ?? 1;
|
|
97
|
+
object.strokeWidth = options?.strokeWidth ?? 4;
|
|
98
|
+
object.stroke = options?.stroke ?? { light: '#000000', dark: '#ffffff' };
|
|
99
|
+
object.opacity = options?.opacity ?? 1;
|
|
100
|
+
object.startAnchor = options?.startAnchor;
|
|
101
|
+
object.endAnchor = options?.endAnchor;
|
|
102
|
+
object.arrows = options?.arrows;
|
|
103
|
+
object.zIndex = core.store.currentZIndex;
|
|
104
|
+
object.updateDimensions();
|
|
105
|
+
return object;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Resizes the line to fit within the specified dimensions.
|
|
109
|
+
* Scales both endpoints and control point proportionally, then repositions the line.
|
|
110
|
+
* @param x - New X position for the line (or null to keep current)
|
|
111
|
+
* @param y - New Y position for the line (or null to keep current)
|
|
112
|
+
* @param width - New width to scale the line to (must be > 1)
|
|
113
|
+
* @param height - New height to scale the line to (must be > 1)
|
|
114
|
+
*/
|
|
115
|
+
resize(x, y, width, height) {
|
|
116
|
+
if (width <= 1 || height <= 1) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const scaleX = width / this.width;
|
|
120
|
+
const scaleY = height / this.height;
|
|
121
|
+
// Scale the line endpoints
|
|
122
|
+
this.startX = this.startX * scaleX;
|
|
123
|
+
this.startY = this.startY * scaleY;
|
|
124
|
+
this.endX = this.endX * scaleX;
|
|
125
|
+
this.endY = this.endY * scaleY;
|
|
126
|
+
if (this.controlX !== undefined && this.controlY !== undefined) {
|
|
127
|
+
this.controlX = this.controlX * scaleX;
|
|
128
|
+
this.controlY = this.controlY * scaleY;
|
|
129
|
+
}
|
|
130
|
+
// Recalculate dimensions from scaled endpoints
|
|
131
|
+
const { minX, minY, maxX, maxY } = this.calculateBoundingBox();
|
|
132
|
+
this.width = maxX - minX;
|
|
133
|
+
this.height = maxY - minY;
|
|
134
|
+
this.x = minX;
|
|
135
|
+
this.y = minY;
|
|
136
|
+
// Set the new position
|
|
137
|
+
this.translateX = x;
|
|
138
|
+
this.translateY = y;
|
|
139
|
+
this._adjustedPoints = null;
|
|
140
|
+
this._clipInfo = null;
|
|
141
|
+
this._core.store.objects.update(this);
|
|
142
|
+
// Update anchors after the line is updated
|
|
143
|
+
this._core.anchorManager.updateAnchorsForObject(this.id);
|
|
144
|
+
if (this.startAnchor) {
|
|
145
|
+
this._core.anchorManager.updateAnchorsForObject(this.startAnchor.objectId);
|
|
146
|
+
}
|
|
147
|
+
if (this.endAnchor) {
|
|
148
|
+
this._core.anchorManager.updateAnchorsForObject(this.endAnchor.objectId);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Sets the rotation angle of the line around its center.
|
|
153
|
+
* Invalidates cached adjusted points and clip info.
|
|
154
|
+
* @param value - Rotation angle in radians
|
|
155
|
+
*/
|
|
156
|
+
rotate(value) {
|
|
157
|
+
this.rotation = value;
|
|
158
|
+
this._adjustedPoints = null;
|
|
159
|
+
this._clipInfo = null;
|
|
160
|
+
this._core.store.objects.update(this);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Moves the line by calculating the delta between start and end positions.
|
|
164
|
+
* Updates anchored objects if the line has anchor connections.
|
|
165
|
+
* @param startX - Starting X position of the drag in screen coordinates
|
|
166
|
+
* @param startY - Starting Y position of the drag in screen coordinates
|
|
167
|
+
* @param endX - Ending X position of the drag in screen coordinates
|
|
168
|
+
* @param endY - Ending Y position of the drag in screen coordinates
|
|
169
|
+
*/
|
|
170
|
+
move(startX, startY, endX, endY) {
|
|
171
|
+
const deltaX = (startX - endX) / this._core.store.state.scale;
|
|
172
|
+
const deltaY = (startY - endY) / this._core.store.state.scale;
|
|
173
|
+
this.translateX += deltaX;
|
|
174
|
+
this.translateY += deltaY;
|
|
175
|
+
// If the line is anchored, we need to ensure the anchored endpoints stay at the target
|
|
176
|
+
if (this.startAnchor) {
|
|
177
|
+
this._core.anchorManager.updateAnchorsForObject(this.startAnchor.objectId);
|
|
178
|
+
}
|
|
179
|
+
if (this.endAnchor) {
|
|
180
|
+
this._core.anchorManager.updateAnchorsForObject(this.endAnchor.objectId);
|
|
181
|
+
}
|
|
182
|
+
this._adjustedPoints = null;
|
|
183
|
+
this._clipInfo = null;
|
|
184
|
+
this._core.store.objects.update(this);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Tests if a point intersects with the line within the stroke tolerance.
|
|
188
|
+
* Uses distance to line segment for straight lines, or distance to Bezier curve for curved lines.
|
|
189
|
+
* @param x - X coordinate of the point to test in world coordinates
|
|
190
|
+
* @param y - Y coordinate of the point to test in world coordinates
|
|
191
|
+
* @returns True if the point is within the stroke width tolerance of the line
|
|
192
|
+
*/
|
|
193
|
+
hitTest(x, y) {
|
|
194
|
+
const minHitThreshold = 20;
|
|
195
|
+
const strokeWidth = Math.max(this.strokeWidth, minHitThreshold);
|
|
196
|
+
const halfStroke = strokeWidth / this.scale / 2;
|
|
197
|
+
if (this._adjustedPoints === null) {
|
|
198
|
+
this._adjustedPoints = this.computeAdjustedPoints();
|
|
199
|
+
}
|
|
200
|
+
// For curved lines, use distance to the Bezier curve
|
|
201
|
+
if (this.controlX !== undefined && this.controlY !== undefined) {
|
|
202
|
+
const clip = this.getClipInfo();
|
|
203
|
+
const startT = clip.start?.t ?? 0;
|
|
204
|
+
const endT = clip.end?.t ?? 1;
|
|
205
|
+
const distance = this.pointToBezierDistance(x, y, startT, endT);
|
|
206
|
+
return distance <= halfStroke;
|
|
207
|
+
}
|
|
208
|
+
// For straight lines, use distance to line segment
|
|
209
|
+
const clip = this.getClipInfo();
|
|
210
|
+
const p1 = clip.start ? [clip.start.x, clip.start.y] : this._adjustedPoints[0];
|
|
211
|
+
const p2 = clip.end ? [clip.end.x, clip.end.y] : this._adjustedPoints[1];
|
|
212
|
+
const distance = this.pointToLineSegmentDistance(x, y, p1[0], p1[1], p2[0], p2[1]);
|
|
213
|
+
return distance <= halfStroke;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Tests if the line intersects with or is contained within a polygon.
|
|
217
|
+
* Checks endpoint containment, polygon vertex proximity, curve sampling for Bezier curves,
|
|
218
|
+
* and line-edge intersections for straight lines.
|
|
219
|
+
* @param polygon - The polygon to test intersection with, defined by four corner points
|
|
220
|
+
* @returns True if any part of the line intersects with the polygon
|
|
221
|
+
*/
|
|
222
|
+
hitTestPolygon(polygon) {
|
|
223
|
+
const halfStroke = this.strokeWidth / this.scale / 2;
|
|
224
|
+
if (this._adjustedPoints === null) {
|
|
225
|
+
this._adjustedPoints = this.computeAdjustedPoints();
|
|
226
|
+
}
|
|
227
|
+
const clip = this.getClipInfo();
|
|
228
|
+
const polyPoints = [
|
|
229
|
+
{ x: polygon.bottomLeft.x, y: polygon.bottomLeft.y },
|
|
230
|
+
{ x: polygon.bottomRight.x, y: polygon.bottomRight.y },
|
|
231
|
+
{ x: polygon.topRight.x, y: polygon.topRight.y },
|
|
232
|
+
{ x: polygon.topLeft.x, y: polygon.topLeft.y },
|
|
233
|
+
];
|
|
234
|
+
// Check if any endpoint is inside the polygon
|
|
235
|
+
// Use clipped endpoints
|
|
236
|
+
const p1 = clip.start ? [clip.start.x, clip.start.y] : this._adjustedPoints[0];
|
|
237
|
+
const p2 = clip.end ? [clip.end.x, clip.end.y] : this._adjustedPoints[1];
|
|
238
|
+
const endpoints = [p1, p2];
|
|
239
|
+
for (const [px, py] of endpoints) {
|
|
240
|
+
if (KritzelGeometryHelper.isPointInPolygon({ x: px, y: py }, polyPoints)) {
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Check if any polygon vertex is on the line/curve
|
|
245
|
+
for (const pt of polyPoints) {
|
|
246
|
+
if (this.hitTest(pt.x, pt.y)) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// For curved lines, sample points along the curve and check if any are inside the polygon
|
|
251
|
+
if (this.controlX !== undefined && this.controlY !== undefined) {
|
|
252
|
+
const p0 = this._adjustedPoints[0];
|
|
253
|
+
const p2 = this._adjustedPoints[1];
|
|
254
|
+
const controlAdjusted = this.computeAdjustedControlPoint();
|
|
255
|
+
const startT = clip.start?.t ?? 0;
|
|
256
|
+
const endT = clip.end?.t ?? 1;
|
|
257
|
+
const samples = 20;
|
|
258
|
+
for (let i = 0; i <= samples; i++) {
|
|
259
|
+
const fraction = i / samples;
|
|
260
|
+
const t = startT + fraction * (endT - startT);
|
|
261
|
+
const oneMinusT = 1 - t;
|
|
262
|
+
const bx = oneMinusT * oneMinusT * p0[0] + 2 * oneMinusT * t * controlAdjusted[0] + t * t * p2[0];
|
|
263
|
+
const by = oneMinusT * oneMinusT * p0[1] + 2 * oneMinusT * t * controlAdjusted[1] + t * t * p2[1];
|
|
264
|
+
if (KritzelGeometryHelper.isPointInPolygon({ x: bx, y: by }, polyPoints)) {
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
// Also check if curve point is within stroke distance of polygon edges
|
|
268
|
+
for (let j = 0; j < polyPoints.length; j++) {
|
|
269
|
+
const q1 = polyPoints[j];
|
|
270
|
+
const q2 = polyPoints[(j + 1) % polyPoints.length];
|
|
271
|
+
const d = this.pointToLineSegmentDistance(bx, by, q1.x, q1.y, q2.x, q2.y);
|
|
272
|
+
if (d <= halfStroke) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
}
|
|
279
|
+
// For straight lines, check if line intersects any polygon edge
|
|
280
|
+
const checkP1 = { x: p1[0], y: p1[1] };
|
|
281
|
+
const checkP2 = { x: p2[0], y: p2[1] };
|
|
282
|
+
for (let j = 0; j < polyPoints.length; j++) {
|
|
283
|
+
const q1 = polyPoints[j];
|
|
284
|
+
const q2 = polyPoints[(j + 1) % polyPoints.length];
|
|
285
|
+
if (KritzelGeometryHelper.intersectLines(checkP1, checkP2, q1, q2)) {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
// Check distance from polygon edges to line segment
|
|
289
|
+
const d1 = this.pointToLineSegmentDistance(q1.x, q1.y, checkP1.x, checkP1.y, checkP2.x, checkP2.y);
|
|
290
|
+
const d2 = this.pointToLineSegmentDistance(q2.x, q2.y, checkP1.x, checkP1.y, checkP2.x, checkP2.y);
|
|
291
|
+
const d3 = this.pointToLineSegmentDistance(checkP1.x, checkP1.y, q1.x, q1.y, q2.x, q2.y);
|
|
292
|
+
const d4 = this.pointToLineSegmentDistance(checkP2.x, checkP2.y, q1.x, q1.y, q2.x, q2.y);
|
|
293
|
+
const minD = Math.min(d1, d2, d3, d4);
|
|
294
|
+
if (minD <= halfStroke) {
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Updates the translation position of the line without recalculating dimensions.
|
|
302
|
+
* Invalidates cached adjusted points and clip info.
|
|
303
|
+
* @param x - New X translation in world coordinates
|
|
304
|
+
* @param y - New Y translation in world coordinates
|
|
305
|
+
*/
|
|
306
|
+
updatePosition(x, y) {
|
|
307
|
+
this.translateX = x;
|
|
308
|
+
this.translateY = y;
|
|
309
|
+
this._adjustedPoints = null;
|
|
310
|
+
this._clipInfo = null;
|
|
311
|
+
this._core.store.objects.update(this);
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Updates a specific endpoint of the line (start or end).
|
|
315
|
+
* Recalculates the bounding box dimensions and adjusts translation to maintain
|
|
316
|
+
* the visual position after the origin shift, accounting for rotation.
|
|
317
|
+
* @param handleType - Which endpoint to update: 'start' or 'end'
|
|
318
|
+
* @param newX - New X coordinate in viewBox-local space (relative to x, y origin)
|
|
319
|
+
* @param newY - New Y coordinate in viewBox-local space (relative to x, y origin)
|
|
320
|
+
*/
|
|
321
|
+
updateEndpoint(handleType, newX, newY) {
|
|
322
|
+
// Update the appropriate endpoint
|
|
323
|
+
if (handleType === 'start') {
|
|
324
|
+
this.startX = newX;
|
|
325
|
+
this.startY = newY;
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
this.endX = newX;
|
|
329
|
+
this.endY = newY;
|
|
330
|
+
}
|
|
331
|
+
const oldWidth = this.width;
|
|
332
|
+
const oldHeight = this.height;
|
|
333
|
+
// Recalculate the bounding box (viewBox dimensions)
|
|
334
|
+
const { minX, minY, maxX, maxY } = this.calculateBoundingBox();
|
|
335
|
+
// Calculate the change in origin (in local coordinates)
|
|
336
|
+
const deltaX = minX - this.x;
|
|
337
|
+
const deltaY = minY - this.y;
|
|
338
|
+
const newWidth = maxX - minX;
|
|
339
|
+
const newHeight = maxY - minY;
|
|
340
|
+
const deltaWidth = newWidth - oldWidth;
|
|
341
|
+
const deltaHeight = newHeight - oldHeight;
|
|
342
|
+
const deltaCx = deltaWidth / 2;
|
|
343
|
+
const deltaCy = deltaHeight / 2;
|
|
344
|
+
// Update viewBox dimensions
|
|
345
|
+
this.x = minX;
|
|
346
|
+
this.y = minY;
|
|
347
|
+
this.width = newWidth;
|
|
348
|
+
this.height = newHeight;
|
|
349
|
+
// Rotate the delta to world coordinates before applying to translate
|
|
350
|
+
const cos = Math.cos(this.rotation);
|
|
351
|
+
const sin = Math.sin(this.rotation);
|
|
352
|
+
// We need to compensate for:
|
|
353
|
+
// 1. The shift of the top-left corner (deltaX, deltaY)
|
|
354
|
+
// 2. The shift of the center point (deltaCx, deltaCy) which affects rotation pivot
|
|
355
|
+
// Formula: DeltaT = R(DeltaPos + DeltaCenter) - DeltaCenter
|
|
356
|
+
const vx = deltaX + deltaCx;
|
|
357
|
+
const vy = deltaY + deltaCy;
|
|
358
|
+
const rotatedVx = vx * cos - vy * sin;
|
|
359
|
+
const rotatedVy = vx * sin + vy * cos;
|
|
360
|
+
const correctionX = rotatedVx - deltaCx;
|
|
361
|
+
const correctionY = rotatedVy - deltaCy;
|
|
362
|
+
// Adjust translateX/Y to compensate for the origin shift
|
|
363
|
+
// so the line stays visually in the same position
|
|
364
|
+
this.translateX += correctionX / this.scale;
|
|
365
|
+
this.translateY += correctionY / this.scale;
|
|
366
|
+
// Clear cached adjusted points
|
|
367
|
+
this._adjustedPoints = null;
|
|
368
|
+
this._clipInfo = null;
|
|
369
|
+
this._core.store.objects.update(this);
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Updates the control point for a quadratic Bezier curve.
|
|
373
|
+
* Recalculates bounding box and adjusts translation to maintain visual position.
|
|
374
|
+
* Pass undefined for both parameters to convert the line back to a straight line.
|
|
375
|
+
* @param newX - New X coordinate for the control point, or undefined to remove
|
|
376
|
+
* @param newY - New Y coordinate for the control point, or undefined to remove
|
|
377
|
+
*/
|
|
378
|
+
updateControlPoint(newX, newY) {
|
|
379
|
+
this.controlX = newX;
|
|
380
|
+
this.controlY = newY;
|
|
381
|
+
const oldWidth = this.width;
|
|
382
|
+
const oldHeight = this.height;
|
|
383
|
+
// Recalculate the bounding box (viewBox dimensions)
|
|
384
|
+
const { minX, minY, maxX, maxY } = this.calculateBoundingBox();
|
|
385
|
+
// Calculate the change in origin (in local coordinates)
|
|
386
|
+
const deltaX = minX - this.x;
|
|
387
|
+
const deltaY = minY - this.y;
|
|
388
|
+
const newWidth = maxX - minX;
|
|
389
|
+
const newHeight = maxY - minY;
|
|
390
|
+
const deltaWidth = newWidth - oldWidth;
|
|
391
|
+
const deltaHeight = newHeight - oldHeight;
|
|
392
|
+
const deltaCx = deltaWidth / 2;
|
|
393
|
+
const deltaCy = deltaHeight / 2;
|
|
394
|
+
// Update viewBox dimensions
|
|
395
|
+
this.x = minX;
|
|
396
|
+
this.y = minY;
|
|
397
|
+
this.width = newWidth;
|
|
398
|
+
this.height = newHeight;
|
|
399
|
+
// Rotate the delta to world coordinates before applying to translate
|
|
400
|
+
const cos = Math.cos(this.rotation);
|
|
401
|
+
const sin = Math.sin(this.rotation);
|
|
402
|
+
// We need to compensate for:
|
|
403
|
+
// 1. The shift of the top-left corner (deltaX, deltaY)
|
|
404
|
+
// 2. The shift of the center point (deltaCx, deltaCy) which affects rotation pivot
|
|
405
|
+
// Formula: DeltaT = R(DeltaPos + DeltaCenter) - DeltaCenter
|
|
406
|
+
const vx = deltaX + deltaCx;
|
|
407
|
+
const vy = deltaY + deltaCy;
|
|
408
|
+
const rotatedVx = vx * cos - vy * sin;
|
|
409
|
+
const rotatedVy = vx * sin + vy * cos;
|
|
410
|
+
const correctionX = rotatedVx - deltaCx;
|
|
411
|
+
const correctionY = rotatedVy - deltaCy;
|
|
412
|
+
// Adjust translateX/Y to compensate for the origin shift
|
|
413
|
+
// so the line stays visually in the same position
|
|
414
|
+
this.translateX += correctionX / this.scale;
|
|
415
|
+
this.translateY += correctionY / this.scale;
|
|
416
|
+
// Clear cached adjusted points
|
|
417
|
+
this._adjustedPoints = null;
|
|
418
|
+
this._clipInfo = null;
|
|
419
|
+
this._core.store.objects.update(this);
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Computes the line endpoints in world coordinates, accounting for rotation,
|
|
423
|
+
* scale, and translation transformations.
|
|
424
|
+
* @returns Array of two points [[startX, startY], [endX, endY]] in world coordinates
|
|
425
|
+
*/
|
|
426
|
+
computeAdjustedPoints() {
|
|
427
|
+
const points = [
|
|
428
|
+
[this.startX, this.startY],
|
|
429
|
+
[this.endX, this.endY],
|
|
430
|
+
];
|
|
431
|
+
const angle = this.rotation;
|
|
432
|
+
const cos = Math.cos(angle);
|
|
433
|
+
const sin = Math.sin(angle);
|
|
434
|
+
const xs = points.map(p => p[0]);
|
|
435
|
+
const ys = points.map(p => p[1]);
|
|
436
|
+
const pivot = {
|
|
437
|
+
x: (Math.min(...xs) + Math.max(...xs)) / 2,
|
|
438
|
+
y: (Math.min(...ys) + Math.max(...ys)) / 2,
|
|
439
|
+
};
|
|
440
|
+
const { x: cx, y: cy } = pivot;
|
|
441
|
+
const rotatedPoints = points.map(([x, y]) => {
|
|
442
|
+
const dx = x - cx;
|
|
443
|
+
const dy = y - cy;
|
|
444
|
+
return [cx + dx * cos - dy * sin, cy + dx * sin + dy * cos];
|
|
445
|
+
});
|
|
446
|
+
return rotatedPoints.map(([px, py]) => [(px - this.x) / this.scale + this.translateX, (py - this.y) / this.scale + this.translateY]);
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Calculates the minimum distance from a point to a line segment.
|
|
450
|
+
* Uses parametric projection to find the closest point on the segment.
|
|
451
|
+
* @param x - X coordinate of the test point
|
|
452
|
+
* @param y - Y coordinate of the test point
|
|
453
|
+
* @param x1 - X coordinate of the segment start
|
|
454
|
+
* @param y1 - Y coordinate of the segment start
|
|
455
|
+
* @param x2 - X coordinate of the segment end
|
|
456
|
+
* @param y2 - Y coordinate of the segment end
|
|
457
|
+
* @returns The minimum distance from the point to the line segment
|
|
458
|
+
*/
|
|
459
|
+
pointToLineSegmentDistance(x, y, x1, y1, x2, y2) {
|
|
460
|
+
const A = x - x1;
|
|
461
|
+
const B = y - y1;
|
|
462
|
+
const C = x2 - x1;
|
|
463
|
+
const D = y2 - y1;
|
|
464
|
+
const dot = A * C + B * D;
|
|
465
|
+
const len_sq = C * C + D * D;
|
|
466
|
+
let param = -1;
|
|
467
|
+
if (len_sq !== 0) {
|
|
468
|
+
param = dot / len_sq;
|
|
469
|
+
}
|
|
470
|
+
let xx, yy;
|
|
471
|
+
if (param < 0) {
|
|
472
|
+
xx = x1;
|
|
473
|
+
yy = y1;
|
|
474
|
+
}
|
|
475
|
+
else if (param > 1) {
|
|
476
|
+
xx = x2;
|
|
477
|
+
yy = y2;
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
xx = x1 + param * C;
|
|
481
|
+
yy = y1 + param * D;
|
|
482
|
+
}
|
|
483
|
+
const dx = x - xx;
|
|
484
|
+
const dy = y - yy;
|
|
485
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Calculates the minimum distance from a point to a quadratic Bezier curve.
|
|
489
|
+
* Uses sampling along the curve (20 samples) to approximate the closest point.
|
|
490
|
+
* @param x - X coordinate of the test point in world coordinates
|
|
491
|
+
* @param y - Y coordinate of the test point in world coordinates
|
|
492
|
+
* @param startT - Start parameter for curve sampling (0-1), used for clipped curves
|
|
493
|
+
* @param endT - End parameter for curve sampling (0-1), used for clipped curves
|
|
494
|
+
* @returns The minimum distance from the point to the sampled curve
|
|
495
|
+
*/
|
|
496
|
+
pointToBezierDistance(x, y, startT = 0, endT = 1) {
|
|
497
|
+
if (this._adjustedPoints === null) {
|
|
498
|
+
this._adjustedPoints = this.computeAdjustedPoints();
|
|
499
|
+
}
|
|
500
|
+
const p0 = this._adjustedPoints[0];
|
|
501
|
+
const p2 = this._adjustedPoints[1];
|
|
502
|
+
// Calculate the adjusted control point
|
|
503
|
+
const controlAdjusted = this.computeAdjustedControlPoint();
|
|
504
|
+
let minDistance = Infinity;
|
|
505
|
+
const samples = 20; // Number of samples along the curve
|
|
506
|
+
for (let i = 0; i <= samples; i++) {
|
|
507
|
+
const fraction = i / samples;
|
|
508
|
+
const t = startT + fraction * (endT - startT);
|
|
509
|
+
const oneMinusT = 1 - t;
|
|
510
|
+
// Quadratic Bezier: B(t) = (1-t)²P₀ + 2(1-t)tP₁ + t²P₂
|
|
511
|
+
const bx = oneMinusT * oneMinusT * p0[0] + 2 * oneMinusT * t * controlAdjusted[0] + t * t * p2[0];
|
|
512
|
+
const by = oneMinusT * oneMinusT * p0[1] + 2 * oneMinusT * t * controlAdjusted[1] + t * t * p2[1];
|
|
513
|
+
const dx = x - bx;
|
|
514
|
+
const dy = y - by;
|
|
515
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
516
|
+
if (distance < minDistance) {
|
|
517
|
+
minDistance = distance;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return minDistance;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Retrieves or computes the clip information for anchored line endpoints.
|
|
524
|
+
* Caches the result to avoid recalculation on subsequent calls.
|
|
525
|
+
* @returns Object containing optional start and end clip points with world coordinates
|
|
526
|
+
* and parametric t values for curve clipping
|
|
527
|
+
*/
|
|
528
|
+
getClipInfo() {
|
|
529
|
+
if (this._clipInfo)
|
|
530
|
+
return this._clipInfo;
|
|
531
|
+
const startAnchor = this.startAnchor;
|
|
532
|
+
const endAnchor = this.endAnchor;
|
|
533
|
+
const result = {};
|
|
534
|
+
if (startAnchor) {
|
|
535
|
+
const target = this._core.anchorManager.findAnchorTarget(this, 'start');
|
|
536
|
+
if (target) {
|
|
537
|
+
const clip = this._core.anchorManager.computeAnchorClipInfo(this, 'start', target);
|
|
538
|
+
if (clip) {
|
|
539
|
+
result.start = { x: clip.worldX, y: clip.worldY, t: clip.t };
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (endAnchor) {
|
|
544
|
+
const target = this._core.anchorManager.findAnchorTarget(this, 'end');
|
|
545
|
+
if (target) {
|
|
546
|
+
const clip = this._core.anchorManager.computeAnchorClipInfo(this, 'end', target);
|
|
547
|
+
if (clip) {
|
|
548
|
+
result.end = { x: clip.worldX, y: clip.worldY, t: clip.t };
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
this._clipInfo = result;
|
|
553
|
+
return result;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Computes the adjusted control point in world coordinates.
|
|
557
|
+
* Applies rotation around the bounding box center, then scale and translation transforms.
|
|
558
|
+
* @returns Array [x, y] representing the control point in world coordinates,
|
|
559
|
+
* or the midpoint of the line if no control point is defined
|
|
560
|
+
*/
|
|
561
|
+
computeAdjustedControlPoint() {
|
|
562
|
+
if (this.controlX === undefined || this.controlY === undefined) {
|
|
563
|
+
// Return midpoint if no control point
|
|
564
|
+
return [(this.startX + this.endX) / 2, (this.startY + this.endY) / 2];
|
|
565
|
+
}
|
|
566
|
+
const angle = this.rotation;
|
|
567
|
+
const cos = Math.cos(angle);
|
|
568
|
+
const sin = Math.sin(angle);
|
|
569
|
+
// Calculate pivot (center of bounding box for endpoints)
|
|
570
|
+
const xs = [this.startX, this.endX];
|
|
571
|
+
const ys = [this.startY, this.endY];
|
|
572
|
+
const pivot = {
|
|
573
|
+
x: (Math.min(...xs) + Math.max(...xs)) / 2,
|
|
574
|
+
y: (Math.min(...ys) + Math.max(...ys)) / 2,
|
|
575
|
+
};
|
|
576
|
+
const { x: cx, y: cy } = pivot;
|
|
577
|
+
// Rotate control point around pivot
|
|
578
|
+
const dx = this.controlX - cx;
|
|
579
|
+
const dy = this.controlY - cy;
|
|
580
|
+
const rotatedX = cx + dx * cos - dy * sin;
|
|
581
|
+
const rotatedY = cy + dx * sin + dy * cos;
|
|
582
|
+
// Transform to world coordinates
|
|
583
|
+
return [(rotatedX - this.x) / this.scale + this.translateX, (rotatedY - this.y) / this.scale + this.translateY];
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Gets the bounding polygon of the line in world coordinates, accounting for rotation.
|
|
587
|
+
* Used for selection bounds and intersection testing.
|
|
588
|
+
* @returns A polygon with four corner points (topLeft, topRight, bottomRight, bottomLeft)
|
|
589
|
+
* transformed to world coordinates with rotation applied
|
|
590
|
+
*/
|
|
591
|
+
get rotatedPolygon() {
|
|
592
|
+
const padding = this.padding;
|
|
593
|
+
// Use the bounding box which accounts for curve extrema
|
|
594
|
+
const { minX, minY, maxX, maxY } = KritzelLine.calculateBoundingBox(this.startX, this.startY, this.endX, this.endY, this.controlX, this.controlY, this.strokeWidth);
|
|
595
|
+
// Convert to local coordinates (relative to this.x, this.y)
|
|
596
|
+
const localMinX = minX - this.x + padding;
|
|
597
|
+
const localMinY = minY - this.y + padding;
|
|
598
|
+
const localMaxX = maxX - this.x + padding;
|
|
599
|
+
const localMaxY = maxY - this.y + padding;
|
|
600
|
+
const c1 = { x: localMinX, y: localMinY }; // top-left
|
|
601
|
+
const c2 = { x: localMaxX, y: localMinY }; // top-right
|
|
602
|
+
const c3 = { x: localMaxX, y: localMaxY }; // bottom-right
|
|
603
|
+
const c4 = { x: localMinX, y: localMaxY }; // bottom-left
|
|
604
|
+
const cx = this.totalWidth / 2;
|
|
605
|
+
const cy = this.totalHeight / 2;
|
|
606
|
+
const angle = this.rotation;
|
|
607
|
+
const cos = Math.cos(angle);
|
|
608
|
+
const sin = Math.sin(angle);
|
|
609
|
+
const transform = (p) => {
|
|
610
|
+
const rx = (p.x - cx) * cos - (p.y - cy) * sin + cx;
|
|
611
|
+
const ry = (p.x - cx) * sin + (p.y - cy) * cos + cy;
|
|
612
|
+
return {
|
|
613
|
+
x: rx / this.scale + this.translateX,
|
|
614
|
+
y: ry / this.scale + this.translateY,
|
|
615
|
+
};
|
|
616
|
+
};
|
|
617
|
+
return {
|
|
618
|
+
topLeft: transform(c1),
|
|
619
|
+
topRight: transform(c2),
|
|
620
|
+
bottomRight: transform(c3),
|
|
621
|
+
bottomLeft: transform(c4),
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Calculates the tight bounding box for a quadratic Bezier curve or straight line.
|
|
626
|
+
* For curves, finds extrema points where the derivative equals zero to ensure
|
|
627
|
+
* the bounding box encompasses the entire curve arc.
|
|
628
|
+
* @param startX - X coordinate of the line start point
|
|
629
|
+
* @param startY - Y coordinate of the line start point
|
|
630
|
+
* @param endX - X coordinate of the line end point
|
|
631
|
+
* @param endY - Y coordinate of the line end point
|
|
632
|
+
* @param controlX - X coordinate of the control point (undefined for straight lines)
|
|
633
|
+
* @param controlY - Y coordinate of the control point (undefined for straight lines)
|
|
634
|
+
* @param strokeWidth - Width of the line stroke for padding calculation
|
|
635
|
+
* @returns Object with minX, minY, maxX, maxY including stroke width padding
|
|
636
|
+
*/
|
|
637
|
+
static calculateBoundingBox(startX, startY, endX, endY, controlX, controlY, strokeWidth) {
|
|
638
|
+
let minX = Math.min(startX, endX);
|
|
639
|
+
let minY = Math.min(startY, endY);
|
|
640
|
+
let maxX = Math.max(startX, endX);
|
|
641
|
+
let maxY = Math.max(startY, endY);
|
|
642
|
+
if (controlX !== undefined && controlY !== undefined) {
|
|
643
|
+
// For a quadratic Bezier: B(t) = (1-t)²P₀ + 2(1-t)tP₁ + t²P₂
|
|
644
|
+
// Derivative: B'(t) = 2(1-t)(P₁-P₀) + 2t(P₂-P₁) = 0
|
|
645
|
+
// Solving for t: t = (P₀ - P₁) / (P₀ - 2P₁ + P₂)
|
|
646
|
+
// Find extrema for X
|
|
647
|
+
const aX = startX - 2 * controlX + endX;
|
|
648
|
+
if (aX !== 0) {
|
|
649
|
+
const tX = (startX - controlX) / aX;
|
|
650
|
+
if (tX > 0 && tX < 1) {
|
|
651
|
+
const extremaX = (1 - tX) * (1 - tX) * startX + 2 * (1 - tX) * tX * controlX + tX * tX * endX;
|
|
652
|
+
minX = Math.min(minX, extremaX);
|
|
653
|
+
maxX = Math.max(maxX, extremaX);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
// Find extrema for Y
|
|
657
|
+
const aY = startY - 2 * controlY + endY;
|
|
658
|
+
if (aY !== 0) {
|
|
659
|
+
const tY = (startY - controlY) / aY;
|
|
660
|
+
if (tY > 0 && tY < 1) {
|
|
661
|
+
const extremaY = (1 - tY) * (1 - tY) * startY + 2 * (1 - tY) * tY * controlY + tY * tY * endY;
|
|
662
|
+
minY = Math.min(minY, extremaY);
|
|
663
|
+
maxY = Math.max(maxY, extremaY);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
const halfStroke = strokeWidth / 2;
|
|
668
|
+
return {
|
|
669
|
+
minX: minX - halfStroke,
|
|
670
|
+
minY: minY - halfStroke,
|
|
671
|
+
maxX: maxX + halfStroke,
|
|
672
|
+
maxY: maxY + halfStroke,
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Calculates the bounding box for this line instance using the current endpoint,
|
|
677
|
+
* control point, and stroke width values.
|
|
678
|
+
* @returns Object with minX, minY, maxX, maxY bounds including stroke width padding
|
|
679
|
+
*/
|
|
680
|
+
calculateBoundingBox() {
|
|
681
|
+
return KritzelLine.calculateBoundingBox(this.startX, this.startY, this.endX, this.endY, this.controlX, this.controlY, this.strokeWidth);
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Serializes the line while excluding transient cache fields.
|
|
685
|
+
* @returns A serializable line object without runtime caches
|
|
686
|
+
*/
|
|
687
|
+
serialize() {
|
|
688
|
+
const serialized = super.serialize();
|
|
689
|
+
delete serialized._adjustedPoints;
|
|
690
|
+
delete serialized._clipInfo;
|
|
691
|
+
return serialized;
|
|
692
|
+
}
|
|
693
|
+
/**
|
|
694
|
+
* Deserializes and resets transient caches so geometry is recomputed lazily.
|
|
695
|
+
* @param object - The serialized line object
|
|
696
|
+
* @returns This instance cast to type T
|
|
697
|
+
*/
|
|
698
|
+
deserialize(object) {
|
|
699
|
+
const result = super.deserialize(object);
|
|
700
|
+
this._adjustedPoints = null;
|
|
701
|
+
this._clipInfo = null;
|
|
702
|
+
return result;
|
|
703
|
+
}
|
|
704
|
+
/**
|
|
705
|
+
* Recalculates and updates the width, height, x, y, and translation properties
|
|
706
|
+
* based on the current endpoint positions and stroke width.
|
|
707
|
+
* Called during construction and after endpoint changes.
|
|
708
|
+
*/
|
|
709
|
+
updateDimensions() {
|
|
710
|
+
const { minX, minY, maxX, maxY } = this.calculateBoundingBox();
|
|
711
|
+
this.width = maxX - minX;
|
|
712
|
+
this.height = maxY - minY;
|
|
713
|
+
this.x = minX;
|
|
714
|
+
this.y = minY;
|
|
715
|
+
this.translateX = (this.x + this.translateX) / this.scale;
|
|
716
|
+
this.translateY = (this.y + this.translateY) / this.scale;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Gets the unique SVG marker ID for the arrow head at the start of the line.
|
|
720
|
+
* Used in SVG defs for marker-start attribute.
|
|
721
|
+
* @returns A unique marker ID string in the format "arrow-start-{lineId}"
|
|
722
|
+
*/
|
|
723
|
+
get startMarkerId() {
|
|
724
|
+
return `arrow-start-${this.id}`;
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Gets the unique SVG marker ID for the arrow head at the end of the line.
|
|
728
|
+
* Used in SVG defs for marker-end attribute.
|
|
729
|
+
* @returns A unique marker ID string in the format "arrow-end-{lineId}"
|
|
730
|
+
*/
|
|
731
|
+
get endMarkerId() {
|
|
732
|
+
return `arrow-end-${this.id}`;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Gets the arrow head size for the specified end of the line.
|
|
736
|
+
* @param end - Which end to get the arrow size for: 'start' or 'end'
|
|
737
|
+
* @returns The configured arrow size, or strokeWidth * 3 as default
|
|
738
|
+
*/
|
|
739
|
+
getArrowSize(end) {
|
|
740
|
+
const config = end === 'start' ? this.arrows?.start : this.arrows?.end;
|
|
741
|
+
return config?.size ?? this.strokeWidth * 3;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Gets the resolved fill color for the arrow head at the specified end.
|
|
745
|
+
* Resolves theme-aware colors to the appropriate value for the current theme.
|
|
746
|
+
* @param end - Which end to get the arrow fill for: 'start' or 'end'
|
|
747
|
+
* @returns The resolved CSS color string for the arrow fill
|
|
748
|
+
*/
|
|
749
|
+
getArrowFill(end) {
|
|
750
|
+
const config = end === 'start' ? this.arrows?.start : this.arrows?.end;
|
|
751
|
+
const color = config?.fill ?? this.stroke;
|
|
752
|
+
return KritzelColorHelper.resolveThemeColor(color, this._core?.themeManager?.currentTheme);
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Generates SVG path data for an arrow head based on the given style.
|
|
756
|
+
* All paths are designed to fit in a 10x10 viewBox with the tip at (10, 5).
|
|
757
|
+
* @param style - The arrow head style: 'triangle' (filled), 'open' (outline),
|
|
758
|
+
* 'diamond' (rhombus), or 'circle'. Defaults to 'triangle'.
|
|
759
|
+
* @returns SVG path data string for use in a marker element
|
|
760
|
+
*/
|
|
761
|
+
getArrowPath(style = 'triangle') {
|
|
762
|
+
switch (style) {
|
|
763
|
+
case 'triangle':
|
|
764
|
+
return 'M 0 0 L 10 5 L 0 10 z';
|
|
765
|
+
case 'open':
|
|
766
|
+
return 'M 0 0 L 10 5 L 0 10';
|
|
767
|
+
case 'diamond':
|
|
768
|
+
return 'M 0 5 L 5 0 L 10 5 L 5 10 z';
|
|
769
|
+
case 'circle':
|
|
770
|
+
return 'M 5,0 A 5,5 0 1,1 5,10 A 5,5 0 1,1 5,0';
|
|
771
|
+
default:
|
|
772
|
+
return 'M 0 0 L 10 5 L 0 10 z';
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Checks if an arrow head is enabled at the start of the line.
|
|
777
|
+
* @returns True if the start arrow configuration exists and is enabled
|
|
778
|
+
*/
|
|
779
|
+
get hasStartArrow() {
|
|
780
|
+
return this.arrows?.start?.enabled === true;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Checks if an arrow head is enabled at the end of the line.
|
|
784
|
+
* @returns True if the end arrow configuration exists and is enabled
|
|
785
|
+
*/
|
|
786
|
+
get hasEndArrow() {
|
|
787
|
+
return this.arrows?.end?.enabled === true;
|
|
788
|
+
}
|
|
789
|
+
}
|