@node-projects/web-component-designer 0.0.152 → 0.0.154

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 (25) hide show
  1. package/ACKNOWLEDGMENTS +5 -1
  2. package/dist/elements/controls/MetricsEditor.d.ts +1 -1
  3. package/dist/elements/controls/MetricsEditor.js +29 -30
  4. package/dist/elements/helper/CssUnitConverter.d.ts +3 -0
  5. package/dist/elements/helper/CssUnitConverter.js +85 -0
  6. package/dist/elements/helper/TextHelper.d.ts +10 -0
  7. package/dist/elements/helper/TextHelper.js +23 -0
  8. package/dist/elements/helper/TransformHelper.d.ts +2 -1
  9. package/dist/elements/helper/TransformHelper.js +12 -8
  10. package/dist/elements/services/placementService/FlexBoxPlacementService.js +8 -0
  11. package/dist/elements/services/propertiesService/services/CssPropertiesService.d.ts +1 -0
  12. package/dist/elements/services/propertiesService/services/CssPropertiesService.js +8 -0
  13. package/dist/elements/widgets/designerView/extensions/ElementDragTitleExtension.d.ts +1 -0
  14. package/dist/elements/widgets/designerView/extensions/ElementDragTitleExtension.js +24 -12
  15. package/dist/elements/widgets/designerView/extensions/ExtensionManager.js +1 -1
  16. package/dist/elements/widgets/designerView/extensions/FlexboxExtension.js +1 -1
  17. package/dist/elements/widgets/designerView/extensions/GrayOutDragOverContainerExtension.js +1 -1
  18. package/dist/elements/widgets/designerView/extensions/InvisibleDivExtension.js +1 -1
  19. package/dist/elements/widgets/designerView/extensions/MouseOverExtension.js +1 -1
  20. package/dist/elements/widgets/designerView/extensions/ResizeExtension.js +1 -1
  21. package/dist/elements/widgets/designerView/extensions/RotateExtension.js +7 -5
  22. package/dist/elements/widgets/designerView/extensions/SelectionDefaultExtension.js +1 -1
  23. package/dist/elements/widgets/designerView/extensions/TransformOriginExtension.d.ts +1 -0
  24. package/dist/elements/widgets/designerView/extensions/TransformOriginExtension.js +26 -14
  25. package/package.json +1 -1
package/ACKNOWLEDGMENTS CHANGED
@@ -6,4 +6,8 @@
6
6
  - Thanks to @chdh for plain-scrollbar component
7
7
  https://github.com/chdh/plain-scrollbar
8
8
  - Thanks to @m-thalmann for contextmenujs
9
- https://github.com/m-thalmann/contextmenujs (also we have heavily modified it)
9
+ https://github.com/m-thalmann/contextmenujs (also we have heavily modified it)
10
+ - Levi Cole for parts of the cssUnits conversion code
11
+ https://stackoverflow.com/a/66569574/579623
12
+ - Domi for text-width code
13
+ https://stackoverflow.com/a/21015393
@@ -8,7 +8,7 @@ export declare class MetricsEditor extends BaseCustomWebComponentConstructorAppe
8
8
  static readonly template: HTMLTemplateElement;
9
9
  property: string;
10
10
  unsetValue: string;
11
- _updateValue(): void;
12
11
  ready(): void;
13
12
  onDoubleClick(event: PointerEvent): void;
13
+ onKeyDown(event: KeyboardEvent): void;
14
14
  }
@@ -30,7 +30,7 @@ export class MetricsEditor extends BaseCustomWebComponentConstructorAppend {
30
30
  }
31
31
 
32
32
  div.ct {
33
- width:280px;height:180px;
33
+ width:280px;height:120px;
34
34
  }
35
35
 
