@node-projects/web-component-designer 0.0.119 → 0.0.121

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.
Files changed (28) hide show
  1. package/dist/elements/helper/PathDataPolyfill.js +5 -28
  2. package/dist/elements/helper/contextMenu/ContextMenuHelper.js +7 -2
  3. package/dist/elements/services/DefaultServiceBootstrap.js +7 -1
  4. package/dist/elements/services/htmlWriterService/HtmlWriterService.js +10 -6
  5. package/dist/elements/widgets/designerView/designerCanvas.js +18 -1
  6. package/dist/elements/widgets/designerView/extensions/ResizeExtensionProvider.js +2 -0
  7. package/dist/elements/widgets/designerView/extensions/contextMenu/SelectAllChildrenContextMenu.js +1 -1
  8. package/dist/elements/widgets/designerView/extensions/svg/EllipsisExtension.d.ts +29 -0
  9. package/dist/elements/widgets/designerView/extensions/svg/EllipsisExtension.js +112 -0
  10. package/dist/elements/widgets/designerView/extensions/svg/EllipsisExtensionProvider.d.ts +9 -0
  11. package/dist/elements/widgets/designerView/extensions/svg/EllipsisExtensionProvider.js +12 -0
  12. package/dist/elements/widgets/designerView/extensions/svg/LineExtension.d.ts +20 -0
  13. package/dist/elements/widgets/designerView/extensions/svg/LineExtension.js +87 -0
  14. package/dist/elements/widgets/designerView/extensions/svg/LineExtensionProvider.d.ts +9 -0
  15. package/dist/elements/widgets/designerView/extensions/svg/LineExtensionProvider.js +12 -0
  16. package/dist/elements/widgets/designerView/extensions/svg/PathExtension.d.ts +23 -0
  17. package/dist/elements/widgets/designerView/extensions/svg/PathExtension.js +286 -0
  18. package/dist/elements/widgets/designerView/extensions/svg/PathExtensionProvider.d.ts +9 -0
  19. package/dist/elements/widgets/designerView/extensions/svg/PathExtensionProvider.js +12 -0
  20. package/dist/elements/widgets/designerView/extensions/svg/RectExtension.d.ts +34 -0
  21. package/dist/elements/widgets/designerView/extensions/svg/RectExtension.js +137 -0
  22. package/dist/elements/widgets/designerView/extensions/svg/RectExtensionProvider.d.ts +9 -0
  23. package/dist/elements/widgets/designerView/extensions/svg/RectExtensionProvider.js +12 -0
  24. package/dist/elements/widgets/designerView/tools/DrawPathTool.js +11 -11
  25. package/dist/elements/widgets/designerView/tools/toolBar/DesignerToolbarButton.js +1 -1
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.js +2 -2
  28. package/package.json +4 -4
