@idraw/core 0.4.0-beta.2 → 0.4.0-beta.20

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 (60) hide show
  1. package/dist/esm/config.d.ts +1 -0
  2. package/dist/esm/config.js +1 -0
  3. package/dist/esm/index.d.ts +17 -5
  4. package/dist/esm/index.js +35 -10
  5. package/dist/esm/lib/cursor-image.d.ts +3 -0
  6. package/dist/esm/lib/cursor-image.js +3 -0
  7. package/dist/esm/lib/cursor.d.ts +3 -12
  8. package/dist/esm/lib/cursor.js +138 -106
  9. package/dist/esm/middleware/dragger/index.d.ts +7 -0
  10. package/dist/esm/middleware/dragger/index.js +43 -0
  11. package/dist/esm/middleware/info/draw-info.d.ts +31 -0
  12. package/dist/esm/middleware/info/draw-info.js +110 -0
  13. package/dist/esm/middleware/info/index.d.ts +3 -0
  14. package/dist/esm/middleware/info/index.js +110 -0
  15. package/dist/esm/middleware/info/types.d.ts +3 -0
  16. package/dist/esm/middleware/info/types.js +1 -0
  17. package/dist/esm/middleware/layout-selector/config.d.ts +6 -0
  18. package/dist/esm/middleware/layout-selector/config.js +6 -0
  19. package/dist/esm/middleware/layout-selector/index.d.ts +3 -0
  20. package/dist/esm/middleware/layout-selector/index.js +251 -0
  21. package/dist/esm/middleware/layout-selector/types.d.ts +12 -0
  22. package/dist/esm/middleware/layout-selector/types.js +2 -0
  23. package/dist/esm/middleware/layout-selector/util.d.ts +5 -0
  24. package/dist/esm/middleware/layout-selector/util.js +93 -0
  25. package/dist/esm/middleware/ruler/index.d.ts +3 -2
  26. package/dist/esm/middleware/ruler/index.js +13 -8
  27. package/dist/esm/middleware/ruler/types.d.ts +3 -0
  28. package/dist/esm/middleware/ruler/types.js +1 -0
  29. package/dist/esm/middleware/ruler/util.d.ts +6 -1
  30. package/dist/esm/middleware/ruler/util.js +55 -1
  31. package/dist/esm/middleware/scaler/index.d.ts +2 -2
  32. package/dist/esm/middleware/scaler/index.js +1 -3
  33. package/dist/esm/middleware/scroller/index.d.ts +2 -1
  34. package/dist/esm/middleware/scroller/index.js +5 -5
  35. package/dist/esm/middleware/scroller/types.d.ts +9 -0
  36. package/dist/esm/middleware/scroller/types.js +1 -0
  37. package/dist/esm/middleware/scroller/util.js +1 -1
  38. package/dist/esm/middleware/selector/config.d.ts +12 -0
  39. package/dist/esm/middleware/selector/config.js +12 -0
  40. package/dist/esm/middleware/selector/draw-auxiliary.d.ts +7 -0
  41. package/dist/esm/middleware/selector/draw-auxiliary.js +46 -0
  42. package/dist/esm/middleware/selector/draw-base.d.ts +30 -0
  43. package/dist/esm/middleware/selector/draw-base.js +100 -0
  44. package/dist/esm/middleware/selector/draw-reference.d.ts +5 -0
  45. package/dist/esm/middleware/selector/draw-reference.js +31 -0
  46. package/dist/esm/middleware/selector/draw-wrapper.d.ts +9 -1
  47. package/dist/esm/middleware/selector/draw-wrapper.js +34 -26
  48. package/dist/esm/middleware/selector/index.d.ts +7 -4
  49. package/dist/esm/middleware/selector/index.js +275 -68
  50. package/dist/esm/middleware/selector/reference.d.ts +13 -0
  51. package/dist/esm/middleware/selector/reference.js +273 -0
  52. package/dist/esm/middleware/selector/types.d.ts +8 -4
  53. package/dist/esm/middleware/selector/types.js +1 -1
  54. package/dist/esm/middleware/selector/util.d.ts +11 -2
  55. package/dist/esm/middleware/selector/util.js +36 -14
  56. package/dist/esm/middleware/text-editor/index.d.ts +20 -2
  57. package/dist/esm/middleware/text-editor/index.js +79 -17
  58. package/dist/index.global.js +3477 -1066
  59. package/dist/index.global.min.js +1 -1
  60. package/package.json +5 -5
