@idraw/renderer 0.4.0-beta.9 → 0.4.0
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/README.md +2 -2
- package/dist/esm/calculator.d.ts +44 -0
- package/dist/esm/calculator.js +180 -0
- package/dist/esm/draw/box.d.ts +15 -3
- package/dist/esm/draw/box.js +93 -31
- package/dist/esm/draw/circle.js +25 -19
- package/dist/esm/draw/elements.js +1 -1
- package/dist/esm/draw/global.d.ts +2 -0
- package/dist/esm/draw/global.js +9 -0
- package/dist/esm/draw/group.js +13 -8
- package/dist/esm/draw/html.js +4 -4
- package/dist/esm/draw/image.js +48 -7
- package/dist/esm/draw/index.d.ts +3 -1
- package/dist/esm/draw/index.js +3 -1
- package/dist/esm/draw/layout.d.ts +2 -0
- package/dist/esm/draw/layout.js +44 -0
- package/dist/esm/draw/path.js +49 -8
- package/dist/esm/draw/rect.js +3 -3
- package/dist/esm/draw/svg.js +4 -4
- package/dist/esm/draw/text.js +38 -85
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.js +39 -12
- package/dist/esm/loader.d.ts +4 -1
- package/dist/esm/loader.js +85 -27
- package/dist/esm/view-visible/index.d.ts +22 -0
- package/dist/esm/view-visible/index.js +63 -0
- package/dist/esm/virtual-flat/index.d.ts +7 -0
- package/dist/esm/virtual-flat/index.js +45 -0
- package/dist/esm/virtual-flat/text.d.ts +2 -0
- package/dist/esm/virtual-flat/text.js +151 -0
- package/dist/index.global.js +1464 -344
- package/dist/index.global.min.js +1 -1
- package/package.json +4 -4
- package/dist/esm/draw/underlay.d.ts +0 -2
- package/dist/esm/draw/underlay.js +0 -23
package/dist/esm/loader.js
CHANGED
|
@@ -18,7 +18,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
18
18
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
19
19
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
20
20
|
};
|
|
21
|
-
var _Loader_instances, _Loader_loadFuncMap, _Loader_currentLoadItemMap, _Loader_storageLoadItemMap, _Loader_registerLoadFunc, _Loader_getLoadElementSource, _Loader_createLoadItem, _Loader_emitLoad, _Loader_emitError, _Loader_loadResource, _Loader_isExistingErrorStorage;
|
|
21
|
+
var _Loader_instances, _Loader_loadFuncMap, _Loader_currentLoadItemMap, _Loader_storageLoadItemMap, _Loader_hasDestroyed, _Loader_registerLoadFunc, _Loader_getLoadElementSource, _Loader_createLoadItem, _Loader_emitLoad, _Loader_emitError, _Loader_loadResource, _Loader_isExistingErrorStorage;
|
|
22
22
|
import { loadImage, loadHTML, loadSVG, EventEmitter, createAssetId, isAssetId, createUUID } from '@idraw/util';
|
|
23
23
|
const supportElementTypes = ['image', 'svg', 'html'];
|
|
24
24
|
const getAssetIdFromElement = (element) => {
|
|
@@ -37,9 +37,9 @@ const getAssetIdFromElement = (element) => {
|
|
|
37
37
|
if (isAssetId(source)) {
|
|
38
38
|
return source;
|
|
39
39
|
}
|
|
40
|
-
return createAssetId(source);
|
|
40
|
+
return createAssetId(source, element.uuid);
|
|
41
41
|
}
|
|
42
|
-
return createAssetId(`${createUUID()}-${element.uuid}-${createUUID()}-${createUUID()}
|
|
42
|
+
return createAssetId(`${createUUID()}-${element.uuid}-${createUUID()}-${createUUID()}`, element.uuid);
|
|
43
43
|
};
|
|
44
44
|
export class Loader extends EventEmitter {
|
|
45
45
|
constructor() {
|
|
@@ -48,6 +48,7 @@ export class Loader extends EventEmitter {
|
|
|
48
48
|
_Loader_loadFuncMap.set(this, {});
|
|
49
49
|
_Loader_currentLoadItemMap.set(this, {});
|
|
50
50
|
_Loader_storageLoadItemMap.set(this, {});
|
|
51
|
+
_Loader_hasDestroyed.set(this, false);
|
|
51
52
|
__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_registerLoadFunc).call(this, 'image', (elem, assets) => __awaiter(this, void 0, void 0, function* () {
|
|
52
53
|
var _a;
|
|
53
54
|
const src = ((_a = assets[elem.detail.src]) === null || _a === void 0 ? void 0 : _a.value) || elem.detail.src;
|
|
@@ -59,8 +60,8 @@ export class Loader extends EventEmitter {
|
|
|
59
60
|
};
|
|
60
61
|
}));
|
|
61
62
|
__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_registerLoadFunc).call(this, 'html', (elem, assets) => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
var
|
|
63
|
-
const html = ((
|
|
63
|
+
var _a;
|
|
64
|
+
const html = ((_a = assets[elem.detail.html]) === null || _a === void 0 ? void 0 : _a.value) || elem.detail.html;
|
|
64
65
|
const content = yield loadHTML(html, {
|
|
65
66
|
width: elem.detail.originW || elem.w,
|
|
66
67
|
height: elem.detail.originH || elem.h
|
|
@@ -72,8 +73,8 @@ export class Loader extends EventEmitter {
|
|
|
72
73
|
};
|
|
73
74
|
}));
|
|
74
75
|
__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_registerLoadFunc).call(this, 'svg', (elem, assets) => __awaiter(this, void 0, void 0, function* () {
|
|
75
|
-
var
|
|
76
|
-
const svg = ((
|
|
76
|
+
var _a;
|
|
77
|
+
const svg = ((_a = assets[elem.detail.svg]) === null || _a === void 0 ? void 0 : _a.value) || elem.detail.svg;
|
|
77
78
|
const content = yield loadSVG(svg);
|
|
78
79
|
return {
|
|
79
80
|
uuid: elem.uuid,
|
|
@@ -82,12 +83,56 @@ export class Loader extends EventEmitter {
|
|
|
82
83
|
};
|
|
83
84
|
}));
|
|
84
85
|
}
|
|
86
|
+
isDestroyed() {
|
|
87
|
+
return __classPrivateFieldGet(this, _Loader_hasDestroyed, "f");
|
|
88
|
+
}
|
|
89
|
+
reset() {
|
|
90
|
+
if (__classPrivateFieldGet(this, _Loader_hasDestroyed, "f") === true) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
__classPrivateFieldSet(this, _Loader_currentLoadItemMap, {}, "f");
|
|
94
|
+
__classPrivateFieldSet(this, _Loader_storageLoadItemMap, {}, "f");
|
|
95
|
+
}
|
|
96
|
+
resetElementAsset(element) {
|
|
97
|
+
var _a, _b, _c;
|
|
98
|
+
if (supportElementTypes.includes(element.type)) {
|
|
99
|
+
let assetId = null;
|
|
100
|
+
let resource = null;
|
|
101
|
+
if (element.type === 'image' && typeof ((_a = element === null || element === void 0 ? void 0 : element.detail) === null || _a === void 0 ? void 0 : _a.src) === 'string') {
|
|
102
|
+
resource = element.detail.src;
|
|
103
|
+
}
|
|
104
|
+
else if (element.type === 'svg' && typeof ((_b = element === null || element === void 0 ? void 0 : element.detail) === null || _b === void 0 ? void 0 : _b.svg) === 'string') {
|
|
105
|
+
resource = element.detail.svg;
|
|
106
|
+
}
|
|
107
|
+
else if (element.type === 'html' && typeof ((_c = element === null || element === void 0 ? void 0 : element.detail) === null || _c === void 0 ? void 0 : _c.html) === 'string') {
|
|
108
|
+
resource = element.detail.html;
|
|
109
|
+
}
|
|
110
|
+
if (typeof resource === 'string') {
|
|
111
|
+
this.load(element, {});
|
|
112
|
+
if (isAssetId(resource)) {
|
|
113
|
+
assetId = resource;
|
|
114
|
+
}
|
|
115
|
+
else if (element.uuid) {
|
|
116
|
+
assetId = createAssetId(resource, element.uuid);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (assetId && isAssetId(assetId)) {
|
|
120
|
+
delete __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId];
|
|
121
|
+
delete __classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")[assetId];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
85
125
|
destroy() {
|
|
126
|
+
__classPrivateFieldSet(this, _Loader_hasDestroyed, true, "f");
|
|
127
|
+
this.clear();
|
|
86
128
|
__classPrivateFieldSet(this, _Loader_loadFuncMap, null, "f");
|
|
87
129
|
__classPrivateFieldSet(this, _Loader_currentLoadItemMap, null, "f");
|
|
88
130
|
__classPrivateFieldSet(this, _Loader_storageLoadItemMap, null, "f");
|
|
89
131
|
}
|
|
90
132
|
load(element, assets) {
|
|
133
|
+
if (__classPrivateFieldGet(this, _Loader_hasDestroyed, "f") === true) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
91
136
|
if (__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_isExistingErrorStorage).call(this, element)) {
|
|
92
137
|
return;
|
|
93
138
|
}
|
|
@@ -107,7 +152,7 @@ export class Loader extends EventEmitter {
|
|
|
107
152
|
__classPrivateFieldSet(this, _Loader_storageLoadItemMap, itemMap, "f");
|
|
108
153
|
}
|
|
109
154
|
}
|
|
110
|
-
_Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(), _Loader_storageLoadItemMap = new WeakMap(), _Loader_instances = new WeakSet(), _Loader_registerLoadFunc = function _Loader_registerLoadFunc(type, func) {
|
|
155
|
+
_Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(), _Loader_storageLoadItemMap = new WeakMap(), _Loader_hasDestroyed = new WeakMap(), _Loader_instances = new WeakSet(), _Loader_registerLoadFunc = function _Loader_registerLoadFunc(type, func) {
|
|
111
156
|
__classPrivateFieldGet(this, _Loader_loadFuncMap, "f")[type] = func;
|
|
112
157
|
}, _Loader_getLoadElementSource = function _Loader_getLoadElementSource(element) {
|
|
113
158
|
var _a, _b, _c;
|
|
@@ -135,42 +180,52 @@ _Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(),
|
|
|
135
180
|
}, _Loader_emitLoad = function _Loader_emitLoad(item) {
|
|
136
181
|
const assetId = getAssetIdFromElement(item.element);
|
|
137
182
|
const storageItem = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId];
|
|
138
|
-
if (
|
|
139
|
-
if (storageItem
|
|
183
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
184
|
+
if (storageItem) {
|
|
185
|
+
if (storageItem.startTime < item.startTime) {
|
|
186
|
+
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
187
|
+
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
140
191
|
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
141
192
|
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
142
193
|
}
|
|
143
194
|
}
|
|
144
|
-
else {
|
|
145
|
-
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
146
|
-
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
147
|
-
}
|
|
148
195
|
}, _Loader_emitError = function _Loader_emitError(item) {
|
|
196
|
+
var _a;
|
|
149
197
|
const assetId = getAssetIdFromElement(item.element);
|
|
150
|
-
const storageItem = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId];
|
|
151
|
-
if (
|
|
152
|
-
if (storageItem
|
|
198
|
+
const storageItem = (_a = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")) === null || _a === void 0 ? void 0 : _a[assetId];
|
|
199
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
200
|
+
if (storageItem) {
|
|
201
|
+
if (storageItem.startTime < item.startTime) {
|
|
202
|
+
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
203
|
+
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
153
207
|
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
154
208
|
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
155
209
|
}
|
|
156
210
|
}
|
|
157
|
-
else {
|
|
158
|
-
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
159
|
-
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
160
|
-
}
|
|
161
211
|
}, _Loader_loadResource = function _Loader_loadResource(element, assets) {
|
|
162
212
|
const item = __classPrivateFieldGet(this, _Loader_instances, "m", _Loader_createLoadItem).call(this, element);
|
|
163
213
|
const assetId = getAssetIdFromElement(element);
|
|
214
|
+
if (__classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")[assetId]) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
164
217
|
__classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")[assetId] = item;
|
|
165
218
|
const loadFunc = __classPrivateFieldGet(this, _Loader_loadFuncMap, "f")[element.type];
|
|
166
|
-
if (typeof loadFunc === 'function') {
|
|
219
|
+
if (typeof loadFunc === 'function' && !__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
167
220
|
item.startTime = Date.now();
|
|
168
221
|
loadFunc(element, assets)
|
|
169
222
|
.then((result) => {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
223
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
224
|
+
item.content = result.content;
|
|
225
|
+
item.endTime = Date.now();
|
|
226
|
+
item.status = 'load';
|
|
227
|
+
__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_emitLoad).call(this, item);
|
|
228
|
+
}
|
|
174
229
|
})
|
|
175
230
|
.catch((err) => {
|
|
176
231
|
console.warn(`Load element source "${item.source}" fail`, err, element);
|
|
@@ -184,7 +239,10 @@ _Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(),
|
|
|
184
239
|
var _a;
|
|
185
240
|
const assetId = getAssetIdFromElement(element);
|
|
186
241
|
const existItem = (_a = __classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")) === null || _a === void 0 ? void 0 : _a[assetId];
|
|
187
|
-
if (existItem &&
|
|
242
|
+
if (existItem &&
|
|
243
|
+
existItem.status === 'error' &&
|
|
244
|
+
existItem.source &&
|
|
245
|
+
existItem.source === __classPrivateFieldGet(this, _Loader_instances, "m", _Loader_getLoadElementSource).call(this, element)) {
|
|
188
246
|
return true;
|
|
189
247
|
}
|
|
190
248
|
return false;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Elements, ViewScaleInfo, ViewSizeInfo, ViewRectInfo, VirtualFlatItemMap, ViewContext2D } from '@idraw/types';
|
|
2
|
+
export declare function sortElementsViewVisiableInfoMap(elements: Elements, opts: {
|
|
3
|
+
viewScaleInfo: ViewScaleInfo;
|
|
4
|
+
viewSizeInfo: ViewSizeInfo;
|
|
5
|
+
tempContext: ViewContext2D;
|
|
6
|
+
}): {
|
|
7
|
+
virtualFlatItemMap: VirtualFlatItemMap;
|
|
8
|
+
visibleCount: number;
|
|
9
|
+
invisibleCount: number;
|
|
10
|
+
};
|
|
11
|
+
export declare function updateVirtualFlatItemMapStatus(virtualFlatItemMap: VirtualFlatItemMap, opts: {
|
|
12
|
+
viewScaleInfo: ViewScaleInfo;
|
|
13
|
+
viewSizeInfo: ViewSizeInfo;
|
|
14
|
+
}): {
|
|
15
|
+
virtualFlatItemMap: VirtualFlatItemMap;
|
|
16
|
+
visibleCount: number;
|
|
17
|
+
invisibleCount: number;
|
|
18
|
+
};
|
|
19
|
+
export declare function calcVisibleOriginCanvasRectInfo(opts: {
|
|
20
|
+
viewScaleInfo: ViewScaleInfo;
|
|
21
|
+
viewSizeInfo: ViewSizeInfo;
|
|
22
|
+
}): ViewRectInfo;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { calcElementCenter } from '@idraw/util';
|
|
2
|
+
import { elementsToVirtualFlatMap } from '../virtual-flat';
|
|
3
|
+
export function sortElementsViewVisiableInfoMap(elements, opts) {
|
|
4
|
+
const { viewScaleInfo, viewSizeInfo, tempContext } = opts;
|
|
5
|
+
const visibleInfoMap = elementsToVirtualFlatMap(elements, { tempContext });
|
|
6
|
+
return updateVirtualFlatItemMapStatus(visibleInfoMap, { viewScaleInfo, viewSizeInfo });
|
|
7
|
+
}
|
|
8
|
+
function isRangeRectInfoCollide(info1, info2) {
|
|
9
|
+
const rect1MinX = Math.min(info1.topLeft.x, info1.topRight.x, info1.bottomLeft.x, info1.bottomRight.x);
|
|
10
|
+
const rect1MaxX = Math.max(info1.topLeft.x, info1.topRight.x, info1.bottomLeft.x, info1.bottomRight.x);
|
|
11
|
+
const rect1MinY = Math.min(info1.topLeft.y, info1.topRight.y, info1.bottomLeft.y, info1.bottomRight.y);
|
|
12
|
+
const rect1MaxY = Math.max(info1.topLeft.y, info1.topRight.y, info1.bottomLeft.y, info1.bottomRight.y);
|
|
13
|
+
const rect2MinX = Math.min(info2.topLeft.x, info2.topRight.x, info2.bottomLeft.x, info2.bottomRight.x);
|
|
14
|
+
const rect2MaxX = Math.max(info2.topLeft.x, info2.topRight.x, info2.bottomLeft.x, info2.bottomRight.x);
|
|
15
|
+
const rect2MinY = Math.min(info2.topLeft.y, info2.topRight.y, info2.bottomLeft.y, info2.bottomRight.y);
|
|
16
|
+
const rect2MaxY = Math.max(info2.topLeft.y, info2.topRight.y, info2.bottomLeft.y, info2.bottomRight.y);
|
|
17
|
+
if ((rect1MinX <= rect2MaxX && rect1MaxX >= rect2MinX && rect1MinY <= rect2MaxY && rect1MaxY >= rect2MinY) ||
|
|
18
|
+
(rect2MaxX <= rect1MaxY && rect2MaxX >= rect1MaxY && rect2MaxX <= rect1MaxY && rect2MaxX >= rect1MaxY)) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
export function updateVirtualFlatItemMapStatus(virtualFlatItemMap, opts) {
|
|
24
|
+
const canvasRectInfo = calcVisibleOriginCanvasRectInfo(opts);
|
|
25
|
+
let visibleCount = 0;
|
|
26
|
+
let invisibleCount = 0;
|
|
27
|
+
Object.keys(virtualFlatItemMap).forEach((uuid) => {
|
|
28
|
+
const info = virtualFlatItemMap[uuid];
|
|
29
|
+
info.isVisibleInView = isRangeRectInfoCollide(info.rangeRectInfo, canvasRectInfo);
|
|
30
|
+
info.isVisibleInView ? visibleCount++ : invisibleCount++;
|
|
31
|
+
});
|
|
32
|
+
return { virtualFlatItemMap, visibleCount, invisibleCount };
|
|
33
|
+
}
|
|
34
|
+
export function calcVisibleOriginCanvasRectInfo(opts) {
|
|
35
|
+
const { viewScaleInfo, viewSizeInfo } = opts;
|
|
36
|
+
const { scale, offsetTop, offsetLeft } = viewScaleInfo;
|
|
37
|
+
const { width, height } = viewSizeInfo;
|
|
38
|
+
const x = 0 - offsetLeft / scale;
|
|
39
|
+
const y = 0 - offsetTop / scale;
|
|
40
|
+
const w = width / scale;
|
|
41
|
+
const h = height / scale;
|
|
42
|
+
const center = calcElementCenter({ x, y, w, h });
|
|
43
|
+
const topLeft = { x, y };
|
|
44
|
+
const topRight = { x: x + w, y };
|
|
45
|
+
const bottomLeft = { x, y: y + h };
|
|
46
|
+
const bottomRight = { x: x + w, y: y + h };
|
|
47
|
+
const left = { x, y: center.y };
|
|
48
|
+
const top = { x: center.x, y };
|
|
49
|
+
const right = { x: x + w, y: center.y };
|
|
50
|
+
const bottom = { x: center.x, y: y + h };
|
|
51
|
+
const rectInfo = {
|
|
52
|
+
center,
|
|
53
|
+
topLeft,
|
|
54
|
+
topRight,
|
|
55
|
+
bottomLeft,
|
|
56
|
+
bottomRight,
|
|
57
|
+
left,
|
|
58
|
+
top,
|
|
59
|
+
right,
|
|
60
|
+
bottom
|
|
61
|
+
};
|
|
62
|
+
return rectInfo;
|
|
63
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Element, Elements, VirtualFlatItemMap, VirtualFlatDetail, ViewContext2D } from '@idraw/types';
|
|
2
|
+
export declare function calcVirtualFlatDetail(elem: Element, opts: {
|
|
3
|
+
tempContext: ViewContext2D;
|
|
4
|
+
}): VirtualFlatDetail;
|
|
5
|
+
export declare function elementsToVirtualFlatMap(elements: Elements, opts: {
|
|
6
|
+
tempContext: ViewContext2D;
|
|
7
|
+
}): VirtualFlatItemMap;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { is, getGroupQueueByElementPosition, calcElementOriginRectInfo, originRectInfoToRangeRectInfo } from '@idraw/util';
|
|
2
|
+
import { calcVirtualTextDetail } from './text';
|
|
3
|
+
export function calcVirtualFlatDetail(elem, opts) {
|
|
4
|
+
let virtualDetail = {};
|
|
5
|
+
if (elem.type === 'text') {
|
|
6
|
+
virtualDetail = calcVirtualTextDetail(elem, opts);
|
|
7
|
+
}
|
|
8
|
+
return virtualDetail;
|
|
9
|
+
}
|
|
10
|
+
export function elementsToVirtualFlatMap(elements, opts) {
|
|
11
|
+
const virtualFlatMap = {};
|
|
12
|
+
const currentPosition = [];
|
|
13
|
+
const _walk = (elem) => {
|
|
14
|
+
const baseInfo = {
|
|
15
|
+
type: elem.type,
|
|
16
|
+
isVisibleInView: true,
|
|
17
|
+
position: [...currentPosition]
|
|
18
|
+
};
|
|
19
|
+
let originRectInfo = null;
|
|
20
|
+
const groupQueue = getGroupQueueByElementPosition(elements, currentPosition);
|
|
21
|
+
originRectInfo = calcElementOriginRectInfo(elem, {
|
|
22
|
+
groupQueue: groupQueue || []
|
|
23
|
+
});
|
|
24
|
+
const virtualItem = Object.assign(Object.assign(Object.assign({}, baseInfo), {
|
|
25
|
+
originRectInfo: originRectInfo,
|
|
26
|
+
rangeRectInfo: is.angle(elem.angle)
|
|
27
|
+
? originRectInfoToRangeRectInfo(originRectInfo)
|
|
28
|
+
: originRectInfo
|
|
29
|
+
}), calcVirtualFlatDetail(elem, opts));
|
|
30
|
+
virtualFlatMap[elem.uuid] = virtualItem;
|
|
31
|
+
if (elem.type === 'group') {
|
|
32
|
+
elem.detail.children.forEach((ele, i) => {
|
|
33
|
+
currentPosition.push(i);
|
|
34
|
+
_walk(ele);
|
|
35
|
+
currentPosition.pop();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
elements.forEach((elem, index) => {
|
|
40
|
+
currentPosition.push(index);
|
|
41
|
+
_walk(elem);
|
|
42
|
+
currentPosition.pop();
|
|
43
|
+
});
|
|
44
|
+
return virtualFlatMap;
|
|
45
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { enhanceFontFamliy, getDefaultElementDetailConfig } from '@idraw/util';
|
|
2
|
+
const detailConfig = getDefaultElementDetailConfig();
|
|
3
|
+
function isTextWidthWithinErrorRange(w0, w1, scale) {
|
|
4
|
+
if (scale < 0.5) {
|
|
5
|
+
if (w0 < w1 && (w0 - w1) / w0 > -0.15) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
return w0 >= w1;
|
|
10
|
+
}
|
|
11
|
+
export function calcVirtualTextDetail(elem, opts) {
|
|
12
|
+
const { w, h } = elem;
|
|
13
|
+
const x = 0;
|
|
14
|
+
const y = 0;
|
|
15
|
+
const ctx = opts.tempContext;
|
|
16
|
+
const lines = [];
|
|
17
|
+
const detail = Object.assign(Object.assign({}, detailConfig), elem.detail);
|
|
18
|
+
const originFontSize = detail.fontSize || detailConfig.fontSize;
|
|
19
|
+
const fontSize = originFontSize;
|
|
20
|
+
if (fontSize < 2) {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
const originLineHeight = detail.lineHeight || originFontSize;
|
|
24
|
+
const lineHeight = originLineHeight;
|
|
25
|
+
ctx.textBaseline = 'top';
|
|
26
|
+
ctx.$setFont({
|
|
27
|
+
fontWeight: detail.fontWeight,
|
|
28
|
+
fontSize: fontSize,
|
|
29
|
+
fontFamily: enhanceFontFamliy(detail.fontFamily)
|
|
30
|
+
});
|
|
31
|
+
let detailText = detail.text.replace(/\r\n/gi, '\n');
|
|
32
|
+
if (detail.textTransform === 'lowercase') {
|
|
33
|
+
detailText = detailText.toLowerCase();
|
|
34
|
+
}
|
|
35
|
+
else if (detail.textTransform === 'uppercase') {
|
|
36
|
+
detailText = detailText.toUpperCase();
|
|
37
|
+
}
|
|
38
|
+
const fontHeight = lineHeight;
|
|
39
|
+
const detailTextList = detailText.split('\n');
|
|
40
|
+
let lineNum = 0;
|
|
41
|
+
detailTextList.forEach((itemText, idx) => {
|
|
42
|
+
if (detail.minInlineSize === 'maxContent') {
|
|
43
|
+
lines.push({
|
|
44
|
+
x,
|
|
45
|
+
y: 0,
|
|
46
|
+
text: itemText,
|
|
47
|
+
width: ctx.$undoPixelRatio(ctx.measureText(itemText).width)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
let lineText = '';
|
|
52
|
+
let splitStr = '';
|
|
53
|
+
let tempStrList = itemText.split(splitStr);
|
|
54
|
+
if (detail.wordBreak === 'normal') {
|
|
55
|
+
splitStr = ' ';
|
|
56
|
+
const wordList = itemText.split(splitStr);
|
|
57
|
+
tempStrList = [];
|
|
58
|
+
wordList.forEach((word, idx) => {
|
|
59
|
+
tempStrList.push(word);
|
|
60
|
+
if (idx < wordList.length - 1) {
|
|
61
|
+
tempStrList.push(splitStr);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (tempStrList.length === 1 && detail.overflow === 'visible') {
|
|
66
|
+
lines.push({
|
|
67
|
+
x,
|
|
68
|
+
y: 0,
|
|
69
|
+
text: tempStrList[0],
|
|
70
|
+
width: ctx.$undoPixelRatio(ctx.measureText(tempStrList[0]).width)
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else if (tempStrList.length > 0) {
|
|
74
|
+
for (let i = 0; i < tempStrList.length; i++) {
|
|
75
|
+
if (isTextWidthWithinErrorRange(ctx.$doPixelRatio(w), ctx.measureText(lineText + tempStrList[i]).width, 1)) {
|
|
76
|
+
lineText += tempStrList[i] || '';
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
lines.push({
|
|
80
|
+
x,
|
|
81
|
+
y: 0,
|
|
82
|
+
text: lineText,
|
|
83
|
+
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
|
84
|
+
});
|
|
85
|
+
lineText = tempStrList[i] || '';
|
|
86
|
+
lineNum++;
|
|
87
|
+
}
|
|
88
|
+
if ((lineNum + 1) * fontHeight > h && detail.overflow === 'hidden') {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
if (tempStrList.length - 1 === i) {
|
|
92
|
+
if ((lineNum + 1) * fontHeight <= h) {
|
|
93
|
+
lines.push({
|
|
94
|
+
x,
|
|
95
|
+
y: 0,
|
|
96
|
+
text: lineText,
|
|
97
|
+
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
|
98
|
+
});
|
|
99
|
+
if (idx < detailTextList.length - 1) {
|
|
100
|
+
lineNum++;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push({
|
|
109
|
+
x,
|
|
110
|
+
y: 0,
|
|
111
|
+
text: '',
|
|
112
|
+
width: 0
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
let startY = 0;
|
|
118
|
+
let eachLineStartY = 0;
|
|
119
|
+
if (fontHeight > fontSize) {
|
|
120
|
+
eachLineStartY = (fontHeight - fontSize) / 2;
|
|
121
|
+
}
|
|
122
|
+
if (lines.length * fontHeight < h) {
|
|
123
|
+
if (detail.verticalAlign === 'top') {
|
|
124
|
+
startY = 0;
|
|
125
|
+
}
|
|
126
|
+
else if (detail.verticalAlign === 'bottom') {
|
|
127
|
+
startY += h - lines.length * fontHeight;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
startY += (h - lines.length * fontHeight) / 2;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
{
|
|
134
|
+
const _y = y + startY;
|
|
135
|
+
lines.forEach((line, i) => {
|
|
136
|
+
let _x = x;
|
|
137
|
+
if (detail.textAlign === 'center') {
|
|
138
|
+
_x = x + (w - line.width) / 2;
|
|
139
|
+
}
|
|
140
|
+
else if (detail.textAlign === 'right') {
|
|
141
|
+
_x = x + (w - line.width);
|
|
142
|
+
}
|
|
143
|
+
lines[i].x = _x;
|
|
144
|
+
lines[i].y = _y + fontHeight * i + eachLineStartY;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const virtualTextDetail = {
|
|
148
|
+
textLines: lines
|
|
149
|
+
};
|
|
150
|
+
return virtualTextDetail;
|
|
151
|
+
}
|