@idraw/util 0.3.0 → 0.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/esm/index.d.ts +26 -71
  2. package/dist/esm/index.js +26 -29
  3. package/dist/esm/lib/canvas.d.ts +15 -0
  4. package/dist/esm/lib/canvas.js +36 -0
  5. package/dist/esm/lib/check.d.ts +8 -8
  6. package/dist/esm/lib/check.js +32 -33
  7. package/dist/esm/lib/color.d.ts +1 -0
  8. package/dist/esm/lib/color.js +152 -1
  9. package/dist/esm/lib/context2d.d.ts +75 -0
  10. package/dist/esm/lib/context2d.js +226 -0
  11. package/dist/esm/lib/controller.d.ts +6 -0
  12. package/dist/esm/lib/controller.js +99 -0
  13. package/dist/esm/lib/data.d.ts +5 -1
  14. package/dist/esm/lib/data.js +67 -2
  15. package/dist/esm/lib/element.d.ts +18 -0
  16. package/dist/esm/lib/element.js +241 -0
  17. package/dist/esm/lib/event.d.ts +9 -0
  18. package/dist/esm/lib/event.js +50 -0
  19. package/dist/esm/lib/html.d.ts +3 -0
  20. package/dist/esm/lib/html.js +170 -0
  21. package/dist/esm/lib/image.d.ts +4 -0
  22. package/dist/esm/lib/image.js +27 -0
  23. package/dist/esm/lib/is.d.ts +4 -2
  24. package/dist/esm/lib/is.js +34 -15
  25. package/dist/esm/lib/istype.d.ts +1 -2
  26. package/dist/esm/lib/istype.js +3 -4
  27. package/dist/esm/lib/{loader.js → load.js} +2 -2
  28. package/dist/esm/lib/middleware.d.ts +3 -0
  29. package/dist/esm/lib/middleware.js +22 -0
  30. package/dist/esm/lib/number.d.ts +3 -0
  31. package/dist/esm/lib/number.js +4 -0
  32. package/dist/esm/lib/parser.js +4 -1
  33. package/dist/esm/lib/point.d.ts +8 -0
  34. package/dist/esm/lib/point.js +30 -0
  35. package/dist/esm/lib/rect.d.ts +2 -0
  36. package/dist/esm/lib/rect.js +11 -0
  37. package/dist/esm/lib/rotate.d.ts +13 -0
  38. package/dist/esm/lib/rotate.js +205 -0
  39. package/dist/esm/lib/store.d.ts +12 -0
  40. package/dist/esm/lib/store.js +22 -0
  41. package/dist/esm/lib/svg-path.d.ts +10 -0
  42. package/dist/esm/lib/svg-path.js +36 -0
  43. package/dist/esm/lib/uuid.d.ts +2 -0
  44. package/dist/esm/lib/uuid.js +27 -2
  45. package/dist/esm/lib/vertex.d.ts +10 -0
  46. package/dist/esm/lib/vertex.js +73 -0
  47. package/dist/esm/lib/view-calc.d.ts +49 -0
  48. package/dist/esm/lib/view-calc.js +167 -0
  49. package/dist/index.global.js +1706 -330
  50. package/dist/index.global.min.js +1 -1
  51. package/package.json +4 -4
  52. package/LICENSE +0 -21
  53. package/dist/esm/lib/context.d.ts +0 -80
  54. package/dist/esm/lib/context.js +0 -194
  55. /package/dist/esm/lib/{loader.d.ts → load.d.ts} +0 -0
