@idraw/renderer 0.4.0-beta.4 → 0.4.0-beta.40
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 +43 -0
- package/dist/esm/calculator.js +168 -0
- package/dist/esm/draw/box.d.ts +17 -3
- package/dist/esm/draw/box.js +102 -49
- package/dist/esm/draw/circle.js +55 -31
- package/dist/esm/draw/elements.js +5 -2
- package/dist/esm/draw/global.d.ts +2 -0
- package/dist/esm/draw/global.js +9 -0
- package/dist/esm/draw/group.js +20 -8
- package/dist/esm/draw/html.js +7 -7
- package/dist/esm/draw/image.js +50 -9
- package/dist/esm/draw/index.d.ts +3 -0
- package/dist/esm/draw/index.js +3 -0
- package/dist/esm/draw/layout.d.ts +2 -0
- package/dist/esm/draw/layout.js +44 -0
- package/dist/esm/draw/path.js +48 -8
- package/dist/esm/draw/rect.js +4 -3
- package/dist/esm/draw/svg.js +7 -7
- package/dist/esm/draw/text.js +34 -84
- package/dist/esm/index.d.ts +8 -0
- package/dist/esm/index.js +42 -7
- package/dist/esm/loader.d.ts +2 -0
- package/dist/esm/loader.js +50 -26
- 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 +1474 -312
- package/dist/index.global.min.js +1 -1
- package/package.json +4 -4
package/dist/esm/loader.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import { EventEmitter } from '@idraw/util';
|
|
|
3
3
|
export declare class Loader extends EventEmitter<LoaderEventMap> implements RendererLoader {
|
|
4
4
|
#private;
|
|
5
5
|
constructor();
|
|
6
|
+
isDestroyed(): boolean;
|
|
7
|
+
destroy(): void;
|
|
6
8
|
load(element: Element<LoadElementType>, assets: ElementAssets): void;
|
|
7
9
|
getContent(element: Element<LoadElementType>): LoadContent | null;
|
|
8
10
|
getLoadItemMap(): LoadItemMap;
|
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) => {
|
|
@@ -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,11 +60,11 @@ 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
|
-
width: elem.detail.
|
|
66
|
-
height: elem.detail.
|
|
66
|
+
width: elem.detail.originW || elem.w,
|
|
67
|
+
height: elem.detail.originH || elem.h
|
|
67
68
|
});
|
|
68
69
|
return {
|
|
69
70
|
uuid: elem.uuid,
|
|
@@ -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,7 +83,20 @@ export class Loader extends EventEmitter {
|
|
|
82
83
|
};
|
|
83
84
|
}));
|
|
84
85
|
}
|
|
86
|
+
isDestroyed() {
|
|
87
|
+
return __classPrivateFieldGet(this, _Loader_hasDestroyed, "f");
|
|
88
|
+
}
|
|
89
|
+
destroy() {
|
|
90
|
+
__classPrivateFieldSet(this, _Loader_hasDestroyed, true, "f");
|
|
91
|
+
this.clear();
|
|
92
|
+
__classPrivateFieldSet(this, _Loader_loadFuncMap, null, "f");
|
|
93
|
+
__classPrivateFieldSet(this, _Loader_currentLoadItemMap, null, "f");
|
|
94
|
+
__classPrivateFieldSet(this, _Loader_storageLoadItemMap, null, "f");
|
|
95
|
+
}
|
|
85
96
|
load(element, assets) {
|
|
97
|
+
if (__classPrivateFieldGet(this, _Loader_hasDestroyed, "f") === true) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
86
100
|
if (__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_isExistingErrorStorage).call(this, element)) {
|
|
87
101
|
return;
|
|
88
102
|
}
|
|
@@ -102,7 +116,7 @@ export class Loader extends EventEmitter {
|
|
|
102
116
|
__classPrivateFieldSet(this, _Loader_storageLoadItemMap, itemMap, "f");
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
|
-
_Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(), _Loader_storageLoadItemMap = new WeakMap(), _Loader_instances = new WeakSet(), _Loader_registerLoadFunc = function _Loader_registerLoadFunc(type, func) {
|
|
119
|
+
_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) {
|
|
106
120
|
__classPrivateFieldGet(this, _Loader_loadFuncMap, "f")[type] = func;
|
|
107
121
|
}, _Loader_getLoadElementSource = function _Loader_getLoadElementSource(element) {
|
|
108
122
|
var _a, _b, _c;
|
|
@@ -130,42 +144,52 @@ _Loader_loadFuncMap = new WeakMap(), _Loader_currentLoadItemMap = new WeakMap(),
|
|
|
130
144
|
}, _Loader_emitLoad = function _Loader_emitLoad(item) {
|
|
131
145
|
const assetId = getAssetIdFromElement(item.element);
|
|
132
146
|
const storageItem = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId];
|
|
133
|
-
if (
|
|
134
|
-
if (storageItem
|
|
147
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
148
|
+
if (storageItem) {
|
|
149
|
+
if (storageItem.startTime < item.startTime) {
|
|
150
|
+
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
151
|
+
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
135
155
|
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
136
156
|
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
137
157
|
}
|
|
138
158
|
}
|
|
139
|
-
else {
|
|
140
|
-
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
141
|
-
this.trigger('load', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
142
|
-
}
|
|
143
159
|
}, _Loader_emitError = function _Loader_emitError(item) {
|
|
160
|
+
var _a;
|
|
144
161
|
const assetId = getAssetIdFromElement(item.element);
|
|
145
|
-
const storageItem = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId];
|
|
146
|
-
if (
|
|
147
|
-
if (storageItem
|
|
162
|
+
const storageItem = (_a = __classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")) === null || _a === void 0 ? void 0 : _a[assetId];
|
|
163
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
164
|
+
if (storageItem) {
|
|
165
|
+
if (storageItem.startTime < item.startTime) {
|
|
166
|
+
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
167
|
+
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
148
171
|
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
149
172
|
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
150
173
|
}
|
|
151
174
|
}
|
|
152
|
-
else {
|
|
153
|
-
__classPrivateFieldGet(this, _Loader_storageLoadItemMap, "f")[assetId] = item;
|
|
154
|
-
this.trigger('error', Object.assign(Object.assign({}, item), { countTime: item.endTime - item.startTime }));
|
|
155
|
-
}
|
|
156
175
|
}, _Loader_loadResource = function _Loader_loadResource(element, assets) {
|
|
157
176
|
const item = __classPrivateFieldGet(this, _Loader_instances, "m", _Loader_createLoadItem).call(this, element);
|
|
158
177
|
const assetId = getAssetIdFromElement(element);
|
|
178
|
+
if (__classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")[assetId]) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
159
181
|
__classPrivateFieldGet(this, _Loader_currentLoadItemMap, "f")[assetId] = item;
|
|
160
182
|
const loadFunc = __classPrivateFieldGet(this, _Loader_loadFuncMap, "f")[element.type];
|
|
161
|
-
if (typeof loadFunc === 'function') {
|
|
183
|
+
if (typeof loadFunc === 'function' && !__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
162
184
|
item.startTime = Date.now();
|
|
163
185
|
loadFunc(element, assets)
|
|
164
186
|
.then((result) => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
187
|
+
if (!__classPrivateFieldGet(this, _Loader_hasDestroyed, "f")) {
|
|
188
|
+
item.content = result.content;
|
|
189
|
+
item.endTime = Date.now();
|
|
190
|
+
item.status = 'load';
|
|
191
|
+
__classPrivateFieldGet(this, _Loader_instances, "m", _Loader_emitLoad).call(this, item);
|
|
192
|
+
}
|
|
169
193
|
})
|
|
170
194
|
.catch((err) => {
|
|
171
195
|
console.warn(`Load element source "${item.source}" fail`, err, element);
|
|
@@ -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 (elem.detail.verticalAlign === 'top') {
|
|
124
|
+
startY = 0;
|
|
125
|
+
}
|
|
126
|
+
else if (elem.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
|
+
}
|