@idraw/core 0.4.0-beta.16 → 0.4.0-beta.17

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.
@@ -0,0 +1,273 @@
1
+ import { is } from '@idraw/util';
2
+ const unitSize = 2;
3
+ function getViewBoxInfo(rectInfo) {
4
+ const boxInfo = {
5
+ minX: rectInfo.topLeft.x,
6
+ minY: rectInfo.topLeft.y,
7
+ maxX: rectInfo.bottomRight.x,
8
+ maxY: rectInfo.bottomRight.y,
9
+ midX: rectInfo.center.x,
10
+ midY: rectInfo.center.y
11
+ };
12
+ return boxInfo;
13
+ }
14
+ const getClosestNumInSortedKeys = (sortedKeys, target) => {
15
+ if (sortedKeys.length === 0) {
16
+ throw null;
17
+ }
18
+ if (sortedKeys.length === 1) {
19
+ return sortedKeys[0];
20
+ }
21
+ let left = 0;
22
+ let right = sortedKeys.length - 1;
23
+ while (left <= right) {
24
+ const mid = Math.floor((left + right) / 2);
25
+ if (sortedKeys[mid] === target) {
26
+ return sortedKeys[mid];
27
+ }
28
+ else if (sortedKeys[mid] < target) {
29
+ left = mid + 1;
30
+ }
31
+ else {
32
+ right = mid - 1;
33
+ }
34
+ }
35
+ if (left >= sortedKeys.length) {
36
+ return sortedKeys[right];
37
+ }
38
+ if (right < 0) {
39
+ return sortedKeys[left];
40
+ }
41
+ return Math.abs(sortedKeys[right] - target) <= Math.abs(sortedKeys[left] - target) ? sortedKeys[right] : sortedKeys[left];
42
+ };
43
+ const isEqualNum = (a, b) => Math.abs(a - b) < 0.00001;
44
+ export function calcReferenceInfo(uuid, opts) {
45
+ var _a, _b;
46
+ const { data, groupQueue, calculator, viewScaleInfo, viewSizeInfo } = opts;
47
+ let targetElements = data.elements || [];
48
+ if ((groupQueue === null || groupQueue === void 0 ? void 0 : groupQueue.length) > 0) {
49
+ targetElements = ((_b = (_a = groupQueue[groupQueue.length - 1]) === null || _a === void 0 ? void 0 : _a.detail) === null || _b === void 0 ? void 0 : _b.children) || [];
50
+ }
51
+ const siblingViewRectInfoList = [];
52
+ targetElements.forEach((elem) => {
53
+ if (elem.uuid !== uuid) {
54
+ const info = calculator.calcViewRectInfoFromRange(elem.uuid, { checkVisible: true, viewScaleInfo, viewSizeInfo });
55
+ if (info) {
56
+ siblingViewRectInfoList.push(info);
57
+ }
58
+ }
59
+ });
60
+ const targetRectInfo = calculator.calcViewRectInfoFromRange(uuid, { viewScaleInfo, viewSizeInfo });
61
+ if (!targetRectInfo) {
62
+ return null;
63
+ }
64
+ const vTargetLineDotMap = {};
65
+ const hTargetLineDotMap = {};
66
+ const vRefLineDotMap = {};
67
+ const hRefLineDotMap = {};
68
+ const vHelperLineDotMapList = [];
69
+ const hHelperLineDotMapList = [];
70
+ let sortedRefXKeys = [];
71
+ let sortedRefYKeys = [];
72
+ const targetBox = getViewBoxInfo(targetRectInfo);
73
+ vTargetLineDotMap[targetBox.minX] = [targetBox.minY, targetBox.midY, targetBox.maxY];
74
+ vTargetLineDotMap[targetBox.midX] = [targetBox.minY, targetBox.midY, targetBox.maxY];
75
+ vTargetLineDotMap[targetBox.maxX] = [targetBox.minY, targetBox.midY, targetBox.maxY];
76
+ hTargetLineDotMap[targetBox.minY] = [targetBox.minX, targetBox.midX, targetBox.maxX];
77
+ hTargetLineDotMap[targetBox.midY] = [targetBox.minX, targetBox.midX, targetBox.maxX];
78
+ hTargetLineDotMap[targetBox.maxY] = [targetBox.minX, targetBox.midX, targetBox.maxX];
79
+ siblingViewRectInfoList.forEach((info) => {
80
+ const box = getViewBoxInfo(info);
81
+ if (!vRefLineDotMap[box.minX]) {
82
+ vRefLineDotMap[box.minX] = [];
83
+ }
84
+ if (!vRefLineDotMap[box.midX]) {
85
+ vRefLineDotMap[box.midX] = [];
86
+ }
87
+ if (!vRefLineDotMap[box.maxX]) {
88
+ vRefLineDotMap[box.maxX] = [];
89
+ }
90
+ if (!hRefLineDotMap[box.minY]) {
91
+ hRefLineDotMap[box.minY] = [];
92
+ }
93
+ if (!hRefLineDotMap[box.midY]) {
94
+ hRefLineDotMap[box.midY] = [];
95
+ }
96
+ if (!hRefLineDotMap[box.maxY]) {
97
+ hRefLineDotMap[box.maxY] = [];
98
+ }
99
+ vRefLineDotMap[box.minX] = [box.minY, box.midY, box.maxY];
100
+ vRefLineDotMap[box.midX] = [box.minY, box.midY, box.maxY];
101
+ vRefLineDotMap[box.maxX] = [box.minY, box.midY, box.maxY];
102
+ sortedRefXKeys.push(box.minX);
103
+ sortedRefXKeys.push(box.midX);
104
+ sortedRefXKeys.push(box.maxX);
105
+ hRefLineDotMap[box.minY] = [box.minX, box.midX, box.maxX];
106
+ hRefLineDotMap[box.midY] = [box.minX, box.midX, box.maxX];
107
+ hRefLineDotMap[box.maxY] = [box.minX, box.midX, box.maxX];
108
+ sortedRefYKeys.push(box.minY);
109
+ sortedRefYKeys.push(box.midY);
110
+ sortedRefYKeys.push(box.maxY);
111
+ });
112
+ sortedRefXKeys = sortedRefXKeys.sort((a, b) => a - b);
113
+ sortedRefYKeys = sortedRefYKeys.sort((a, b) => a - b);
114
+ let offsetX = null;
115
+ let offsetY = null;
116
+ let closestMinX = null;
117
+ let closestMidX = null;
118
+ let closestMaxX = null;
119
+ let closestMinY = null;
120
+ let closestMidY = null;
121
+ let closestMaxY = null;
122
+ if (sortedRefXKeys.length > 0) {
123
+ closestMinX = getClosestNumInSortedKeys(sortedRefXKeys, targetBox.minX);
124
+ closestMidX = getClosestNumInSortedKeys(sortedRefXKeys, targetBox.midX);
125
+ closestMaxX = getClosestNumInSortedKeys(sortedRefXKeys, targetBox.maxX);
126
+ const distMinX = Math.abs(closestMinX - targetBox.minX);
127
+ const distMidX = Math.abs(closestMidX - targetBox.midX);
128
+ const distMaxX = Math.abs(closestMaxX - targetBox.maxX);
129
+ const closestXDist = Math.min(distMinX, distMidX, distMaxX);
130
+ if (closestXDist <= unitSize / viewScaleInfo.scale) {
131
+ if (isEqualNum(closestXDist, distMinX)) {
132
+ offsetX = closestMinX - targetBox.minX;
133
+ }
134
+ else if (isEqualNum(closestXDist, distMidX)) {
135
+ offsetX = closestMidX - targetBox.midX;
136
+ }
137
+ else if (isEqualNum(closestXDist, distMaxX)) {
138
+ offsetX = closestMaxX - targetBox.maxX;
139
+ }
140
+ }
141
+ }
142
+ if (sortedRefYKeys.length > 0) {
143
+ closestMinY = getClosestNumInSortedKeys(sortedRefYKeys, targetBox.minY);
144
+ closestMidY = getClosestNumInSortedKeys(sortedRefYKeys, targetBox.midY);
145
+ closestMaxY = getClosestNumInSortedKeys(sortedRefYKeys, targetBox.maxY);
146
+ const distMinY = Math.abs(closestMinY - targetBox.minY);
147
+ const distMidY = Math.abs(closestMidY - targetBox.midY);
148
+ const distMaxY = Math.abs(closestMaxY - targetBox.maxY);
149
+ const closestYDist = Math.min(distMinY, distMidY, distMaxY);
150
+ if (closestYDist <= unitSize / viewScaleInfo.scale) {
151
+ if (isEqualNum(closestYDist, distMinY)) {
152
+ offsetY = closestMinY - targetBox.minY;
153
+ }
154
+ else if (isEqualNum(closestYDist, distMidY)) {
155
+ offsetY = closestMidY - targetBox.midY;
156
+ }
157
+ else if (isEqualNum(closestYDist, distMaxY)) {
158
+ offsetY = closestMaxY - targetBox.maxY;
159
+ }
160
+ }
161
+ }
162
+ const newTargetBox = Object.assign({}, targetBox);
163
+ if (offsetX !== null) {
164
+ newTargetBox.minX += offsetX;
165
+ newTargetBox.midX += offsetX;
166
+ newTargetBox.maxX += offsetX;
167
+ }
168
+ if (offsetY !== null) {
169
+ newTargetBox.minY += offsetY;
170
+ newTargetBox.midY += offsetY;
171
+ newTargetBox.maxY += offsetY;
172
+ }
173
+ if (is.x(offsetX) && offsetX !== null && closestMinX !== null && closestMidX !== null && closestMaxX !== null) {
174
+ if (isEqualNum(offsetX, closestMinX - targetBox.minX)) {
175
+ const vLine = {
176
+ x: closestMinX,
177
+ yList: []
178
+ };
179
+ vLine.yList.push(newTargetBox.minY);
180
+ vLine.yList.push(newTargetBox.midY);
181
+ vLine.yList.push(newTargetBox.maxY);
182
+ vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMinX]) || []));
183
+ vHelperLineDotMapList.push(vLine);
184
+ }
185
+ if (isEqualNum(offsetX, closestMidX - targetBox.minX)) {
186
+ const vLine = {
187
+ x: closestMidX,
188
+ yList: []
189
+ };
190
+ vLine.yList.push(newTargetBox.minY);
191
+ vLine.yList.push(newTargetBox.midY);
192
+ vLine.yList.push(newTargetBox.maxY);
193
+ vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMidX]) || []));
194
+ vHelperLineDotMapList.push(vLine);
195
+ }
196
+ if (isEqualNum(offsetX, closestMaxX - targetBox.minX)) {
197
+ const vLine = {
198
+ x: closestMaxX,
199
+ yList: []
200
+ };
201
+ vLine.yList.push(newTargetBox.minY);
202
+ vLine.yList.push(newTargetBox.midY);
203
+ vLine.yList.push(newTargetBox.maxY);
204
+ vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMaxX]) || []));
205
+ vHelperLineDotMapList.push(vLine);
206
+ }
207
+ }
208
+ if (is.y(offsetY) && offsetY !== null && closestMinY !== null && closestMidY !== null && closestMaxY !== null) {
209
+ if (isEqualNum(offsetY, closestMinY - targetBox.minY)) {
210
+ const hLine = {
211
+ y: closestMinY,
212
+ xList: []
213
+ };
214
+ hLine.xList.push(newTargetBox.minX);
215
+ hLine.xList.push(newTargetBox.midX);
216
+ hLine.xList.push(newTargetBox.maxX);
217
+ hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMinY]) || []));
218
+ hHelperLineDotMapList.push(hLine);
219
+ }
220
+ if (isEqualNum(offsetY, closestMidY - targetBox.midY)) {
221
+ const hLine = {
222
+ y: closestMidY,
223
+ xList: []
224
+ };
225
+ hLine.xList.push(newTargetBox.minX);
226
+ hLine.xList.push(newTargetBox.midX);
227
+ hLine.xList.push(newTargetBox.maxX);
228
+ hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMinY]) || []));
229
+ hHelperLineDotMapList.push(hLine);
230
+ }
231
+ if (isEqualNum(offsetY, closestMaxY - targetBox.maxY)) {
232
+ const hLine = {
233
+ y: closestMaxY,
234
+ xList: []
235
+ };
236
+ hLine.xList.push(newTargetBox.minX);
237
+ hLine.xList.push(newTargetBox.midX);
238
+ hLine.xList.push(newTargetBox.maxX);
239
+ hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMaxY]) || []));
240
+ hHelperLineDotMapList.push(hLine);
241
+ }
242
+ }
243
+ const yLines = [];
244
+ if ((vHelperLineDotMapList === null || vHelperLineDotMapList === void 0 ? void 0 : vHelperLineDotMapList.length) > 0) {
245
+ vHelperLineDotMapList.forEach((item, i) => {
246
+ yLines.push([]);
247
+ item.yList.forEach((y) => {
248
+ yLines[i].push({
249
+ x: item.x,
250
+ y
251
+ });
252
+ });
253
+ });
254
+ }
255
+ const xLines = [];
256
+ if ((hHelperLineDotMapList === null || hHelperLineDotMapList === void 0 ? void 0 : hHelperLineDotMapList.length) > 0) {
257
+ hHelperLineDotMapList.forEach((item, i) => {
258
+ xLines.push([]);
259
+ item.xList.forEach((x) => {
260
+ xLines[i].push({
261
+ x,
262
+ y: item.y
263
+ });
264
+ });
265
+ });
266
+ }
267
+ return {
268
+ offsetX,
269
+ offsetY,
270
+ yLines,
271
+ xLines
272
+ };
273
+ }
@@ -1,6 +1,5 @@
1
- import type { ElementSizeController } from '@idraw/types';
2
- import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keyIsMoving, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
3
- import { Data, ElementSize, ElementType, Element, ViewContext2D, Point, PointSize, ViewScaleInfo, ViewSizeInfo, ViewCalculator, PointWatcherEvent, BoardMiddleware, ViewRectVertexes } from '@idraw/types';
1
+ import { Data, ElementSize, ElementType, Element, ViewContext2D, Point, PointSize, ViewScaleInfo, ViewSizeInfo, ViewCalculator, PointWatcherEvent, BoardMiddleware, ViewRectVertexes, ElementSizeController, ElementPosition } from '@idraw/types';
2
+ import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keySelectedElementPosition, keySelectedReferenceXLines, keySelectedReferenceYLines, keyIsMoving, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
4
3
  export { Data, ElementType, Element, ElementSize, ViewContext2D, Point, PointSize, ViewScaleInfo, ViewSizeInfo, ViewCalculator, PointWatcherEvent, BoardMiddleware };
