@idraw/renderer 0.4.0-beta.39 → 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/dist/esm/calculator.d.ts +43 -0
- package/dist/esm/calculator.js +168 -0
- package/dist/esm/draw/box.d.ts +3 -0
- package/dist/esm/draw/box.js +22 -17
- package/dist/esm/draw/circle.js +0 -2
- package/dist/esm/draw/layout.js +1 -1
- package/dist/esm/draw/text.js +16 -123
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +13 -3
- 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 +999 -198
- package/dist/index.global.min.js +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Point, Data, Element, ElementType, ViewCalculator, ViewCalculatorOptions, ViewScaleInfo, ViewSizeInfo, ViewRectInfo, ModifyOptions, VirtualFlatItem } from '@idraw/types';
|
|
2
|
+
export declare class Calculator implements ViewCalculator {
|
|
3
|
+
#private;
|
|
4
|
+
constructor(opts: ViewCalculatorOptions);
|
|
5
|
+
toGridNum(num: number, opts?: {
|
|
6
|
+
ignore?: boolean;
|
|
7
|
+
}): number;
|
|
8
|
+
destroy(): void;
|
|
9
|
+
needRender(elem: Element<ElementType>): boolean;
|
|
10
|
+
getPointElement(p: Point, opts: {
|
|
11
|
+
data: Data;
|
|
12
|
+
viewScaleInfo: ViewScaleInfo;
|
|
13
|
+
viewSizeInfo: ViewSizeInfo;
|
|
14
|
+
}): {
|
|
15
|
+
index: number;
|
|
16
|
+
element: null | Element<ElementType>;
|
|
17
|
+
groupQueueIndex: number;
|
|
18
|
+
};
|
|
19
|
+
resetVirtualFlatItemMap(data: Data, opts: {
|
|
20
|
+
viewScaleInfo: ViewScaleInfo;
|
|
21
|
+
viewSizeInfo: ViewSizeInfo;
|
|
22
|
+
}): void;
|
|
23
|
+
updateVisiableStatus(opts: {
|
|
24
|
+
viewScaleInfo: ViewScaleInfo;
|
|
25
|
+
viewSizeInfo: ViewSizeInfo;
|
|
26
|
+
}): void;
|
|
27
|
+
calcViewRectInfoFromOrigin(uuid: string, opts: {
|
|
28
|
+
checkVisible?: boolean;
|
|
29
|
+
viewScaleInfo: ViewScaleInfo;
|
|
30
|
+
viewSizeInfo: ViewSizeInfo;
|
|
31
|
+
}): ViewRectInfo | null;
|
|
32
|
+
calcViewRectInfoFromRange(uuid: string, opts: {
|
|
33
|
+
checkVisible?: boolean;
|
|
34
|
+
viewScaleInfo: ViewScaleInfo;
|
|
35
|
+
viewSizeInfo: ViewSizeInfo;
|
|
36
|
+
}): ViewRectInfo | null;
|
|
37
|
+
modifyVirtualFlatItemMap(data: Data, opts: {
|
|
38
|
+
modifyOptions: ModifyOptions;
|
|
39
|
+
viewScaleInfo: ViewScaleInfo;
|
|
40
|
+
viewSizeInfo: ViewSizeInfo;
|
|
41
|
+
}): void;
|
|
42
|
+
getVirtualFlatItem(uuid: string): VirtualFlatItem | null;
|
|
43
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
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");
|
|
5
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var _Calculator_opts, _Calculator_store;
|
|
13
|
+
import { is, getViewPointAtElement, Store, calcViewPointSize, findElementFromListByPosition, getGroupQueueByElementPosition, calcElementOriginRectInfo, originRectInfoToRangeRectInfo } from '@idraw/util';
|
|
14
|
+
import { sortElementsViewVisiableInfoMap, updateVirtualFlatItemMapStatus } from './view-visible';
|
|
15
|
+
import { calcVirtualFlatDetail } from './virtual-flat';
|
|
16
|
+
export class Calculator {
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
_Calculator_opts.set(this, void 0);
|
|
19
|
+
_Calculator_store.set(this, void 0);
|
|
20
|
+
__classPrivateFieldSet(this, _Calculator_opts, opts, "f");
|
|
21
|
+
__classPrivateFieldSet(this, _Calculator_store, new Store({
|
|
22
|
+
defaultStorage: {
|
|
23
|
+
virtualFlatItemMap: {},
|
|
24
|
+
visibleCount: 0,
|
|
25
|
+
invisibleCount: 0
|
|
26
|
+
}
|
|
27
|
+
}), "f");
|
|
28
|
+
}
|
|
29
|
+
toGridNum(num, opts) {
|
|
30
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.ignore) === true) {
|
|
31
|
+
return num;
|
|
32
|
+
}
|
|
33
|
+
return Math.round(num);
|
|
34
|
+
}
|
|
35
|
+
destroy() {
|
|
36
|
+
__classPrivateFieldSet(this, _Calculator_opts, null, "f");
|
|
37
|
+
}
|
|
38
|
+
needRender(elem) {
|
|
39
|
+
const virtualFlatItemMap = __classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap');
|
|
40
|
+
const info = virtualFlatItemMap[elem.uuid];
|
|
41
|
+
if (!info) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return info.isVisibleInView;
|
|
45
|
+
}
|
|
46
|
+
getPointElement(p, opts) {
|
|
47
|
+
const context2d = __classPrivateFieldGet(this, _Calculator_opts, "f").tempContext;
|
|
48
|
+
return getViewPointAtElement(p, Object.assign(Object.assign({}, opts), { context2d }));
|
|
49
|
+
}
|
|
50
|
+
resetVirtualFlatItemMap(data, opts) {
|
|
51
|
+
if (data) {
|
|
52
|
+
const { virtualFlatItemMap, invisibleCount, visibleCount } = sortElementsViewVisiableInfoMap(data.elements, Object.assign(Object.assign({}, opts), {
|
|
53
|
+
tempContext: __classPrivateFieldGet(this, _Calculator_opts, "f").tempContext
|
|
54
|
+
}));
|
|
55
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('virtualFlatItemMap', virtualFlatItemMap);
|
|
56
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('invisibleCount', invisibleCount);
|
|
57
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('visibleCount', visibleCount);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
updateVisiableStatus(opts) {
|
|
61
|
+
const { virtualFlatItemMap, invisibleCount, visibleCount } = updateVirtualFlatItemMapStatus(__classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap'), opts);
|
|
62
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('virtualFlatItemMap', virtualFlatItemMap);
|
|
63
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('invisibleCount', invisibleCount);
|
|
64
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('visibleCount', visibleCount);
|
|
65
|
+
}
|
|
66
|
+
calcViewRectInfoFromOrigin(uuid, opts) {
|
|
67
|
+
const infoData = __classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap')[uuid];
|
|
68
|
+
if (!(infoData === null || infoData === void 0 ? void 0 : infoData.originRectInfo)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const { checkVisible, viewScaleInfo, viewSizeInfo } = opts;
|
|
72
|
+
const { center, left, right, bottom, top, topLeft, topRight, bottomLeft, bottomRight } = infoData.originRectInfo;
|
|
73
|
+
if (checkVisible === true && infoData.isVisibleInView === false) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
const calcOpts = { viewScaleInfo, viewSizeInfo };
|
|
77
|
+
const viewRectInfo = {
|
|
78
|
+
center: calcViewPointSize(center, calcOpts),
|
|
79
|
+
left: calcViewPointSize(left, calcOpts),
|
|
80
|
+
right: calcViewPointSize(right, calcOpts),
|
|
81
|
+
bottom: calcViewPointSize(bottom, calcOpts),
|
|
82
|
+
top: calcViewPointSize(top, calcOpts),
|
|
83
|
+
topLeft: calcViewPointSize(topLeft, calcOpts),
|
|
84
|
+
topRight: calcViewPointSize(topRight, calcOpts),
|
|
85
|
+
bottomLeft: calcViewPointSize(bottomLeft, calcOpts),
|
|
86
|
+
bottomRight: calcViewPointSize(bottomRight, calcOpts)
|
|
87
|
+
};
|
|
88
|
+
return viewRectInfo;
|
|
89
|
+
}
|
|
90
|
+
calcViewRectInfoFromRange(uuid, opts) {
|
|
91
|
+
const infoData = __classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap')[uuid];
|
|
92
|
+
if (!(infoData === null || infoData === void 0 ? void 0 : infoData.originRectInfo)) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const { checkVisible, viewScaleInfo, viewSizeInfo } = opts;
|
|
96
|
+
const { center, left, right, bottom, top, topLeft, topRight, bottomLeft, bottomRight } = infoData.rangeRectInfo;
|
|
97
|
+
if (checkVisible === true && infoData.isVisibleInView === false) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const calcOpts = { viewScaleInfo, viewSizeInfo };
|
|
101
|
+
const viewRectInfo = {
|
|
102
|
+
center: calcViewPointSize(center, calcOpts),
|
|
103
|
+
left: calcViewPointSize(left, calcOpts),
|
|
104
|
+
right: calcViewPointSize(right, calcOpts),
|
|
105
|
+
bottom: calcViewPointSize(bottom, calcOpts),
|
|
106
|
+
top: calcViewPointSize(top, calcOpts),
|
|
107
|
+
topLeft: calcViewPointSize(topLeft, calcOpts),
|
|
108
|
+
topRight: calcViewPointSize(topRight, calcOpts),
|
|
109
|
+
bottomLeft: calcViewPointSize(bottomLeft, calcOpts),
|
|
110
|
+
bottomRight: calcViewPointSize(bottomRight, calcOpts)
|
|
111
|
+
};
|
|
112
|
+
return viewRectInfo;
|
|
113
|
+
}
|
|
114
|
+
modifyVirtualFlatItemMap(data, opts) {
|
|
115
|
+
const { modifyOptions, viewScaleInfo, viewSizeInfo } = opts;
|
|
116
|
+
const { type, content } = modifyOptions;
|
|
117
|
+
const list = data.elements;
|
|
118
|
+
const virtualFlatItemMap = __classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap');
|
|
119
|
+
if (type === 'deleteElement') {
|
|
120
|
+
const { element } = content;
|
|
121
|
+
const uuids = [];
|
|
122
|
+
const _walk = (e) => {
|
|
123
|
+
uuids.push(e.uuid);
|
|
124
|
+
if (e.type === 'group' && Array.isArray(e.detail.children)) {
|
|
125
|
+
e.detail.children.forEach((child) => {
|
|
126
|
+
_walk(child);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
_walk(element);
|
|
131
|
+
uuids.forEach((uuid) => {
|
|
132
|
+
delete virtualFlatItemMap[uuid];
|
|
133
|
+
});
|
|
134
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('virtualFlatItemMap', virtualFlatItemMap);
|
|
135
|
+
}
|
|
136
|
+
else if (type === 'addElement' || type === 'updateElement') {
|
|
137
|
+
const { position } = content;
|
|
138
|
+
const element = findElementFromListByPosition(position, data.elements);
|
|
139
|
+
const groupQueue = getGroupQueueByElementPosition(list, position);
|
|
140
|
+
if (element) {
|
|
141
|
+
if (type === 'updateElement' && element.type === 'group') {
|
|
142
|
+
this.resetVirtualFlatItemMap(data, { viewScaleInfo, viewSizeInfo });
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
const originRectInfo = calcElementOriginRectInfo(element, {
|
|
146
|
+
groupQueue: groupQueue || []
|
|
147
|
+
});
|
|
148
|
+
const newVirtualFlatItem = Object.assign({ type: element.type, originRectInfo, rangeRectInfo: is.angle(element.angle) ? originRectInfoToRangeRectInfo(originRectInfo) : originRectInfo, isVisibleInView: true, position: [...position] }, calcVirtualFlatDetail(element, {
|
|
149
|
+
tempContext: __classPrivateFieldGet(this, _Calculator_opts, "f").tempContext
|
|
150
|
+
}));
|
|
151
|
+
virtualFlatItemMap[element.uuid] = newVirtualFlatItem;
|
|
152
|
+
__classPrivateFieldGet(this, _Calculator_store, "f").set('virtualFlatItemMap', virtualFlatItemMap);
|
|
153
|
+
if (type === 'updateElement') {
|
|
154
|
+
this.updateVisiableStatus({ viewScaleInfo, viewSizeInfo });
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else if (type === 'moveElement') {
|
|
160
|
+
this.resetVirtualFlatItemMap(data, { viewScaleInfo, viewSizeInfo });
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
getVirtualFlatItem(uuid) {
|
|
164
|
+
const itemMap = __classPrivateFieldGet(this, _Calculator_store, "f").get('virtualFlatItemMap');
|
|
165
|
+
return itemMap[uuid] || null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
_Calculator_opts = new WeakMap(), _Calculator_store = new WeakMap();
|
package/dist/esm/draw/box.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ViewContext2D, Element, ElementType, ElementSize, ViewScaleInfo, ViewSizeInfo } from '@idraw/types';
|
|
2
|
+
import { Calculator } from '../calculator';
|
|
2
3
|
export declare function getOpacity(elem: Element): number;
|
|
3
4
|
export declare function drawBox(ctx: ViewContext2D, viewElem: Element, opts: {
|
|
4
5
|
originElem: Element;
|
|
@@ -15,8 +16,10 @@ export declare function drawBoxBackground(ctx: ViewContext2D, viewElem: Element<
|
|
|
15
16
|
viewSizeInfo: ViewSizeInfo;
|
|
16
17
|
}): void;
|
|
17
18
|
export declare function drawBoxBorder(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
|
|
19
|
+
originElem: Element;
|
|
18
20
|
viewScaleInfo: ViewScaleInfo;
|
|
19
21
|
viewSizeInfo: ViewSizeInfo;
|
|
22
|
+
calculator?: Calculator;
|
|
20
23
|
}): void;
|
|
21
24
|
export declare function drawBoxShadow(ctx: ViewContext2D, viewElem: Element<ElementType>, opts: {
|
|
22
25
|
viewScaleInfo: ViewScaleInfo;
|
package/dist/esm/draw/box.js
CHANGED
|
@@ -18,7 +18,7 @@ export function drawBox(ctx, viewElem, opts) {
|
|
|
18
18
|
ctx.globalAlpha = opacity;
|
|
19
19
|
drawBoxBackground(ctx, viewElem, { pattern, viewScaleInfo, viewSizeInfo });
|
|
20
20
|
renderContent === null || renderContent === void 0 ? void 0 : renderContent();
|
|
21
|
-
drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
|
|
21
|
+
drawBoxBorder(ctx, viewElem, { originElem, viewScaleInfo, viewSizeInfo });
|
|
22
22
|
ctx.globalAlpha = parentOpacity;
|
|
23
23
|
};
|
|
24
24
|
if (clipPath) {
|
|
@@ -79,7 +79,12 @@ function drawClipPathStroke(ctx, viewElem, opts) {
|
|
|
79
79
|
const { renderContent, originElem, calcElemSize, viewSizeInfo, parentOpacity } = opts;
|
|
80
80
|
const totalScale = viewSizeInfo.devicePixelRatio;
|
|
81
81
|
const { clipPath, clipPathStrokeColor, clipPathStrokeWidth } = (originElem === null || originElem === void 0 ? void 0 : originElem.detail) || {};
|
|
82
|
-
if (clipPath &&
|
|
82
|
+
if (clipPath &&
|
|
83
|
+
calcElemSize &&
|
|
84
|
+
clipPath.commands &&
|
|
85
|
+
typeof clipPathStrokeWidth === 'number' &&
|
|
86
|
+
clipPathStrokeWidth > 0 &&
|
|
87
|
+
clipPathStrokeColor) {
|
|
83
88
|
const { x, y, w, h } = calcElemSize;
|
|
84
89
|
const { originW, originH, originX, originY } = clipPath;
|
|
85
90
|
const scaleW = w / originW;
|
|
@@ -182,12 +187,17 @@ export function drawBoxBorder(ctx, viewElem, opts) {
|
|
|
182
187
|
if (isColorStr(viewElem.detail.borderColor) === true) {
|
|
183
188
|
borderColor = viewElem.detail.borderColor;
|
|
184
189
|
}
|
|
185
|
-
const { borderWidth, borderRadius,
|
|
186
|
-
let
|
|
187
|
-
if (
|
|
188
|
-
|
|
190
|
+
const { borderDash, borderWidth, borderRadius, boxSizing = defaultElemConfig.boxSizing } = viewElem.detail;
|
|
191
|
+
let viewBorderDash = [];
|
|
192
|
+
if (Array.isArray(borderDash) && borderDash.length > 0) {
|
|
193
|
+
viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
|
|
194
|
+
}
|
|
195
|
+
if (viewBorderDash.length > 0) {
|
|
196
|
+
ctx.lineCap = 'butt';
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
ctx.lineCap = 'square';
|
|
189
200
|
}
|
|
190
|
-
bw = bw * scale;
|
|
191
201
|
let radiusList = [0, 0, 0, 0];
|
|
192
202
|
if (typeof borderRadius === 'number') {
|
|
193
203
|
const br = borderRadius * scale;
|
|
@@ -196,11 +206,12 @@ export function drawBoxBorder(ctx, viewElem, opts) {
|
|
|
196
206
|
else if (Array.isArray(borderRadius) && (borderRadius === null || borderRadius === void 0 ? void 0 : borderRadius.length) === 4) {
|
|
197
207
|
radiusList = [borderRadius[0] * scale, borderRadius[1] * scale, borderRadius[2] * scale, borderRadius[3] * scale];
|
|
198
208
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
viewBorderDash = borderDash.map((num) => Math.ceil(num * scale));
|
|
209
|
+
let bw = 0;
|
|
210
|
+
if (typeof borderWidth === 'number') {
|
|
211
|
+
bw = borderWidth || 1;
|
|
203
212
|
}
|
|
213
|
+
bw = bw * scale;
|
|
214
|
+
ctx.strokeStyle = borderColor;
|
|
204
215
|
let borderTop = 0;
|
|
205
216
|
let borderRight = 0;
|
|
206
217
|
let borderBottom = 0;
|
|
@@ -285,12 +296,6 @@ export function drawBoxBorder(ctx, viewElem, opts) {
|
|
|
285
296
|
w = viewElem.w;
|
|
286
297
|
h = viewElem.h;
|
|
287
298
|
}
|
|
288
|
-
if (viewBorderDash.length > 0) {
|
|
289
|
-
ctx.lineCap = 'butt';
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
ctx.lineCap = 'square';
|
|
293
|
-
}
|
|
294
299
|
w = Math.max(w, 1);
|
|
295
300
|
h = Math.max(h, 1);
|
|
296
301
|
radiusList = radiusList.map((r) => {
|
package/dist/esm/draw/circle.js
CHANGED
package/dist/esm/draw/layout.js
CHANGED
|
@@ -39,6 +39,6 @@ export function drawLayout(ctx, layout, opts, renderContent) {
|
|
|
39
39
|
if (layout.detail.overflow === 'hidden') {
|
|
40
40
|
ctx.restore();
|
|
41
41
|
}
|
|
42
|
-
drawBoxBorder(ctx, viewElem, { viewScaleInfo, viewSizeInfo });
|
|
42
|
+
drawBoxBorder(ctx, viewElem, { originElem: elem, viewScaleInfo, viewSizeInfo });
|
|
43
43
|
ctx.globalAlpha = parentOpacity;
|
|
44
44
|
}
|
package/dist/esm/draw/text.js
CHANGED
|
@@ -2,19 +2,12 @@ import { rotateElement, calcViewElementSize, enhanceFontFamliy } from '@idraw/ut
|
|
|
2
2
|
import { is, isColorStr, getDefaultElementDetailConfig } from '@idraw/util';
|
|
3
3
|
import { drawBox, drawBoxShadow } from './box';
|
|
4
4
|
const detailConfig = getDefaultElementDetailConfig();
|
|
5
|
-
function isTextWidthWithinErrorRange(w0, w1, scale) {
|
|
6
|
-
if (scale < 0.5) {
|
|
7
|
-
if (w0 < w1 && (w0 - w1) / w0 > -0.15) {
|
|
8
|
-
return true;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return w0 >= w1;
|
|
12
|
-
}
|
|
13
5
|
export function drawText(ctx, elem, opts) {
|
|
14
|
-
const { viewScaleInfo, viewSizeInfo, parentOpacity } = opts;
|
|
6
|
+
const { viewScaleInfo, viewSizeInfo, parentOpacity, calculator } = opts;
|
|
15
7
|
const { x, y, w, h, angle } = calcViewElementSize(elem, { viewScaleInfo }) || elem;
|
|
16
8
|
const viewElem = Object.assign(Object.assign({}, elem), { x, y, w, h, angle });
|
|
17
9
|
rotateElement(ctx, { x, y, w, h, angle }, () => {
|
|
10
|
+
var _a, _b;
|
|
18
11
|
drawBoxShadow(ctx, viewElem, {
|
|
19
12
|
viewScaleInfo,
|
|
20
13
|
viewSizeInfo,
|
|
@@ -35,8 +28,6 @@ export function drawText(ctx, elem, opts) {
|
|
|
35
28
|
if (fontSize < 2) {
|
|
36
29
|
return;
|
|
37
30
|
}
|
|
38
|
-
const originLineHeight = detail.lineHeight || originFontSize;
|
|
39
|
-
const lineHeight = originLineHeight * viewScaleInfo.scale;
|
|
40
31
|
ctx.fillStyle = elem.detail.color || detailConfig.color;
|
|
41
32
|
ctx.textBaseline = 'top';
|
|
42
33
|
ctx.$setFont({
|
|
@@ -44,123 +35,25 @@ export function drawText(ctx, elem, opts) {
|
|
|
44
35
|
fontSize: fontSize,
|
|
45
36
|
fontFamily: enhanceFontFamliy(detail.fontFamily)
|
|
46
37
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
detailText = detailText.toUpperCase();
|
|
53
|
-
}
|
|
54
|
-
const fontHeight = lineHeight;
|
|
55
|
-
const detailTextList = detailText.split('\n');
|
|
56
|
-
const lines = [];
|
|
57
|
-
let lineNum = 0;
|
|
58
|
-
detailTextList.forEach((itemText, idx) => {
|
|
59
|
-
if (detail.minInlineSize === 'maxContent') {
|
|
60
|
-
lines.push({
|
|
61
|
-
text: itemText,
|
|
62
|
-
width: ctx.$undoPixelRatio(ctx.measureText(itemText).width)
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
let lineText = '';
|
|
67
|
-
let splitStr = '';
|
|
68
|
-
let tempStrList = itemText.split(splitStr);
|
|
69
|
-
if (detail.wordBreak === 'normal') {
|
|
70
|
-
const splitStr = ' ';
|
|
71
|
-
const wordList = itemText.split(splitStr);
|
|
72
|
-
tempStrList = [];
|
|
73
|
-
wordList.forEach((word, idx) => {
|
|
74
|
-
tempStrList.push(word);
|
|
75
|
-
if (idx < wordList.length - 1) {
|
|
76
|
-
tempStrList.push(splitStr);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
38
|
+
{
|
|
39
|
+
const virtualTextDetail = calculator.getVirtualFlatItem(elem.uuid);
|
|
40
|
+
if (Array.isArray(virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) && ((_a = virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
41
|
+
if (detail.textShadowColor !== undefined && isColorStr(detail.textShadowColor)) {
|
|
42
|
+
ctx.shadowColor = detail.textShadowColor;
|
|
79
43
|
}
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
text: tempStrList[0],
|
|
83
|
-
width: ctx.$undoPixelRatio(ctx.measureText(tempStrList[0]).width)
|
|
84
|
-
});
|
|
44
|
+
if (detail.textShadowOffsetX !== undefined && is.number(detail.textShadowOffsetX)) {
|
|
45
|
+
ctx.shadowOffsetX = detail.textShadowOffsetX;
|
|
85
46
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (isTextWidthWithinErrorRange(ctx.$doPixelRatio(w), ctx.measureText(lineText + tempStrList[i]).width, viewScaleInfo.scale)) {
|
|
89
|
-
lineText += tempStrList[i] || '';
|
|
90
|
-
}
|
|
91
|
-
else {
|
|
92
|
-
lines.push({
|
|
93
|
-
text: lineText,
|
|
94
|
-
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
|
95
|
-
});
|
|
96
|
-
lineText = tempStrList[i] || '';
|
|
97
|
-
lineNum++;
|
|
98
|
-
}
|
|
99
|
-
if ((lineNum + 1) * fontHeight > h && detail.overflow === 'hidden') {
|
|
100
|
-
break;
|
|
101
|
-
}
|
|
102
|
-
if (tempStrList.length - 1 === i) {
|
|
103
|
-
if ((lineNum + 1) * fontHeight <= h) {
|
|
104
|
-
lines.push({
|
|
105
|
-
text: lineText,
|
|
106
|
-
width: ctx.$undoPixelRatio(ctx.measureText(lineText).width)
|
|
107
|
-
});
|
|
108
|
-
if (idx < detailTextList.length - 1) {
|
|
109
|
-
lineNum++;
|
|
110
|
-
}
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
47
|
+
if (detail.textShadowOffsetY !== undefined && is.number(detail.textShadowOffsetY)) {
|
|
48
|
+
ctx.shadowOffsetY = detail.textShadowOffsetY;
|
|
115
49
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
text: '',
|
|
119
|
-
width: 0
|
|
120
|
-
});
|
|
50
|
+
if (detail.textShadowBlur !== undefined && is.number(detail.textShadowBlur)) {
|
|
51
|
+
ctx.shadowBlur = detail.textShadowBlur;
|
|
121
52
|
}
|
|
53
|
+
(_b = virtualTextDetail === null || virtualTextDetail === void 0 ? void 0 : virtualTextDetail.textLines) === null || _b === void 0 ? void 0 : _b.forEach((line) => {
|
|
54
|
+
ctx.fillText(line.text, x + line.x * viewScaleInfo.scale, y + line.y * viewScaleInfo.scale);
|
|
55
|
+
});
|
|
122
56
|
}
|
|
123
|
-
});
|
|
124
|
-
let startY = 0;
|
|
125
|
-
let eachLineStartY = 0;
|
|
126
|
-
if (fontHeight > fontSize) {
|
|
127
|
-
eachLineStartY = (fontHeight - fontSize) / 2;
|
|
128
|
-
}
|
|
129
|
-
if (lines.length * fontHeight < h) {
|
|
130
|
-
if (elem.detail.verticalAlign === 'top') {
|
|
131
|
-
startY = 0;
|
|
132
|
-
}
|
|
133
|
-
else if (elem.detail.verticalAlign === 'bottom') {
|
|
134
|
-
startY += h - lines.length * fontHeight;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
startY += (h - lines.length * fontHeight) / 2;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
{
|
|
141
|
-
const _y = y + startY;
|
|
142
|
-
if (detail.textShadowColor !== undefined && isColorStr(detail.textShadowColor)) {
|
|
143
|
-
ctx.shadowColor = detail.textShadowColor;
|
|
144
|
-
}
|
|
145
|
-
if (detail.textShadowOffsetX !== undefined && is.number(detail.textShadowOffsetX)) {
|
|
146
|
-
ctx.shadowOffsetX = detail.textShadowOffsetX;
|
|
147
|
-
}
|
|
148
|
-
if (detail.textShadowOffsetY !== undefined && is.number(detail.textShadowOffsetY)) {
|
|
149
|
-
ctx.shadowOffsetY = detail.textShadowOffsetY;
|
|
150
|
-
}
|
|
151
|
-
if (detail.textShadowBlur !== undefined && is.number(detail.textShadowBlur)) {
|
|
152
|
-
ctx.shadowBlur = detail.textShadowBlur;
|
|
153
|
-
}
|
|
154
|
-
lines.forEach((line, i) => {
|
|
155
|
-
let _x = x;
|
|
156
|
-
if (detail.textAlign === 'center') {
|
|
157
|
-
_x = x + (w - line.width) / 2;
|
|
158
|
-
}
|
|
159
|
-
else if (detail.textAlign === 'right') {
|
|
160
|
-
_x = x + (w - line.width);
|
|
161
|
-
}
|
|
162
|
-
ctx.fillText(line.text, _x, _y + fontHeight * i + eachLineStartY);
|
|
163
|
-
});
|
|
164
57
|
}
|
|
165
58
|
}
|
|
166
59
|
});
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { EventEmitter } from '@idraw/util';
|
|
|
2
2
|
import type { LoadItemMap } from '@idraw/types';
|
|
3
3
|
import { Loader } from './loader';
|
|
4
4
|
import type { Data, BoardRenderer, RendererOptions, RendererEventMap, RendererDrawOptions } from '@idraw/types';
|
|
5
|
+
import { Calculator } from './calculator';
|
|
6
|
+
export { Calculator };
|
|
5
7
|
export declare class Renderer extends EventEmitter<RendererEventMap> implements BoardRenderer {
|
|
6
8
|
#private;
|
|
7
9
|
constructor(opts: RendererOptions);
|
|
@@ -13,5 +15,6 @@ export declare class Renderer extends EventEmitter<RendererEventMap> implements
|
|
|
13
15
|
setLoadItemMap(itemMap: LoadItemMap): void;
|
|
14
16
|
getLoadItemMap(): LoadItemMap;
|
|
15
17
|
getLoader(): Loader;
|
|
18
|
+
getCalculator(): Calculator;
|
|
16
19
|
}
|
|
17
20
|
export { drawCircle, drawRect, drawImage, drawSVG, drawHTML, drawText, drawGroup, drawElement, drawElementList, drawLayout, drawGlobalBackground } from './draw';
|
package/dist/esm/index.js
CHANGED
|
@@ -9,18 +9,24 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
10
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
11
|
};
|
|
12
|
-
var _Renderer_instances, _Renderer_opts, _Renderer_loader, _Renderer_hasDestroyed, _Renderer_init;
|
|
12
|
+
var _Renderer_instances, _Renderer_opts, _Renderer_loader, _Renderer_calculator, _Renderer_hasDestroyed, _Renderer_init;
|
|
13
13
|
import { EventEmitter } from '@idraw/util';
|
|
14
14
|
import { drawElementList, drawLayout, drawGlobalBackground } from './draw/index';
|
|
15
15
|
import { Loader } from './loader';
|
|
16
|
+
import { Calculator } from './calculator';
|
|
17
|
+
export { Calculator };
|
|
16
18
|
export class Renderer extends EventEmitter {
|
|
17
19
|
constructor(opts) {
|
|
18
20
|
super();
|
|
19
21
|
_Renderer_instances.add(this);
|
|
20
22
|
_Renderer_opts.set(this, void 0);
|
|
21
23
|
_Renderer_loader.set(this, new Loader());
|
|
24
|
+
_Renderer_calculator.set(this, void 0);
|
|
22
25
|
_Renderer_hasDestroyed.set(this, false);
|
|
23
26
|
__classPrivateFieldSet(this, _Renderer_opts, opts, "f");
|
|
27
|
+
__classPrivateFieldSet(this, _Renderer_calculator, new Calculator({
|
|
28
|
+
tempContext: opts.tempContext
|
|
29
|
+
}), "f");
|
|
24
30
|
__classPrivateFieldGet(this, _Renderer_instances, "m", _Renderer_init).call(this);
|
|
25
31
|
}
|
|
26
32
|
isDestroyed() {
|
|
@@ -38,7 +44,8 @@ export class Renderer extends EventEmitter {
|
|
|
38
44
|
}
|
|
39
45
|
drawData(data, opts) {
|
|
40
46
|
const loader = __classPrivateFieldGet(this, _Renderer_loader, "f");
|
|
41
|
-
const
|
|
47
|
+
const calculator = __classPrivateFieldGet(this, _Renderer_calculator, "f");
|
|
48
|
+
const { sharer } = __classPrivateFieldGet(this, _Renderer_opts, "f");
|
|
42
49
|
const viewContext = __classPrivateFieldGet(this, _Renderer_opts, "f").viewContext;
|
|
43
50
|
viewContext.clearRect(0, 0, viewContext.canvas.width, viewContext.canvas.height);
|
|
44
51
|
const parentElementSize = {
|
|
@@ -94,8 +101,11 @@ export class Renderer extends EventEmitter {
|
|
|
94
101
|
getLoader() {
|
|
95
102
|
return __classPrivateFieldGet(this, _Renderer_loader, "f");
|
|
96
103
|
}
|
|
104
|
+
getCalculator() {
|
|
105
|
+
return __classPrivateFieldGet(this, _Renderer_calculator, "f");
|
|
106
|
+
}
|
|
97
107
|
}
|
|
98
|
-
_Renderer_opts = new WeakMap(), _Renderer_loader = new WeakMap(), _Renderer_hasDestroyed = new WeakMap(), _Renderer_instances = new WeakSet(), _Renderer_init = function _Renderer_init() {
|
|
108
|
+
_Renderer_opts = new WeakMap(), _Renderer_loader = new WeakMap(), _Renderer_calculator = new WeakMap(), _Renderer_hasDestroyed = new WeakMap(), _Renderer_instances = new WeakSet(), _Renderer_init = function _Renderer_init() {
|
|
99
109
|
const loader = __classPrivateFieldGet(this, _Renderer_loader, "f");
|
|
100
110
|
loader.on('load', (e) => {
|
|
101
111
|
this.trigger('load', e);
|
|
@@ -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;
|