@@ -0,0 +1,226 @@
1
+ export class Context2D {
2
+ constructor(ctx, opts) {
3
+ this._devicePixelRatio = 1;
4
+ const { devicePixelRatio = 1 } = opts;
5
+ this._ctx = ctx;
6
+ this._devicePixelRatio = devicePixelRatio;
7
+ }
8
+ $undoPixelRatio(num) {
9
+ return num / this._devicePixelRatio;
10
+ }
11
+ $doPixelRatio(num) {
12
+ return this._devicePixelRatio * num;
13
+ }
14
+ $getContext() {
15
+ return this._ctx;
16
+ }
17
+ $setFont(opts) {
18
+ const strList = [];
19
+ if (opts.fontWeight) {
20
+ strList.push(`${opts.fontWeight}`);
21
+ }
22
+ strList.push(`${this.$doPixelRatio(opts.fontSize || 12)}px`);
23
+ strList.push(`${opts.fontFamily || 'sans-serif'}`);
24
+ this._ctx.font = `${strList.join(' ')}`;
25
+ }
26
+ $resize(opts) {
27
+ const { width, height, devicePixelRatio } = opts;
28
+ const { canvas } = this._ctx;
29
+ canvas.width = width * devicePixelRatio;
30
+ canvas.height = height * devicePixelRatio;
31
+ this._devicePixelRatio = devicePixelRatio;
32
+ }
33
+ get canvas() {
34
+ return this._ctx.canvas;
35
+ }
36
+ get fillStyle() {
37
+ return this._ctx.fillStyle;
38
+ }
39
+ set fillStyle(value) {
40
+ this._ctx.fillStyle = value;
41
+ }
42
+ get strokeStyle() {
43
+ return this._ctx.strokeStyle;
44
+ }
45
+ set strokeStyle(color) {
46
+ this._ctx.strokeStyle = color;
47
+ }
48
+ get lineWidth() {
49
+ return this.$undoPixelRatio(this._ctx.lineWidth);
50
+ }
51
+ set lineWidth(w) {
52
+ this._ctx.lineWidth = this.$doPixelRatio(w);
53
+ }
54
+ get textAlign() {
55
+ return this._ctx.textAlign;
56
+ }
57
+ set textAlign(align) {
58
+ this._ctx.textAlign = align;
59
+ }
60
+ get textBaseline() {
61
+ return this._ctx.textBaseline;
62
+ }
63
+ set textBaseline(baseline) {
64
+ this._ctx.textBaseline = baseline;
65
+ }
66
+ get globalAlpha() {
67
+ return this._ctx.globalAlpha;
68
+ }
69
+ set globalAlpha(alpha) {
70
+ this._ctx.globalAlpha = alpha;
71
+ }
72
+ get shadowColor() {
73
+ return this._ctx.shadowColor;
74
+ }
75
+ set shadowColor(color) {
76
+ this._ctx.shadowColor = color;
77
+ }
78
+ get shadowOffsetX() {
79
+ return this.$undoPixelRatio(this._ctx.shadowOffsetX);
80
+ }
81
+ set shadowOffsetX(offsetX) {
82
+ this._ctx.shadowOffsetX = this.$doPixelRatio(offsetX);
83
+ }
84
+ get shadowOffsetY() {
85
+ return this.$undoPixelRatio(this._ctx.shadowOffsetY);
86
+ }
87
+ set shadowOffsetY(offsetY) {
88
+ this._ctx.shadowOffsetY = this.$doPixelRatio(offsetY);
89
+ }
90
+ get shadowBlur() {
91
+ return this.$undoPixelRatio(this._ctx.shadowBlur);
92
+ }
93
+ set shadowBlur(blur) {
94
+ this._ctx.shadowBlur = this.$doPixelRatio(blur);
95
+ }
96
+ get lineCap() {
97
+ return this._ctx.lineCap;
98
+ }
99
+ set lineCap(lineCap) {
100
+ this._ctx.lineCap = lineCap;
101
+ }
102
+ get globalCompositeOperation() {
103
+ return this._ctx.globalCompositeOperation;
104
+ }
105
+ set globalCompositeOperation(operations) {
106
+ this._ctx.globalCompositeOperation = operations;
107
+ }
108
+ fill(...args) {
109
+ return this._ctx.fill(...args);
110
+ }
111
+ arc(x, y, radius, startAngle, endAngle, anticlockwise) {
112
+ return this._ctx.arc(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(radius), startAngle, endAngle, anticlockwise);
113
+ }
114
+ rect(x, y, w, h) {
115
+ return this._ctx.rect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
116
+ }
117
+ fillRect(x, y, w, h) {
118
+ return this._ctx.fillRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
119
+ }
120
+ clearRect(x, y, w, h) {
121
+ return this._ctx.clearRect(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(w), this.$doPixelRatio(h));
122
+ }
123
+ beginPath() {
124
+ return this._ctx.beginPath();
125
+ }
126
+ closePath() {
127
+ return this._ctx.closePath();
128
+ }
129
+ lineTo(x, y) {
130
+ return this._ctx.lineTo(this.$doPixelRatio(x), this.$doPixelRatio(y));
131
+ }
132
+ moveTo(x, y) {
133
+ return this._ctx.moveTo(this.$doPixelRatio(x), this.$doPixelRatio(y));
134
+ }
135
+ arcTo(x1, y1, x2, y2, radius) {
136
+ return this._ctx.arcTo(this.$doPixelRatio(x1), this.$doPixelRatio(y1), this.$doPixelRatio(x2), this.$doPixelRatio(y2), this.$doPixelRatio(radius));
137
+ }
138
+ getLineDash() {
139
+ return this._ctx.getLineDash();
140
+ }
141
+ setLineDash(nums) {
142
+ return this._ctx.setLineDash(nums.map((n) => this.$doPixelRatio(n)));
143
+ }
144
+ stroke(path) {
145
+ return path ? this._ctx.stroke(path) : this._ctx.stroke();
146
+ }
147
+ translate(x, y) {
148
+ return this._ctx.translate(this.$doPixelRatio(x), this.$doPixelRatio(y));
149
+ }
150
+ rotate(angle) {
151
+ return this._ctx.rotate(angle);
152
+ }
153
+ drawImage(...args) {
154
+ const image = args[0];
155
+ const sx = args[1];
156
+ const sy = args[2];
157
+ const sw = args[3];
158
+ const sh = args[4];
159
+ const dx = args[args.length - 4];
160
+ const dy = args[args.length - 3];
161
+ const dw = args[args.length - 2];
162
+ const dh = args[args.length - 1];
163
+ if (args.length === 9) {
164
+ return this._ctx.drawImage(image, this.$doPixelRatio(sx), this.$doPixelRatio(sy), this.$doPixelRatio(sw), this.$doPixelRatio(sh), this.$doPixelRatio(dx), this.$doPixelRatio(dy), this.$doPixelRatio(dw), this.$doPixelRatio(dh));
165
+ }
166
+ else {
167
+ return this._ctx.drawImage(image, this.$doPixelRatio(dx), this.$doPixelRatio(dy), this.$doPixelRatio(dw), this.$doPixelRatio(dh));
168
+ }
169
+ }
170
+ createPattern(image, repetition) {
171
+ return this._ctx.createPattern(image, repetition);
172
+ }
173
+ measureText(text) {
174
+ const textMetrics = this._ctx.measureText(text);
175
+ return textMetrics;
176
+ }
177
+ fillText(text, x, y, maxWidth) {
178
+ if (maxWidth !== undefined) {
179
+ return this._ctx.fillText(text, this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(maxWidth));
180
+ }
181
+ else {
182
+ return this._ctx.fillText(text, this.$doPixelRatio(x), this.$doPixelRatio(y));
183
+ }
184
+ }
185
+ strokeText(text, x, y, maxWidth) {
186
+ if (maxWidth !== undefined) {
187
+ return this._ctx.strokeText(text, this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(maxWidth));
188
+ }
189
+ else {
190
+ return this._ctx.strokeText(text, this.$doPixelRatio(x), this.$doPixelRatio(y));
191
+ }
192
+ }
193
+ save() {
194
+ this._ctx.save();
195
+ }
196
+ restore() {
197
+ this._ctx.restore();
198
+ }
199
+ scale(ratioX, ratioY) {
200
+ this._ctx.scale(ratioX, ratioY);
201
+ }
202
+ circle(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise) {
203
+ this._ctx.ellipse(this.$doPixelRatio(x), this.$doPixelRatio(y), this.$doPixelRatio(radiusX), this.$doPixelRatio(radiusY), rotation, startAngle, endAngle, counterclockwise);
204
+ }
205
+ isPointInPath(x, y) {
206
+ return this._ctx.isPointInPath(this.$doPixelRatio(x), this.$doPixelRatio(y));
207
+ }
208
+ clip(...args) {
209
+ return this._ctx.clip(...args);
210
+ }
211
+ setTransform(a, b, c, d, e, f) {
212
+ return this._ctx.setTransform(a, b, c, d, e, f);
213
+ }
214
+ getTransform() {
215
+ return this._ctx.getTransform();
216
+ }
217
+ createLinearGradient(x0, y0, x1, y1) {
218
+ return this._ctx.createLinearGradient(this.$doPixelRatio(x0), this.$doPixelRatio(y0), this.$doPixelRatio(x1), this.$doPixelRatio(y1));
219
+ }
220
+ createRadialGradient(x0, y0, r0, x1, y1, r1) {
221
+ return this._ctx.createRadialGradient(this.$doPixelRatio(x0), this.$doPixelRatio(y0), this.$doPixelRatio(r0), this.$doPixelRatio(x1), this.$doPixelRatio(y1), this.$doPixelRatio(r1));
222
+ }
223
+ createConicGradient(startAngle, x, y) {
224
+ return this._ctx.createConicGradient(startAngle, this.$doPixelRatio(x), this.$doPixelRatio(y));
225
+ }
226
+ }
@@ -0,0 +1,6 @@
1
+ import type { Element, ElementSize, ElementSizeController, ViewScaleInfo } from '@idraw/types';
2
+ export declare function calcElementSizeController(elemSize: ElementSize, opts: {
3
+ groupQueue: Element<'group'>[];
4
+ controllerSize?: number;
5
+ viewScaleInfo: ViewScaleInfo;
6
+ }): ElementSizeController;
@@ -0,0 +1,99 @@
1
+ import { createUUID } from './uuid';
2
+ import { getCenterFromTwoPoints } from './point';
3
+ import { calcElementVertexesInGroup, calcElementVertexes } from './vertex';
4
+ function createControllerElementSizeFromCenter(center, opts) {
5
+ const { x, y } = center;
6
+ const { size, angle } = opts;
7
+ return {
8
+ x: x - size / 2,
9
+ y: y - size / 2,
10
+ w: size,
11
+ h: size,
12
+ angle
13
+ };
14
+ }
15
+ export function calcElementSizeController(elemSize, opts) {
16
+ const { groupQueue, controllerSize, viewScaleInfo } = opts;
17
+ const ctrlSize = (controllerSize && controllerSize > 0 ? controllerSize : 8) / viewScaleInfo.scale;
18
+ const { x, y, w, h, angle = 0 } = elemSize;
19
+ const ctrlGroupQueue = [
20
+ ...[
21
+ {
22
+ uuid: createUUID(),
23
+ x,
24
+ y,
25
+ w,
26
+ h,
27
+ angle,
28
+ type: 'group',
29
+ detail: { children: [] }
30
+ }
31
+ ],
32
+ ...groupQueue
33
+ ];
34
+ let totalAngle = 0;
35
+ ctrlGroupQueue.forEach(({ angle = 0 }) => {
36
+ totalAngle += angle;
37
+ });
38
+ const vertexes = calcElementVertexesInGroup(elemSize, { groupQueue });
39
+ const topCenter = getCenterFromTwoPoints(vertexes[0], vertexes[1]);
40
+ const rightCenter = getCenterFromTwoPoints(vertexes[1], vertexes[2]);
41
+ const bottomCenter = getCenterFromTwoPoints(vertexes[2], vertexes[3]);
42
+ const leftCenter = getCenterFromTwoPoints(vertexes[3], vertexes[0]);
43
+ const topLeftCenter = vertexes[0];
44
+ const topRightCenter = vertexes[1];
45
+ const bottomRightCenter = vertexes[2];
46
+ const bottomLeftCenter = vertexes[3];
47
+ const topSize = createControllerElementSizeFromCenter(topCenter, { size: ctrlSize, angle: totalAngle });
48
+ const rightSize = createControllerElementSizeFromCenter(rightCenter, { size: ctrlSize, angle: totalAngle });
49
+ const bottomSize = createControllerElementSizeFromCenter(bottomCenter, { size: ctrlSize, angle: totalAngle });
50
+ const leftSize = createControllerElementSizeFromCenter(leftCenter, { size: ctrlSize, angle: totalAngle });
51
+ const topLeftSize = createControllerElementSizeFromCenter(topLeftCenter, { size: ctrlSize, angle: totalAngle });
52
+ const topRightSize = createControllerElementSizeFromCenter(topRightCenter, { size: ctrlSize, angle: totalAngle });
53
+ const bottomLeftSize = createControllerElementSizeFromCenter(bottomLeftCenter, { size: ctrlSize, angle: totalAngle });
54
+ const bottomRightSize = createControllerElementSizeFromCenter(bottomRightCenter, { size: ctrlSize, angle: totalAngle });
55
+ const sizeController = {
56
+ elementWrapper: vertexes,
57
+ left: {
58
+ type: 'left',
59
+ vertexes: calcElementVertexes(leftSize),
60
+ center: leftCenter
61
+ },
62
+ right: {
63
+ type: 'right',
64
+ vertexes: calcElementVertexes(rightSize),
65
+ center: rightCenter
66
+ },
67
+ top: {
68
+ type: 'top',
69
+ vertexes: calcElementVertexes(topSize),
70
+ center: topCenter
71
+ },
72
+ bottom: {
73
+ type: 'bottom',
74
+ vertexes: calcElementVertexes(bottomSize),
75
+ center: bottomCenter
76
+ },
77
+ topLeft: {
78
+ type: 'top-left',
79
+ vertexes: calcElementVertexes(topLeftSize),
80
+ center: topLeftCenter
81
+ },
82
+ topRight: {
83
+ type: 'top-right',
84
+ vertexes: calcElementVertexes(topRightSize),
85
+ center: topRightCenter
86
+ },
87
+ bottomLeft: {
88
+ type: 'bottom-left',
89
+ vertexes: calcElementVertexes(bottomLeftSize),
90
+ center: bottomLeftCenter
91
+ },
92
+ bottomRight: {
93
+ type: 'bottom-right',
94
+ vertexes: calcElementVertexes(bottomRightSize),
95
+ center: bottomRightCenter
96
+ }
97
+ };
98
+ return sizeController;
99
+ }
@@ -1 +1,5 @@
1
- export declare function deepClone(target: any): any;
1
+ import type { Data } from '@idraw/types';
2
+ export declare function deepClone<T extends any = any>(target: T): T;
3
+ export declare function sortDataAsserts(data: Data, opts?: {
4
+ clone?: boolean;
5
+ }): Data;
@@ -1,3 +1,4 @@
1
+ import { createAssetId } from './uuid';
1
2
  export function deepClone(target) {
2
3
  function _clone(t) {
3
4
  const type = is(t);
@@ -17,11 +18,75 @@ export function deepClone(target) {
17
18
  keys.forEach((key) => {
18
19
  obj[key] = _clone(t[key]);
19
20
  });
21
+ const symbolKeys = Object.getOwnPropertySymbols(t);
22
+ symbolKeys.forEach((key) => {
23
+ obj[key] = _clone(t[key]);
24
+ });
20
25
  return obj;
21
26
  }
22
27
  }
23
28
  return _clone(target);
24
29
  }