5
4
  export type ControllerStyle = ElementSize & {
6
5
  borderWidth: number;
@@ -31,6 +30,9 @@ export type DeepSelectorSharedStorage = {
31
30
  [keySelectedElementList]: Array<Element<ElementType>>;
32
31
  [keySelectedElementListVertexes]: ViewRectVertexes | null;
33
32
  [keySelectedElementController]: ElementSizeController | null;
33
+ [keySelectedElementPosition]: ElementPosition;
34
+ [keySelectedReferenceXLines]: Array<PointSize[]>;
35
+ [keySelectedReferenceYLines]: Array<PointSize[]>;
34
36
  [keyIsMoving]: boolean | null;
35
37
  [keyDebugElemCenter]: PointSize | null;
36
38
  [keyDebugEnd0]: PointSize | null;
@@ -1 +1 @@
1
- import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keyIsMoving, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
1
+ import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keySelectedElementPosition, keySelectedReferenceXLines, keySelectedReferenceYLines, keyIsMoving, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
@@ -1,4 +1,4 @@
1
- import { calcElementCenter, rotateElementVertexes, calcElementVertexesInGroup, calcElementQueueVertexesQueueInGroup, calcViewPointSize, rotatePointInGroup, rotatePoint, parseAngleToRadian, parseRadianToAngle, limitAngle, calcRadian } from '@idraw/util';
1
+ import { calcElementCenter, rotateElementVertexes, calcElementVertexesInGroup, calcElementQueueVertexesQueueInGroup, calcViewPointSize, calcViewElementSize, rotatePointInGroup, rotatePoint, parseAngleToRadian, parseRadianToAngle, limitAngle, calcRadian } from '@idraw/util';
2
2
  function parseRadian(angle) {
3
3
  return (angle * Math.PI) / 180;
4
4
  }
@@ -9,11 +9,11 @@ function changeMoveDistDirect(moveDist, moveDirect) {
9
9
  return moveDirect > 0 ? Math.abs(moveDist) : 0 - Math.abs(moveDist);
10
10
  }
11
11
  export function isPointInViewActiveVertexes(p, opts) {
12
- const { ctx, viewScaleInfo, viewSizeInfo, vertexes } = opts;
13
- const v0 = calcViewPointSize(vertexes[0], { viewScaleInfo, viewSizeInfo });
14
- const v1 = calcViewPointSize(vertexes[1], { viewScaleInfo, viewSizeInfo });
15
- const v2 = calcViewPointSize(vertexes[2], { viewScaleInfo, viewSizeInfo });
16
- const v3 = calcViewPointSize(vertexes[3], { viewScaleInfo, viewSizeInfo });
12
+ const { ctx, viewScaleInfo, vertexes } = opts;
13
+ const v0 = calcViewPointSize(vertexes[0], { viewScaleInfo });
14
+ const v1 = calcViewPointSize(vertexes[1], { viewScaleInfo });
15
+ const v2 = calcViewPointSize(vertexes[2], { viewScaleInfo });
16
+ const v3 = calcViewPointSize(vertexes[3], { viewScaleInfo });
17
17
  ctx.beginPath();
18
18
  ctx.moveTo(v0.x, v0.y);
19
19
  ctx.lineTo(v1.x, v1.y);
@@ -673,10 +673,9 @@ export function resizeElement(elem, opts) {
673
673
  }
674
674
  export function rotateElement(elem, opts) {
675
675
  const { x, y, w, h, angle = 0 } = elem;
676
- const { center, start, end, viewScaleInfo, viewSizeInfo } = opts;
676
+ const { center, start, end, viewScaleInfo } = opts;
677
677
  const elemCenter = calcViewPointSize(center, {
678
- viewScaleInfo,
679
- viewSizeInfo
678
+ viewScaleInfo
680
679
  });
681
680
  const startAngle = limitAngle(angle);
682
681
  const changedRadian = calcRadian(elemCenter, start, end);
@@ -694,7 +693,7 @@ export function getSelectedListArea(data, opts) {
694
693
  const indexes = [];
695
694
  const uuids = [];
696
695
  const elements = [];
697
- const { calculator, viewScaleInfo, viewSizeInfo, start, end } = opts;
696
+ const { viewScaleInfo, viewSizeInfo, start, end } = opts;
698
697
  if (!(Array.isArray(data.elements) && start && end)) {
699
698
  return { indexes, uuids, elements };
700
699
  }
@@ -707,7 +706,7 @@ export function getSelectedListArea(data, opts) {
707
706
  if (((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.lock) === true) {
708
707
  continue;
709
708
  }
710
- const elemSize = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
709
+ const elemSize = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
711
710
  const center = calcElementCenter(elemSize);
712
711
  if (center.x >= startX && center.x <= endX && center.y >= startY && center.y <= endY) {
713
712
  indexes.push(idx);
@@ -734,14 +733,14 @@ export function calcSelectedElementsArea(elements, opts) {
734
733
  return null;
735
734
  }
736
735
  const area = { x: 0, y: 0, w: 0, h: 0 };
737
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
736
+ const { viewScaleInfo, viewSizeInfo } = opts;
738
737
  let prevElemSize = null;
739
738
  for (let i = 0; i < elements.length; i++) {
740
739
  const elem = elements[i];
741
740
  if ((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.invisible) {
742
741
  continue;
743
742
  }
744
- const elemSize = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
743
+ const elemSize = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
745
744
  if (elemSize.angle && (elemSize.angle > 0 || elemSize.angle < 0)) {
746
745
  const ves = rotateElementVertexes(elemSize);
747
746
  if (ves.length === 4) {