@@ -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, 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, keyEnableSelectInGroup, 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;
@@ -8,7 +7,7 @@ export type ControllerStyle = ElementSize & {
8
7
  background: string;
9
8
  };
10
9
  export type SelectedElementSizeController = Record<string, ControllerStyle>;
11
- export type ResizeType = 'resize-left' | 'resize-right' | 'resize-top' | 'resize-bottom' | 'resize-top-left' | 'resize-top-right' | 'resize-bottom-left' | 'resize-bottom-right';
10
+ export type ResizeType = 'resize-left' | 'resize-right' | 'resize-top' | 'resize-bottom' | 'resize-top-left' | 'resize-top-right' | 'resize-bottom-left' | 'resize-bottom-right' | 'resize-rotate';
12
11
  export type PointTargetType = null | ResizeType | 'list-area' | 'over-element';
13
12
  export interface PointTarget {
14
13
  type: PointTargetType;
@@ -31,6 +30,11 @@ 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[]>;
36
+ [keyIsMoving]: boolean | null;
37
+ [keyEnableSelectInGroup]: boolean | null;
34
38
  [keyDebugElemCenter]: PointSize | null;
35
39
  [keyDebugEnd0]: PointSize | null;
36
40
  [keyDebugEndHorizontal]: PointSize | null;
@@ -1 +1 @@
1
- import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, 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, keyEnableSelectInGroup, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
@@ -1,5 +1,5 @@
1
- import type { ViewRectVertexes, ElementSizeController, StoreSharer } from '@idraw/types';
2
- import type { Data, Element, ViewContext2D, Point, PointSize, PointTarget, ViewScaleInfo, ViewCalculator, ElementType, ElementSize, ResizeType, AreaSize, ViewSizeInfo } from './types';
1
+ import type { ViewRectVertexes, ElementSizeController, StoreSharer, ViewScaleInfo, ViewSizeInfo } from '@idraw/types';
2
+ import type { Data, Element, ViewContext2D, Point, PointSize, PointTarget, ViewCalculator, ElementType, ElementSize, ResizeType, AreaSize } from './types';
3
3
  export declare function isPointInViewActiveVertexes(p: PointSize, opts: {
4
4
  ctx: ViewContext2D;
5
5
  vertexes: ViewRectVertexes;
@@ -30,6 +30,15 @@ export declare function resizeElement(elem: Element<ElementType>, opts: {
30
30
  scale: number;
31
31
  sharer: StoreSharer;
32
32
  }): ElementSize;
33
+ export declare function rotateElement(elem: Element<ElementType>, opts: {
34
+ center: PointSize;
35
+ start: PointSize;
36
+ end: PointSize;
37
+ resizeType: ResizeType;
38
+ viewScaleInfo: ViewScaleInfo;
39
+ viewSizeInfo: ViewSizeInfo;
40
+ sharer: StoreSharer;
41
+ }): ElementSize;
33
42
  export declare function getSelectedListArea(data: Data, opts: {
34
43
  start: Point;
35
44
  end: Point;
@@ -1,4 +1,4 @@
1
- import { calcElementCenter, rotateElementVertexes, calcElementVertexesInGroup, calcElementQueueVertexesQueueInGroup, calcViewPointSize, rotatePointInGroup, rotatePoint, parseAngleToRadian, limitAngle } 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);
@@ -49,8 +49,8 @@ export function getPointTarget(p, opts) {
49
49
  };
50
50
  const { ctx, data, calculator, selectedElements, viewScaleInfo, viewSizeInfo, areaSize, groupQueue, selectedElementController } = opts;
51
51
  if (selectedElementController) {
52
- const { left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight } = selectedElementController;
53
- const ctrls = [left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight];
52
+ const { left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate } = selectedElementController;
53
+ const ctrls = [left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate];
54
54
  for (let i = 0; i < ctrls.length; i++) {
55
55
  const ctrl = ctrls[i];
56
56
  if (isPointInViewActiveVertexes(p, { ctx, vertexes: ctrl.vertexes, viewSizeInfo, viewScaleInfo })) {
@@ -671,11 +671,29 @@ export function resizeElement(elem, opts) {
671
671
  }
672
672
  return { x, y, w, h, angle: elem.angle };
673
673
  }
674
+ export function rotateElement(elem, opts) {
675
+ const { x, y, w, h, angle = 0 } = elem;
676
+ const { center, start, end, viewScaleInfo } = opts;
677
+ const elemCenter = calcViewPointSize(center, {
678
+ viewScaleInfo
679
+ });
680
+ const startAngle = limitAngle(angle);
681
+ const changedRadian = calcRadian(elemCenter, start, end);
682
+ const endAngle = startAngle + parseRadianToAngle(changedRadian);
683
+ return {
684
+ x,
685
+ y,
686
+ w,
687
+ h,
688
+ angle: endAngle
689
+ };
690
+ }
674
691
  export function getSelectedListArea(data, opts) {
692
+ var _a;
675
693
  const indexes = [];
676
694
  const uuids = [];
677
695
  const elements = [];
678
- const { calculator, viewScaleInfo, viewSizeInfo, start, end } = opts;
696
+ const { viewScaleInfo, viewSizeInfo, start, end } = opts;
679
697
  if (!(Array.isArray(data.elements) && start && end)) {
680
698
  return { indexes, uuids, elements };
681
699
  }
@@ -683,8 +701,12 @@ export function getSelectedListArea(data, opts) {
683
701
  const endX = Math.max(start.x, end.x);
684
702
  const startY = Math.min(start.y, end.y);
685
703
  const endY = Math.max(start.y, end.y);
686
- data.elements.forEach((elem, idx) => {
687
- const elemSize = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
704
+ for (let idx = 0; idx < data.elements.length; idx++) {
705
+ const elem = data.elements[idx];
706
+ if (((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.lock) === true) {
707
+ continue;
708
+ }
709
+ const elemSize = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
688
710
  const center = calcElementCenter(elemSize);
689
711
  if (center.x >= startX && center.x <= endX && center.y >= startY && center.y <= endY) {
690
712
  indexes.push(idx);
@@ -702,7 +724,7 @@ export function getSelectedListArea(data, opts) {
702
724
  }
703
725
  }
704
726
  }
705
- });
727
+ }
706
728
  return { indexes, uuids, elements };
707
729
  }
708
730
  export function calcSelectedElementsArea(elements, opts) {
@@ -711,14 +733,14 @@ export function calcSelectedElementsArea(elements, opts) {
711
733
  return null;
712
734
  }
713
735
  const area = { x: 0, y: 0, w: 0, h: 0 };
714
- const { calculator, viewScaleInfo, viewSizeInfo } = opts;
736
+ const { viewScaleInfo, viewSizeInfo } = opts;
715
737
  let prevElemSize = null;
716
738
  for (let i = 0; i < elements.length; i++) {
717
739
  const elem = elements[i];
718
740
  if ((_a = elem === null || elem === void 0 ? void 0 : elem.operations) === null || _a === void 0 ? void 0 : _a.invisible) {
719
741
  continue;
720
742
  }
721
- const elemSize = calculator.elementSize(elem, viewScaleInfo, viewSizeInfo);
743
+ const elemSize = calcViewElementSize(elem, { viewScaleInfo, viewSizeInfo });
722
744
  if (elemSize.angle && (elemSize.angle > 0 || elemSize.angle < 0)) {
723
745
  const ves = rotateElementVertexes(elemSize);
724
746
  if (ves.length === 4) {
@@ -1,3 +1,21 @@
1
- import type { BoardMiddleware, CoreEvent } from '@idraw/types';
1
+ import type { BoardMiddleware, CoreEventMap, Element, ViewScaleInfo, ElementPosition } from '@idraw/types';
2
2
  export declare const middlewareEventTextEdit = "@middleware/text-edit";
3
- export declare const MiddlewareTextEditor: BoardMiddleware<Record<string, any>, CoreEvent>;
3
+ export declare const middlewareEventTextChange = "@middleware/text-change";
4
+ type TextEditEvent = {
5
+ element: Element<'text'>;
6
+ position: ElementPosition;
7
+ groupQueue: Element<'group'>[];
8
+ viewScaleInfo: ViewScaleInfo;
9
+ };
10
+ type TextChangeEvent = {
11
+ element: {
12
+ uuid: string;
13
+ detail: {
14
+ text: string;
15
+ };
16
+ };
17
+ position: ElementPosition;
18
+ };
19
+ type ExtendEventMap = Record<typeof middlewareEventTextEdit, TextEditEvent> & Record<typeof middlewareEventTextChange, TextChangeEvent>;
20
+ export declare const MiddlewareTextEditor: BoardMiddleware<ExtendEventMap, CoreEventMap & ExtendEventMap>;
21
+ export {};
@@ -1,15 +1,17 @@
1
1
  import { limitAngle, getDefaultElementDetailConfig } from '@idraw/util';
2
2
  export const middlewareEventTextEdit = '@middleware/text-edit';
3
+ export const middlewareEventTextChange = '@middleware/text-change';
3
4
  const defaultElementDetail = getDefaultElementDetailConfig();
4
5
  export const MiddlewareTextEditor = (opts) => {
5
- const key = 'SELECT';
6
- const { eventHub, viewContent, viewer } = opts;
7
- const canvas = viewContent.boardContext.canvas;
8
- const textarea = document.createElement('textarea');
6
+ const { eventHub, boardContent, viewer } = opts;
7
+ const canvas = boardContent.boardContext.canvas;
8
+ const textarea = document.createElement('div');
9
+ textarea.setAttribute('contenteditable', 'true');
9
10
  const canvasWrapper = document.createElement('div');
10
11
  const container = opts.container || document.body;
11
12
  const mask = document.createElement('div');
12
13
  let activeElem = null;
14
+ let activePosition = [];
13
15
  canvasWrapper.appendChild(textarea);
14
16
  canvasWrapper.style.position = 'absolute';
15
17
  mask.appendChild(canvasWrapper);
@@ -28,6 +30,7 @@ export const MiddlewareTextEditor = (opts) => {
28
30
  const hideTextArea = () => {
29
31
  mask.style.display = 'none';
30
32
  activeElem = null;
33
+ activePosition = [];
31
34
  };
32
35
  const getCanvasRect = () => {
33
36
  const clientRect = canvas.getBoundingClientRect();
@@ -85,11 +88,28 @@ export const MiddlewareTextEditor = (opts) => {
85
88
  elemW = element.w * scale;
86
89
  elemH = element.h * scale;
87
90
  }
91
+ let justifyContent = 'center';
92
+ let alignItems = 'center';
93
+ if (detail.textAlign === 'left') {
94
+ justifyContent = 'start';
95
+ }
96
+ else if (detail.textAlign === 'right') {
97
+ justifyContent = 'end';
98
+ }
99
+ if (detail.verticalAlign === 'top') {
100
+ alignItems = 'start';
101
+ }
102
+ else if (detail.verticalAlign === 'bottom') {
103
+ alignItems = 'end';
104
+ }
105
+ textarea.style.display = 'inline-flex';
106
+ textarea.style.justifyContent = justifyContent;
107
+ textarea.style.alignItems = alignItems;
88
108
  textarea.style.position = 'absolute';
89
- textarea.style.left = `${elemX}px`;
90
- textarea.style.top = `${elemY}px`;
91
- textarea.style.width = `${elemW}px`;
92
- textarea.style.height = `${elemH}px`;
109
+ textarea.style.left = `${elemX - 1}px`;
110
+ textarea.style.top = `${elemY - 1}px`;
111
+ textarea.style.width = `${elemW + 2}px`;
112
+ textarea.style.height = `${elemH + 2}px`;
93
113
  textarea.style.transform = `rotate(${limitAngle(element.angle || 0)}deg)`;
94
114
  textarea.style.boxSizing = 'border-box';
95
115
  textarea.style.border = '1px solid #1973ba';
@@ -102,7 +122,10 @@ export const MiddlewareTextEditor = (opts) => {
102
122
  textarea.style.lineHeight = `${detail.lineHeight * scale}px`;
103
123
  textarea.style.fontFamily = detail.fontFamily;
104
124
  textarea.style.fontWeight = `${detail.fontWeight}`;
105
- textarea.value = detail.text || '';
125
+ textarea.style.padding = '0';
126
+ textarea.style.margin = '0';
127
+ textarea.style.outline = 'none';
128
+ textarea.innerText = detail.text || '';
106
129
  parent.appendChild(textarea);
107
130
  };
108
131
  const resetCanvasWrapper = () => {
@@ -120,24 +143,63 @@ export const MiddlewareTextEditor = (opts) => {
120
143
  textarea.addEventListener('click', (e) => {
121
144
  e.stopPropagation();
122
145
  });
123
- textarea.addEventListener('input', (e) => {
124
- if (activeElem) {
125
- activeElem.detail.text = e.target.value || '';
146
+ textarea.addEventListener('input', () => {
147
+ if (activeElem && activePosition) {
148
+ activeElem.detail.text = textarea.innerText || '';
149
+ eventHub.trigger(middlewareEventTextChange, {
150
+ element: {
151
+ uuid: activeElem.uuid,
152
+ detail: {
153
+ text: activeElem.detail.text
154
+ }
155
+ },
156
+ position: [...(activePosition || [])]
157
+ });
126
158
  viewer.drawFrame();
127
159
  }
128
160
  });
129
161
  textarea.addEventListener('blur', () => {
162
+ if (activeElem && activePosition) {
163
+ eventHub.trigger(middlewareEventTextChange, {
164
+ element: {
165
+ uuid: activeElem.uuid,
166
+ detail: {
167
+ text: activeElem.detail.text
168
+ }
169
+ },
170
+ position: [...activePosition]
171
+ });
172
+ }
130
173
  hideTextArea();
131
174
  });
132
- eventHub.on(middlewareEventTextEdit, (e) => {
175
+ textarea.addEventListener('keydown', (e) => {
176
+ e.stopPropagation();
177
+ });
178
+ textarea.addEventListener('keypress', (e) => {
179
+ e.stopPropagation();
180
+ });
181
+ textarea.addEventListener('keyup', (e) => {
182
+ e.stopPropagation();
183
+ });
184
+ textarea.addEventListener('wheel', (e) => {
185
+ e.stopPropagation();
186
+ e.preventDefault();
187
+ });
188
+ const textEditCallback = (e) => {
133
189
  var _a;
134
- if ((e === null || e === void 0 ? void 0 : e.element) && ((_a = e === null || e === void 0 ? void 0 : e.element) === null || _a === void 0 ? void 0 : _a.type) === 'text') {
190
+ if ((e === null || e === void 0 ? void 0 : e.position) && (e === null || e === void 0 ? void 0 : e.element) && ((_a = e === null || e === void 0 ? void 0 : e.element) === null || _a === void 0 ? void 0 : _a.type) === 'text') {
135
191
  activeElem = e.element;
192
+ activePosition = e.position;
136
193
  }
137
194
  showTextArea(e);
138
- });
195
+ };
139
196
  return {
140
- mode: key,
141
- isDefault: true
197
+ name: '@middleware/text-editor',
198
+ use() {
199
+ eventHub.on(middlewareEventTextEdit, textEditCallback);
200
+ },
201
+ disuse() {
202
+ eventHub.off(middlewareEventTextEdit, textEditCallback);
203
+ }
142
204
  };
143
205
  };