@idraw/core 0.4.0-beta.3 → 0.4.0-beta.30
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.
- package/dist/esm/config.d.ts +1 -0
- package/dist/esm/config.js +1 -0
- package/dist/esm/index.d.ts +15 -5
- package/dist/esm/index.js +29 -8
- package/dist/esm/lib/cursor-image.d.ts +1 -0
- package/dist/esm/lib/cursor-image.js +1 -0
- package/dist/esm/lib/cursor.d.ts +3 -12
- package/dist/esm/lib/cursor.js +136 -112
- package/dist/esm/middleware/dragger/index.d.ts +2 -2
- package/dist/esm/middleware/dragger/index.js +1 -0
- package/dist/esm/middleware/info/draw-info.d.ts +31 -0
- package/dist/esm/middleware/info/draw-info.js +110 -0
- package/dist/esm/middleware/info/index.d.ts +3 -0
- package/dist/esm/middleware/info/index.js +110 -0
- package/dist/esm/middleware/info/types.d.ts +3 -0
- package/dist/esm/middleware/info/types.js +1 -0
- package/dist/esm/middleware/layout-selector/config.d.ts +9 -0
- package/dist/esm/middleware/layout-selector/config.js +9 -0
- package/dist/esm/middleware/layout-selector/index.d.ts +5 -0
- package/dist/esm/middleware/layout-selector/index.js +332 -0
- package/dist/esm/middleware/layout-selector/types.d.ts +15 -0
- package/dist/esm/middleware/layout-selector/types.js +2 -0
- package/dist/esm/middleware/layout-selector/util.d.ts +8 -0
- package/dist/esm/middleware/layout-selector/util.js +108 -0
- package/dist/esm/middleware/ruler/index.d.ts +3 -2
- package/dist/esm/middleware/ruler/index.js +12 -9
- package/dist/esm/middleware/ruler/types.d.ts +3 -0
- package/dist/esm/middleware/ruler/types.js +1 -0
- package/dist/esm/middleware/ruler/util.d.ts +15 -4
- package/dist/esm/middleware/ruler/util.js +81 -4
- package/dist/esm/middleware/scaler/index.d.ts +2 -2
- package/dist/esm/middleware/scaler/index.js +1 -0
- package/dist/esm/middleware/scroller/config.d.ts +2 -0
- package/dist/esm/middleware/scroller/config.js +2 -0
- package/dist/esm/middleware/scroller/index.d.ts +2 -1
- package/dist/esm/middleware/scroller/index.js +33 -5
- package/dist/esm/middleware/scroller/types.d.ts +11 -0
- package/dist/esm/middleware/scroller/types.js +1 -0
- package/dist/esm/middleware/scroller/util.d.ts +1 -1
- package/dist/esm/middleware/scroller/util.js +22 -17
- package/dist/esm/middleware/selector/config.d.ts +12 -0
- package/dist/esm/middleware/selector/config.js +12 -0
- package/dist/esm/middleware/selector/draw-auxiliary.d.ts +7 -0
- package/dist/esm/middleware/selector/draw-auxiliary.js +46 -0
- package/dist/esm/middleware/selector/draw-base.d.ts +30 -0
- package/dist/esm/middleware/selector/draw-base.js +100 -0
- package/dist/esm/middleware/selector/draw-reference.d.ts +5 -0
- package/dist/esm/middleware/selector/draw-reference.js +31 -0
- package/dist/esm/middleware/selector/draw-wrapper.d.ts +9 -1
- package/dist/esm/middleware/selector/draw-wrapper.js +34 -26
- package/dist/esm/middleware/selector/index.d.ts +7 -4
- package/dist/esm/middleware/selector/index.js +280 -45
- package/dist/esm/middleware/selector/reference.d.ts +13 -0
- package/dist/esm/middleware/selector/reference.js +267 -0
- package/dist/esm/middleware/selector/types.d.ts +9 -4
- package/dist/esm/middleware/selector/types.js +2 -1
- package/dist/esm/middleware/selector/util.d.ts +11 -2
- package/dist/esm/middleware/selector/util.js +36 -14
- package/dist/esm/middleware/text-editor/index.d.ts +20 -2
- package/dist/esm/middleware/text-editor/index.js +92 -16
- package/dist/index.global.js +3685 -953
- package/dist/index.global.min.js +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,267 @@
|
|
|
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.maxY);
|
|
181
|
+
vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMinX]) || []));
|
|
182
|
+
vHelperLineDotMapList.push(vLine);
|
|
183
|
+
}
|
|
184
|
+
if (isEqualNum(offsetX, closestMidX - targetBox.minX)) {
|
|
185
|
+
const vLine = {
|
|
186
|
+
x: closestMidX,
|
|
187
|
+
yList: []
|
|
188
|
+
};
|
|
189
|
+
vLine.yList.push(newTargetBox.minY);
|
|
190
|
+
vLine.yList.push(newTargetBox.maxY);
|
|
191
|
+
vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMidX]) || []));
|
|
192
|
+
vHelperLineDotMapList.push(vLine);
|
|
193
|
+
}
|
|
194
|
+
if (isEqualNum(offsetX, closestMaxX - targetBox.minX)) {
|
|
195
|
+
const vLine = {
|
|
196
|
+
x: closestMaxX,
|
|
197
|
+
yList: []
|
|
198
|
+
};
|
|
199
|
+
vLine.yList.push(newTargetBox.minY);
|
|
200
|
+
vLine.yList.push(newTargetBox.maxY);
|
|
201
|
+
vLine.yList.push(...((hRefLineDotMap === null || hRefLineDotMap === void 0 ? void 0 : hRefLineDotMap[closestMaxX]) || []));
|
|
202
|
+
vHelperLineDotMapList.push(vLine);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (is.y(offsetY) && offsetY !== null && closestMinY !== null && closestMidY !== null && closestMaxY !== null) {
|
|
206
|
+
if (isEqualNum(offsetY, closestMinY - targetBox.minY)) {
|
|
207
|
+
const hLine = {
|
|
208
|
+
y: closestMinY,
|
|
209
|
+
xList: []
|
|
210
|
+
};
|
|
211
|
+
hLine.xList.push(newTargetBox.minX);
|
|
212
|
+
hLine.xList.push(newTargetBox.maxX);
|
|
213
|
+
hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMinY]) || []));
|
|
214
|
+
hHelperLineDotMapList.push(hLine);
|
|
215
|
+
}
|
|
216
|
+
if (isEqualNum(offsetY, closestMidY - targetBox.midY)) {
|
|
217
|
+
const hLine = {
|
|
218
|
+
y: closestMidY,
|
|
219
|
+
xList: []
|
|
220
|
+
};
|
|
221
|
+
hLine.xList.push(newTargetBox.minX);
|
|
222
|
+
hLine.xList.push(newTargetBox.maxX);
|
|
223
|
+
hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMinY]) || []));
|
|
224
|
+
hHelperLineDotMapList.push(hLine);
|
|
225
|
+
}
|
|
226
|
+
if (isEqualNum(offsetY, closestMaxY - targetBox.maxY)) {
|
|
227
|
+
const hLine = {
|
|
228
|
+
y: closestMaxY,
|
|
229
|
+
xList: []
|
|
230
|
+
};
|
|
231
|
+
hLine.xList.push(newTargetBox.minX);
|
|
232
|
+
hLine.xList.push(newTargetBox.maxX);
|
|
233
|
+
hLine.xList.push(...((vRefLineDotMap === null || vRefLineDotMap === void 0 ? void 0 : vRefLineDotMap[closestMaxY]) || []));
|
|
234
|
+
hHelperLineDotMapList.push(hLine);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
const yLines = [];
|
|
238
|
+
if ((vHelperLineDotMapList === null || vHelperLineDotMapList === void 0 ? void 0 : vHelperLineDotMapList.length) > 0) {
|
|
239
|
+
vHelperLineDotMapList.forEach((item, i) => {
|
|
240
|
+
yLines.push([]);
|
|
241
|
+
item.yList.forEach((y) => {
|
|
242
|
+
yLines[i].push({
|
|
243
|
+
x: item.x,
|
|
244
|
+
y
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
const xLines = [];
|
|
250
|
+
if ((hHelperLineDotMapList === null || hHelperLineDotMapList === void 0 ? void 0 : hHelperLineDotMapList.length) > 0) {
|
|
251
|
+
hHelperLineDotMapList.forEach((item, i) => {
|
|
252
|
+
xLines.push([]);
|
|
253
|
+
item.xList.forEach((x) => {
|
|
254
|
+
xLines[i].push({
|
|
255
|
+
x,
|
|
256
|
+
y: item.y
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
offsetX,
|
|
263
|
+
offsetY,
|
|
264
|
+
yLines,
|
|
265
|
+
xLines
|
|
266
|
+
};
|
|
267
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
|
|
3
|
-
import {
|
|
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, keyIsMoving, keyEnableSelectInGroup, keyEnableSnapToGrid, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
|
|
3
|
+
import { keyLayoutIsSelected } from '../layout-selector';
|
|
4
4
|
export { Data, ElementType, Element, ElementSize, ViewContext2D, Point, PointSize, ViewScaleInfo, ViewSizeInfo, ViewCalculator, PointWatcherEvent, BoardMiddleware };
|
|
5
5
|
export type ControllerStyle = ElementSize & {
|
|
6
6
|
borderWidth: number;
|
|
@@ -8,7 +8,7 @@ export type ControllerStyle = ElementSize & {
|
|
|
8
8
|
background: string;
|
|
9
9
|
};
|
|
10
10
|
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';
|
|
11
|
+
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
12
|
export type PointTargetType = null | ResizeType | 'list-area' | 'over-element';
|
|
13
13
|
export interface PointTarget {
|
|
14
14
|
type: PointTargetType;
|
|
@@ -31,10 +31,15 @@ export type DeepSelectorSharedStorage = {
|
|
|
31
31
|
[keySelectedElementList]: Array<Element<ElementType>>;
|
|
32
32
|
[keySelectedElementListVertexes]: ViewRectVertexes | null;
|
|
33
33
|
[keySelectedElementController]: ElementSizeController | null;
|
|
34
|
+
[keySelectedElementPosition]: ElementPosition;
|
|
35
|
+
[keyIsMoving]: boolean | null;
|
|
36
|
+
[keyEnableSelectInGroup]: boolean | null;
|
|
37
|
+
[keyEnableSnapToGrid]: boolean | null;
|
|
34
38
|
[keyDebugElemCenter]: PointSize | null;
|
|
35
39
|
[keyDebugEnd0]: PointSize | null;
|
|
36
40
|
[keyDebugEndHorizontal]: PointSize | null;
|
|
37
41
|
[keyDebugEndVertical]: PointSize | null;
|
|
38
42
|
[keyDebugStartHorizontal]: PointSize | null;
|
|
39
43
|
[keyDebugStartVertical]: PointSize | null;
|
|
44
|
+
[keyLayoutIsSelected]: boolean | null;
|
|
40
45
|
};
|
|
@@ -1 +1,2 @@
|
|
|
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, keyIsMoving, keyEnableSelectInGroup, keyEnableSnapToGrid, keyDebugElemCenter, keyDebugEnd0, keyDebugEndHorizontal, keyDebugEndVertical, keyDebugStartHorizontal, keyDebugStartVertical } from './config';
|
|
2
|
+
import { keyLayoutIsSelected } from '../layout-selector';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ViewRectVertexes, ElementSizeController, StoreSharer } from '@idraw/types';
|
|
2
|
-
import type { Data, Element, ViewContext2D, Point, PointSize, PointTarget,
|
|
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,
|
|
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
|
|
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 {
|
|
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.
|
|
687
|
-
const
|
|
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 {
|
|
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 =
|
|
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,
|
|
1
|
+
import type { BoardMiddleware, CoreEventMap, Element, ViewScaleInfo, ElementPosition } from '@idraw/types';
|
|
2
2
|
export declare const middlewareEventTextEdit = "@middleware/text-edit";
|
|
3
|
-
export declare const
|
|
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,14 +1,17 @@
|
|
|
1
|
-
import { limitAngle, getDefaultElementDetailConfig } from '@idraw/util';
|
|
1
|
+
import { limitAngle, getDefaultElementDetailConfig, enhanceFontFamliy } 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 { eventHub, boardContent, viewer } = opts;
|
|
6
|
+
const { eventHub, boardContent, viewer, sharer } = opts;
|
|
6
7
|
const canvas = boardContent.boardContext.canvas;
|
|
7
|
-
const textarea = document.createElement('
|
|
8
|
+
const textarea = document.createElement('div');
|
|
9
|
+
textarea.setAttribute('contenteditable', 'true');
|
|
8
10
|
const canvasWrapper = document.createElement('div');
|
|
9
11
|
const container = opts.container || document.body;
|
|
10
12
|
const mask = document.createElement('div');
|
|
11
13
|
let activeElem = null;
|
|
14
|
+
let activePosition = [];
|
|
12
15
|
canvasWrapper.appendChild(textarea);
|
|
13
16
|
canvasWrapper.style.position = 'absolute';
|
|
14
17
|
mask.appendChild(canvasWrapper);
|
|
@@ -23,10 +26,27 @@ export const MiddlewareTextEditor = (opts) => {
|
|
|
23
26
|
resetCanvasWrapper();
|
|
24
27
|
resetTextArea(e);
|
|
25
28
|
mask.style.display = 'block';
|
|
29
|
+
if (activeElem === null || activeElem === void 0 ? void 0 : activeElem.uuid) {
|
|
30
|
+
sharer.setActiveOverrideElemenentMap({
|
|
31
|
+
[activeElem.uuid]: {
|
|
32
|
+
operations: { invisible: true }
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
viewer.drawFrame();
|
|
36
|
+
}
|
|
26
37
|
};
|
|
27
38
|
const hideTextArea = () => {
|
|
39
|
+
if (activeElem === null || activeElem === void 0 ? void 0 : activeElem.uuid) {
|
|
40
|
+
const map = sharer.getActiveOverrideElemenentMap();
|
|
41
|
+
if (map) {
|
|
42
|
+
delete map[activeElem.uuid];
|
|
43
|
+
}
|
|
44
|
+
sharer.setActiveOverrideElemenentMap(map);
|
|
45
|
+
viewer.drawFrame();
|
|
46
|
+
}
|
|
28
47
|
mask.style.display = 'none';
|
|
29
48
|
activeElem = null;
|
|
49
|
+
activePosition = [];
|
|
30
50
|
};
|
|
31
51
|
const getCanvasRect = () => {
|
|
32
52
|
const clientRect = canvas.getBoundingClientRect();
|
|
@@ -84,24 +104,45 @@ export const MiddlewareTextEditor = (opts) => {
|
|
|
84
104
|
elemW = element.w * scale;
|
|
85
105
|
elemH = element.h * scale;
|
|
86
106
|
}
|
|
107
|
+
let justifyContent = 'center';
|
|
108
|
+
let alignItems = 'center';
|
|
109
|
+
if (detail.textAlign === 'left') {
|
|
110
|
+
justifyContent = 'start';
|
|
111
|
+
}
|
|
112
|
+
else if (detail.textAlign === 'right') {
|
|
113
|
+
justifyContent = 'end';
|
|
114
|
+
}
|
|
115
|
+
if (detail.verticalAlign === 'top') {
|
|
116
|
+
alignItems = 'start';
|
|
117
|
+
}
|
|
118
|
+
else if (detail.verticalAlign === 'bottom') {
|
|
119
|
+
alignItems = 'end';
|
|
120
|
+
}
|
|
121
|
+
textarea.style.display = 'inline-flex';
|
|
122
|
+
textarea.style.justifyContent = justifyContent;
|
|
123
|
+
textarea.style.alignItems = alignItems;
|
|
87
124
|
textarea.style.position = 'absolute';
|
|
88
|
-
textarea.style.left = `${elemX}px`;
|
|
89
|
-
textarea.style.top = `${elemY}px`;
|
|
90
|
-
textarea.style.width = `${elemW}px`;
|
|
91
|
-
textarea.style.height = `${elemH}px`;
|
|
125
|
+
textarea.style.left = `${elemX - 1}px`;
|
|
126
|
+
textarea.style.top = `${elemY - 1}px`;
|
|
127
|
+
textarea.style.width = `${elemW + 2}px`;
|
|
128
|
+
textarea.style.height = `${elemH + 2}px`;
|
|
92
129
|
textarea.style.transform = `rotate(${limitAngle(element.angle || 0)}deg)`;
|
|
93
130
|
textarea.style.boxSizing = 'border-box';
|
|
94
131
|
textarea.style.border = '1px solid #1973ba';
|
|
95
132
|
textarea.style.resize = 'none';
|
|
96
133
|
textarea.style.overflow = 'hidden';
|
|
97
134
|
textarea.style.wordBreak = 'break-all';
|
|
98
|
-
textarea.style.
|
|
99
|
-
textarea.style.
|
|
135
|
+
textarea.style.borderRadius = `${(typeof detail.borderRadius === 'number' ? detail.borderRadius : 0) * scale}px`;
|
|
136
|
+
textarea.style.background = `${detail.background || 'transparent'}`;
|
|
137
|
+
textarea.style.color = `${detail.color || '#333333'}`;
|
|
100
138
|
textarea.style.fontSize = `${detail.fontSize * scale}px`;
|
|
101
|
-
textarea.style.lineHeight = `${detail.lineHeight * scale}px`;
|
|
102
|
-
textarea.style.fontFamily = detail.fontFamily;
|
|
139
|
+
textarea.style.lineHeight = `${(detail.lineHeight || detail.fontSize) * scale}px`;
|
|
140
|
+
textarea.style.fontFamily = enhanceFontFamliy(detail.fontFamily);
|
|
103
141
|
textarea.style.fontWeight = `${detail.fontWeight}`;
|
|
104
|
-
textarea.
|
|
142
|
+
textarea.style.padding = '0';
|
|
143
|
+
textarea.style.margin = '0';
|
|
144
|
+
textarea.style.outline = 'none';
|
|
145
|
+
textarea.innerText = detail.text || '';
|
|
105
146
|
parent.appendChild(textarea);
|
|
106
147
|
};
|
|
107
148
|
const resetCanvasWrapper = () => {
|
|
@@ -119,23 +160,58 @@ export const MiddlewareTextEditor = (opts) => {
|
|
|
119
160
|
textarea.addEventListener('click', (e) => {
|
|
120
161
|
e.stopPropagation();
|
|
121
162
|
});
|
|
122
|
-
textarea.addEventListener('input', (
|
|
123
|
-
if (activeElem) {
|
|
124
|
-
activeElem.detail.text =
|
|
163
|
+
textarea.addEventListener('input', () => {
|
|
164
|
+
if (activeElem && activePosition) {
|
|
165
|
+
activeElem.detail.text = textarea.innerText || '';
|
|
166
|
+
eventHub.trigger(middlewareEventTextChange, {
|
|
167
|
+
element: {
|
|
168
|
+
uuid: activeElem.uuid,
|
|
169
|
+
detail: {
|
|
170
|
+
text: activeElem.detail.text
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
position: [...(activePosition || [])]
|
|
174
|
+
});
|
|
125
175
|
viewer.drawFrame();
|
|
126
176
|
}
|
|
127
177
|
});
|
|
128
178
|
textarea.addEventListener('blur', () => {
|
|
179
|
+
if (activeElem && activePosition) {
|
|
180
|
+
eventHub.trigger(middlewareEventTextChange, {
|
|
181
|
+
element: {
|
|
182
|
+
uuid: activeElem.uuid,
|
|
183
|
+
detail: {
|
|
184
|
+
text: activeElem.detail.text
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
position: [...activePosition]
|
|
188
|
+
});
|
|
189
|
+
}
|
|
129
190
|
hideTextArea();
|
|
130
191
|
});
|
|
192
|
+
textarea.addEventListener('keydown', (e) => {
|
|
193
|
+
e.stopPropagation();
|
|
194
|
+
});
|
|
195
|
+
textarea.addEventListener('keypress', (e) => {
|
|
196
|
+
e.stopPropagation();
|
|
197
|
+
});
|
|
198
|
+
textarea.addEventListener('keyup', (e) => {
|
|
199
|
+
e.stopPropagation();
|
|
200
|
+
});
|
|
201
|
+
textarea.addEventListener('wheel', (e) => {
|
|
202
|
+
e.stopPropagation();
|
|
203
|
+
e.preventDefault();
|
|
204
|
+
});
|
|
131
205
|
const textEditCallback = (e) => {
|
|
132
206
|
var _a;
|
|
133
|
-
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') {
|
|
207
|
+
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') {
|
|
134
208
|
activeElem = e.element;
|
|
209
|
+
activePosition = e.position;
|
|
135
210
|
}
|
|
136
211
|
showTextArea(e);
|
|
137
212
|
};
|
|
138
213
|
return {
|
|
214
|
+
name: '@middleware/text-editor',
|
|
139
215
|
use() {
|
|
140
216
|
eventHub.on(middlewareEventTextEdit, textEditCallback);
|
|
141
217
|
},
|