@idraw/util 0.3.1 → 0.4.0-alpha.2

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,205 @@
1
+ import { calcDistance } from './point';
2
+ export function parseRadianToAngle(radian) {
3
+ return (radian / Math.PI) * 180;
4
+ }
5
+ export function parseAngleToRadian(angle) {
6
+ return (angle / 180) * Math.PI;
7
+ }
8
+ export function rotateElement(ctx, elemSize, callback) {
9
+ const center = calcElementCenter(elemSize);
10
+ const radian = parseAngleToRadian(elemSize.angle || 0);
11
+ if (center && (radian > 0 || radian < 0)) {
12
+ ctx.translate(center.x, center.y);
13
+ ctx.rotate(radian);
14
+ ctx.translate(-center.x, -center.y);
15
+ }
16
+ callback(ctx);
17
+ if (center && (radian > 0 || radian < 0)) {
18
+ ctx.translate(center.x, center.y);
19
+ ctx.rotate(-radian);
20
+ ctx.translate(-center.x, -center.y);
21
+ }
22
+ }
23
+ export function calcElementCenter(elem) {
24
+ const p = {
25
+ x: elem.x + elem.w / 2,
26
+ y: elem.y + elem.h / 2
27
+ };
28
+ return p;
29
+ }
30
+ export function calcElementCenterFromVertexes(ves) {
31
+ const startX = Math.min(ves[0].x, ves[1].x, ves[2].x, ves[3].x);
32
+ const startY = Math.min(ves[0].y, ves[1].y, ves[2].y, ves[3].y);
33
+ const endX = Math.max(ves[0].x, ves[1].x, ves[2].x, ves[3].x);
34
+ const endY = Math.max(ves[0].y, ves[1].y, ves[2].y, ves[3].y);
35
+ const elemSize = {
36
+ x: startX,
37
+ y: startY,
38
+ w: endX - startX,
39
+ h: endY - startY
40
+ };
41
+ return calcElementCenter(elemSize);
42
+ }
43
+ export function calcRadian(center, start, end) {
44
+ const startAngle = calcLineRadian(center, start);
45
+ const endAngle = calcLineRadian(center, end);
46
+ if (endAngle !== null && startAngle !== null) {
47
+ if (startAngle > (Math.PI * 3) / 2 && endAngle < Math.PI / 2) {
48
+ return endAngle + (Math.PI * 2 - startAngle);
49
+ }
50
+ else if (endAngle > (Math.PI * 3) / 2 && startAngle < Math.PI / 2) {
51
+ return startAngle + (Math.PI * 2 - endAngle);
52
+ }
53
+ else {
54
+ return endAngle - startAngle;
55
+ }
56
+ }
57
+ else {
58
+ return 0;
59
+ }
60
+ }
61
+ function calcLineRadian(center, p) {
62
+ const x = p.x - center.x;
63
+ const y = p.y - center.y;
64
+ if (x === 0) {
65
+ if (y < 0) {
66
+ return 0;
67
+ }
68
+ else if (y > 0) {
69
+ return Math.PI;
70
+ }
71
+ }
72
+ else if (y === 0) {
73
+ if (x < 0) {
74
+ return (Math.PI * 3) / 2;
75
+ }
76
+ else if (x > 0) {
77
+ return Math.PI / 2;
78
+ }
79
+ }
80
+ if (x > 0 && y < 0) {
81
+ return Math.atan(Math.abs(x) / Math.abs(y));
82
+ }
83
+ else if (x > 0 && y > 0) {
84
+ return Math.PI - Math.atan(Math.abs(x) / Math.abs(y));
85
+ }
86
+ else if (x < 0 && y > 0) {
87
+ return Math.PI + Math.atan(Math.abs(x) / Math.abs(y));
88
+ }
89
+ else if (x < 0 && y < 0) {
90
+ return 2 * Math.PI - Math.atan(Math.abs(x) / Math.abs(y));
91
+ }
92
+ return 0;
93
+ }
94
+ export function rotatePoint(center, start, radian) {
95
+ const startRadian = calcLineRadian(center, start);
96
+ const rotateRadian = radian;
97
+ let endRadian = startRadian + rotateRadian;
98
+ if (endRadian > Math.PI * 2) {
99
+ endRadian = endRadian - Math.PI * 2;
100
+ }
101
+ else if (endRadian < 0 - Math.PI * 2) {
102
+ endRadian = endRadian + Math.PI * 2;
103
+ }
104
+ if (endRadian < 0) {
105
+ endRadian = endRadian + Math.PI * 2;
106
+ }
107
+ const length = calcDistance(center, start);
108
+ let x = 0;
109
+ let y = 0;
110
+ if (endRadian === 0) {
111
+ x = 0;
112
+ y = 0 - length;
113
+ }
114
+ else if (endRadian > 0 && endRadian < Math.PI / 2) {
115
+ x = Math.sin(endRadian) * length;
116
+ y = 0 - Math.cos(endRadian) * length;
117
+ }
118
+ else if (endRadian === Math.PI / 2) {
119
+ x = length;
120
+ y = 0;
121
+ }
122
+ else if (endRadian > Math.PI / 2 && endRadian < Math.PI) {
123
+ x = Math.sin(Math.PI - endRadian) * length;
124
+ y = Math.cos(Math.PI - endRadian) * length;
125
+ }
126
+ else if (endRadian === Math.PI) {
127
+ x = 0;
128
+ y = length;
129
+ }
130
+ else if (endRadian > Math.PI && endRadian < (3 / 2) * Math.PI) {
131
+ x = 0 - Math.sin(endRadian - Math.PI) * length;
132
+ y = Math.cos(endRadian - Math.PI) * length;
133
+ }
134
+ else if (endRadian === (3 / 2) * Math.PI) {
135
+ x = 0 - length;
136
+ y = 0;
137
+ }
138
+ else if (endRadian > (3 / 2) * Math.PI && endRadian < 2 * Math.PI) {
139
+ x = 0 - Math.sin(2 * Math.PI - endRadian) * length;
140
+ y = 0 - Math.cos(2 * Math.PI - endRadian) * length;
141
+ }
142
+ else if (endRadian === 2 * Math.PI) {
143
+ x = 0;
144
+ y = 0 - length;
145
+ }
146
+ x += center.x;
147
+ y += center.y;
148
+ return { x, y };
149
+ }
150
+ export function rotatePointInGroup(point, groupQueue) {
151
+ if ((groupQueue === null || groupQueue === void 0 ? void 0 : groupQueue.length) > 0) {
152
+ let resultX = point.x;
153
+ let resultY = point.y;
154
+ groupQueue.forEach((group) => {
155
+ const { x, y, w, h, angle = 0 } = group;
156
+ const center = calcElementCenter({ x, y, w, h, angle });
157
+ const temp = rotatePoint(center, { x: resultX, y: resultY }, parseAngleToRadian(angle));
158
+ resultX = temp.x;
159
+ resultY = temp.y;
160
+ });
161
+ return {
162
+ x: resultX,
163
+ y: resultY
164
+ };
165
+ }
166
+ return point;
167
+ }
168
+ export function getElementRotateVertexes(elemSize, center, angle) {
169
+ const { x, y, w, h } = elemSize;
170
+ let p1 = { x, y };
171
+ let p2 = { x: x + w, y };
172
+ let p3 = { x: x + w, y: y + h };
173
+ let p4 = { x, y: y + h };
174
+ if (angle && (angle > 0 || angle < 0)) {
175
+ const radian = parseAngleToRadian(limitAngle(angle));
176
+ p1 = rotatePoint(center, p1, radian);
177
+ p2 = rotatePoint(center, p2, radian);
178
+ p3 = rotatePoint(center, p3, radian);
179
+ p4 = rotatePoint(center, p4, radian);
180
+ }
181
+ return [p1, p2, p3, p4];
182
+ }
183
+ export function rotateElementVertexes(elemSize) {
184
+ const { angle = 0 } = elemSize;
185
+ const center = calcElementCenter(elemSize);
186
+ return getElementRotateVertexes(elemSize, center, angle);
187
+ }
188
+ export function rotateVertexes(center, ves, radian) {
189
+ return [
190
+ rotatePoint(center, { x: ves[0].x, y: ves[0].y }, radian),
191
+ rotatePoint(center, { x: ves[1].x, y: ves[1].y }, radian),
192
+ rotatePoint(center, { x: ves[2].x, y: ves[2].y }, radian),
193
+ rotatePoint(center, { x: ves[3].x, y: ves[3].y }, radian)
194
+ ];
195
+ }
196
+ export function limitAngle(angle) {
197
+ if (!(angle > 0 || angle < 0) || angle === 0) {
198
+ return 0;
199
+ }
200
+ let num = angle % 360;
201
+ if (num < 0) {
202
+ num += 360;
203
+ }
204
+ return num;
205
+ }
@@ -0,0 +1,12 @@
1
+ export declare class Store<T extends Record<string | symbol, any>> {
2
+ private _temp;
3
+ private _backUpDefaultStorage;
4
+ constructor(opts: {
5
+ defaultStorage: T;
6
+ });
7
+ set<K extends keyof T>(name: K, value: T[K]): void;
8
+ get<K extends keyof T>(name: K): T[K];
9
+ getSnapshot(): T;
10
+ clear(): void;
11
+ private _createTempStorage;
12
+ }
@@ -0,0 +1,22 @@
1
+ import { deepClone } from './data';
2
+ export class Store {
3
+ constructor(opts) {
4
+ this._backUpDefaultStorage = deepClone(opts.defaultStorage);
5
+ this._temp = this._createTempStorage();
6
+ }
7
+ set(name, value) {
8
+ this._temp[name] = value;
9
+ }
10
+ get(name) {
11
+ return this._temp[name];
12
+ }
13
+ getSnapshot() {
14
+ return deepClone(this._temp);
15
+ }
16
+ clear() {
17
+ this._temp = this._createTempStorage();
18
+ }
19
+ _createTempStorage() {
20
+ return deepClone(this._backUpDefaultStorage);
21
+ }
22
+ }
@@ -0,0 +1,10 @@
1
+ import type { SVGPathCommand, ElementSize } from '@idraw/types';
2
+ export declare function parseSVGPath(path: string): SVGPathCommand[];
3
+ export declare function generateSVGPath(commands: SVGPathCommand[]): string;
4
+ type FilterSVGPathResult = ElementSize & {
5
+ detail: {
6
+ commands: SVGPathCommand[];
7
+ };
8
+ };
9
+ export declare function filterSVGPath(commands: SVGPathCommand[]): FilterSVGPathResult;
10
+ export {};
@@ -0,0 +1,36 @@
1
+ const cmdReg = /([astvzqmhlc])([^astvzqmhlc]*)/gi;
2
+ const numReg = /(-?\d+(?:\.\d+)?)/gi;
3
+ export function parseSVGPath(path) {
4
+ const commands = [];
5
+ path.replace(cmdReg, (match, cmd, paramStr) => {
6
+ const matchParams = paramStr.match(numReg);
7
+ const params = matchParams ? matchParams.map(Number) : [];
8
+ const command = {
9
+ type: cmd,
10
+ params
11
+ };
12
+ commands.push(command);
13
+ return match;
14
+ });
15
+ return commands;
16
+ }
17
+ export function generateSVGPath(commands) {
18
+ let path = '';
19
+ commands.forEach((item) => {
20
+ path += item.type + item.params.join(' ');
21
+ });
22
+ return path;
23
+ }
24
+ export function filterSVGPath(commands) {
25
+ const filteredCommands = [];
26
+ const result = {
27
+ x: 0,
28
+ y: 0,
29
+ h: 0,
30
+ w: 0,
31
+ detail: {
32
+ commands: filteredCommands
33
+ }
34
+ };
35
+ return result;
36
+ }
@@ -1 +1,3 @@
1
1
  export declare function createUUID(): string;