@@ -944,34 +944,11 @@ export function moveSVGPath(path, xFactor, yFactor) {
944
944
  export function createPathD(path) {
945
945
  let pathD = "";
946
946
  for (let p of path) {
947
- switch (p.type) {
948
- case 'M':
949
- pathD += p.type + p.values[0] + " " + p.values[1];
950
- break;
951
- case 'L':
952
- pathD += p.type + p.values[0] + " " + p.values[1];
953
- break;
954
- case 'H':
955
- break;
956
- case 'V':
957
- break;
958
- case 'Z':
959
- pathD += p.type;
960
- break;
961
- case 'C':
962
- case 'c':
963
- pathD += p.type + p.values[0] + " " + p.values[1] + " " + p.values[2] + " " + p.values[3] + " " + p.values[4] + " " + p.values[5];
964
- break;
965
- case 'S':
966
- break;
967
- case 'Q':
968
- case 'q':
969
- pathD += p.type + p.values[0] + " " + p.values[1] + " " + p.values[2] + " " + p.values[3];
970
- break;
971
- case 'T':
972
- break;
973
- case 'A':
974
- break;
947
+ pathD += p.type + " ";
948
+ for (var i = 0; i < p.values.length; i++) {
949
+ if (p.values[i] != null && !isNaN(p.values[i])) {
950
+ pathD += p.values[i] + " ";
951
+ }
975
952
  }
976
953
  }
977
954
  return pathD;
@@ -133,12 +133,17 @@ export class ContextMenuHelper {
133
133
  let ul = document.createElement('ul');
134
134
  ul.className = 'context-menu__items';
135
135
  nav.appendChild(ul);
136
+ let lastWasSeperator = false;
136
137
  for (let i of items) {
137
138
  if (i.title == '-') {
138
- let hr = document.createElement('hr');
139
- ul.appendChild(hr);
139
+ if (!lastWasSeperator) {
140
+ let hr = document.createElement('hr');
141
+ ul.appendChild(hr);
142
+ lastWasSeperator = true;
143
+ }
140
144
  }
141
145
  else {
146
+ lastWasSeperator = false;
142
147
  let li = document.createElement('li');
143
148
  li.className = 'context-menu__item';
144
149
  let div = document.createElement('div');
@@ -14,7 +14,7 @@ import { GridExtensionProvider } from '../widgets/designerView/extensions/GridEx
14
14
  import { TransformOriginExtensionProvider } from '../widgets/designerView/extensions/TransformOriginExtensionProvider.js';
15
15
  import { CanvasExtensionProvider } from '../widgets/designerView/extensions/CanvasExtensionProvider.js';
16
16
  import { PositionExtensionProvider } from '../widgets/designerView/extensions/PositionExtensionProvider.js';
17
- import { PathExtensionProvider } from '../widgets/designerView/extensions/PathExtensionProvider.js';
17
+ import { PathExtensionProvider } from '../widgets/designerView/extensions/svg/PathExtensionProvider.js';
18
18
  import { MouseOverExtensionProvider } from '../widgets/designerView/extensions/MouseOverExtensionProvider.js';
19
19
  import { NamedTools } from '../widgets/designerView/tools/NamedTools.js';
20
20
  import { PointerTool } from '../widgets/designerView/tools/PointerTool.js';
@@ -64,6 +64,9 @@ import { DrawToolButtonProvider } from '../widgets/designerView/tools/toolBar/bu
64
64
  import { TextToolButtonProvider } from '../widgets/designerView/tools/toolBar/buttons/TextToolButtonProvider.js';
65
65
  import { SelectorToolButtonProvider } from '../widgets/designerView/tools/toolBar/buttons/SelectorToolButtonProvider.js';
66
66
  import { GrayOutDragOverContainerExtensionProvider } from '../widgets/designerView/extensions/GrayOutDragOverContainerExtensionProvider.js';
67
+ import { LineExtensionProvider } from '../widgets/designerView/extensions/svg/LineExtensionProvider.js';
68
+ import { RectExtentionProvider } from '../widgets/designerView/extensions/svg/RectExtensionProvider.js';
69
+ import { EllipsisExtensionProvider } from '../widgets/designerView/extensions/svg/EllipsisExtensionProvider.js';
67
70
  export function createDefaultServiceContainer() {
68
71
  let serviceContainer = new ServiceContainer();
69
72
  serviceContainer.register("propertyService", new PolymerPropertiesService());
@@ -95,7 +98,10 @@ export function createDefaultServiceContainer() {
95
98
  new TransformOriginExtensionProvider(),
96
99
  new CanvasExtensionProvider(),
97
100
  new PositionExtensionProvider(),
101
+ new EllipsisExtensionProvider(),
102
+ new LineExtensionProvider(),
98
103
  new PathExtensionProvider(),
104
+ new RectExtentionProvider(),
99
105
  new ResizeExtensionProvider(true),
100
106
  new RotateExtensionProvider(),
101
107
  ]);
@@ -6,12 +6,14 @@ export class HtmlWriterService extends AbstractHtmlWriterService {
6
6
  _conditionalyWriteIndent(indentedTextWriter, designItem) {
7
7
  if ((designItem.element instanceof HTMLElement && !isInline(designItem.element)) ||
8
8
  (designItem.element.previousElementSibling instanceof HTMLElement && !isInline(designItem.element.previousElementSibling)) ||
9
- (designItem.element.previousElementSibling == null && !isInline(designItem.element.parentElement) && (designItem.element.previousSibling == null || isEmptyTextNode(designItem.element.previousSibling))))
9
+ (designItem.element.previousElementSibling == null && !isInline(designItem.element.parentElement) && (designItem.element.previousSibling == null || isEmptyTextNode(designItem.element.previousSibling))) ||
10
+ (designItem.element instanceof SVGElement))
10
11
  indentedTextWriter.writeIndent();
11
12
  }
12
13
  _conditionalyWriteNewline(indentedTextWriter, designItem) {
13
14
  if ((designItem.element instanceof HTMLElement && !isInline(designItem.element)) ||
14
- (designItem.element.nextElementSibling instanceof HTMLElement && !isInline(designItem.element.nextElementSibling)))
15
+ (designItem.element.nextElementSibling instanceof HTMLElement && !isInline(designItem.element.nextElementSibling)) ||
16
+ (designItem.element instanceof SVGElement))
15
17
  indentedTextWriter.writeNewline();
16
18
  }
17
19
  write(indentedTextWriter, designItems, rootContainerKeepInline, options, designItemsAssignmentList) {
@@ -48,7 +50,7 @@ export class HtmlWriterService extends AbstractHtmlWriterService {
48
50
  this.writeTextNode(indentedTextWriter, designItem, false);
49
51
  }
50
52
  else {
51
- if (designItem.element instanceof HTMLElement && !isInline(designItem.element)) {
53
+ if (designItem.element instanceof HTMLElement && !isInline(designItem.element) || (designItem.element instanceof SVGElement)) {
52
54
  indentedTextWriter.writeNewline();
53
55
  indentedTextWriter.levelRaise();
54
56
  }
@@ -56,9 +58,10 @@ export class HtmlWriterService extends AbstractHtmlWriterService {
56
58
  this.internalWrite(indentedTextWriter, c, options, designItemsAssignmentList);
57
59
  let childSingleTextNode = c.childCount === 1 && c.firstChild.nodeType === NodeType.TextNode;
58
60
  if (childSingleTextNode)
59
- indentedTextWriter.writeNewline();
61
+ if (!indentedTextWriter.isLastCharNewline())
62
+ indentedTextWriter.writeNewline();
60
63
  }
61
- if (designItem.element instanceof HTMLElement && !isInline(designItem.element)) {
64
+ if (designItem.element instanceof HTMLElement && !isInline(designItem.element) || (designItem.element instanceof SVGElement)) {
62
65
  indentedTextWriter.levelShrink();
63
66
  if (!indentedTextWriter.isLastCharNewline())
64
67
  indentedTextWriter.writeNewline();
@@ -73,7 +76,8 @@ export class HtmlWriterService extends AbstractHtmlWriterService {
73
76
  if (!DomConverter.IsSelfClosingElement(designItem.name))
74
77
  indentedTextWriter.write('</' + designItem.name + '>');
75
78
  //if (!contentSingleTextNode)
76
- this._conditionalyWriteNewline(indentedTextWriter, designItem);
79
+ if (!indentedTextWriter.isLastCharNewline())
80
+ this._conditionalyWriteNewline(indentedTextWriter, designItem);
77
81
  }
78
82
  if (designItemsAssignmentList) {
79
83
  designItemsAssignmentList.set(designItem, { start: start, length: indentedTextWriter.position - start - 1 });
@@ -319,9 +319,26 @@ export class DesignerCanvas extends BaseCustomWebComponentLazyAppend {
319
319
  async handlePasteCommand() {
320
320
  const designItems = await this.serviceContainer.copyPasteService.getPasteItems(this.serviceContainer, this.instanceServiceContainer);
321
321
  let grp = this.rootDesignItem.openGroup("Insert");
322
+ let pasteContainer = this.rootDesignItem;
323
+ let pCon = this.instanceServiceContainer.selectionService.primarySelection;
324
+ while (pCon != null) {
325
+ const containerStyle = getComputedStyle(pCon.element);
326
+ let newContainerService;
327
+ newContainerService = this.serviceContainer.getLastServiceWhere('containerService', x => x.serviceForContainer(pCon, containerStyle));
328
+ if (newContainerService) {
329
+ if (newContainerService.canEnter(pCon, designItems)) {
330
+ pasteContainer = pCon;
331
+ break;
332
+ }
333
+ else {
334
+ pCon = pCon.parent;
335
+ continue;
336
+ }
337
+ }
338
+ }
322
339
  if (designItems) {
323
340
  for (let di of designItems) {
324
- this.instanceServiceContainer.undoService.execute(new InsertAction(this.rootDesignItem, this.rootDesignItem.childCount, di));
341
+ this.instanceServiceContainer.undoService.execute(new InsertAction(pasteContainer, pasteContainer.childCount, di));
325
342
  }
326
343
  const intializationService = this.serviceContainer.intializationService;
327
344
  if (intializationService) {
@@ -7,6 +7,8 @@ export class ResizeExtensionProvider {
7
7
  this.resizeAllSelected = resizeAllSelected;
8
8
  }
9
9
  shouldExtend(extensionManager, designerView, designItem) {
10
+ if (designItem.element instanceof SVGElement)
11
+ return false;
10
12
  return designItem.nodeType == NodeType.Element;
11
13
  }
12
14
  getExtension(extensionManager, designerView, designItem) {
@@ -5,7 +5,7 @@ export class SelectAllChildrenContextMenu {
5
5
  }
6
6
  provideContextMenuItems(event, designerCanvas, designItem) {
7
7
  return [{
8
- title: 'Select all Children', action: () => {
8
+ title: 'select all Children', action: () => {
9
9
  designerCanvas.instanceServiceContainer.selectionService.setSelectedElements(Array.from(designItem.children()).filter(x => x.nodeType == NodeType.Element));
10
10
  }
11
11
  }];
@@ -0,0 +1,29 @@
1
+ import { IDesignItem } from "../../../../item/IDesignItem";
2
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
3
+ import { AbstractExtension } from "../AbstractExtension";
4
+ import { IExtensionManager } from "../IExtensionManger";
5
+ export declare class EllipsisExtension extends AbstractExtension {
6
+ private _parentRect;
7
+ private _ellipseElement;
8
+ private _circlePos;
9
+ private _startPos;
10
+ private _lastPos;
11
+ private _originalPoint;
12
+ private _cx;
13
+ private _cy;
14
+ private _rx;
15
+ private _ry;
16
+ private _newRx;
17
+ private _newRy;
18
+ private _circle1;
19
+ private _circle2;
20
+ private _circle3;
21
+ private _circle4;
22
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
23
+ extend(): void;
24
+ pointerEvent(event: PointerEvent, circle: SVGCircleElement, e: SVGEllipseElement, index: number): void;
25
+ _drawPathCircle(x: number, y: number, e: SVGEllipseElement, index: number): SVGCircleElement;
26
+ _redrawPathCircle(x: number, y: number, oldCircle: SVGCircleElement): SVGCircleElement;
27
+ refresh(): void;
28
+ dispose(): void;
29
+ }
@@ -0,0 +1,112 @@
1
+ import { EventNames } from "../../../../../enums/EventNames";
2
+ import { AbstractExtension } from "../AbstractExtension";
3
+ export class EllipsisExtension extends AbstractExtension {
4
+ _parentRect;
5
+ _ellipseElement;
6
+ _circlePos;
7
+ _startPos;
8
+ _lastPos;
9
+ _originalPoint;
10
+ _cx;
11
+ _cy;
12
+ _rx;
13
+ _ry;
14
+ _newRx;
15
+ _newRy;
16
+ _circle1;
17
+ _circle2;
18
+ _circle3;
19
+ _circle4;
20
+ constructor(extensionManager, designerView, extendedItem) {
21
+ super(extensionManager, designerView, extendedItem);
22
+ }
23
+ extend() {
24
+ this._parentRect = this.extendedItem.element.parentElement.getBoundingClientRect();
25
+ this._ellipseElement = this.extendedItem.node;
26
+ this._cx = this._ellipseElement.cx.baseVal.value;
27
+ this._cy = this._ellipseElement.cy.baseVal.value;
28
+ this._rx = this._ellipseElement.rx.baseVal.value;
29
+ this._ry = this._ellipseElement.ry.baseVal.value;
30
+ this._circle1 = this._drawPathCircle(this._cx, this._cy - this._ry, this._ellipseElement, 0);
31
+ this._circle2 = this._drawPathCircle(this._cx + this._rx, this._cy, this._ellipseElement, 1);
32
+ this._circle3 = this._drawPathCircle(this._cx, this._cy + this._ry, this._ellipseElement, 2);
33
+ this._circle4 = this._drawPathCircle(this._cx - this._rx, this._cy, this._ellipseElement, 3);
34
+ }
35
+ pointerEvent(event, circle, e, index) {
36
+ event.stopPropagation();
37
+ const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
38
+ switch (event.type) {
39
+ case EventNames.PointerDown:
40
+ event.target.setPointerCapture(event.pointerId);
41
+ this._startPos = cursorPos;
42
+ this._circlePos = { x: parseFloat(circle.getAttribute("cx")), y: parseFloat(circle.getAttribute("cy")) };
43
+ this._originalPoint = { x: this._rx, y: this._ry };
44
+ break;
45
+ case EventNames.PointerMove:
46
+ if (this._startPos && event.buttons > 0) {
47
+ this._lastPos = { x: this._startPos.x, y: this._startPos.y };
48
+ const cx = cursorPos.x - this._lastPos.x + this._circlePos.x;
49
+ const cy = cursorPos.y - this._lastPos.y + this._circlePos.y;
50
+ let dx = cx - this._circlePos.x;
51
+ let dy = cy - this._circlePos.y;
52
+ switch (index) {
53
+ case 0:
54
+ this._newRx = this._originalPoint.x;
55
+ this._newRy = Math.abs(this._originalPoint.y - dy);
56
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
57
+ break;
58
+ case 1:
59
+ this._newRx = Math.abs(this._originalPoint.x + dx);
60
+ this._newRy = this._originalPoint.y;
61
+ circle.setAttribute("cx", (this._circlePos.x + dx).toString());
62
+ break;
63
+ case 2:
64
+ this._newRx = this._originalPoint.x;
65
+ this._newRy = Math.abs(this._originalPoint.y + dy);
66
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
67
+ break;
68
+ case 3:
69
+ this._newRx = Math.abs(this._originalPoint.x - dx);
70
+ this._newRy = this._originalPoint.y;
71
+ circle.setAttribute("cx", (this._circlePos.x + dx).toString());
72
+ break;
73
+ }
74
+ e.setAttribute("rx", this._newRx.toString());
75
+ e.setAttribute("ry", this._newRy.toString());
76
+ this._redrawPathCircle(this._cx, this._cy - this._newRy, this._circle1);
77
+ this._redrawPathCircle(this._cx + this._newRx, this._cy, this._circle2);
78
+ this._redrawPathCircle(this._cx, this._cy + this._newRy, this._circle3);
79
+ this._redrawPathCircle(this._cx - this._newRx, this._cy, this._circle4);
80
+ }
81
+ break;
82
+ case EventNames.PointerUp:
83
+ event.target.releasePointerCapture(event.pointerId);
84
+ this._startPos = null;
85
+ this._circlePos = null;
86
+ this._originalPoint = null;
87
+ this.extendedItem.setAttribute("rx", this._newRx.toString());
88
+ this.extendedItem.setAttribute("ry", this._newRy.toString());
89
+ break;
90
+ }
91
+ }
92
+ _drawPathCircle(x, y, e, index) {
93
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path');
94
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
95
+ circle.addEventListener(EventNames.PointerDown, event => this.pointerEvent(event, circle, e, index));
96
+ circle.addEventListener(EventNames.PointerMove, event => this.pointerEvent(event, circle, e, index));
97
+ circle.addEventListener(EventNames.PointerUp, event => this.pointerEvent(event, circle, e, index));
98
+ return circle;
99
+ }
100
+ _redrawPathCircle(x, y, oldCircle) {
101
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path', oldCircle);
102
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
103
+ return circle;
104
+ }
105
+ refresh() {
106
+ this._removeAllOverlays();
107
+ this.extend();
108
+ }
109
+ dispose() {
110
+ this._removeAllOverlays();
111
+ }
112
+ }
@@ -0,0 +1,9 @@
1
+ import { IDesignerExtensionProvider } from "../IDesignerExtensionProvider";
2
+ import { IDesignItem } from "../../../../item/IDesignItem";
3
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
4
+ import { IDesignerExtension } from "../IDesignerExtension";
5
+ import { IExtensionManager } from "../IExtensionManger";
6
+ export declare class EllipsisExtensionProvider implements IDesignerExtensionProvider {
7
+ shouldExtend(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): boolean;
8
+ getExtension(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): IDesignerExtension;
9
+ }
@@ -0,0 +1,12 @@
1
+ import { EllipsisExtension } from "./EllipsisExtension";
2
+ export class EllipsisExtensionProvider {
3
+ shouldExtend(extensionManager, designerView, designItem) {
4
+ if (designItem.node instanceof SVGEllipseElement) {
5
+ return true;
6
+ }
7
+ return false;
8
+ }
9
+ getExtension(extensionManager, designerView, designItem) {
10
+ return new EllipsisExtension(extensionManager, designerView, designItem);
11
+ }
12
+ }
@@ -0,0 +1,20 @@
1
+ import { IDesignItem } from "../../../../item/IDesignItem";
2
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
3
+ import { AbstractExtension } from "../AbstractExtension";
4
+ import { IExtensionManager } from "../IExtensionManger";
5
+ export declare class LineExtension extends AbstractExtension {
6
+ private _parentRect;
7
+ private _lineElement;
8
+ private _circlePos;
9
+ private _startPos;
10
+ private _lastPos;
11
+ private _originalPoint;
12
+ private _newLinePoint;
13
+ private _newCirclePoint;
14
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
15
+ extend(): void;
16
+ pointerEvent(event: PointerEvent, circle: SVGCircleElement, l: SVGLineElement, index: number): void;
17
+ _drawPathCircle(x: number, y: number, l: SVGLineElement, index: number): void;
18
+ refresh(): void;
19
+ dispose(): void;
20
+ }
@@ -0,0 +1,87 @@
1
+ import { EventNames } from "../../../../../enums/EventNames";
2
+ import { AbstractExtension } from "../AbstractExtension";
3
+ export class LineExtension extends AbstractExtension {
4
+ _parentRect;
5
+ _lineElement;
6
+ _circlePos;
7
+ _startPos;
8
+ _lastPos;
9
+ _originalPoint;
10
+ _newLinePoint;
11
+ _newCirclePoint;
12
+ constructor(extensionManager, designerView, extendedItem) {
13
+ super(extensionManager, designerView, extendedItem);
14
+ }
15
+ extend() {
16
+ this._parentRect = this.extendedItem.element.parentElement.getBoundingClientRect();
17
+ this._lineElement = this.extendedItem.node;
18
+ const x1 = this._lineElement.x1.baseVal.value;
19
+ const y1 = this._lineElement.y1.baseVal.value;
20
+ const x2 = this._lineElement.x2.baseVal.value;
21
+ const y2 = this._lineElement.y2.baseVal.value;
22
+ this._drawPathCircle(x1, y1, this._lineElement, 1);
23
+ this._drawPathCircle(x2, y2, this._lineElement, 2);
24
+ }
25
+ pointerEvent(event, circle, l, index) {
26
+ event.stopPropagation();
27
+ const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
28
+ switch (event.type) {
29
+ case EventNames.PointerDown:
30
+ event.target.setPointerCapture(event.pointerId);
31
+ this._startPos = cursorPos;
32
+ this._circlePos = { x: parseFloat(circle.getAttribute("cx")), y: parseFloat(circle.getAttribute("cy")) };
33
+ this._originalPoint = { x: parseFloat(l.getAttribute("x" + index)), y: parseFloat(l.getAttribute("y" + index)) };
34
+ break;
35
+ case EventNames.PointerMove:
36
+ if (this._startPos && event.buttons > 0) {
37
+ this._lastPos = { x: this._startPos.x, y: this._startPos.y };
38
+ const cx = cursorPos.x - this._lastPos.x + this._circlePos.x;
39
+ const cy = cursorPos.y - this._lastPos.y + this._circlePos.y;
40
+ const dx = cx - this._circlePos.x;
41
+ const dy = cy - this._circlePos.y;
42
+ if (event.shiftKey) {
43
+ if (Math.abs(dx) >= Math.abs(dy)) {
44
+ this._newCirclePoint = { x: this._circlePos.x + dx, y: this._circlePos.y };
45
+ this._newLinePoint = { x: this._originalPoint.x + dx, y: this._originalPoint.y };
46
+ }
47
+ else {
48
+ this._newCirclePoint = { x: this._circlePos.x, y: this._circlePos.y + dy };
49
+ this._newLinePoint = { x: this._originalPoint.x, y: this._originalPoint.y + dy };
50
+ }
51
+ }
52
+ else {
53
+ this._newCirclePoint = { x: this._circlePos.x + dx, y: this._circlePos.y + dy };
54
+ this._newLinePoint = { x: this._originalPoint.x + dx, y: this._originalPoint.y + dy };
55
+ }
56
+ circle.setAttribute("cx", this._newCirclePoint.x.toString());
57
+ circle.setAttribute("cy", this._newCirclePoint.y.toString());
58
+ l.setAttribute("x" + index, this._newLinePoint.x.toString());
59
+ l.setAttribute("y" + index, this._newLinePoint.y.toString());
60
+ }
61
+ break;
62
+ case EventNames.PointerUp:
63
+ event.target.releasePointerCapture(event.pointerId);
64
+ this._startPos = null;
65
+ this._circlePos = null;
66
+ this._lastPos = null;
67
+ this._originalPoint = null;
68
+ this.extendedItem.setAttribute('x' + index, this._newLinePoint.x.toString());
69
+ this.extendedItem.setAttribute('y' + index, this._newLinePoint.y.toString());
70
+ break;
71
+ }
72
+ }
73
+ _drawPathCircle(x, y, l, index) {
74
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path');
75
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
76
+ circle.addEventListener(EventNames.PointerDown, event => this.pointerEvent(event, circle, l, index));
77
+ circle.addEventListener(EventNames.PointerMove, event => this.pointerEvent(event, circle, l, index));
78
+ circle.addEventListener(EventNames.PointerUp, event => this.pointerEvent(event, circle, l, index));
79
+ }
80
+ refresh() {
81
+ this._removeAllOverlays();
82
+ this.extend();
83
+ }
84
+ dispose() {
85
+ this._removeAllOverlays();
86
+ }
87
+ }
@@ -0,0 +1,9 @@
1
+ import { IDesignerExtensionProvider } from "../IDesignerExtensionProvider";
2
+ import { IDesignItem } from "../../../../item/IDesignItem";
3
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
4
+ import { IDesignerExtension } from "../IDesignerExtension";
5
+ import { IExtensionManager } from "../IExtensionManger";
6
+ export declare class LineExtensionProvider implements IDesignerExtensionProvider {
7
+ shouldExtend(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): boolean;
8
+ getExtension(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): IDesignerExtension;
9
+ }
@@ -0,0 +1,12 @@
1
+ import { LineExtension } from "./LineExtension";
2
+ export class LineExtensionProvider {
3
+ shouldExtend(extensionManager, designerView, designItem) {
4
+ if (designItem.node instanceof SVGLineElement) {
5
+ return true;
6
+ }
7
+ return false;
8
+ }
9
+ getExtension(extensionManager, designerView, designItem) {
10
+ return new LineExtension(extensionManager, designerView, designItem);
11
+ }
12
+ }
@@ -0,0 +1,23 @@
1
+ import { IDesignItem } from "../../../../item/IDesignItem";
2
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
3
+ import { AbstractExtension } from "../AbstractExtension";
4
+ import "../../../../helper/PathDataPolyfill";
5
+ import { IPoint } from "../../../../../interfaces/IPoint";
6
+ import { IExtensionManager } from "../IExtensionManger";
7
+ import { PathData } from "../../../../helper/PathDataPolyfill";
8
+ export declare class PathExtension extends AbstractExtension {
9
+ private _lastPos;
10
+ private _parentRect;
11
+ private _startPos;
12
+ private _circlePos;
13
+ private _originalPathPoint;
14
+ private _pathdata;
15
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
16
+ extend(): void;
17
+ pointerEvent(event: PointerEvent, circle: SVGCircleElement, p: PathData, index: number): void;
18
+ _drawPathCircle(x: number, y: number, p: PathData, index: number): void;
19
+ _drawPathLine(x1: number, y1: number, x2: number, y2: number): void;
20
+ _checkCircleIndex(p: PathData, circlePos: IPoint): boolean;
21
+ refresh(): void;
22
+ dispose(): void;
23
+ }
@@ -0,0 +1,286 @@
1
+ import { AbstractExtension } from "../AbstractExtension";
2
+ import "../../../../helper/PathDataPolyfill";
3
+ import { EventNames } from "../../../../../enums/EventNames";
4
+ import { createPathD } from "../../../../helper/PathDataPolyfill";
5
+ import { ContextMenuHelper } from "../../../../helper/contextMenu/ContextMenuHelper";
6
+ export class PathExtension extends AbstractExtension {
7
+ _lastPos;
8
+ _parentRect;
9
+ _startPos;
10
+ _circlePos;
11
+ _originalPathPoint;
12
+ _pathdata;
13
+ constructor(extensionManager, designerView, extendedItem) {
14
+ super(extensionManager, designerView, extendedItem);
15
+ }
16
+ extend() {
17
+ this._parentRect = this.extendedItem.element.parentElement.getBoundingClientRect();
18
+ this._pathdata = this.extendedItem.node.getPathData({ normalize: false });
19
+ this._lastPos = { x: 0, y: 0 };
20
+ for (let p of this._pathdata) {
21
+ switch (p.type) {
22
+ case 'M':
23
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
24
+ this._lastPos = { x: p.values[0], y: p.values[1] };
25
+ break;
26
+ case 'm':
27
+ this._drawPathCircle(p.values[0] + this._lastPos.x, p.values[1] + this._lastPos.y, p, 0);
28
+ this._lastPos = { x: p.values[0] + this._lastPos.x, y: p.values[1] + this._lastPos.y };
29
+ break;
30
+ case 'L':
31
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
32
+ this._lastPos = { x: p.values[0], y: p.values[1] };
33
+ break;
34
+ case 'l':
35
+ this._drawPathCircle(p.values[0] + this._lastPos.x, p.values[1] + this._lastPos.y, p, 0);
36
+ this._lastPos = { x: p.values[0] + this._lastPos.x, y: p.values[1] + this._lastPos.y };
37
+ break;
38
+ case 'H':
39
+ this._drawPathCircle(p.values[0], this._lastPos.y, p, 0);
40
+ this._lastPos = { x: p.values[0], y: this._lastPos.y };
41
+ break;
42
+ case 'h':
43
+ this._drawPathCircle(p.values[0] + this._lastPos.x, this._lastPos.y, p, 0);
44
+ this._lastPos = { x: p.values[0] + this._lastPos.x, y: this._lastPos.y };
45
+ break;
46
+ case 'V':
47
+ this._drawPathCircle(this._lastPos.x, p.values[0], p, 0);
48
+ this._lastPos = { x: this._lastPos.x, y: p.values[0] };
49
+ break;
50
+ case 'v':
51
+ this._drawPathCircle(this._lastPos.x, p.values[0] + this._lastPos.y, p, 0);
52
+ this._lastPos = { x: this._lastPos.x, y: p.values[0] + this._lastPos.y };
53
+ break;
54
+ case 'Z':
55
+ break;
56
+ case 'C':
57
+ this._drawPathLine(this._lastPos.x, this._lastPos.y, p.values[0], p.values[1]);
58
+ this._drawPathLine(p.values[4], p.values[5], p.values[2], p.values[3]);
59
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
60
+ this._drawPathCircle(p.values[2], p.values[3], p, 2);
61
+ this._drawPathCircle(p.values[4], p.values[5], p, 4);
62
+ this._lastPos = { x: p.values[4], y: p.values[5] };
63
+ break;
64
+ case 'c':
65
+ this._drawPathLine(this._lastPos.x, this._lastPos.y, p.values[0], p.values[1]);
66
+ this._drawPathLine(this._lastPos.x + p.values[4], this._lastPos.y + p.values[5], p.values[2], p.values[3]);
67
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
68
+ this._drawPathCircle(p.values[2], p.values[3], p, 2);
69
+ this._drawPathCircle(this._lastPos.x + p.values[4], this._lastPos.y + p.values[5], p, 4);
70
+ this._lastPos = { x: p.values[4] + this._lastPos.x, y: p.values[5] + this._lastPos.y };
71
+ break;
72
+ case 'S':
73
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
74
+ this._drawPathCircle(p.values[2], p.values[3], p, 2);
75
+ this._drawPathLine(this._lastPos.x, this._lastPos.y, p.values[0], p.values[1]);
76
+ this._drawPathLine(p.values[0], p.values[1], p.values[2], p.values[3]);
77
+ this._lastPos = { x: p.values[2], y: p.values[3] };
78
+ break;
79
+ case 's':
80
+ this._drawPathCircle(p.values[0] + this._lastPos.x, p.values[1] + this._lastPos.y, p, 0);
81
+ this._drawPathCircle(p.values[2] + this._lastPos.x, p.values[3] + this._lastPos.y, p, 2);
82
+ this._drawPathLine(this._lastPos.x, this._lastPos.y, p.values[0] + this._lastPos.x, p.values[1] + this._lastPos.y);
83
+ this._drawPathLine(p.values[0] + this._lastPos.x, p.values[1] + this._lastPos.y, p.values[2] + this._lastPos.x, p.values[3] + this._lastPos.y);
84
+ this._lastPos = { x: p.values[2] + this._lastPos.x, y: p.values[3] + this._lastPos.y };
85
+ break;
86
+ case 'Q':
87
+ this._drawPathLine(this._lastPos.x, this._lastPos.y, p.values[0], p.values[1]);
88
+ this._drawPathLine(p.values[0], p.values[1], p.values[2], p.values[3]);
89
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
90
+ this._drawPathCircle(p.values[2], p.values[3], p, 2);
91
+ this._lastPos = { x: p.values[2], y: p.values[3] };
92
+ break;
93
+ case 'T':
94
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
95
+ this._lastPos = { x: p.values[0], y: p.values[1] };
96
+ break;
97
+ case 'A':
98
+ this._drawPathCircle(p.values[0], p.values[1], p, 0);
99
+ this._drawPathCircle(p.values[5], p.values[6], p, 5);
100
+ this._lastPos = { x: p.values[0], y: p.values[1] };
101
+ break;
102
+ }
103
+ }
104
+ }
105
+ pointerEvent(event, circle, p, index) {
106
+ event.stopPropagation();
107
+ const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
108
+ switch (event.type) {
109
+ case EventNames.PointerDown:
110
+ event.target.setPointerCapture(event.pointerId);
111
+ this._startPos = cursorPos;
112
+ this._circlePos = { x: parseFloat(circle.getAttribute("cx")), y: parseFloat(circle.getAttribute("cy")) };
113
+ this._originalPathPoint = { x: p.values[index], y: p.values[index + 1] };
114
+ break;
115
+ case EventNames.PointerMove:
116
+ if (this._startPos && event.buttons > 0) {
117
+ this._lastPos = { x: this._startPos.x, y: this._startPos.y };
118
+ const cx = cursorPos.x - this._lastPos.x + this._circlePos.x;
119
+ const cy = cursorPos.y - this._lastPos.y + this._circlePos.y;
120
+ const dx = cx - this._circlePos.x;
121
+ const dy = cy - this._circlePos.y;
122
+ if (event.shiftKey) {
123
+ if (Math.abs(dx) >= Math.abs(dy)) {
124
+ p.values[index] = this._originalPathPoint.x + dx;
125
+ circle.setAttribute("cx", (this._circlePos.x + dx).toString());
126
+ p.values[index + 1] = this._originalPathPoint.y;
127
+ circle.setAttribute("cy", (this._circlePos.y).toString());
128
+ }
129
+ else {
130
+ p.values[index] = this._originalPathPoint.x;
131
+ circle.setAttribute("cx", (this._circlePos.x).toString());
132
+ p.values[index + 1] = this._originalPathPoint.y + dy;
133
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
134
+ }
135
+ }
136
+ else {
137
+ p.values[index] = this._originalPathPoint.x + dx;
138
+ p.values[index + 1] = this._originalPathPoint.y + dy;
139
+ if (p.type == 'V' || p.type == 'v') {
140
+ p.values[index] = this._originalPathPoint.x + dy;
141
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
142
+ }
143
+ else if (p.type == 'H' || p.type == 'h') {
144
+ circle.setAttribute("cy", (this._circlePos.x + dx).toString());
145
+ }
146
+ else {
147
+ circle.setAttribute("cx", (this._circlePos.x + dx).toString());
148
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
149
+ }
150
+ }
151
+ this.extendedItem.element.setAttribute("d", createPathD(this._pathdata));
152
+ }
153
+ break;
154
+ case EventNames.PointerUp:
155
+ event.target.releasePointerCapture(event.pointerId);
156
+ this._startPos = null;
157
+ this._circlePos = null;
158
+ this._lastPos = null;
159
+ this.extendedItem.setAttribute('d', createPathD(this._pathdata));
160
+ break;
161
+ }
162
+ }
163
+ _drawPathCircle(x, y, p, index) {
164
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path');
165
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
166
+ let circlePos = { x: x, y: y };
167
+ const items = [];
168
+ const pidx = this._pathdata.indexOf(p);
169
+ items.push({
170
+ title: 'delete point', action: () => {
171
+ this._pathdata.splice(pidx, 1);
172
+ if (pidx == 0)
173
+ this._pathdata[0].type = 'M';
174
+ this.extendedItem.setAttribute('d', createPathD(this._pathdata));
175
+ }
176
+ });
177
+ items.push({
178
+ title: 'insert point after', action: () => {
179
+ const l = { type: 'L', values: [p.values[0], p.values[1]] };
180
+ this._pathdata.splice(pidx + 1, 0, l);
181
+ this.extendedItem.setAttribute('d', createPathD(this._pathdata));
182
+ }
183
+ });
184
+ if (pidx != 0 && this._checkCircleIndex(p, circlePos)) {
185
+ items.push({
186
+ title: 'convert to quadratic bézier', action: () => {
187
+ let p1x = this._pathdata[pidx - 1].values[0];
188
+ let p1y = this._pathdata[pidx - 1].values[1];
189
+ if (this._pathdata[pidx - 1].type === 'C') {
190
+ p1x = this._pathdata[pidx - 1].values[4];
191
+ p1y = this._pathdata[pidx - 1].values[5];
192
+ }
193
+ else if (this._pathdata[pidx - 1].type === 'Q') {
194
+ p1x = this._pathdata[pidx - 1].values[2];
195
+ p1y = this._pathdata[pidx - 1].values[3];
196
+ }
197
+ const p2x = this._pathdata[pidx].values[0];
198
+ const p2y = this._pathdata[pidx].values[1];
199
+ const mpx = (p2x + p1x) * 0.5;
200
+ const mpy = (p2y + p1y) * 0.5;
201
+ const theta = Math.atan2(p2y - p1y, p2x - p1x) - Math.PI / 2;
202
+ const offset = 50;
203
+ const c1x = mpx + offset * Math.cos(theta);
204
+ const c1y = mpy + offset * Math.sin(theta);
205
+ this._pathdata[pidx].type = 'Q';
206
+ this._pathdata[pidx].values[0] = c1x;
207
+ this._pathdata[pidx].values[1] = c1y;
208
+ this._pathdata[pidx].values[2] = p2x;
209
+ this._pathdata[pidx].values[3] = p2y;
210
+ this.extendedItem.setAttribute('d', createPathD(this._pathdata));
211
+ }
212
+ });
213
+ }
214
+ if (pidx != 0 && this._checkCircleIndex(p, circlePos)) {
215
+ items.push({
216
+ title: 'convert to cubic bézier', action: () => {
217
+ let p1x = this._pathdata[pidx - 1].values[0];
218
+ let p1y = this._pathdata[pidx - 1].values[1];
219
+ if (this._pathdata[pidx - 1].type === 'C') {
220
+ p1x = this._pathdata[pidx - 1].values[4];
221
+ p1y = this._pathdata[pidx - 1].values[5];
222
+ }
223
+ else if (this._pathdata[pidx - 1].type === 'Q') {
224
+ p1x = this._pathdata[pidx - 1].values[2];
225
+ p1y = this._pathdata[pidx - 1].values[3];
226
+ }
227
+ const p2x = this._pathdata[pidx].values[0];
228
+ const p2y = this._pathdata[pidx].values[1];
229
+ const mpx = (p2x + p1x) * 0.5;
230
+ const mpy = (p2y + p1y) * 0.5;
231
+ const theta = Math.atan2(p2y - p1y, p2x - p1x) - Math.PI / 2;
232
+ const offset = 50;
233
+ let c1x = mpx + offset * Math.cos(theta);
234
+ let c1y = mpy + offset * Math.sin(theta);
235
+ c1x = p.values[0] + 2 * (p1x - p.values[0]) / 3;
236
+ c1y = p.values[1] + 2 * (p1y - p.values[1]) / 3;
237
+ const c2x = x + 2 * (p1x - x) / 3;
238
+ const c2y = y + 2 * (p1y - y) / 3;
239
+ this._pathdata[pidx].type = 'C';
240
+ this._pathdata[pidx].values[0] = c1x;
241
+ this._pathdata[pidx].values[1] = c1y;
242
+ this._pathdata[pidx].values[2] = c2x;
243
+ this._pathdata[pidx].values[3] = c2y;
244
+ this._pathdata[pidx].values[4] = p2x;
245
+ this._pathdata[pidx].values[5] = p2y;
246
+ this.extendedItem.setAttribute('d', createPathD(this._pathdata));
247
+ }
248
+ });
249
+ }
250
+ circle.addEventListener(EventNames.PointerDown, event => this.pointerEvent(event, circle, p, index));
251
+ circle.addEventListener(EventNames.PointerMove, event => this.pointerEvent(event, circle, p, index));
252
+ circle.addEventListener(EventNames.PointerUp, event => this.pointerEvent(event, circle, p, index));
253
+ circle.addEventListener(EventNames.ContextMenu, event => {
254
+ event.preventDefault();
255
+ ContextMenuHelper.showContextMenu(null, event, null, items);
256
+ });
257
+ }
258
+ _drawPathLine(x1, y1, x2, y2) {
259
+ this._drawLine((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x1, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y1, (this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x2, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y2, 'svg-path-line');
260
+ }
261
+ _checkCircleIndex(p, circlePos) {
262
+ switch (p.type) {
263
+ case 'M':
264
+ case 'L':
265
+ if (p.values[0] == circlePos.x && p.values[1] == circlePos.y)
266
+ return true;
267
+ break;
268
+ case 'Q':
269
+ if (p.values[2] == circlePos.x && p.values[3] == circlePos.y)
270
+ return true;
271
+ break;
272
+ case 'C':
273
+ if (p.values[4] == circlePos.x && p.values[5] == circlePos.y)
274
+ return true;
275
+ break;
276
+ }
277
+ return false;
278
+ }
279
+ refresh() {
280
+ this._removeAllOverlays();
281
+ this.extend();
282
+ }
283
+ dispose() {
284
+ this._removeAllOverlays();
285
+ }
286
+ }
@@ -0,0 +1,9 @@
1
+ import { IDesignerExtensionProvider } from "../IDesignerExtensionProvider";
2
+ import { IDesignItem } from "../../../../item/IDesignItem";
3
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
4
+ import { IDesignerExtension } from "../IDesignerExtension";
5
+ import { IExtensionManager } from "../IExtensionManger";
6
+ export declare class PathExtensionProvider implements IDesignerExtensionProvider {
7
+ shouldExtend(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): boolean;
8
+ getExtension(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): IDesignerExtension;
9
+ }
@@ -0,0 +1,12 @@
1
+ import { PathExtension } from "./PathExtension";
2
+ export class PathExtensionProvider {
3
+ shouldExtend(extensionManager, designerView, designItem) {
4
+ if (designItem.node instanceof SVGPathElement) {
5
+ return true;
6
+ }
7
+ return false;
8
+ }
9
+ getExtension(extensionManager, designerView, designItem) {
10
+ return new PathExtension(extensionManager, designerView, designItem);
11
+ }
12
+ }
@@ -0,0 +1,34 @@
1
+ import { IDesignItem } from "../../../../item/IDesignItem";
2
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
3
+ import { AbstractExtension } from "../AbstractExtension";
4
+ import { IExtensionManager } from "../IExtensionManger";
5
+ export declare class RectExtension extends AbstractExtension {
6
+ private _parentRect;
7
+ private _rectElement;
8
+ private _circlePos;
9
+ private _startPos;
10
+ private _lastPos;
11
+ private _originalPoint;
12
+ private _x;
13
+ private _y;
14
+ private _w;
15
+ private _h;
16
+ private _circle1;
17
+ private _circle2;
18
+ private _circle3;
19
+ private _circle4;
20
+ private _rect;
21
+ constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
22
+ extend(): void;
23
+ pointerEvent(event: PointerEvent, circle: SVGCircleElement, r: SVGRectElement, index: number): void;
24
+ _drawPathCircle(x: number, y: number, r: SVGRectElement, index: number): SVGCircleElement;
25
+ _redrawPathCircle(x: number, y: number, oldCircle: SVGCircleElement): SVGCircleElement;
26
+ _calculateRect(x: number, y: number, w: number, h: number): {
27
+ x: number;
28
+ y: number;
29
+ w: number;
30
+ h: number;
31
+ };
32
+ refresh(): void;
33
+ dispose(): void;
34
+ }
@@ -0,0 +1,137 @@
1
+ import { EventNames } from "../../../../../enums/EventNames";
2
+ import { AbstractExtension } from "../AbstractExtension";
3
+ export class RectExtension extends AbstractExtension {
4
+ _parentRect;
5
+ _rectElement;
6
+ _circlePos;
7
+ _startPos;
8
+ _lastPos;
9
+ _originalPoint;
10
+ _x;
11
+ _y;
12
+ _w;
13
+ _h;
14
+ _circle1;
15
+ _circle2;
16
+ _circle3;
17
+ _circle4;
18
+ _rect = { x: 0, y: 0, w: 0, h: 0 };
19
+ constructor(extensionManager, designerView, extendedItem) {
20
+ super(extensionManager, designerView, extendedItem);
21
+ }
22
+ extend() {
23
+ this._parentRect = this.extendedItem.element.parentElement.getBoundingClientRect();
24
+ this._rectElement = this.extendedItem.node;
25
+ this._x = this._rectElement.x.baseVal.value;
26
+ this._y = this._rectElement.y.baseVal.value;
27
+ this._w = this._rectElement.width.baseVal.value;
28
+ this._h = this._rectElement.height.baseVal.value;
29
+ this._circle1 = this._drawPathCircle(this._x, this._y, this._rectElement, 0);
30
+ this._circle2 = this._drawPathCircle(this._x + this._w, this._y, this._rectElement, 1);
31
+ this._circle3 = this._drawPathCircle(this._x + this._w, this._y + this._h, this._rectElement, 2);
32
+ this._circle4 = this._drawPathCircle(this._x, this._y + this._h, this._rectElement, 3);
33
+ }
34
+ pointerEvent(event, circle, r, index) {
35
+ event.stopPropagation();
36
+ const cursorPos = this.designerCanvas.getNormalizedEventCoordinates(event);
37
+ switch (event.type) {
38
+ case EventNames.PointerDown:
39
+ event.target.setPointerCapture(event.pointerId);
40
+ this._startPos = cursorPos;
41
+ this._circlePos = { x: parseFloat(circle.getAttribute("cx")), y: parseFloat(circle.getAttribute("cy")) };
42
+ this._originalPoint = { x: this._x, y: this._y };
43
+ break;
44
+ case EventNames.PointerMove:
45
+ if (this._startPos && event.buttons > 0) {
46
+ this._lastPos = { x: this._startPos.x, y: this._startPos.y };
47
+ const cx = cursorPos.x - this._lastPos.x + this._circlePos.x;
48
+ const cy = cursorPos.y - this._lastPos.y + this._circlePos.y;
49
+ let dx = cx - this._circlePos.x;
50
+ let dy = cy - this._circlePos.y;
51
+ if (event.shiftKey) {
52
+ if (Math.abs(dx) < Math.abs(dy)) {
53
+ dx = 0;
54
+ }
55
+ else {
56
+ dy = 0;
57
+ }
58
+ }
59
+ switch (index) {
60
+ case 0:
61
+ this._rect = this._calculateRect(this._originalPoint.x + dx, this._originalPoint.y + dy, this._w - dx, this._h - dy);
62
+ break;
63
+ case 1:
64
+ this._rect = this._calculateRect(this._originalPoint.x, this._originalPoint.y + dy, this._w + dx, this._h - dy);
65
+ break;
66
+ case 2:
67
+ this._rect = this._calculateRect(this._originalPoint.x, this._originalPoint.y, this._w + dx, this._h + dy);
68
+ break;
69
+ case 3:
70
+ this._rect = this._calculateRect(this._originalPoint.x + dx, this._originalPoint.y, this._w - dx, this._h + dy);
71
+ break;
72
+ }
73
+ r.setAttribute("x", this._rect.x.toString());
74
+ r.setAttribute("y", this._rect.y.toString());
75
+ r.setAttribute("width", this._rect.w.toString());
76
+ r.setAttribute("height", this._rect.h.toString());
77
+ circle.setAttribute("cx", (this._circlePos.x + dx).toString());
78
+ circle.setAttribute("cy", (this._circlePos.y + dy).toString());
79
+ this._redrawPathCircle(this._rect.x, this._rect.y, this._circle1);
80
+ this._redrawPathCircle(this._rect.x + this._rect.w, this._rect.y, this._circle2);
81
+ this._redrawPathCircle(this._rect.x + this._rect.w, this._rect.y + this._rect.h, this._circle3);
82
+ this._redrawPathCircle(this._rect.x, this._rect.y + this._rect.h, this._circle4);
83
+ }
84
+ break;
85
+ case EventNames.PointerUp:
86
+ event.target.releasePointerCapture(event.pointerId);
87
+ this._startPos = null;
88
+ this._circlePos = null;
89
+ this._originalPoint = null;
90
+ this.extendedItem.setAttribute("x", this._rect.x.toString());
91
+ this.extendedItem.setAttribute("y", this._rect.y.toString());
92
+ this.extendedItem.setAttribute("width", this._rect.w.toString());
93
+ this.extendedItem.setAttribute("height", this._rect.h.toString());
94
+ break;
95
+ }
96
+ }
97
+ _drawPathCircle(x, y, r, index) {
98
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path');
99
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
100
+ circle.addEventListener(EventNames.PointerDown, event => this.pointerEvent(event, circle, r, index));
101
+ circle.addEventListener(EventNames.PointerMove, event => this.pointerEvent(event, circle, r, index));
102
+ circle.addEventListener(EventNames.PointerUp, event => this.pointerEvent(event, circle, r, index));
103
+ return circle;
104
+ }
105
+ _redrawPathCircle(x, y, oldCircle) {
106
+ let circle = this._drawCircle((this._parentRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor + x, (this._parentRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor + y, 5 / this.designerCanvas.scaleFactor, 'svg-path', oldCircle);
107
+ circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
108
+ return circle;
109
+ }
110
+ _calculateRect(x, y, w, h) {
111
+ let rect = { x: 0, y: 0, w: 0, h: 0 };
112
+ if (w >= 0) {
113
+ rect.x = x;
114
+ rect.w = w;
115
+ }
116
+ else {
117
+ rect.x = x + w;
118
+ rect.w = -w;
119
+ }
120
+ if (h >= 0) {
121
+ rect.y = y;
122
+ rect.h = h;
123
+ }
124
+ else {
125
+ rect.y = y + h;
126
+ rect.h = -h;
127
+ }
128
+ return rect;
129
+ }
130
+ refresh() {
131
+ this._removeAllOverlays();
132
+ this.extend();
133
+ }
134
+ dispose() {
135
+ this._removeAllOverlays();
136
+ }
137
+ }
@@ -0,0 +1,9 @@
1
+ import { IDesignerExtensionProvider } from "../IDesignerExtensionProvider";
2
+ import { IDesignItem } from "../../../../item/IDesignItem";
3
+ import { IDesignerCanvas } from "../../IDesignerCanvas";
4
+ import { IDesignerExtension } from "../IDesignerExtension";
5
+ import { IExtensionManager } from "../IExtensionManger";
6
+ export declare class RectExtentionProvider implements IDesignerExtensionProvider {
7
+ shouldExtend(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): boolean;
8
+ getExtension(extensionManager: IExtensionManager, designerView: IDesignerCanvas, designItem: IDesignItem): IDesignerExtension;
9
+ }
@@ -0,0 +1,12 @@
1
+ import { RectExtension } from "./RectExtension";
2
+ export class RectExtentionProvider {
3
+ shouldExtend(extensionManager, designerView, designItem) {
4
+ if (designItem.node instanceof SVGRectElement) {
5
+ return true;
6
+ }
7
+ return false;
8
+ }
9
+ getExtension(extensionManager, designerView, designItem) {
10
+ return new RectExtension(extensionManager, designerView, designItem);
11
+ }
12
+ }
@@ -22,7 +22,7 @@ export class DrawPathTool {
22
22
  }
23
23
  pointerEventHandler(designerCanvas, event, currentElement) {
24
24
  const currentPoint = designerCanvas.getNormalizedEventCoordinates(event);
25
- const offset = 50;
25
+ const offset = 10;
26
26
  switch (event.type) {
27
27
  case EventNames.PointerDown:
28
28
  this._eventStarted = true;
@@ -30,7 +30,7 @@ export class DrawPathTool {
30
30
  event.target.setPointerCapture(event.pointerId);
31
31
  designerCanvas.captureActiveTool(this);
32
32
  this._path = document.createElementNS("http://www.w3.org/2000/svg", "path");
33
- this._pathD = "M" + currentPoint.x + " " + currentPoint.y;
33
+ this._pathD = "M " + currentPoint.x + " " + currentPoint.y + " ";
34
34
  this._path.setAttribute("d", this._pathD);
35
35
  this._path.setAttribute("stroke", designerCanvas.serviceContainer.globalContext.strokeColor);
36
36
  this._path.setAttribute("fill", designerCanvas.serviceContainer.globalContext.fillBrush);
@@ -55,7 +55,7 @@ export class DrawPathTool {
55
55
  if (!this._p2pMode) {
56
56
  this._dragMode = true;
57
57
  if (this._path) {
58
- this._pathD += "L" + currentPoint.x + " " + currentPoint.y;
58
+ this._pathD += "L " + currentPoint.x + " " + currentPoint.y + " ";
59
59
  this._path.setAttribute("d", this._pathD);
60
60
  }
61
61
  }
@@ -65,7 +65,7 @@ export class DrawPathTool {
65
65
  if (event.shiftKey) {
66
66
  straightLine = straightenLine(this._lastPoint, currentPoint);
67
67
  }
68
- this._path.setAttribute("d", this._pathD + "L" + straightLine.x + " " + straightLine.y);
68
+ this._path.setAttribute("d", this._pathD + "L " + straightLine.x + " " + straightLine.y) + " ";
69
69
  }
70
70
  }
71
71
  break;
@@ -77,12 +77,12 @@ export class DrawPathTool {
77
77
  if (this._path) {
78
78
  if (event.shiftKey) {
79
79
  let straightLine = straightenLine(this._lastPoint, currentPoint);
80
- this._pathD += "L" + straightLine.x + " " + straightLine.y;
80
+ this._pathD += "L " + straightLine.x + " " + straightLine.y + " ";
81
81
  this._path.setAttribute("d", this._pathD);
82
82
  this._lastPoint = straightLine;
83
83
  }
84
84
  else {
85
- this._pathD += "L" + currentPoint.x + " " + currentPoint.y;
85
+ this._pathD += "L " + currentPoint.x + " " + currentPoint.y + " ";
86
86
  this._path.setAttribute("d", this._pathD);
87
87
  this._lastPoint = currentPoint;
88
88
  }
@@ -96,19 +96,19 @@ export class DrawPathTool {
96
96
  this._pointerMoved = false;
97
97
  this._samePoint = false;
98
98
  this._dragMode = false;
99
- const rect = this._path.getBoundingClientRect();
99
+ let coords = designerCanvas.getNormalizedElementCoordinates(this._path);
100
100
  designerCanvas.overlayLayer.removeOverlay(this._path);
101
101
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
102
- const mvX = rect.x - designerCanvas.containerBoundingRect.x - offset;
103
- const mvY = rect.y - designerCanvas.containerBoundingRect.y - offset;
102
+ const mvX = coords.x - offset;
103
+ const mvY = coords.y - offset;
104
104
  const d = moveSVGPath(this._path, mvX, mvY);
105
105
  this._path.setAttribute("d", d);
106
106
  svg.appendChild(this._path);
107
107
  svg.style.left = (mvX) + 'px';
108
108
  svg.style.top = (mvY) + 'px';
109
109
  svg.style.position = 'absolute';
110
- svg.style.width = (rect.width + 2 * offset) + 'px';
111
- svg.style.height = (rect.height + 2 * offset) + 'px';
110
+ svg.style.width = (coords.width + 2 * offset) + 'px';
111
+ svg.style.height = (coords.height + 2 * offset) + 'px';
112
112
  svg.style.overflow = 'visible';
113
113
  //designerView.rootDesignItem.element.appendChild(svg);
114
114
  this._path = null;
@@ -30,7 +30,7 @@ export class DesignerToolbarButton extends BaseCustomWebComponentConstructorAppe
30
30
  this.tools = tools;
31
31
  this._img = this._getDomElement('img');
32
32
  this._div = this._getDomElement('div');
33
- this._img.onclick = () => {
33
+ this._div.onclick = () => {
34
34
  if (this.popup) {
35
35
  this.getRootNode().host.showPopup(this);
36
36
  }
package/dist/index.d.ts CHANGED
@@ -153,8 +153,8 @@ export * from "./elements/widgets/designerView/extensions/InvisibleDivExtension.
153
153
  export * from "./elements/widgets/designerView/extensions/InvisibleDivExtensionProvider.js";
154
154
  export * from "./elements/widgets/designerView/extensions/MouseOverExtension.js";
155
155
  export * from "./elements/widgets/designerView/extensions/MouseOverExtensionProvider.js";
156
- export * from "./elements/widgets/designerView/extensions/PathExtension.js";
157
- export * from "./elements/widgets/designerView/extensions/PathExtensionProvider.js";
156
+ export * from "./elements/widgets/designerView/extensions/svg/PathExtension.js";
157
+ export * from "./elements/widgets/designerView/extensions/svg/PathExtensionProvider.js";
158
158
  export * from "./elements/widgets/designerView/extensions/PositionExtension.js";
159
159
  export * from "./elements/widgets/designerView/extensions/PositionExtensionProvider.js";
160
160
  export * from "./elements/widgets/designerView/extensions/ElementDragTitleExtension.js";
package/dist/index.js CHANGED
@@ -111,8 +111,8 @@ export * from "./elements/widgets/designerView/extensions/InvisibleDivExtension.
111
111
  export * from "./elements/widgets/designerView/extensions/InvisibleDivExtensionProvider.js";
112
112
  export * from "./elements/widgets/designerView/extensions/MouseOverExtension.js";
113
113
  export * from "./elements/widgets/designerView/extensions/MouseOverExtensionProvider.js";
114
- export * from "./elements/widgets/designerView/extensions/PathExtension.js";
115
- export * from "./elements/widgets/designerView/extensions/PathExtensionProvider.js";
114
+ export * from "./elements/widgets/designerView/extensions/svg/PathExtension.js";
115
+ export * from "./elements/widgets/designerView/extensions/svg/PathExtensionProvider.js";
116
116
  export * from "./elements/widgets/designerView/extensions/PositionExtension.js";
117
117
  export * from "./elements/widgets/designerView/extensions/PositionExtensionProvider.js";
118
118
  export * from "./elements/widgets/designerView/extensions/ElementDragTitleExtension.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "description": "A UI designer for Polymer apps",
3
3
  "name": "@node-projects/web-component-designer",
4
- "version": "0.0.119",
4
+ "version": "0.0.121",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "author": "",
@@ -13,7 +13,7 @@
13
13
  "prepublishOnly": "npm run build"
14
14
  },
15
15
  "dependencies": {
16
- "@node-projects/base-custom-webcomponent": "^0.9.2",
16
+ "@node-projects/base-custom-webcomponent": "^0.10.1",
17
17
  "construct-style-sheets-polyfill": "^3.1.0"
18
18
  },
19
19
  "devDependencies": {
@@ -27,11 +27,11 @@
27
27
  "codemirror": "^6.0.1",
28
28
  "esprima-next": "^5.8.4",
29
29
  "html2canvas": "*",
30
- "jest": "^29.1.1",
30
+ "jest": "^29.1.2",
31
31
  "jquery": "^3.6.1",
32
32
  "jquery.fancytree": "^2.38.2",
33
33
  "monaco-editor": "^0.34.0",
34
- "ts-jest": "^29.0.2",
34
+ "ts-jest": "^29.0.3",
35
35
  "typescript": "^4.8.4",
36
36
  "typescript-lit-html-plugin": "^0.9.0"
37
37
  },