25
- function is(data) {
26
- return Object.prototype.toString.call(data).replace(/[\]|\[]{1,1}/ig, '').split(' ')[1];
30
+ function is(target) {
31
+ return Object.prototype.toString
32
+ .call(target)
33
+ .replace(/[\]|\[]{1,1}/gi, '')
34
+ .split(' ')[1];
35
+ }
36
+ export function sortDataAsserts(data, opts) {
37
+ const assets = data.assets || {};
38
+ let sortedData = data;
39
+ if ((opts === null || opts === void 0 ? void 0 : opts.clone) === true) {
40
+ sortedData = deepClone(data);
41
+ }
42
+ const _scanElements = (elems) => {
43
+ elems.forEach((elem) => {
44
+ if (elem.type === 'image' && elem.detail.src) {
45
+ const src = elem.detail.src;
46
+ const assetUUID = createAssetId(src);
47
+ if (!assets[assetUUID]) {
48
+ assets[assetUUID] = {
49
+ type: 'image',
50
+ value: src
51
+ };
52
+ }
53
+ elem.detail.src = assetUUID;
54
+ }
55
+ else if (elem.type === 'svg') {
56
+ const svg = elem.detail.svg;
57
+ const assetUUID = createAssetId(svg);
58
+ if (!assets[assetUUID]) {
59
+ assets[assetUUID] = {
60
+ type: 'svg',
61
+ value: svg
62
+ };
63
+ }
64
+ elem.detail.svg = assetUUID;
65
+ }
66
+ else if (elem.type === 'html') {
67
+ const html = elem.detail.html;
68
+ const assetUUID = createAssetId(html);
69
+ if (!assets[assetUUID]) {
70
+ assets[assetUUID] = {
71
+ type: 'svg',
72
+ value: html
73
+ };
74
+ }
75
+ elem.detail.html = assetUUID;
76
+ }
77
+ else if (elem.type === 'group' && Array.isArray(elem.detail.children)) {
78
+ const groupAssets = elem.detail.assets || {};
79
+ Object.keys(groupAssets).forEach((assetId) => {
80
+ if (!assets[assetId]) {
81
+ assets[assetId] = groupAssets[assetId];
82
+ }
83
+ });
84
+ delete elem.detail.assets;
85
+ _scanElements(elem.detail.children);
86
+ }
87
+ });
88
+ };
89
+ _scanElements(sortedData.elements);
90
+ sortedData.assets = assets;
91
+ return sortedData;
27
92
  }
@@ -0,0 +1,18 @@
1
+ import type { Data, Element, Elements, ElementType, ViewContextSize, ViewSizeInfo, RecursivePartial } from '@idraw/types';
2
+ export declare function getSelectedElementUUIDs(data: Data, indexes: Array<number | string>): string[];
3
+ export declare function validateElements(elements: Array<Element<ElementType>>): boolean;
4
+ export declare function calcElementsContextSize(elements: Array<Element<ElementType>>, opts?: {
5
+ viewWidth: number;
6
+ viewHeight: number;
7
+ extend?: boolean;
8
+ }): ViewContextSize;
9
+ export declare function calcElementsViewInfo(elements: Array<Element<ElementType>>, prevViewSize: ViewSizeInfo, options?: {
10
+ extend: boolean;
11
+ }): {
12
+ contextSize: ViewContextSize;
13
+ };
14
+ export declare function getElemenetsAssetIds(elements: Elements): string[];
15
+ export declare function findElementFromList(uuid: string, list: Element<ElementType>[]): Element<ElementType> | null;
16
+ export declare function findElementsFromList(uuids: string[], list: Element<ElementType>[]): Element<ElementType>[];
17
+ export declare function getGroupQueueFromList(uuid: string, elements: Element<ElementType>[]): Element<'group'>[];
18
+ export declare function updateElementInList(uuid: string, updateContent: RecursivePartial<Element<ElementType>>, elements: Element<ElementType>[]): Element<ElementType>[];
@@ -0,0 +1,241 @@
1
+ import { rotateElementVertexes } from './rotate';
2
+ import { isAssetId } from './uuid';
3
+ function getGroupUUIDs(elements, index) {
4
+ var _a;
5
+ const uuids = [];
6
+ if (typeof index === 'string' && /^\d+(\.\d+)*$/.test(index)) {
7
+ const nums = index.split('.');
8
+ let target = elements;
9
+ while (nums.length > 0) {
10
+ const num = nums.shift();
11
+ if (typeof num === 'string') {
12
+ const elem = target[parseInt(num)];
13
+ if (elem && nums.length === 0) {
14
+ uuids.push(elem.uuid);
15
+ }
16
+ else if (elem.type === 'group' && nums.length > 0) {
17
+ target = ((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children) || [];
18
+ }
19
+ }
20
+ break;
21
+ }
22
+ }
23
+ return uuids;
24
+ }
25
+ export function getSelectedElementUUIDs(data, indexes) {
26
+ var _a;
27
+ let uuids = [];
28
+ if (Array.isArray(data === null || data === void 0 ? void 0 : data.elements) && ((_a = data === null || data === void 0 ? void 0 : data.elements) === null || _a === void 0 ? void 0 : _a.length) > 0 && Array.isArray(indexes) && indexes.length > 0) {
29
+ indexes.forEach((idx) => {
30
+ var _a;
31
+ if (typeof idx === 'number') {
32
+ if ((_a = data === null || data === void 0 ? void 0 : data.elements) === null || _a === void 0 ? void 0 : _a[idx]) {
33
+ uuids.push(data.elements[idx].uuid);
34
+ }
35
+ }
36
+ else if (typeof idx === 'string') {
37
+ uuids = uuids.concat(getGroupUUIDs(data.elements, idx));
38
+ }
39
+ });
40
+ }
41
+ return uuids;
42
+ }
43
+ export function validateElements(elements) {
44
+ let isValid = true;
45
+ if (Array.isArray(elements)) {
46
+ const uuids = [];
47
+ elements.forEach((elem) => {
48
+ var _a;
49
+ if (typeof elem.uuid === 'string' && elem.uuid) {
50
+ if (uuids.includes(elem.uuid)) {
51
+ isValid = false;
52
+ console.warn(`Duplicate uuids: ${elem.uuid}`);
53
+ }
54
+ else {
55
+ uuids.push(elem.uuid);
56
+ }
57
+ }
58
+ else {
59
+ isValid = false;
60
+ console.warn('Element missing uuid', elem);
61
+ }
62
+ if (elem.type === 'group') {
63
+ isValid = validateElements((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children);
64
+ }
65
+ });
66
+ }
67
+ return isValid;
68
+ }
69
+ export function calcElementsContextSize(elements, opts) {
70
+ const area = { x: 0, y: 0, w: 0, h: 0 };
71
+ elements.forEach((elem) => {
72
+ const elemSize = {
73
+ x: elem.x,
74
+ y: elem.y,
75
+ w: elem.w,
76
+ h: elem.h,
77
+ angle: elem.angle
78
+ };
79
+ if (elemSize.angle && (elemSize.angle > 0 || elemSize.angle < 0)) {
80
+ const ves = rotateElementVertexes(elemSize);
81
+ if (ves.length === 4) {
82
+ const xList = [ves[0].x, ves[1].x, ves[2].x, ves[3].x];
83
+ const yList = [ves[0].y, ves[1].y, ves[2].y, ves[3].y];
84
+ elemSize.x = Math.min(...xList);
85
+ elemSize.y = Math.min(...yList);
86
+ elemSize.w = Math.abs(Math.max(...xList) - Math.min(...xList));
87
+ elemSize.h = Math.abs(Math.max(...yList) - Math.min(...yList));
88
+ }
89
+ }
90
+ const areaStartX = Math.min(elemSize.x, area.x);
91
+ const areaStartY = Math.min(elemSize.y, area.y);
92
+ const areaEndX = Math.max(elemSize.x + elemSize.w, area.x + area.w);
93
+ const areaEndY = Math.max(elemSize.y + elemSize.h, area.y + area.h);
94
+ area.x = areaStartX;
95
+ area.y = areaStartY;
96
+ area.w = Math.abs(areaEndX - areaStartX);
97
+ area.h = Math.abs(areaEndY - areaStartY);
98
+ });
99
+ if (opts === null || opts === void 0 ? void 0 : opts.extend) {
100
+ area.x = Math.min(area.x, 0);
101
+ area.y = Math.min(area.y, 0);
102
+ }
103
+ const ctxSize = {
104
+ contextWidth: area.w,
105
+ contextHeight: area.h
106
+ };
107
+ if ((opts === null || opts === void 0 ? void 0 : opts.viewWidth) && (opts === null || opts === void 0 ? void 0 : opts.viewHeight) && (opts === null || opts === void 0 ? void 0 : opts.viewWidth) > 0 && (opts === null || opts === void 0 ? void 0 : opts.viewHeight) > 0) {
108
+ if (opts.viewWidth > area.x + area.w) {
109
+ ctxSize.contextWidth = opts.viewWidth - area.x;
110
+ }
111
+ if (opts.viewHeight > area.y + area.h) {
112
+ ctxSize.contextHeight = opts.viewHeight - area.y;
113
+ }
114
+ }
115
+ return ctxSize;
116
+ }
117
+ export function calcElementsViewInfo(elements, prevViewSize, options) {
118
+ const contextSize = calcElementsContextSize(elements, { viewWidth: prevViewSize.width, viewHeight: prevViewSize.height, extend: options === null || options === void 0 ? void 0 : options.extend });
119
+ if ((options === null || options === void 0 ? void 0 : options.extend) === true) {
120
+ contextSize.contextWidth = Math.max(contextSize.contextWidth, prevViewSize.contextWidth);
121
+ contextSize.contextHeight = Math.max(contextSize.contextHeight, prevViewSize.contextHeight);
122
+ }
123
+ return {
124
+ contextSize
125
+ };
126
+ }
127
+ export function getElemenetsAssetIds(elements) {
128
+ const assetIds = [];
129
+ const _scanElements = (elems) => {
130
+ elems.forEach((elem) => {
131
+ if (elem.type === 'image' && isAssetId(elem.detail.src)) {
132
+ assetIds.push(elem.detail.src);
133
+ }
134
+ else if (elem.type === 'svg' && isAssetId(elem.detail.svg)) {
135
+ assetIds.push(elem.detail.svg);
136
+ }
137
+ else if (elem.type === 'html' && elem.detail.html) {
138
+ assetIds.push(elem.detail.html);
139
+ }
140
+ else if (elem.type === 'group' && Array.isArray(elem.detail.children)) {
141
+ _scanElements(elem.detail.children);
142
+ }
143
+ });
144
+ };
145
+ _scanElements(elements);
146
+ return assetIds;
147
+ }
148
+ export function findElementFromList(uuid, list) {
149
+ var _a;
150
+ let result = null;
151
+ for (let i = 0; i < list.length; i++) {
152
+ const elem = list[i];
153
+ if (elem.uuid === uuid) {
154
+ result = elem;
155
+ break;
156
+ }
157
+ else if (!result && elem.type === 'group') {
158
+ const resultInGroup = findElementFromList(uuid, ((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children) || []);
159
+ if ((resultInGroup === null || resultInGroup === void 0 ? void 0 : resultInGroup.uuid) === uuid) {
160
+ result = resultInGroup;
161
+ break;
162
+ }
163
+ }
164
+ }
165
+ return result;
166
+ }
167
+ export function findElementsFromList(uuids, list) {
168
+ const result = [];
169
+ function _find(elements) {
170
+ var _a;
171
+ for (let i = 0; i < elements.length; i++) {
172
+ const elem = elements[i];
173
+ if (uuids.includes(elem.uuid)) {
174
+ result.push(elem);
175
+ }
176
+ else if (elem.type === 'group') {
177
+ _find(((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children) || []);
178
+ }
179
+ }
180
+ }
181
+ _find(list);
182
+ return result;
183
+ }
184
+ export function getGroupQueueFromList(uuid, elements) {
185
+ const groupQueue = [];
186
+ function _scan(uuid, elements) {
187
+ var _a;
188
+ let result = null;
189
+ for (let i = 0; i < elements.length; i++) {
190
+ const elem = elements[i];
191
+ if (elem.uuid === uuid) {
192
+ result = elem;
193
+ break;
194
+ }
195
+ else if (!result && elem.type === 'group') {
196
+ groupQueue.push(elem);
197
+ const resultInGroup = _scan(uuid, ((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children) || []);
198
+ if ((resultInGroup === null || resultInGroup === void 0 ? void 0 : resultInGroup.uuid) === uuid) {
199
+ result = resultInGroup;
200
+ break;
201
+ }
202
+ groupQueue.pop();
203
+ }
204
+ }
205
+ return result;
206
+ }
207
+ _scan(uuid, elements);
208
+ return groupQueue;
209
+ }
210
+ function mergeElement(originElem, updateContent) {
211
+ const commonKeys = Object.keys(updateContent);
212
+ for (let i = 0; i < commonKeys.length; i++) {
213
+ const commonKey = commonKeys[i];
214
+ if (['x', 'y', 'w', 'h', 'angle', 'name'].includes(commonKey)) {
215
+ originElem[commonKey] = updateContent[commonKey];
216
+ }
217
+ else if (['detail', 'operations'].includes(commonKey)) {
218
+ if (istype.json(updateContent[commonKey]) && istype.json(originElem[commonKey])) {
219
+ originElem[commonKey] = Object.assign(Object.assign({}, originElem[commonKey]), updateContent[commonKey]);
220
+ }
221
+ else if (istype.array(updateContent[commonKey]) && istype.array(originElem[commonKey])) {
222
+ originElem[commonKey] = Object.assign(Object.assign({}, originElem[commonKey]), updateContent[commonKey]);
223
+ }
224
+ }
225
+ }
226
+ return originElem;
227
+ }
228
+ export function updateElementInList(uuid, updateContent, elements) {
229
+ var _a;
230
+ for (let i = 0; i < elements.length; i++) {
231
+ const elem = elements[i];
232
+ if (elem.uuid === uuid) {
233
+ mergeElement(elem, updateContent);
234
+ break;
235
+ }
236
+ else if (elem.type === 'group') {
237
+ updateElementInList(uuid, updateContent, ((_a = elem === null || elem === void 0 ? void 0 : elem.detail) === null || _a === void 0 ? void 0 : _a.children) || []);
238
+ }
239
+ }
240
+ return elements;
241
+ }
@@ -0,0 +1,9 @@
1
+ import type { UtilEventEmitter } from '@idraw/types';
2
+ export declare class EventEmitter<T extends Record<string, any>> implements UtilEventEmitter<T> {
3
+ private _listeners;
4
+ constructor();
5
+ on<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
6
+ off<K extends keyof T>(eventKey: K, callback: (e: T[K]) => void): void;
7
+ trigger<K extends keyof T>(eventKey: K, e: T[K]): boolean;
8
+ has<K extends keyof T>(name: K | string): boolean;
9
+ }