2
+ export declare function createAssetId(assetStr: string): string;
3
+ export declare function isAssetId(id: any | string): boolean;
@@ -1,6 +1,31 @@
1
1
  export function createUUID() {
2
- function str4() {
2
+ function _createStr() {
3
3
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
4
4
  }
5
- return `${str4()}${str4()}-${str4()}-${str4()}-${str4()}-${str4()}${str4()}${str4()}`;
5
+ return `${_createStr()}${_createStr()}-${_createStr()}-${_createStr()}-${_createStr()}-${_createStr()}${_createStr()}${_createStr()}`;
6
+ }
7
+ function limitHexStr(str) {
8
+ let count = 0;
9
+ for (let i = 0; i < str.length; i++) {
10
+ count += str.charCodeAt(i) * str.charCodeAt(i) * i * i;
11
+ }
12
+ return count.toString(16).substring(0, 4);
13
+ }
14
+ export function createAssetId(assetStr) {
15
+ const len = assetStr.length;
16
+ const mid = Math.floor(len / 2);
17
+ const start4 = assetStr.substring(0, 4).padEnd(4, '0');
18
+ const end4 = assetStr.substring(0, 4).padEnd(4, '0');
19
+ const str1 = limitHexStr(len.toString(16).padEnd(4, start4));
20
+ const str2 = limitHexStr(assetStr.substring(mid - 4, mid).padEnd(4, start4)).padEnd(4, 'f');
21
+ const str3 = limitHexStr(assetStr.substring(mid - 8, mid - 4).padEnd(4, start4)).padEnd(4, 'f');
22
+ const str4 = limitHexStr(assetStr.substring(mid - 12, mid - 8).padEnd(4, start4)).padEnd(4, 'f');
23
+ const str5 = limitHexStr(assetStr.substring(mid - 16, mid - 12).padEnd(4, end4)).padEnd(4, 'f');
24
+ const str6 = limitHexStr(assetStr.substring(mid, mid + 4).padEnd(4, end4)).padEnd(4, 'f');
25
+ const str7 = limitHexStr(assetStr.substring(mid + 4, mid + 8).padEnd(4, end4)).padEnd(4, 'f');
26
+ const str8 = limitHexStr(end4.padEnd(4, start4).padEnd(4, end4));
27
+ return `@assets/${str1}${str2}-${str3}-${str4}-${str5}-${str6}${str7}${str8}`;
28
+ }
29
+ export function isAssetId(id) {
30
+ return /^@assets\/[0-9a-z]{8,8}\-[0-9a-z]{4,4}\-[0-9a-z]{4,4}\-[0-9a-z]{4,4}\-[0-9a-z]{12,12}$/.test(`${id}`);
6
31
  }
@@ -0,0 +1,10 @@
1
+ import { Element, ElementSize, ViewRectVertexes } from '@idraw/types';
2
+ export declare function getElementVertexes(elemSize: ElementSize): ViewRectVertexes;
3
+ export declare function calcElementVertexes(elemSize: ElementSize): ViewRectVertexes;
4
+ export declare function calcElementQueueVertexesQueueInGroup(groupQueue: ElementSize[]): ViewRectVertexes[];
5
+ export declare function calcElementVertexesQueueInGroup(targetElem: ElementSize, opts: {
6
+ groupQueue: Element<'group'>[];
7
+ }): ViewRectVertexes[];
8
+ export declare function calcElementVertexesInGroup(targetElem: ElementSize, opts: {
9
+ groupQueue: Element<'group'>[];
10
+ }): ViewRectVertexes | null;
@@ -0,0 +1,73 @@
1
+ import { getElementRotateVertexes, calcElementCenter, parseAngleToRadian, rotateVertexes, calcElementCenterFromVertexes } from './rotate';
2
+ export function getElementVertexes(elemSize) {
3
+ const { x, y, h, w } = elemSize;
4
+ return [
5
+ { x, y },
6
+ { x: x + w, y },
7
+ { x: x + w, y: y + h },
8
+ { x, y: y + h }
9
+ ];
10
+ }
11
+ export function calcElementVertexes(elemSize) {
12
+ const { x, y, w, h, angle = 0 } = elemSize;
13
+ if (angle === 0) {
14
+ return getElementVertexes(elemSize);
15
+ }
16
+ return getElementRotateVertexes(elemSize, calcElementCenter({ x, y, w, h, angle }), angle);
17
+ }
18
+ export function calcElementQueueVertexesQueueInGroup(groupQueue) {
19
+ const vesList = [];
20
+ let totalX = 0;
21
+ let totalY = 0;
22
+ const rotateActionList = [];
23
+ const elemQueue = [...groupQueue];
24
+ for (let i = 0; i < elemQueue.length; i++) {
25
+ const { x, y, w, h, angle = 0 } = elemQueue[i];
26
+ totalX += x;
27
+ totalY += y;
28
+ let ves;
29
+ if (i === 0) {
30
+ const elemSize = { x: totalX, y: totalY, w, h, angle };
31
+ ves = calcElementVertexes({ x, y, w, h, angle });
32
+ rotateActionList.push({
33
+ center: calcElementCenter(elemSize),
34
+ angle,
35
+ radian: parseAngleToRadian(angle)
36
+ });
37
+ }
38
+ else {
39
+ const elemSize = { x: totalX, y: totalY, w, h, angle };
40
+ ves = getElementVertexes(elemSize);
41
+ for (let aIdx = 0; aIdx < rotateActionList.length; aIdx++) {
42
+ const { center, radian } = rotateActionList[aIdx];
43
+ ves = rotateVertexes(center, ves, radian);
44
+ }
45
+ const vesCenter = calcElementCenterFromVertexes(ves);
46
+ if (angle > 0 || angle < 0) {
47
+ const radian = parseAngleToRadian(angle);
48
+ ves = rotateVertexes(vesCenter, ves, radian);
49
+ }
50
+ rotateActionList.push({
51
+ center: vesCenter,
52
+ angle,
53
+ radian: parseAngleToRadian(angle)
54
+ });
55
+ }
56
+ vesList.push(ves);
57
+ }
58
+ return vesList;
59
+ }
60
+ export function calcElementVertexesQueueInGroup(targetElem, opts) {
61
+ const { groupQueue } = opts;
62
+ if (!(groupQueue.length > 0)) {
63
+ return [calcElementVertexes(targetElem)];
64
+ }
65
+ const elemQueue = [...groupQueue, ...[targetElem]];
66
+ const vesList = calcElementQueueVertexesQueueInGroup(elemQueue);
67
+ return vesList;
68
+ }
69
+ export function calcElementVertexesInGroup(targetElem, opts) {
70
+ const vesList = calcElementVertexesQueueInGroup(targetElem, opts);
71
+ const ves = vesList.pop();
72
+ return ves || null;
73
+ }
@@ -0,0 +1,49 @@
1
+ import { Point, PointSize, Data, ViewScaleInfo, ViewSizeInfo, Element, ElementType, ElementSize, ViewContext2D, ViewRectVertexes } from '@idraw/types';
2
+ export declare function viewScale(opts: {
3
+ scale: number;
4
+ point: PointSize;
5
+ viewScaleInfo: ViewScaleInfo;
6
+ viewSizeInfo: ViewSizeInfo;
7
+ }): {
8
+ moveX: number;
9
+ moveY: number;
10
+ };
11
+ export declare function viewScroll(opts: {
12
+ moveX?: number;
13
+ moveY?: number;
14
+ viewScaleInfo: ViewScaleInfo;
15
+ viewSizeInfo: ViewSizeInfo;
16
+ }): ViewScaleInfo;
17
+ export declare function calcViewElementSize(size: ElementSize, opts: {
18
+ viewScaleInfo: ViewScaleInfo;
19
+ viewSizeInfo: ViewSizeInfo;
20
+ }): ElementSize;
21
+ export declare function calcViewPointSize(size: PointSize, opts: {
22
+ viewScaleInfo: ViewScaleInfo;
23
+ viewSizeInfo: ViewSizeInfo;
24
+ }): PointSize;
25
+ export declare function calcViewVertexes(vertexes: ViewRectVertexes, opts: {
26
+ viewScaleInfo: ViewScaleInfo;
27
+ viewSizeInfo: ViewSizeInfo;
28
+ }): ViewRectVertexes;
29
+ export declare function isViewPointInElement(p: Point, opts: {
30
+ context2d: ViewContext2D;
31
+ element: ElementSize;
32
+ viewScaleInfo: ViewScaleInfo;
33
+ viewSizeInfo: ViewSizeInfo;
34
+ }): boolean;
35
+ export declare function getViewPointAtElement(p: Point, opts: {
36
+ context2d: ViewContext2D;
37
+ data: Data;
38
+ viewScaleInfo: ViewScaleInfo;
39
+ viewSizeInfo: ViewSizeInfo;
40
+ groupQueue?: Element<'group'>[];
41
+ }): {
42
+ index: number;
43
+ element: null | Element<ElementType>;
44
+ groupQueueIndex: number;
45
+ };
46
+ export declare function isElementInView(elem: ElementSize, opts: {
47
+ viewScaleInfo: ViewScaleInfo;
48
+ viewSizeInfo: ViewSizeInfo;
49
+ }): boolean;
@@ -0,0 +1,167 @@
1
+ import { rotateElementVertexes } from './rotate';
2
+ import { checkRectIntersect } from './rect';
3
+ export function viewScale(opts) {
4
+ const { scale, point, viewScaleInfo: prevViewScaleInfo } = opts;
5
+ const { offsetLeft, offsetTop } = prevViewScaleInfo;
6
+ const scaleDiff = scale / prevViewScaleInfo.scale;
7
+ const x0 = point.x;
8
+ const y0 = point.y;
9
+ const moveX = x0 - x0 * scaleDiff + (offsetLeft * scaleDiff - offsetLeft);
10
+ const moveY = y0 - y0 * scaleDiff + (offsetTop * scaleDiff - offsetTop);
11
+ return {
12
+ moveX,
13
+ moveY
14
+ };
15
+ }
16
+ export function viewScroll(opts) {
17
+ const { moveX = 0, moveY = 0, viewScaleInfo, viewSizeInfo } = opts;
18
+ const { scale } = viewScaleInfo;
19
+ const { width, height, contextWidth, contextHeight } = viewSizeInfo;
20
+ let offsetLeft = viewScaleInfo.offsetLeft;
21
+ let offsetRight = viewScaleInfo.offsetRight;
22
+ let offsetTop = viewScaleInfo.offsetTop;
23
+ let offsetBottom = viewScaleInfo.offsetBottom;
24
+ offsetLeft += moveX;
25
+ offsetTop += moveY;
26
+ const w = contextWidth * scale;
27
+ const h = contextHeight * scale;
28
+ offsetRight = width - (w + offsetLeft);
29
+ offsetBottom = height - (h + offsetTop);
30
+ return {
31
+ scale,
32
+ offsetTop,
33
+ offsetLeft,
34
+ offsetRight,
35
+ offsetBottom
36
+ };
37
+ }
38
+ export function calcViewElementSize(size, opts) {
39
+ const { viewScaleInfo } = opts;
40
+ const { x, y, w, h, angle } = size;
41
+ const { scale, offsetTop, offsetLeft } = viewScaleInfo;
42
+ const newSize = {
43
+ x: x * scale + offsetLeft,
44
+ y: y * scale + offsetTop,
45
+ w: w * scale,
46
+ h: h * scale,
47
+ angle
48
+ };
49
+ return newSize;
50
+ }
51
+ export function calcViewPointSize(size, opts) {
52
+ const { viewScaleInfo } = opts;
53
+ const { x, y } = size;
54
+ const { scale, offsetTop, offsetLeft } = viewScaleInfo;
55
+ const newSize = {
56
+ x: x * scale + offsetLeft,
57
+ y: y * scale + offsetTop
58
+ };
59
+ return newSize;
60
+ }
61
+ export function calcViewVertexes(vertexes, opts) {
62
+ return [
63
+ calcViewPointSize(vertexes[0], opts),
64
+ calcViewPointSize(vertexes[1], opts),
65
+ calcViewPointSize(vertexes[2], opts),
66
+ calcViewPointSize(vertexes[3], opts)
67
+ ];
68
+ }
69
+ export function isViewPointInElement(p, opts) {
70
+ const { context2d: ctx, element: elem, viewScaleInfo, viewSizeInfo } = opts;
71
+ const { angle = 0 } = elem;
72
+ const { x, y, w, h } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
73
+ const vertexes = rotateElementVertexes({ x, y, w, h, angle });
74
+ if (vertexes.length >= 2) {
75
+ ctx.beginPath();
76
+ ctx.moveTo(vertexes[0].x, vertexes[0].y);
77
+ for (let i = 1; i < vertexes.length; i++) {
78
+ ctx.lineTo(vertexes[i].x, vertexes[i].y);
79
+ }
80
+ ctx.closePath();
81
+ }
82
+ if (ctx.isPointInPath(p.x, p.y)) {
83
+ return true;
84
+ }
85
+ return false;
86
+ }
87
+ export function getViewPointAtElement(p, opts) {
88
+ var _a, _b, _c;
89
+ const { context2d: ctx, data, viewScaleInfo, viewSizeInfo, groupQueue } = opts;
90
+ const result = {
91
+ index: -1,
92
+ element: null,
93
+ groupQueueIndex: -1
94
+ };
95
+ if (groupQueue && Array.isArray(groupQueue) && (groupQueue === null || groupQueue === void 0 ? void 0 : groupQueue.length) > 0) {
96
+ for (let gIdx = groupQueue.length - 1; gIdx >= 0; gIdx--) {
97
+ let totalX = 0;
98
+ let totalY = 0;
99
+ let totalAngle = 0;
100
+ for (let i = 0; i <= gIdx; i++) {
101
+ totalX += groupQueue[i].x;
102
+ totalY += groupQueue[i].y;
103
+ totalAngle += groupQueue[i].angle || 0;
104
+ }
105
+ const lastGroup = groupQueue[gIdx];
106
+ if (lastGroup && lastGroup.type === 'group' && Array.isArray((_a = lastGroup.detail) === null || _a === void 0 ? void 0 : _a.children)) {
107
+ for (let i = 0; i < lastGroup.detail.children.length; i++) {
108
+ const child = lastGroup.detail.children[i];
109
+ if (((_b = child === null || child === void 0 ? void 0 : child.operations) === null || _b === void 0 ? void 0 : _b.invisible) === true) {
110
+ continue;
111
+ }
112
+ if (child) {
113
+ const elemSize = {
114
+ x: totalX + child.x,
115
+ y: totalY + child.y,
116
+ w: child.w,
117
+ h: child.h,
118
+ angle: totalAngle + (child.angle || 0)
119
+ };
120
+ if (isViewPointInElement(p, { context2d: ctx, element: elemSize, viewScaleInfo, viewSizeInfo })) {
121
+ result.element = child;
122
+ if (gIdx < groupQueue.length - 1 || child.type !== 'group') {
123
+ result.groupQueueIndex = gIdx;
124
+ }
125
+ break;
126
+ }
127
+ }
128
+ else {
129
+ break;
130
+ }
131
+ }
132
+ }
133
+ if (result.element) {
134
+ break;
135
+ }
136
+ }
137
+ }
138
+ if (result.element) {
139
+ return result;
140
+ }
141
+ for (let i = data.elements.length - 1; i >= 0; i--) {
142
+ const elem = data.elements[i];
143
+ if (((_c = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _c === void 0 ? void 0 : _c.invisible) === true) {
144
+ continue;
145
+ }
146
+ if (isViewPointInElement(p, { context2d: ctx, element: elem, viewScaleInfo, viewSizeInfo })) {
147
+ result.index = i;
148
+ result.element = elem;
149
+ break;
150
+ }
151
+ }
152
+ return result;
153
+ }
154
+ export function isElementInView(elem, opts) {
155
+ const { viewSizeInfo, viewScaleInfo } = opts;
156
+ const { width, height } = viewSizeInfo;
157
+ const { angle } = elem;
158
+ const { x, y, w, h } = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
159
+ const ves = rotateElementVertexes({ x, y, w, h, angle });
160
+ const viewSize = { x: 0, y: 0, w: width, h: height };
161
+ const elemStartX = Math.min(ves[0].x, ves[1].x, ves[2].x, ves[3].x);
162
+ const elemStartY = Math.min(ves[0].y, ves[1].y, ves[2].y, ves[3].y);
163
+ const elemEndX = Math.max(ves[0].x, ves[1].x, ves[2].x, ves[3].x);
164
+ const elemEndY = Math.max(ves[0].y, ves[1].y, ves[2].y, ves[3].y);
165
+ const elemSize = { x: elemStartX, y: elemStartY, w: elemEndX - elemStartX, h: elemEndY - elemStartY };
166
+ return checkRectIntersect(viewSize, elemSize);
167
+ }