36
36
  div span {
@@ -83,44 +83,43 @@ span {
83
83
  }`;
84
84
  static template = html `
85
85
  <div class="ct"><span title="position">position</span>
86
- <div class="top">-</div><br><div class="left">-</div><div class="ct"><span title="margin">margin</span>
87
- <div id="testdiv" [contentEditable]="contentEditable" @dblclick="onDoubleClick" class="top">-</div><br><div class="left">-</div><div class="ct"><span title="border">border</span>
88
- <div class="top">-</div><br><div class="left">-</div><div class="ct"><span title="padding">padding</span>
89
- <div class="top">-</div><br><div class="left">-</div><div class="ct" style="font-size:6px"><div class="left">-</div>
90
- x
91
- <div class="right">-</div>
92
- </div><div class="right">-</div><br><div class="bottom">-</div></div><div class="right">-</div><br><div class="bottom">-</div></div><div class="right">-</div><br><div class="bottom">-</div></div><div class="right">-</div><br><div class="bottom">-</div></div>
86
+ <div data-style="position" @keydown="onKeyDown" @dblclick="onDoubleClick" class="top">-</div><br><div data-style="position" @keydown="onKeyDown" @dblclick="onDoubleClick" class="left">-</div><div class="ct"><span title="margin">margin</span>
87
+ <div data-style="margin" @keydown="onKeyDown" @dblclick="onDoubleClick" class="top">-</div><br><div @keydown="onKeyDown" @dblclick="onDoubleClick" class="left">-</div><div class="ct"><span title="border">border</span>
88
+ <div data-style="border" @keydown="onKeyDown" @dblclick="onDoubleClick" class="top">-</div><br><div @keydown="onKeyDown" @dblclick="onDoubleClick" class="left">-</div><div class="ct"><span title="padding">padding</span>
89
+ <div data-style="padding" @keydown="onKeyDown" @dblclick="onDoubleClick" class="top">-</div><br><div @keydown="onKeyDown" @dblclick="onDoubleClick" class="left">-</div><div class="ct" style="font-size:6px"><div data-style="element" @keydown="onKeyDown" @dblclick="onDoubleClick" class="left">-</div>
90
+ &nbsp;x&nbsp;
91
+ <div data-style="element" @keydown="onKeyDown" @dblclick="onDoubleClick" class="right">-</div>
92
+ </div><div data-style="padding" @keydown="onKeyDown" @dblclick="onDoubleClick" class="right">-</div><br><div data-style="padding" @keydown="onKeyDown" @dblclick="onDoubleClick" class="bottom">-</div></div><div data-style="border" @keydown="onKeyDown" @dblclick="onDoubleClick" class="right">-</div><br><div data-style="border" @keydown="onKeyDown" @dblclick="onDoubleClick" class="bottom">-</div></div><div data-style="margin" @keydown="onKeyDown" @dblclick="onDoubleClick" class="right">-</div><br><div data-style="margin" @keydown="onKeyDown" @dblclick="onDoubleClick" class="bottom">-</div></div><div data-style="position" @keydown="onKeyDown" @dblclick="onDoubleClick" class="right">-</div><br><div data-style="position" @keydown="onKeyDown" @dblclick="onDoubleClick" class="bottom">-</div></div>
93
93
  `;
94
94
  property;
95
95
  unsetValue;
96
- //private _root: HTMLDivElement;
97
- //private _contentEditable: HTMLDivElement;
98
- _updateValue() {
99
- }
100
96
  ready() {
101
- //this._root = this._getDomElement<HTMLDivElement>("testdiv");
102
97
  this._parseAttributesToProperties();
103
- this._updateValue();
104
98
  this._assignEvents();
105
99
  }
106
100
  onDoubleClick(event) {
107
- let element = this._getDomElement("testdiv");
108
- // contentEditable setzten
101
+ const element = event.target;
109
102
  element.setAttribute("contentEditable", "");
110
- // - rausnehmen
111
- element.innerHTML = "-";
112
- // Input auswerten
113
- //Input in div schreiben
114
- // contentEditable false setzen mit EnterTaste
115
- element.onkeydown = (e) => {
116
- if (e.key == "Enter") {
117
- let _input = element.innerHTML;
118
- //let value = document.createElement("input");
119
- element.style.marginTop = _input;
120
- element.removeAttribute("contentEditable");
121
- element.innerHTML = "-";
122
- }
123
- };
103
+ const range = document.createRange();
104
+ const sel = window.getSelection();
105
+ range.setStart(element.firstChild, 0);
106
+ range.setEndAfter(element.lastChild);
107
+ sel.removeAllRanges();
108
+ sel.addRange(range);
109
+ }
110
+ onKeyDown(event) {
111
+ const element = event.target;
112
+ if (event.key == "Enter") {
113
+ element.removeAttribute("contentEditable");
114
+ const value = element.innerHTML;
115
+ const valueChangedEvent = new CustomEvent('value-changed', {
116
+ detail: {
117
+ style: element.dataset['style'],
118
+ value: value
119
+ }
120
+ });
121
+ this.dispatchEvent(valueChangedEvent);
122
+ }
124
123
  }
125
124
  }
126
125
  customElements.define('node-projects-metrics-editor', MetricsEditor);
@@ -0,0 +1,3 @@
1
+ export declare function convertCssUnitToPixel(cssValue: string, target: HTMLElement, percentTarget: 'width' | 'heigth'): number;
2
+ export declare function getCssUnit(cssValue: string): string;
3
+ export declare function convertCssUnit(cssValue: string | number, target: HTMLElement, percentTarget: 'width' | 'heigth', unit: string): string | number;
@@ -0,0 +1,85 @@
1
+ //unsupported: ex, ch, svw, svh, vw, lvh, dvw, dvh
2
+ const units = ['px', 'cm', 'mm', 'q', 'in', 'pc', 'pt', 'rem', 'em', 'vw', 'vh', 'vmin', 'vmax', 'lh', 'rlh', '%', 'ms', 's', 'deg', 'rad', 'grad', 'turn'];
3
+ const pattern = new RegExp(`^([\-\+]?(?:\\d+(?:\\.\\d+)?))(${units.join('|')})$`, 'i');
4
+ export function convertCssUnitToPixel(cssValue, target, percentTarget) {
5
+ const supportedUnits = {
6
+ // Absolute sizes
7
+ 'px': value => value,
8
+ 'cm': value => value * 38,
9
+ 'mm': value => value * 3.8,
10
+ 'q': value => value * 0.95,
11
+ 'in': value => value * 96,
12
+ 'pc': value => value * 16,
13
+ 'pt': value => value * 1.333333,
14
+ // Relative sizes
15
+ 'rem': value => value * parseFloat(getComputedStyle(document.documentElement).fontSize),
16
+ 'em': value => value * parseFloat(getComputedStyle(target).fontSize),
17
+ 'vw': value => value / 100 * window.innerWidth,
18
+ 'vh': value => value / 100 * window.innerHeight,
19
+ 'vmin': value => value / 100 * (window.innerHeight < window.innerWidth ? window.innerHeight : window.innerWidth),
20
+ 'vmax': value => value / 100 * (window.innerHeight > window.innerWidth ? window.innerHeight : window.innerWidth),
21
+ 'lh': value => value * parseFloat(getComputedStyle(target).lineHeight),
22
+ 'rlh': value => value * parseFloat(getComputedStyle(document.documentElement).lineHeight),
23
+ '%': value => value / 100 * (percentTarget == 'heigth' ? target.getBoundingClientRect().height : target.getBoundingClientRect().width),
24
+ // Times
25
+ 'ms': value => value,
26
+ 's': value => value * 1000,
27
+ // Angles
28
+ 'deg': value => value,
29
+ 'rad': value => value * (180 / Math.PI),
30
+ 'grad': value => value * (180 / 200),
31
+ 'turn': value => value * 360
32
+ };
33
+ // If is a match, return example: [ "-2.75rem", "-2.75", "rem" ]
34
+ const matches = cssValue.trim().match(pattern);
35
+ if (matches) {
36
+ const value = Number(matches[1]);
37
+ const unit = matches[2].toLowerCase();
38
+ // Sanity check, make sure unit conversion function exists
39
+ if (unit in supportedUnits) {
40
+ return supportedUnits[unit](value);
41
+ }
42
+ }
43
+ //@ts-ignore
44
+ return cssValue;
45
+ }
46
+ export function getCssUnit(cssValue) {
47
+ const matches = cssValue.trim().match(pattern);
48
+ return matches[2].toLowerCase();
49
+ }
50
+ export function convertCssUnit(cssValue, target, percentTarget, unit) {
51
+ const supportedUnits = {
52
+ // Absolute sizes
53
+ 'px': value => value,
54
+ 'cm': value => value / 38,
55
+ 'mm': value => value / 3.8,
56
+ 'q': value => value / 0.95,
57
+ 'in': value => value / 96,
58
+ 'pc': value => value / 16,
59
+ 'pt': value => value / 1.333333,
60
+ // Relative sizes
61
+ 'rem': value => value / parseFloat(getComputedStyle(document.documentElement).fontSize),
62
+ 'em': value => value / parseFloat(getComputedStyle(target).fontSize),
63
+ 'vw': value => value * 100 / window.innerWidth,
64
+ 'vh': value => value * 100 / window.innerHeight,
65
+ 'vmin': value => value * 100 / (window.innerHeight < window.innerWidth ? window.innerHeight : window.innerWidth),
66
+ 'vmax': value => value * 100 / (window.innerHeight > window.innerWidth ? window.innerHeight : window.innerWidth),
67
+ 'lh': value => value / parseFloat(getComputedStyle(target).lineHeight),
68
+ 'rlh': value => value / parseFloat(getComputedStyle(document.documentElement).lineHeight),
69
+ '%': value => value * 100 / (percentTarget == 'heigth' ? target.getBoundingClientRect().height : target.getBoundingClientRect().width),
70
+ // Times
71
+ 'ms': value => value,
72
+ 's': value => value / 1000,
73
+ // Angles
74
+ 'deg': value => value,
75
+ 'rad': value => value / (180 / Math.PI),
76
+ 'grad': value => value / (180 / 200),
77
+ 'turn': value => value / 360
78
+ };
79
+ if (typeof cssValue == 'string')
80
+ cssValue = convertCssUnitToPixel(cssValue, target, percentTarget);
81
+ if (unit in supportedUnits) {
82
+ return supportedUnits[unit](cssValue) + unit;
83
+ }
84
+ return cssValue;
85
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
3
+ *
4
+ * @param {String} text The text to be rendered.
5
+ * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
6
+ *
7
+ * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
8
+ */
9
+ export declare function getTextWidth(text: string, font: string): number;
10
+ export declare function getFont(el: Element): string;
@@ -0,0 +1,23 @@
1
+ let canvas;
2
+ /**
3
+ * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
4
+ *
5
+ * @param {String} text The text to be rendered.
6
+ * @param {String} font The css font descriptor that text is to be rendered with (e.g. "bold 14px verdana").
7
+ *
8
+ * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
9
+ */
10
+ export function getTextWidth(text, font) {
11
+ if (!canvas)
12
+ canvas = document.createElement("canvas");
13
+ const context = canvas.getContext("2d");
14
+ context.font = font;
15
+ const metrics = context.measureText(text);
16
+ return metrics.width;
17
+ }
18
+ export function getFont(el) {
19
+ const fontWeight = getComputedStyle(el).fontWeight || 'normal';
20
+ const fontSize = getComputedStyle(el).fontSize || '16px';
21
+ const fontFamily = getComputedStyle(el).fontFamily || 'Times New Roman';
22
+ return `${fontWeight} ${fontSize} ${fontFamily}`;
23
+ }
@@ -12,7 +12,8 @@ export declare function addVectors(vectorA: [number, number], vectorB: [number,
12
12
  export declare function getDesignerCanvasNormalizedTransformedOriginWithoutParentTransformation(element: HTMLElement, designerCanvas: IDesignerCanvas): DOMPoint;
13
13
  export declare function getResultingTransformationBetweenElementAndAllAncestors(element: HTMLElement, ancestor: HTMLElement, excludeAncestor?: boolean): DOMMatrix;
14
14
  export declare function getByParentsTransformedPointRelatedToCanvas(element: HTMLElement, point: DOMPoint, designerCanvas: IDesignerCanvas): IPoint;
15
- export declare function getDesignerCanvasNormalizedTransformedCornerDOMPoints(element: HTMLElement, untransformedCornerPointsOffset: number, designerCanvas: IDesignerCanvas): [DOMPoint, DOMPoint, DOMPoint, DOMPoint];
15
+ export declare function getDesignerCanvasNormalizedTransformedPoint(element: HTMLElement, point: IPoint, designerCanvas: IDesignerCanvas): IPoint;
16
+ export declare function getDesignerCanvasNormalizedTransformedCornerDOMPoints(element: HTMLElement, untransformedCornerPointsOffset: IPoint | null, designerCanvas: IDesignerCanvas): [DOMPoint, DOMPoint, DOMPoint, DOMPoint];
16
17
  export declare function extractTranslationFromDOMMatrix(matrix: DOMMatrix): DOMPoint;
17
18
  export declare function extractRotationAngleFromDOMMatrix(matrix: DOMMatrix): number;
18
19
  export declare function normalizeToAbsolutePosition(element: HTMLElement, normalizeProperty: "left" | "top"): string;
@@ -123,11 +123,15 @@ export function getByParentsTransformedPointRelatedToCanvas(element, point, desi
123
123
  }
124
124
  return byParentTransformedPointRelatedToCanvas;
125
125
  }
126
+ export function getDesignerCanvasNormalizedTransformedPoint(element, point, designerCanvas) {
127
+ return getDesignerCanvasNormalizedTransformedCornerDOMPoints(element, { x: -point.x, y: -point.y }, designerCanvas)[0];
128
+ }
126
129
  export function getDesignerCanvasNormalizedTransformedCornerDOMPoints(element, untransformedCornerPointsOffset, designerCanvas) {
127
130
  const topleft = 0;
128
131
  const topright = 1;
129
132
  const bottomleft = 2;
130
133
  const bottomright = 3;
134
+ const intUntransformedCornerPointsOffset = untransformedCornerPointsOffset ? { x: untransformedCornerPointsOffset.x / designerCanvas.scaleFactor, y: untransformedCornerPointsOffset.y / designerCanvas.scaleFactor } : { x: 0, y: 0 };
131
135
  const p0Offsets = getElementsWindowOffsetWithoutSelfAndParentTransformations(element);
132
136
  const p0OffsetsRelatedToCanvas = DOMPoint.fromPoint({
133
137
  x: p0Offsets.offsetLeft - designerCanvas.containerBoundingRect.left,
@@ -151,20 +155,20 @@ export function getDesignerCanvasNormalizedTransformedCornerDOMPoints(element, u
151
155
  }
152
156
  const elementWithoutTransformCornerDOMPoints = [];
153
157
  elementWithoutTransformCornerDOMPoints[topleft] = DOMPoint.fromPoint({
154
- x: p0OffsetsRelatedToCanvas.x - untransformedCornerPointsOffset,
155
- y: p0OffsetsRelatedToCanvas.y - untransformedCornerPointsOffset
158
+ x: p0OffsetsRelatedToCanvas.x - intUntransformedCornerPointsOffset.x,
159
+ y: p0OffsetsRelatedToCanvas.y - intUntransformedCornerPointsOffset.y
156
160
  });
157
161
  elementWithoutTransformCornerDOMPoints[topright] = DOMPoint.fromPoint({
158
- x: p0OffsetsRelatedToCanvas.x + width + untransformedCornerPointsOffset,
159
- y: p0OffsetsRelatedToCanvas.y - untransformedCornerPointsOffset
162
+ x: p0OffsetsRelatedToCanvas.x + width + intUntransformedCornerPointsOffset.x,
163
+ y: p0OffsetsRelatedToCanvas.y - intUntransformedCornerPointsOffset.y
160
164
  });
161
165
  elementWithoutTransformCornerDOMPoints[bottomleft] = DOMPoint.fromPoint({
162
- x: p0OffsetsRelatedToCanvas.x - untransformedCornerPointsOffset,
163
- y: p0OffsetsRelatedToCanvas.y + height + untransformedCornerPointsOffset
166
+ x: p0OffsetsRelatedToCanvas.x - intUntransformedCornerPointsOffset.x,
167
+ y: p0OffsetsRelatedToCanvas.y + height + intUntransformedCornerPointsOffset.y
164
168
  });
165
169
  elementWithoutTransformCornerDOMPoints[bottomright] = DOMPoint.fromPoint({
166
- x: p0OffsetsRelatedToCanvas.x + width + untransformedCornerPointsOffset,
167
- y: p0OffsetsRelatedToCanvas.y + height + untransformedCornerPointsOffset
170
+ x: p0OffsetsRelatedToCanvas.x + width + intUntransformedCornerPointsOffset.x,
171
+ y: p0OffsetsRelatedToCanvas.y + height + intUntransformedCornerPointsOffset.y
168
172
  });
169
173
  const transformOriginWithoutTransformRelatedToCanvas = DOMPointReadOnly.fromPoint({
170
174
  x: p0OffsetsRelatedToCanvas.x + parseInt(getComputedStyle(element).transformOrigin.split(' ')[0]),
@@ -57,18 +57,22 @@ export class FlexBoxPlacementService {
57
57
  if (elBefore && elBefore[0] != items[0]) {
58
58
  if (posBefore + 1 === posDrag)
59
59
  return;
60
+ const sel = [...container.instanceServiceContainer.selectionService.selectedElements];
60
61
  let cg = items[0].openGroup('move in flexbox');
61
62
  items[0].remove();
62
63
  elBefore[0].insertAdjacentElement(items[0], 'afterend');
63
64
  cg.commit();
65
+ container.instanceServiceContainer.selectionService.setSelectedElements(sel);
64
66
  }
65
67
  else if (elBefore == null) {
66
68
  if (posDrag == 0)
67
69
  return;
70
+ const sel = [...container.instanceServiceContainer.selectionService.selectedElements];
68
71
  let cg = items[0].openGroup('move in flexbox');
69
72
  items[0].remove();
70
73
  container.insertChild(items[0], 0);
71
74
  cg.commit();
75
+ container.instanceServiceContainer.selectionService.setSelectedElements(sel);
72
76
  }
73
77
  }
74
78
  else if (style.flexDirection == 'column') {
@@ -84,18 +88,22 @@ export class FlexBoxPlacementService {
84
88
  if (elBefore && elBefore[0] != items[0]) {
85
89
  if (posBefore + 1 === posDrag)
86
90
  return;
91
+ const sel = [...container.instanceServiceContainer.selectionService.selectedElements];
87
92
  let cg = items[0].openGroup('move in flexbox');
88
93
  items[0].remove();
89
94
  elBefore[0].insertAdjacentElement(items[0], 'afterend');
90
95
  cg.commit();
96
+ container.instanceServiceContainer.selectionService.setSelectedElements(sel);
91
97
  }
92
98
  else if (elBefore == null) {
93
99
  if (posDrag == 0)
94
100
  return;
101
+ const sel = [...container.instanceServiceContainer.selectionService.selectedElements];
95
102
  let cg = items[0].openGroup('move in flexbox');
96
103
  items[0].remove();
97
104
  container.insertChild(items[0], 0);
98
105
  cg.commit();
106
+ container.instanceServiceContainer.selectionService.setSelectedElements(sel);
99
107
  }
100
108
  }
101
109
  placementView.extensionManager.refreshAllExtensions([container]);
@@ -12,4 +12,5 @@ export declare class CssPropertiesService extends CommonPropertiesService {
12
12
  getProperty(designItem: IDesignItem, name: string): IProperty;
13
13
  getProperties(designItem: IDesignItem): IProperty[];
14
14
  getPropertyTarget(designItem: IDesignItem, property: IProperty): BindingTarget;
15
+ setValue(designItems: IDesignItem[], property: IProperty, value: any): void;
15
16
  }
@@ -203,4 +203,12 @@ export class CssPropertiesService extends CommonPropertiesService {
203
203
  getPropertyTarget(designItem, property) {
204
204
  return BindingTarget.css;
205
205
  }
206
+ setValue(designItems, property, value) {
207
+ if (this.name == 'styles') {
208
+ super.setValue(designItems, { ...property, propertyType: PropertyType.cssValue }, value);
209
+ }
210
+ else {
211
+ super.setValue(designItems, property, value);
212
+ }
213
+ }
206
214
  }
@@ -5,6 +5,7 @@ import { IExtensionManager } from "./IExtensionManger";
5
5
  export declare class ElementDragTitleExtension extends AbstractExtension {
6
6
  private _rect;
7
7
  private _text;
8
+ private _width;
8
9
  constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
9
10
  extend(): void;
10
11
  _drawMoveOverlay(itemRect: DOMRect): void;
@@ -1,15 +1,26 @@
1
+ import { getTextWidth } from "../../../helper/TextHelper";
2
+ import { getDesignerCanvasNormalizedTransformedCornerDOMPoints } from "../../../helper/TransformHelper";
1
3
  import { NamedTools } from "../tools/NamedTools.js";
2
4
  import { AbstractExtension } from './AbstractExtension';
5
+ const extensionWidth = 60;
3
6
  export class ElementDragTitleExtension extends AbstractExtension {
4
7
  _rect;
5
8
  _text;
9
+ _width;
6
10
  constructor(extensionManager, designerView, extendedItem) {
7
11
  super(extensionManager, designerView, extendedItem);
8
12
  }
9
13
  extend() {
14
+ const transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
10
15
  const boundRect = this.extendedItem.element.getBoundingClientRect();
11
- this._rect = this._drawRect((boundRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor, (boundRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - 16, 60, 15, 'svg-primary-selection-move', this._rect);
12
- this._text = this._drawText(this.extendedItem.name.substring(0, 10) + '…', (boundRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor, (boundRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - 5, 'svg-text-primary', this._text);
16
+ let w = getTextWidth(this.extendedItem.name, '10px monospace');
17
+ let elementWidth = Math.sqrt(Math.pow(transformedCornerPoints[1].x - transformedCornerPoints[0].x, 2) + Math.pow(transformedCornerPoints[1].y - transformedCornerPoints[0].y, 2));
18
+ let text = this.extendedItem.name;
19
+ this._width = Math.max(Math.min(elementWidth, w), extensionWidth);
20
+ if (w > this._width)
21
+ text = this.extendedItem.name.substring(0, 10) + '…';
22
+ this._rect = this._drawRect(transformedCornerPoints[0].x, transformedCornerPoints[0].y - 16, this._width, 15, 'svg-primary-selection-move', this._rect);
23
+ this._text = this._drawText(text, (boundRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor, (boundRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - 5, 'svg-text-primary', this._text);
13
24
  const title = document.createElementNS("http://www.w3.org/2000/svg", "title");
14
25
  title.textContent = this.extendedItem.name;
15
26
  this._text.appendChild(title);
@@ -21,21 +32,22 @@ export class ElementDragTitleExtension extends AbstractExtension {
21
32
  _drawMoveOverlay(itemRect) {
22
33
  }
23
34
  refresh() {
24
- const boundRect = this.extendedItem.element.getBoundingClientRect();
25
- const xr = (boundRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor;
35
+ const transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, { x: 0, y: 16 }, this.designerCanvas);
36
+ const angle = Math.atan2((transformedCornerPoints[1].y - transformedCornerPoints[0].y), (transformedCornerPoints[1].x - transformedCornerPoints[0].x)) * 180 / Math.PI;
37
+ const transformedCornerPointsTx = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, { x: 0, y: 5 }, this.designerCanvas);
26
38
  const h = (15 / this.designerCanvas.scaleFactor);
27
- const w = (60 / this.designerCanvas.scaleFactor);
28
- const yr = (boundRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - h;
29
- this._rect.setAttribute('x', xr);
30
- this._rect.setAttribute('y', yr);
39
+ const w = (this._width / this.designerCanvas.scaleFactor);
40
+ this._rect.setAttribute('x', '' + transformedCornerPoints[0].x);
41
+ this._rect.setAttribute('y', '' + transformedCornerPoints[0].y);
42
+ this._rect.style.rotate = angle + 'deg';
43
+ this._rect.style.transformBox = 'fill-box';
31
44
  this._rect.setAttribute('height', '' + h);
32
45
  this._rect.setAttribute('width', '' + w);
33
46
  this._rect.style.strokeWidth = (1 / this.designerCanvas.scaleFactor).toString();
34
- const x = (boundRect.x - this.designerCanvas.containerBoundingRect.x) / this.designerCanvas.scaleFactor;
35
- const y = (boundRect.y - this.designerCanvas.containerBoundingRect.y) / this.designerCanvas.scaleFactor - 5 / this.designerCanvas.scaleFactor;
36
- this._text.setAttribute('x', x);
37
- this._text.setAttribute('y', y);
47
+ this._text.setAttribute('x', '' + transformedCornerPointsTx[0].x);
48
+ this._text.setAttribute('y', '' + transformedCornerPointsTx[0].y);
38
49
  this._text.style.fontSize = (10 / this.designerCanvas.scaleFactor) + 'px';
50
+ this._text.setAttribute('transform', 'rotate(' + angle + ' ' + transformedCornerPointsTx[0].x + ' ' + transformedCornerPointsTx[0].y + ')');
39
51
  }
40
52
  _pointerEvent(event) {
41
53
  event.preventDefault();
@@ -42,7 +42,7 @@ export class ExtensionManager {
42
42
  const primaryContainer = DesignItem.GetOrCreateDesignItem(selectionChangedEvent.selectedElements[0].parent.element, this.designerCanvas.serviceContainer, this.designerCanvas.instanceServiceContainer);
43
43
  this.applyExtension(primaryContainer, ExtensionType.PrimarySelectionContainer);
44
44
  }
45
- this.refreshExtensions(selectionChangedEvent.selectedElements);
45
+ //this.refreshExtensions(selectionChangedEvent.selectedElements);
46
46
  }
47
47
  applyExtension(designItem, extensionType, recursive = false) {
48
48
  if (designItem && designItem.nodeType == NodeType.Element) {
@@ -7,7 +7,7 @@ export class FlexboxExtension extends AbstractExtension {
7
7
  super(extensionManager, designerView, extendedItem);
8
8
  }
9
9
  extend() {
10
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 0, this.designerCanvas);
10
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
11
11
  this._path = this._drawTransformedRect(transformedCornerPoints, 'svg-flexbox', this._path, OverlayLayer.Background);
12
12
  }
13
13
  refresh() {
@@ -10,7 +10,7 @@ export class GrayOutDragOverContainerExtension extends AbstractExtension {
10
10
  this.refresh();
11
11
  }
12
12
  refresh() {
13
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 0, this.designerCanvas);
13
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
14
14
  this._rect = this._drawTransformedRect(transformedCornerPoints, 'svg-rect-enter-container', this._rect, OverlayLayer.Background);
15
15
  }
16
16
  dispose() {
@@ -10,7 +10,7 @@ export class InvisibleDivExtension extends AbstractExtension {
10
10
  this.refresh();
11
11
  }
12
12
  refresh() {
13
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 0, this.designerCanvas);
13
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
14
14
  this._rect = this._drawTransformedRect(transformedCornerPoints, 'svg-invisible-div', this._rect, OverlayLayer.Background);
15
15
  }
16
16
  dispose() {
@@ -10,7 +10,7 @@ export class MouseOverExtension extends AbstractExtension {
10
10
  this.refresh();
11
11
  }
12
12
  refresh() {
13
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, offset, this.designerCanvas);
13
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, { x: offset, y: offset }, this.designerCanvas);
14
14
  this._rect = this._drawTransformedRect(transformedCornerPoints, 'svg-hover', this._rect);
15
15
  this._rect.style.strokeWidth = (2 / this.designerCanvas.zoomFactor).toString();
16
16
  }
@@ -26,7 +26,7 @@ export class ResizeExtension extends AbstractExtension {
26
26
  }
27
27
  refresh() {
28
28
  //#region Resizer circles
29
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 0, this.designerCanvas);
29
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
30
30
  this._circle1 = this._drawResizerOverlay(transformedCornerPoints[0].x, transformedCornerPoints[0].y, 'nw-resize', this._circle1);
31
31
  this._circle2 = this._drawResizerOverlay((transformedCornerPoints[0].x + (transformedCornerPoints[1].x - transformedCornerPoints[0].x) / 2), (transformedCornerPoints[0].y + (transformedCornerPoints[1].y - transformedCornerPoints[0].y) / 2), 'n-resize', this._circle2);
32
32
  this._circle3 = this._drawResizerOverlay(transformedCornerPoints[1].x, transformedCornerPoints[1].y, 'ne-resize', this._circle3);
@@ -20,7 +20,7 @@ export class RotateExtension extends AbstractExtension {
20
20
  this._rotateIcon = this._drawRotateOverlay(rect, this._rotateIcon);
21
21
  }
22
22
  _drawRotateOverlay(itemRect, oldRotateIcon) {
23
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 10, this.designerCanvas);
23
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, { x: 10, y: 10 }, this.designerCanvas);
24
24
  let rotateIconPosition = transformedCornerPoints[0];
25
25
  if (!oldRotateIcon) {
26
26
  const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
@@ -40,13 +40,13 @@ export class RotateExtension extends AbstractExtension {
40
40
  g.addEventListener(EventNames.PointerMove, event => this._pointerActionTypeRotate(event));
41
41
  g.addEventListener(EventNames.PointerUp, event => this._pointerActionTypeRotate(event));
42
42
  g.setAttribute('class', 'svg-primary-rotate');
43
- g.setAttribute('transform', 'translate(' + rotateIconPosition.x + ',' + rotateIconPosition.y + ')');
43
+ g.setAttribute('transform', 'translate(' + rotateIconPosition.x + ',' + rotateIconPosition.y + ') scale(' + 1 / this.designerCanvas.scaleFactor + ')');
44
44
  this.overlayLayerView.addOverlay(g);
45
45
  this.overlays.push(g);
46
46
  return g;
47
47
  }
48
48
  else {
49
- oldRotateIcon.setAttribute('transform', 'translate(' + rotateIconPosition.x + ',' + rotateIconPosition.y + ')');
49
+ oldRotateIcon.setAttribute('transform', 'translate(' + rotateIconPosition.x + ',' + rotateIconPosition.y + ') scale(' + 1 / this.designerCanvas.scaleFactor + ')');
50
50
  return oldRotateIcon;
51
51
  }
52
52
  }
@@ -75,10 +75,12 @@ export class RotateExtension extends AbstractExtension {
75
75
  let angle = Math.atan2(currentPoint.y - transformOriginInPx.y, currentPoint.x - transformOriginInPx.x) * (180 / Math.PI);
76
76
  angle = angle - this._initialOverlayAngle + this._initialElementAngle;
77
77
  angle *= -1;
78
+ if (!event.ctrlKey)
79
+ angle = Math.ceil(angle / 15) * 15;
78
80
  const rotationMatrix3d = getRotationMatrix3d('z', angle);
79
81
  rotateElementByMatrix3d(this.extendedItem.element, rotationMatrix3d);
80
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 30, this.designerCanvas);
81
- let angleTextPosition = transformedCornerPoints[0];
82
+ const transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, { x: 30, y: 30 }, this.designerCanvas);
83
+ const angleTextPosition = transformedCornerPoints[0];
82
84
  this._textAngle = this._drawTextWithBackground(this._actualRotationAngle + '°', angleTextPosition.x, angleTextPosition.y, 'white', 'svg-rotate-text', this._textAngle);
83
85
  this._textAngle[2].style.fontSize = (12 / this.designerCanvas.scaleFactor) + 'px';
84
86
  this._textAngle[3].style.fontSize = (12 / this.designerCanvas.scaleFactor) + 'px';
@@ -12,7 +12,7 @@ export class SelectionDefaultExtension extends AbstractExtension {
12
12
  this.refresh();
13
13
  }
14
14
  refresh() {
15
- let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, 0, this.designerCanvas);
15
+ let transformedCornerPoints = getDesignerCanvasNormalizedTransformedCornerDOMPoints(this.extendedItem.element, null, this.designerCanvas);
16
16
  this._line1 = this._drawLine(transformedCornerPoints[0].x, transformedCornerPoints[0].y, transformedCornerPoints[1].x, transformedCornerPoints[1].y, 'svg-selection', this._line1);
17
17
  this._line2 = this._drawLine(transformedCornerPoints[0].x, transformedCornerPoints[0].y, transformedCornerPoints[2].x, transformedCornerPoints[2].y, 'svg-selection', this._line2);
18
18
  this._line3 = this._drawLine(transformedCornerPoints[1].x, transformedCornerPoints[1].y, transformedCornerPoints[3].x, transformedCornerPoints[3].y, 'svg-selection', this._line3);
@@ -6,6 +6,7 @@ export declare class TransformOriginExtension extends AbstractExtension {
6
6
  private _startPos;
7
7
  private _circle;
8
8
  private _circle2;
9
+ private _oldValue;
9
10
  constructor(extensionManager: IExtensionManager, designerView: IDesignerCanvas, extendedItem: IDesignItem);
10
11
  extend(): void;
11
12
  pointerEvent(event: PointerEvent): void;
@@ -1,33 +1,30 @@
1
1
  import { EventNames } from "../../../../enums/EventNames";
2
+ import { convertCssUnit, getCssUnit } from "../../../helper/CssUnitConverter";
3
+ import { getDesignerCanvasNormalizedTransformedPoint } from "../../../helper/TransformHelper";
2
4
  import { AbstractExtension } from './AbstractExtension';
3
5
  export class TransformOriginExtension extends AbstractExtension {
4
6
  _startPos;
5
7
  _circle;
6
8
  _circle2;
9
+ _oldValue;
7
10
  constructor(extensionManager, designerView, extendedItem) {
8
11
  super(extensionManager, designerView, extendedItem);
9
12
  }
10
13
  extend() {
11
- const rect = this.designerCanvas.getNormalizedElementCoordinates(this.extendedItem.element);
12
14
  const computed = getComputedStyle(this.extendedItem.element);
13
- const x = 0;
14
- const y = 1;
15
15
  const to = computed.transformOrigin.split(' '); // This value remains the same regardless of scalefactor
16
- const toInPercentage = [];
17
- toInPercentage[0] = parseInt(to[0]) / parseInt(getComputedStyle(this.extendedItem.element).width); // This value remains the same regardless of scalefactor
18
- toInPercentage[1] = parseInt(to[1]) / parseInt(getComputedStyle(this.extendedItem.element).height); // This value remains the same regardless of scalefactor
19
- const toDOMPoint = new DOMPoint(rect.x + toInPercentage[x] * rect.width, rect.y + toInPercentage[y] * rect.height);
20
- this._circle = this._drawCircle(toDOMPoint.x, toDOMPoint.y, 5 / this.designerCanvas.scaleFactor, 'svg-transform-origin');
16
+ const toDOMPoint = getDesignerCanvasNormalizedTransformedPoint(this.extendedItem.element, { x: parseFloat(to[0]), y: parseFloat(to[1]) }, this.designerCanvas);
17
+ this._circle = this._drawCircle(toDOMPoint.x, toDOMPoint.y, 5 / this.designerCanvas.zoomFactor, 'svg-transform-origin');
21
18
  this._circle.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
22
- this._circle.setAttribute('style', 'cursor: pointer');
23
- this._circle2 = this._drawCircle(toDOMPoint.x, toDOMPoint.y, 1 / this.designerCanvas.scaleFactor, 'svg-transform-origin');
19
+ this._circle.style.cursor = 'pointer';
20
+ this._circle2 = this._drawCircle(toDOMPoint.x, toDOMPoint.y, 1 / this.designerCanvas.zoomFactor, 'svg-transform-origin');
24
21
  this._circle2.style.strokeWidth = (1 / this.designerCanvas.zoomFactor).toString();
25
- this._circle2.setAttribute('style', 'pointer-events: none');
22
+ this._circle2.style.pointerEvents = 'none';
26
23
  this._circle.addEventListener(EventNames.PointerDown, event => this.pointerEvent(event));
27
24
  this._circle.addEventListener(EventNames.PointerMove, event => this.pointerEvent(event));
28
25
  this._circle.addEventListener(EventNames.PointerUp, event => this.pointerEvent(event)); //TODO: -> assign to window
29
- if (this.extendedItem.styles.get('transform-origin') == null || this.extendedItem.styles.get('transform-origin') == '') {
30
- this.extendedItem.setStyle('transform-origin', this._circle.getAttribute('cx') + ' ' + this._circle.getAttribute('cy'));
26
+ if (this.extendedItem.styles.get('transform-origin')) {
27
+ this._oldValue = this.extendedItem.styles.get('transform-origin');
31
28
  }
32
29
  }
33
30
  pointerEvent(event) {
@@ -64,7 +61,22 @@ export class TransformOriginExtension extends AbstractExtension {
64
61
  const dy = normalized.y - this._startPos.y;
65
62
  const newX = (dx + parseFloat(to[x]));
66
63
  const newY = (dy + parseFloat(to[y]));
67
- this.extendedItem.setStyle('transform-origin', newX + 'px' + ' ' + newY + 'px');
64
+ if (this._oldValue) { //Restore old units
65
+ try {
66
+ const oldSplit = this._oldValue.split(' ');
67
+ let newXs = convertCssUnit(newX, this.extendedItem.element, 'width', getCssUnit(oldSplit[0]));
68
+ let newYs = convertCssUnit(newX, this.extendedItem.element, 'width', getCssUnit(oldSplit[0]));
69
+ if (oldSplit.length > 1) {
70
+ newYs = convertCssUnit(newY, this.extendedItem.element, 'heigth', getCssUnit(oldSplit[1]));
71
+ }
72
+ this.extendedItem.setStyle('transform-origin', newXs + ' ' + newYs);
73
+ }
74
+ catch (err) {
75
+ this.extendedItem.setStyle('transform-origin', newX + 'px' + ' ' + newY + 'px');
76
+ }
77
+ }
78
+ else
79
+ this.extendedItem.setStyle('transform-origin', newX + 'px' + ' ' + newY + 'px');
68
80
  this.refresh();
69
81
  this._startPos = null;
70
82
  }
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.152",
4
+ "version": "0.0.154",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "author": "",