@leafer-ui/worker 1.7.0 → 1.9.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/dist/worker.cjs +1134 -1016
- package/dist/worker.esm.js +1117 -1011
- package/dist/worker.esm.min.js +1 -1
- package/dist/worker.esm.min.js.map +1 -1
- package/dist/worker.js +4869 -5243
- package/dist/worker.min.cjs +1 -1
- package/dist/worker.min.cjs.map +1 -1
- package/dist/worker.min.js +1 -1
- package/dist/worker.min.js.map +1 -1
- package/dist/worker.module.js +5606 -5054
- package/dist/worker.module.min.js +1 -1
- package/dist/worker.module.min.js.map +1 -1
- package/package.json +11 -11
- package/src/core.ts +2 -2
package/dist/worker.esm.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
1
|
+
import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, Plugin, isObject, Matrix, isUndefined, isString, getMatrixData, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4, isNumber } from "@leafer/core";
|
|
2
|
+
|
|
3
|
+
export * from "@leafer/core";
|
|
4
|
+
|
|
5
|
+
export { LeaferImage } from "@leafer/core";
|
|
6
|
+
|
|
7
|
+
import { HitCanvasManager, InteractionBase } from "@leafer-ui/core";
|
|
8
|
+
|
|
9
|
+
export * from "@leafer-ui/core";
|
|
10
|
+
|
|
11
|
+
import { PaintImage, Paint, ColorConvert, PaintGradient, Export, Group, TextConvert, Effect } from "@leafer-ui/draw";
|
|
7
12
|
|
|
8
13
|
class LeaferCanvas extends LeaferCanvasBase {
|
|
9
|
-
get allowBackgroundColor() {
|
|
14
|
+
get allowBackgroundColor() {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
10
17
|
init() {
|
|
11
18
|
this.__createView();
|
|
12
19
|
this.__createContext();
|
|
@@ -16,7 +23,7 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
16
23
|
this.view = Platform.origin.createCanvas(1, 1);
|
|
17
24
|
}
|
|
18
25
|
updateViewSize() {
|
|
19
|
-
const { width, height, pixelRatio } = this;
|
|
26
|
+
const {width: width, height: height, pixelRatio: pixelRatio} = this;
|
|
20
27
|
this.view.width = Math.ceil(width * pixelRatio);
|
|
21
28
|
this.view.height = Math.ceil(height * pixelRatio);
|
|
22
29
|
this.clientBounds = this.bounds;
|
|
@@ -24,35 +31,44 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
24
31
|
}
|
|
25
32
|
|
|
26
33
|
canvasPatch(OffscreenCanvasRenderingContext2D.prototype);
|
|
34
|
+
|
|
27
35
|
canvasPatch(Path2D.prototype);
|
|
28
36
|
|
|
29
|
-
const { mineType
|
|
37
|
+
const {mineType: mineType} = FileHelper;
|
|
38
|
+
|
|
30
39
|
Object.assign(Creator, {
|
|
31
40
|
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
32
|
-
image:
|
|
41
|
+
image: options => new LeaferImage(options)
|
|
33
42
|
});
|
|
43
|
+
|
|
34
44
|
function useCanvas(_canvasType, _power) {
|
|
35
45
|
Platform.origin = {
|
|
36
46
|
createCanvas: (width, height) => new OffscreenCanvas(width, height),
|
|
37
|
-
canvasToDataURL: (canvas, type, quality) => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
canvasToDataURL: (canvas, type, quality) => new Promise((resolve, reject) => {
|
|
48
|
+
canvas.convertToBlob({
|
|
49
|
+
type: mineType(type),
|
|
50
|
+
quality: quality
|
|
51
|
+
}).then(blob => {
|
|
52
|
+
var reader = new FileReader;
|
|
53
|
+
reader.onload = e => resolve(e.target.result);
|
|
54
|
+
reader.onerror = e => reject(e);
|
|
55
|
+
reader.readAsDataURL(blob);
|
|
56
|
+
}).catch(e => {
|
|
57
|
+
reject(e);
|
|
47
58
|
});
|
|
59
|
+
}),
|
|
60
|
+
canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({
|
|
61
|
+
type: mineType(type),
|
|
62
|
+
quality: quality
|
|
63
|
+
}),
|
|
64
|
+
canvasSaveAs: (_canvas, _filename, _quality) => new Promise(resolve => resolve()),
|
|
65
|
+
download(_url, _filename) {
|
|
66
|
+
return undefined;
|
|
48
67
|
},
|
|
49
|
-
canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({ type: mineType(type), quality }),
|
|
50
|
-
canvasSaveAs: (_canvas, _filename, _quality) => new Promise((resolve) => resolve()),
|
|
51
|
-
download(_url, _filename) { return undefined; },
|
|
52
68
|
loadImage(src) {
|
|
53
69
|
return new Promise((resolve, reject) => {
|
|
54
|
-
let req = new XMLHttpRequest
|
|
55
|
-
req.open(
|
|
70
|
+
let req = new XMLHttpRequest;
|
|
71
|
+
req.open("GET", Platform.image.getRealURL(src), true);
|
|
56
72
|
req.responseType = "blob";
|
|
57
73
|
req.onload = () => {
|
|
58
74
|
createImageBitmap(req.response).then(img => {
|
|
@@ -61,7 +77,7 @@ function useCanvas(_canvasType, _power) {
|
|
|
61
77
|
reject(e);
|
|
62
78
|
});
|
|
63
79
|
};
|
|
64
|
-
req.onerror =
|
|
80
|
+
req.onerror = e => reject(e);
|
|
65
81
|
req.send();
|
|
66
82
|
});
|
|
67
83
|
}
|
|
@@ -69,55 +85,66 @@ function useCanvas(_canvasType, _power) {
|
|
|
69
85
|
Platform.canvas = Creator.canvas();
|
|
70
86
|
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
71
87
|
}
|
|
72
|
-
|
|
88
|
+
|
|
89
|
+
Platform.name = "web";
|
|
90
|
+
|
|
73
91
|
Platform.isWorker = true;
|
|
92
|
+
|
|
74
93
|
Platform.backgrounder = true;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
|
|
95
|
+
Platform.requestRender = function(render) {
|
|
96
|
+
requestAnimationFrame(render);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
defineKey(Platform, "devicePixelRatio", {
|
|
100
|
+
get() {
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const {userAgent: userAgent} = navigator;
|
|
106
|
+
|
|
78
107
|
if (userAgent.indexOf("Firefox") > -1) {
|
|
79
108
|
Platform.conicGradientRotate90 = true;
|
|
80
109
|
Platform.intWheelDeltaY = true;
|
|
81
|
-
}
|
|
82
|
-
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
110
|
+
} else if (/iPhone|iPad|iPod/.test(navigator.userAgent) || /Macintosh/.test(navigator.userAgent) && /Version\/[\d.]+.*Safari/.test(navigator.userAgent)) {
|
|
83
111
|
Platform.fullImageShadow = true;
|
|
84
112
|
}
|
|
85
|
-
|
|
86
|
-
|
|
113
|
+
|
|
114
|
+
if (userAgent.indexOf("Windows") > -1) {
|
|
115
|
+
Platform.os = "Windows";
|
|
87
116
|
Platform.intWheelDeltaY = true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
else if (userAgent.indexOf('Linux') > -1) {
|
|
93
|
-
Platform.os = 'Linux';
|
|
117
|
+
} else if (userAgent.indexOf("Mac") > -1) {
|
|
118
|
+
Platform.os = "Mac";
|
|
119
|
+
} else if (userAgent.indexOf("Linux") > -1) {
|
|
120
|
+
Platform.os = "Linux";
|
|
94
121
|
}
|
|
95
122
|
|
|
96
123
|
class Watcher {
|
|
97
|
-
get childrenChanged() {
|
|
124
|
+
get childrenChanged() {
|
|
125
|
+
return this.hasAdd || this.hasRemove || this.hasVisible;
|
|
126
|
+
}
|
|
98
127
|
get updatedList() {
|
|
99
128
|
if (this.hasRemove) {
|
|
100
|
-
const updatedList = new LeafList
|
|
101
|
-
this.__updatedList.list.forEach(item => {
|
|
102
|
-
updatedList.add(item);
|
|
129
|
+
const updatedList = new LeafList;
|
|
130
|
+
this.__updatedList.list.forEach(item => {
|
|
131
|
+
if (item.leafer) updatedList.add(item);
|
|
132
|
+
});
|
|
103
133
|
return updatedList;
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
134
|
+
} else {
|
|
106
135
|
return this.__updatedList;
|
|
107
136
|
}
|
|
108
137
|
}
|
|
109
138
|
constructor(target, userConfig) {
|
|
110
139
|
this.totalTimes = 0;
|
|
111
140
|
this.config = {};
|
|
112
|
-
this.__updatedList = new LeafList
|
|
141
|
+
this.__updatedList = new LeafList;
|
|
113
142
|
this.target = target;
|
|
114
|
-
if (userConfig)
|
|
115
|
-
this.config = DataHelper.default(userConfig, this.config);
|
|
143
|
+
if (userConfig) this.config = DataHelper.default(userConfig, this.config);
|
|
116
144
|
this.__listenEvents();
|
|
117
145
|
}
|
|
118
146
|
start() {
|
|
119
|
-
if (this.disabled)
|
|
120
|
-
return;
|
|
147
|
+
if (this.disabled) return;
|
|
121
148
|
this.running = true;
|
|
122
149
|
}
|
|
123
150
|
stop() {
|
|
@@ -130,8 +157,7 @@ class Watcher {
|
|
|
130
157
|
}
|
|
131
158
|
update() {
|
|
132
159
|
this.changed = true;
|
|
133
|
-
if (this.running)
|
|
134
|
-
this.target.emit(RenderEvent.REQUEST);
|
|
160
|
+
if (this.running) this.target.emit(RenderEvent.REQUEST);
|
|
135
161
|
}
|
|
136
162
|
__onAttrChange(event) {
|
|
137
163
|
this.__updatedList.add(event.target);
|
|
@@ -141,8 +167,7 @@ class Watcher {
|
|
|
141
167
|
if (event.type === ChildEvent.ADD) {
|
|
142
168
|
this.hasAdd = true;
|
|
143
169
|
this.__pushChild(event.child);
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
170
|
+
} else {
|
|
146
171
|
this.hasRemove = true;
|
|
147
172
|
this.__updatedList.add(event.parent);
|
|
148
173
|
}
|
|
@@ -150,28 +175,22 @@ class Watcher {
|
|
|
150
175
|
}
|
|
151
176
|
__pushChild(child) {
|
|
152
177
|
this.__updatedList.add(child);
|
|
153
|
-
if (child.isBranch)
|
|
154
|
-
this.__loopChildren(child);
|
|
178
|
+
if (child.isBranch) this.__loopChildren(child);
|
|
155
179
|
}
|
|
156
180
|
__loopChildren(parent) {
|
|
157
|
-
const { children
|
|
158
|
-
for (let i = 0, len = children.length; i < len; i++)
|
|
159
|
-
this.__pushChild(children[i]);
|
|
181
|
+
const {children: children} = parent;
|
|
182
|
+
for (let i = 0, len = children.length; i < len; i++) this.__pushChild(children[i]);
|
|
160
183
|
}
|
|
161
184
|
__onRquestData() {
|
|
162
|
-
this.target.emitEvent(new WatchEvent(WatchEvent.DATA, {
|
|
163
|
-
|
|
185
|
+
this.target.emitEvent(new WatchEvent(WatchEvent.DATA, {
|
|
186
|
+
updatedList: this.updatedList
|
|
187
|
+
}));
|
|
188
|
+
this.__updatedList = new LeafList;
|
|
164
189
|
this.totalTimes++;
|
|
165
190
|
this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
|
|
166
191
|
}
|
|
167
192
|
__listenEvents() {
|
|
168
|
-
this.__eventIds = [
|
|
169
|
-
this.target.on_([
|
|
170
|
-
[PropertyEvent.CHANGE, this.__onAttrChange, this],
|
|
171
|
-
[[ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this],
|
|
172
|
-
[WatchEvent.REQUEST, this.__onRquestData, this]
|
|
173
|
-
])
|
|
174
|
-
];
|
|
193
|
+
this.__eventIds = [ this.target.on_([ [ PropertyEvent.CHANGE, this.__onAttrChange, this ], [ [ ChildEvent.ADD, ChildEvent.REMOVE ], this.__onChildEvent, this ], [ WatchEvent.REQUEST, this.__onRquestData, this ] ]) ];
|
|
175
194
|
}
|
|
176
195
|
__removeListenEvents() {
|
|
177
196
|
this.target.off_(this.__eventIds);
|
|
@@ -185,8 +204,10 @@ class Watcher {
|
|
|
185
204
|
}
|
|
186
205
|
}
|
|
187
206
|
|
|
188
|
-
const {
|
|
189
|
-
|
|
207
|
+
const {updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange} = LeafHelper;
|
|
208
|
+
|
|
209
|
+
const {pushAllChildBranch: pushAllChildBranch, pushAllParent: pushAllParent} = BranchHelper;
|
|
210
|
+
|
|
190
211
|
function updateMatrix(updateList, levelList) {
|
|
191
212
|
let layout;
|
|
192
213
|
updateList.list.forEach(leaf => {
|
|
@@ -195,19 +216,17 @@ function updateMatrix(updateList, levelList) {
|
|
|
195
216
|
if (layout.matrixChanged) {
|
|
196
217
|
updateAllMatrix$1(leaf, true);
|
|
197
218
|
levelList.add(leaf);
|
|
198
|
-
if (leaf.isBranch)
|
|
199
|
-
pushAllChildBranch(leaf, levelList);
|
|
219
|
+
if (leaf.isBranch) pushAllChildBranch(leaf, levelList);
|
|
200
220
|
pushAllParent(leaf, levelList);
|
|
201
|
-
}
|
|
202
|
-
else if (layout.boundsChanged) {
|
|
221
|
+
} else if (layout.boundsChanged) {
|
|
203
222
|
levelList.add(leaf);
|
|
204
|
-
if (leaf.isBranch)
|
|
205
|
-
leaf.__tempNumber = 0;
|
|
223
|
+
if (leaf.isBranch) leaf.__tempNumber = 0;
|
|
206
224
|
pushAllParent(leaf, levelList);
|
|
207
225
|
}
|
|
208
226
|
}
|
|
209
227
|
});
|
|
210
228
|
}
|
|
229
|
+
|
|
211
230
|
function updateBounds(boundsList) {
|
|
212
231
|
let list, branch, children;
|
|
213
232
|
boundsList.sort(true);
|
|
@@ -227,18 +246,19 @@ function updateBounds(boundsList) {
|
|
|
227
246
|
}
|
|
228
247
|
});
|
|
229
248
|
}
|
|
249
|
+
|
|
230
250
|
function updateChange(updateList) {
|
|
231
251
|
updateList.list.forEach(updateOneChange);
|
|
232
252
|
}
|
|
233
253
|
|
|
234
|
-
const { worldBounds
|
|
254
|
+
const {worldBounds: worldBounds} = LeafBoundsHelper;
|
|
255
|
+
|
|
235
256
|
class LayoutBlockData {
|
|
236
257
|
constructor(list) {
|
|
237
|
-
this.updatedBounds = new Bounds
|
|
238
|
-
this.beforeBounds = new Bounds
|
|
239
|
-
this.afterBounds = new Bounds
|
|
240
|
-
if (list
|
|
241
|
-
list = new LeafList(list);
|
|
258
|
+
this.updatedBounds = new Bounds;
|
|
259
|
+
this.beforeBounds = new Bounds;
|
|
260
|
+
this.afterBounds = new Bounds;
|
|
261
|
+
if (isArray(list)) list = new LeafList(list);
|
|
242
262
|
this.updatedList = list;
|
|
243
263
|
}
|
|
244
264
|
setBefore() {
|
|
@@ -246,7 +266,7 @@ class LayoutBlockData {
|
|
|
246
266
|
}
|
|
247
267
|
setAfter() {
|
|
248
268
|
this.afterBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
249
|
-
this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
|
|
269
|
+
this.updatedBounds.setList([ this.beforeBounds, this.afterBounds ]);
|
|
250
270
|
}
|
|
251
271
|
merge(data) {
|
|
252
272
|
this.updatedList.addList(data.updatedList.list);
|
|
@@ -259,21 +279,21 @@ class LayoutBlockData {
|
|
|
259
279
|
}
|
|
260
280
|
}
|
|
261
281
|
|
|
262
|
-
const { updateAllMatrix, updateAllChange } = LeafHelper;
|
|
263
|
-
|
|
282
|
+
const {updateAllMatrix: updateAllMatrix, updateAllChange: updateAllChange} = LeafHelper;
|
|
283
|
+
|
|
284
|
+
const debug$1 = Debug.get("Layouter");
|
|
285
|
+
|
|
264
286
|
class Layouter {
|
|
265
287
|
constructor(target, userConfig) {
|
|
266
288
|
this.totalTimes = 0;
|
|
267
289
|
this.config = {};
|
|
268
|
-
this.__levelList = new LeafLevelList
|
|
290
|
+
this.__levelList = new LeafLevelList;
|
|
269
291
|
this.target = target;
|
|
270
|
-
if (userConfig)
|
|
271
|
-
this.config = DataHelper.default(userConfig, this.config);
|
|
292
|
+
if (userConfig) this.config = DataHelper.default(userConfig, this.config);
|
|
272
293
|
this.__listenEvents();
|
|
273
294
|
}
|
|
274
295
|
start() {
|
|
275
|
-
if (this.disabled)
|
|
276
|
-
return;
|
|
296
|
+
if (this.disabled) return;
|
|
277
297
|
this.running = true;
|
|
278
298
|
}
|
|
279
299
|
stop() {
|
|
@@ -285,16 +305,14 @@ class Layouter {
|
|
|
285
305
|
this.disabled = true;
|
|
286
306
|
}
|
|
287
307
|
layout() {
|
|
288
|
-
if (this.layouting || !this.running)
|
|
289
|
-
|
|
290
|
-
const { target } = this;
|
|
308
|
+
if (this.layouting || !this.running) return;
|
|
309
|
+
const {target: target} = this;
|
|
291
310
|
this.times = 0;
|
|
292
311
|
try {
|
|
293
312
|
target.emit(LayoutEvent.START);
|
|
294
313
|
this.layoutOnce();
|
|
295
314
|
target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
296
|
-
}
|
|
297
|
-
catch (e) {
|
|
315
|
+
} catch (e) {
|
|
298
316
|
debug$1.error(e);
|
|
299
317
|
}
|
|
300
318
|
this.layoutedBlocks = null;
|
|
@@ -302,24 +320,20 @@ class Layouter {
|
|
|
302
320
|
layoutAgain() {
|
|
303
321
|
if (this.layouting) {
|
|
304
322
|
this.waitAgain = true;
|
|
305
|
-
}
|
|
306
|
-
else {
|
|
323
|
+
} else {
|
|
307
324
|
this.layoutOnce();
|
|
308
325
|
}
|
|
309
326
|
}
|
|
310
327
|
layoutOnce() {
|
|
311
|
-
if (this.layouting)
|
|
312
|
-
|
|
313
|
-
if (this.times > 3)
|
|
314
|
-
return debug$1.warn('layout max times');
|
|
328
|
+
if (this.layouting) return debug$1.warn("layouting");
|
|
329
|
+
if (this.times > 3) return debug$1.warn("layout max times");
|
|
315
330
|
this.times++;
|
|
316
331
|
this.totalTimes++;
|
|
317
332
|
this.layouting = true;
|
|
318
333
|
this.target.emit(WatchEvent.REQUEST);
|
|
319
334
|
if (this.totalTimes > 1) {
|
|
320
335
|
this.partLayout();
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
336
|
+
} else {
|
|
323
337
|
this.fullLayout();
|
|
324
338
|
}
|
|
325
339
|
this.layouting = false;
|
|
@@ -330,11 +344,10 @@ class Layouter {
|
|
|
330
344
|
}
|
|
331
345
|
partLayout() {
|
|
332
346
|
var _a;
|
|
333
|
-
if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length))
|
|
334
|
-
|
|
335
|
-
const
|
|
336
|
-
const {
|
|
337
|
-
const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
|
|
347
|
+
if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length)) return;
|
|
348
|
+
const t = Run.start("PartLayout");
|
|
349
|
+
const {target: target, __updatedList: updateList} = this;
|
|
350
|
+
const {BEFORE: BEFORE, LAYOUT: LAYOUT, AFTER: AFTER} = LayoutEvent;
|
|
338
351
|
const blocks = this.getBlocks(updateList);
|
|
339
352
|
blocks.forEach(item => item.setBefore());
|
|
340
353
|
target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
|
|
@@ -343,8 +356,7 @@ class Layouter {
|
|
|
343
356
|
updateMatrix(updateList, this.__levelList);
|
|
344
357
|
updateBounds(this.__levelList);
|
|
345
358
|
updateChange(updateList);
|
|
346
|
-
if (this.extraBlock)
|
|
347
|
-
blocks.push(this.extraBlock);
|
|
359
|
+
if (this.extraBlock) blocks.push(this.extraBlock);
|
|
348
360
|
blocks.forEach(item => item.setAfter());
|
|
349
361
|
target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
|
|
350
362
|
target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
|
|
@@ -354,13 +366,15 @@ class Layouter {
|
|
|
354
366
|
Run.end(t);
|
|
355
367
|
}
|
|
356
368
|
fullLayout() {
|
|
357
|
-
const t = Run.start(
|
|
358
|
-
const { target
|
|
359
|
-
const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
|
|
369
|
+
const t = Run.start("FullLayout");
|
|
370
|
+
const {target: target} = this;
|
|
371
|
+
const {BEFORE: BEFORE, LAYOUT: LAYOUT, AFTER: AFTER} = LayoutEvent;
|
|
360
372
|
const blocks = this.getBlocks(new LeafList(target));
|
|
361
373
|
target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
|
|
362
374
|
Layouter.fullLayout(target);
|
|
363
|
-
blocks.forEach(item => {
|
|
375
|
+
blocks.forEach(item => {
|
|
376
|
+
item.setAfter();
|
|
377
|
+
});
|
|
364
378
|
target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
|
|
365
379
|
target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
|
|
366
380
|
this.addBlocks(blocks);
|
|
@@ -368,15 +382,12 @@ class Layouter {
|
|
|
368
382
|
}
|
|
369
383
|
static fullLayout(target) {
|
|
370
384
|
updateAllMatrix(target, true);
|
|
371
|
-
if (target.isBranch)
|
|
372
|
-
BranchHelper.updateBounds(target);
|
|
373
|
-
else
|
|
374
|
-
LeafHelper.updateBounds(target);
|
|
385
|
+
if (target.isBranch) BranchHelper.updateBounds(target); else LeafHelper.updateBounds(target);
|
|
375
386
|
updateAllChange(target);
|
|
376
387
|
}
|
|
377
388
|
addExtra(leaf) {
|
|
378
389
|
if (!this.__updatedList.has(leaf)) {
|
|
379
|
-
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
390
|
+
const {updatedList: updatedList, beforeBounds: beforeBounds} = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
380
391
|
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
381
392
|
updatedList.add(leaf);
|
|
382
393
|
}
|
|
@@ -385,7 +396,7 @@ class Layouter {
|
|
|
385
396
|
return new LayoutBlockData(data);
|
|
386
397
|
}
|
|
387
398
|
getBlocks(list) {
|
|
388
|
-
return [this.createBlock(list)];
|
|
399
|
+
return [ this.createBlock(list) ];
|
|
389
400
|
}
|
|
390
401
|
addBlocks(current) {
|
|
391
402
|
this.layoutedBlocks ? this.layoutedBlocks.push(...current) : this.layoutedBlocks = current;
|
|
@@ -394,13 +405,7 @@ class Layouter {
|
|
|
394
405
|
this.__updatedList = event.data.updatedList;
|
|
395
406
|
}
|
|
396
407
|
__listenEvents() {
|
|
397
|
-
this.__eventIds = [
|
|
398
|
-
this.target.on_([
|
|
399
|
-
[LayoutEvent.REQUEST, this.layout, this],
|
|
400
|
-
[LayoutEvent.AGAIN, this.layoutAgain, this],
|
|
401
|
-
[WatchEvent.DATA, this.__onReceiveWatchData, this]
|
|
402
|
-
])
|
|
403
|
-
];
|
|
408
|
+
this.__eventIds = [ this.target.on_([ [ LayoutEvent.REQUEST, this.layout, this ], [ LayoutEvent.AGAIN, this.layoutAgain, this ], [ WatchEvent.DATA, this.__onReceiveWatchData, this ] ]) ];
|
|
404
409
|
}
|
|
405
410
|
__removeListenEvents() {
|
|
406
411
|
this.target.off_(this.__eventIds);
|
|
@@ -414,9 +419,12 @@ class Layouter {
|
|
|
414
419
|
}
|
|
415
420
|
}
|
|
416
421
|
|
|
417
|
-
const debug = Debug.get(
|
|
422
|
+
const debug = Debug.get("Renderer");
|
|
423
|
+
|
|
418
424
|
class Renderer {
|
|
419
|
-
get needFill() {
|
|
425
|
+
get needFill() {
|
|
426
|
+
return !!(!this.canvas.allowBackgroundColor && this.config.fill);
|
|
427
|
+
}
|
|
420
428
|
constructor(target, canvas, userConfig) {
|
|
421
429
|
this.FPS = 60;
|
|
422
430
|
this.totalTimes = 0;
|
|
@@ -427,8 +435,7 @@ class Renderer {
|
|
|
427
435
|
};
|
|
428
436
|
this.target = target;
|
|
429
437
|
this.canvas = canvas;
|
|
430
|
-
if (userConfig)
|
|
431
|
-
this.config = DataHelper.default(userConfig, this.config);
|
|
438
|
+
if (userConfig) this.config = DataHelper.default(userConfig, this.config);
|
|
432
439
|
this.__listenEvents();
|
|
433
440
|
}
|
|
434
441
|
start() {
|
|
@@ -439,8 +446,7 @@ class Renderer {
|
|
|
439
446
|
this.running = false;
|
|
440
447
|
}
|
|
441
448
|
update(change = true) {
|
|
442
|
-
if (!this.changed)
|
|
443
|
-
this.changed = change;
|
|
449
|
+
if (!this.changed) this.changed = change;
|
|
444
450
|
this.__requestRender();
|
|
445
451
|
}
|
|
446
452
|
requestLayout() {
|
|
@@ -448,7 +454,7 @@ class Renderer {
|
|
|
448
454
|
}
|
|
449
455
|
checkRender() {
|
|
450
456
|
if (this.running) {
|
|
451
|
-
const { target
|
|
457
|
+
const {target: target} = this;
|
|
452
458
|
if (target.isApp) {
|
|
453
459
|
target.emit(RenderEvent.CHILD_START, target);
|
|
454
460
|
target.children.forEach(leafer => {
|
|
@@ -457,54 +463,47 @@ class Renderer {
|
|
|
457
463
|
});
|
|
458
464
|
target.emit(RenderEvent.CHILD_END, target);
|
|
459
465
|
}
|
|
460
|
-
if (this.changed && this.canvas.view)
|
|
461
|
-
this.render();
|
|
466
|
+
if (this.changed && this.canvas.view) this.render();
|
|
462
467
|
this.target.emit(RenderEvent.NEXT);
|
|
463
468
|
}
|
|
464
469
|
}
|
|
465
470
|
render(callback) {
|
|
466
|
-
if (!(this.running && this.canvas.view))
|
|
467
|
-
|
|
468
|
-
const { target } = this;
|
|
471
|
+
if (!(this.running && this.canvas.view)) return this.update();
|
|
472
|
+
const {target: target} = this;
|
|
469
473
|
this.times = 0;
|
|
470
|
-
this.totalBounds = new Bounds
|
|
471
|
-
debug.log(target.innerName,
|
|
474
|
+
this.totalBounds = new Bounds;
|
|
475
|
+
debug.log(target.innerName, "---\x3e");
|
|
472
476
|
try {
|
|
473
477
|
this.emitRender(RenderEvent.START);
|
|
474
478
|
this.renderOnce(callback);
|
|
475
479
|
this.emitRender(RenderEvent.END, this.totalBounds);
|
|
476
480
|
ImageManager.clearRecycled();
|
|
477
|
-
}
|
|
478
|
-
catch (e) {
|
|
481
|
+
} catch (e) {
|
|
479
482
|
this.rendering = false;
|
|
480
483
|
debug.error(e);
|
|
481
484
|
}
|
|
482
|
-
debug.log(
|
|
485
|
+
debug.log("-------------|");
|
|
483
486
|
}
|
|
484
487
|
renderAgain() {
|
|
485
488
|
if (this.rendering) {
|
|
486
489
|
this.waitAgain = true;
|
|
487
|
-
}
|
|
488
|
-
else {
|
|
490
|
+
} else {
|
|
489
491
|
this.renderOnce();
|
|
490
492
|
}
|
|
491
493
|
}
|
|
492
494
|
renderOnce(callback) {
|
|
493
|
-
if (this.rendering)
|
|
494
|
-
|
|
495
|
-
if (this.times > 3)
|
|
496
|
-
return debug.warn('render max times');
|
|
495
|
+
if (this.rendering) return debug.warn("rendering");
|
|
496
|
+
if (this.times > 3) return debug.warn("render max times");
|
|
497
497
|
this.times++;
|
|
498
498
|
this.totalTimes++;
|
|
499
499
|
this.rendering = true;
|
|
500
500
|
this.changed = false;
|
|
501
|
-
this.renderBounds = new Bounds
|
|
501
|
+
this.renderBounds = new Bounds;
|
|
502
502
|
this.renderOptions = {};
|
|
503
503
|
if (callback) {
|
|
504
504
|
this.emitRender(RenderEvent.BEFORE);
|
|
505
505
|
callback();
|
|
506
|
-
}
|
|
507
|
-
else {
|
|
506
|
+
} else {
|
|
508
507
|
this.requestLayout();
|
|
509
508
|
if (this.ignore) {
|
|
510
509
|
this.ignore = this.rendering = false;
|
|
@@ -513,8 +512,7 @@ class Renderer {
|
|
|
513
512
|
this.emitRender(RenderEvent.BEFORE);
|
|
514
513
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
515
514
|
this.partRender();
|
|
516
|
-
}
|
|
517
|
-
else {
|
|
515
|
+
} else {
|
|
518
516
|
this.fullRender();
|
|
519
517
|
}
|
|
520
518
|
}
|
|
@@ -528,16 +526,16 @@ class Renderer {
|
|
|
528
526
|
}
|
|
529
527
|
}
|
|
530
528
|
partRender() {
|
|
531
|
-
const { canvas, updateBlocks: list
|
|
532
|
-
if (!list)
|
|
533
|
-
return;
|
|
529
|
+
const {canvas: canvas, updateBlocks: list} = this;
|
|
530
|
+
if (!list) return;
|
|
534
531
|
this.mergeBlocks();
|
|
535
|
-
list.forEach(block => {
|
|
536
|
-
this.clipRender(block);
|
|
532
|
+
list.forEach(block => {
|
|
533
|
+
if (canvas.bounds.hit(block) && !block.isEmpty()) this.clipRender(block);
|
|
534
|
+
});
|
|
537
535
|
}
|
|
538
536
|
clipRender(block) {
|
|
539
|
-
const t = Run.start(
|
|
540
|
-
const { canvas
|
|
537
|
+
const t = Run.start("PartRender");
|
|
538
|
+
const {canvas: canvas} = this, bounds = block.getIntersect(canvas.bounds), realBounds = new Bounds(bounds);
|
|
541
539
|
canvas.save();
|
|
542
540
|
bounds.spread(Renderer.clipSpread).ceil();
|
|
543
541
|
canvas.clearWorld(bounds, true);
|
|
@@ -547,8 +545,8 @@ class Renderer {
|
|
|
547
545
|
Run.end(t);
|
|
548
546
|
}
|
|
549
547
|
fullRender() {
|
|
550
|
-
const t = Run.start(
|
|
551
|
-
const { canvas
|
|
548
|
+
const t = Run.start("FullRender");
|
|
549
|
+
const {canvas: canvas} = this;
|
|
552
550
|
canvas.save();
|
|
553
551
|
canvas.clear();
|
|
554
552
|
this.__render(canvas.bounds);
|
|
@@ -556,11 +554,14 @@ class Renderer {
|
|
|
556
554
|
Run.end(t);
|
|
557
555
|
}
|
|
558
556
|
__render(bounds, realBounds) {
|
|
559
|
-
const { canvas
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
557
|
+
const {canvas: canvas} = this, includes = bounds.includes(this.target.__world), options = includes ? {
|
|
558
|
+
includes: includes
|
|
559
|
+
} : {
|
|
560
|
+
bounds: bounds,
|
|
561
|
+
includes: includes
|
|
562
|
+
};
|
|
563
|
+
if (this.needFill) canvas.fillWorld(bounds, this.config.fill);
|
|
564
|
+
if (Debug.showRepaint) Debug.drawRepaint(canvas, bounds);
|
|
564
565
|
this.target.__render(canvas, options);
|
|
565
566
|
this.renderBounds = realBounds = realBounds || bounds;
|
|
566
567
|
this.renderOptions = options;
|
|
@@ -568,14 +569,13 @@ class Renderer {
|
|
|
568
569
|
canvas.updateRender(realBounds);
|
|
569
570
|
}
|
|
570
571
|
addBlock(block) {
|
|
571
|
-
if (!this.updateBlocks)
|
|
572
|
-
this.updateBlocks = [];
|
|
572
|
+
if (!this.updateBlocks) this.updateBlocks = [];
|
|
573
573
|
this.updateBlocks.push(block);
|
|
574
574
|
}
|
|
575
575
|
mergeBlocks() {
|
|
576
|
-
const {
|
|
576
|
+
const {updateBlocks: list} = this;
|
|
577
577
|
if (list) {
|
|
578
|
-
const bounds = new Bounds
|
|
578
|
+
const bounds = new Bounds;
|
|
579
579
|
bounds.setList(list);
|
|
580
580
|
list.length = 0;
|
|
581
581
|
list.push(bounds);
|
|
@@ -583,26 +583,23 @@ class Renderer {
|
|
|
583
583
|
}
|
|
584
584
|
__requestRender() {
|
|
585
585
|
const target = this.target;
|
|
586
|
-
if (this.requestTime || !target)
|
|
587
|
-
|
|
588
|
-
if (target.parentApp)
|
|
589
|
-
return target.parentApp.requestRender(false);
|
|
586
|
+
if (this.requestTime || !target) return;
|
|
587
|
+
if (target.parentApp) return target.parentApp.requestRender(false);
|
|
590
588
|
const requestTime = this.requestTime = Date.now();
|
|
591
589
|
Platform.requestRender(() => {
|
|
592
|
-
this.FPS = Math.min(60, Math.ceil(
|
|
590
|
+
this.FPS = Math.min(60, Math.ceil(1e3 / (Date.now() - requestTime)));
|
|
593
591
|
this.requestTime = 0;
|
|
594
592
|
this.checkRender();
|
|
595
593
|
});
|
|
596
594
|
}
|
|
597
595
|
__onResize(e) {
|
|
598
|
-
if (this.canvas.unreal)
|
|
599
|
-
return;
|
|
596
|
+
if (this.canvas.unreal) return;
|
|
600
597
|
if (e.bigger || !e.samePixelRatio) {
|
|
601
|
-
const { width, height } = e.old;
|
|
598
|
+
const {width: width, height: height} = e.old;
|
|
602
599
|
const bounds = new Bounds(0, 0, width, height);
|
|
603
600
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
604
601
|
this.addBlock(this.canvas.bounds);
|
|
605
|
-
this.target.forceUpdate(
|
|
602
|
+
this.target.forceUpdate("surface");
|
|
606
603
|
return;
|
|
607
604
|
}
|
|
608
605
|
}
|
|
@@ -610,34 +607,24 @@ class Renderer {
|
|
|
610
607
|
this.update();
|
|
611
608
|
}
|
|
612
609
|
__onLayoutEnd(event) {
|
|
613
|
-
if (event.data)
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
623
|
-
}
|
|
624
|
-
return empty;
|
|
625
|
-
});
|
|
626
|
-
this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
|
|
610
|
+
if (event.data) event.data.map(item => {
|
|
611
|
+
let empty;
|
|
612
|
+
if (item.updatedList) item.updatedList.list.some(leaf => {
|
|
613
|
+
empty = !leaf.__world.width || !leaf.__world.height;
|
|
614
|
+
if (empty) {
|
|
615
|
+
if (!leaf.isLeafer) debug.tip(leaf.innerName, ": empty");
|
|
616
|
+
empty = !leaf.isBranch || leaf.isBranchLeaf;
|
|
617
|
+
}
|
|
618
|
+
return empty;
|
|
627
619
|
});
|
|
620
|
+
this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
|
|
621
|
+
});
|
|
628
622
|
}
|
|
629
623
|
emitRender(type, bounds, options) {
|
|
630
624
|
this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
|
|
631
625
|
}
|
|
632
626
|
__listenEvents() {
|
|
633
|
-
this.__eventIds = [
|
|
634
|
-
this.target.on_([
|
|
635
|
-
[RenderEvent.REQUEST, this.update, this],
|
|
636
|
-
[LayoutEvent.END, this.__onLayoutEnd, this],
|
|
637
|
-
[RenderEvent.AGAIN, this.renderAgain, this],
|
|
638
|
-
[ResizeEvent.RESIZE, this.__onResize, this]
|
|
639
|
-
])
|
|
640
|
-
];
|
|
627
|
+
this.__eventIds = [ this.target.on_([ [ RenderEvent.REQUEST, this.update, this ], [ LayoutEvent.END, this.__onLayoutEnd, this ], [ RenderEvent.AGAIN, this.renderAgain, this ], [ ResizeEvent.RESIZE, this.__onResize, this ] ]) ];
|
|
641
628
|
}
|
|
642
629
|
__removeListenEvents() {
|
|
643
630
|
this.target.off_(this.__eventIds);
|
|
@@ -650,82 +637,104 @@ class Renderer {
|
|
|
650
637
|
}
|
|
651
638
|
}
|
|
652
639
|
}
|
|
640
|
+
|
|
653
641
|
Renderer.clipSpread = 10;
|
|
654
642
|
|
|
655
|
-
const { hitRadiusPoint
|
|
643
|
+
const {hitRadiusPoint: hitRadiusPoint} = BoundsHelper;
|
|
644
|
+
|
|
656
645
|
class Picker {
|
|
657
646
|
constructor(target, selector) {
|
|
658
647
|
this.target = target;
|
|
659
648
|
this.selector = selector;
|
|
660
649
|
}
|
|
661
650
|
getByPoint(hitPoint, hitRadius, options) {
|
|
662
|
-
if (!hitRadius)
|
|
663
|
-
|
|
664
|
-
if (!options)
|
|
665
|
-
options = {};
|
|
651
|
+
if (!hitRadius) hitRadius = 0;
|
|
652
|
+
if (!options) options = {};
|
|
666
653
|
const through = options.through || false;
|
|
667
654
|
const ignoreHittable = options.ignoreHittable || false;
|
|
668
655
|
const target = options.target || this.target;
|
|
669
656
|
this.exclude = options.exclude || null;
|
|
670
|
-
this.point = {
|
|
657
|
+
this.point = {
|
|
658
|
+
x: hitPoint.x,
|
|
659
|
+
y: hitPoint.y,
|
|
660
|
+
radiusX: hitRadius,
|
|
661
|
+
radiusY: hitRadius
|
|
662
|
+
};
|
|
671
663
|
this.findList = new LeafList(options.findList);
|
|
672
|
-
if (!options.findList)
|
|
673
|
-
|
|
674
|
-
|
|
664
|
+
if (!options.findList) this.hitBranch(target.isBranchLeaf ? {
|
|
665
|
+
children: [ target ]
|
|
666
|
+
} : target);
|
|
667
|
+
const {list: list} = this.findList;
|
|
675
668
|
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
676
669
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
677
670
|
this.clear();
|
|
678
|
-
return through ? {
|
|
671
|
+
return through ? {
|
|
672
|
+
path: path,
|
|
673
|
+
target: leaf,
|
|
674
|
+
throughPath: list.length ? this.getThroughPath(list) : path
|
|
675
|
+
} : {
|
|
676
|
+
path: path,
|
|
677
|
+
target: leaf
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
hitPoint(hitPoint, hitRadius, options) {
|
|
681
|
+
return !!this.getByPoint(hitPoint, hitRadius, options).target;
|
|
679
682
|
}
|
|
680
683
|
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
684
|
+
const findList = this.findList = new LeafList;
|
|
681
685
|
if (list.length) {
|
|
682
686
|
let find;
|
|
683
|
-
|
|
684
|
-
const
|
|
685
|
-
|
|
687
|
+
const {x: x, y: y} = this.point;
|
|
688
|
+
const point = {
|
|
689
|
+
x: x,
|
|
690
|
+
y: y,
|
|
691
|
+
radiusX: 0,
|
|
692
|
+
radiusY: 0
|
|
693
|
+
};
|
|
686
694
|
for (let i = 0, len = list.length; i < len; i++) {
|
|
687
695
|
find = list[i];
|
|
688
696
|
if (ignoreHittable || LeafHelper.worldHittable(find)) {
|
|
689
697
|
this.hitChild(find, point);
|
|
690
|
-
if (
|
|
691
|
-
|
|
698
|
+
if (findList.length) {
|
|
699
|
+
if (find.isBranchLeaf && list.some(item => item !== find && LeafHelper.hasParent(item, find))) {
|
|
700
|
+
findList.reset();
|
|
701
|
+
break;
|
|
702
|
+
}
|
|
703
|
+
return findList.list[0];
|
|
704
|
+
}
|
|
692
705
|
}
|
|
693
706
|
}
|
|
694
707
|
}
|
|
695
708
|
if (bottomList) {
|
|
696
709
|
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
697
710
|
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
698
|
-
if (
|
|
699
|
-
return this.findList.list[0];
|
|
711
|
+
if (findList.length) return findList.list[0];
|
|
700
712
|
}
|
|
701
713
|
}
|
|
702
|
-
return list[0];
|
|
714
|
+
return ignoreHittable ? list[0] : list.find(item => LeafHelper.worldHittable(item));
|
|
703
715
|
}
|
|
704
716
|
getPath(leaf) {
|
|
705
|
-
const path = new LeafList
|
|
717
|
+
const path = new LeafList;
|
|
706
718
|
while (leaf) {
|
|
707
719
|
path.add(leaf);
|
|
708
720
|
leaf = leaf.parent;
|
|
709
721
|
}
|
|
710
|
-
if (this.target)
|
|
711
|
-
path.add(this.target);
|
|
722
|
+
if (this.target) path.add(this.target);
|
|
712
723
|
return path;
|
|
713
724
|
}
|
|
714
725
|
getHitablePath(leaf) {
|
|
715
726
|
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
716
|
-
let item, hittablePath = new LeafList
|
|
727
|
+
let item, hittablePath = new LeafList;
|
|
717
728
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
718
729
|
item = path.list[i];
|
|
719
|
-
if (!item.__.hittable)
|
|
720
|
-
break;
|
|
730
|
+
if (!item.__.hittable) break;
|
|
721
731
|
hittablePath.addAt(item, 0);
|
|
722
|
-
if (!item.__.hitChildren)
|
|
723
|
-
break;
|
|
732
|
+
if (!item.__.hitChildren) break;
|
|
724
733
|
}
|
|
725
734
|
return hittablePath;
|
|
726
735
|
}
|
|
727
736
|
getThroughPath(list) {
|
|
728
|
-
const throughPath = new LeafList
|
|
737
|
+
const throughPath = new LeafList;
|
|
729
738
|
const pathList = [];
|
|
730
739
|
for (let i = list.length - 1; i > -1; i--) {
|
|
731
740
|
pathList.push(this.getPath(list[i]));
|
|
@@ -735,8 +744,7 @@ class Picker {
|
|
|
735
744
|
path = pathList[i], nextPath = pathList[i + 1];
|
|
736
745
|
for (let j = 0, jLen = path.length; j < jLen; j++) {
|
|
737
746
|
leaf = path.list[j];
|
|
738
|
-
if (nextPath && nextPath.has(leaf))
|
|
739
|
-
break;
|
|
747
|
+
if (nextPath && nextPath.has(leaf)) break;
|
|
740
748
|
throughPath.add(leaf);
|
|
741
749
|
}
|
|
742
750
|
}
|
|
@@ -747,32 +755,37 @@ class Picker {
|
|
|
747
755
|
}
|
|
748
756
|
eachFind(children, hitMask) {
|
|
749
757
|
let child, hit;
|
|
750
|
-
const { point
|
|
758
|
+
const {point: point} = this, len = children.length;
|
|
751
759
|
for (let i = len - 1; i > -1; i--) {
|
|
752
760
|
child = children[i];
|
|
753
|
-
if (!child.__.visible ||
|
|
754
|
-
continue;
|
|
761
|
+
if (!child.__.visible || hitMask && !child.__.mask) continue;
|
|
755
762
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
756
763
|
if (child.isBranch) {
|
|
757
764
|
if (hit || child.__ignoreHitWorld) {
|
|
758
765
|
this.eachFind(child.children, child.__onlyHitMask);
|
|
759
|
-
if (child.isBranchLeaf)
|
|
760
|
-
this.hitChild(child, point);
|
|
766
|
+
if (child.isBranchLeaf) this.hitChild(child, point);
|
|
761
767
|
}
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
if (hit)
|
|
765
|
-
this.hitChild(child, point);
|
|
768
|
+
} else {
|
|
769
|
+
if (hit) this.hitChild(child, point);
|
|
766
770
|
}
|
|
767
771
|
}
|
|
768
772
|
}
|
|
769
773
|
hitChild(child, point, proxy) {
|
|
770
|
-
if (this.exclude && this.exclude.has(child))
|
|
771
|
-
return;
|
|
774
|
+
if (this.exclude && this.exclude.has(child)) return;
|
|
772
775
|
if (child.__hitWorld(point)) {
|
|
773
|
-
const { parent
|
|
774
|
-
if (parent && parent.__hasMask && !child.__.mask
|
|
775
|
-
|
|
776
|
+
const {parent: parent} = child;
|
|
777
|
+
if (parent && parent.__hasMask && !child.__.mask) {
|
|
778
|
+
let findMasks = [], item;
|
|
779
|
+
const {children: children} = parent;
|
|
780
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
781
|
+
item = children[i];
|
|
782
|
+
if (item.__.mask) findMasks.push(item);
|
|
783
|
+
if (item === child) {
|
|
784
|
+
if (findMasks && !findMasks.every(value => value.__hitWorld(point))) return;
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
776
789
|
this.findList.add(proxy || child);
|
|
777
790
|
}
|
|
778
791
|
}
|
|
@@ -789,24 +802,24 @@ class Picker {
|
|
|
789
802
|
class Selector {
|
|
790
803
|
constructor(target, userConfig) {
|
|
791
804
|
this.config = {};
|
|
792
|
-
if (userConfig)
|
|
793
|
-
this.config = DataHelper.default(userConfig, this.config);
|
|
805
|
+
if (userConfig) this.config = DataHelper.default(userConfig, this.config);
|
|
794
806
|
this.picker = new Picker(this.target = target, this);
|
|
795
807
|
this.finder = Creator.finder && Creator.finder();
|
|
796
808
|
}
|
|
797
809
|
getByPoint(hitPoint, hitRadius, options) {
|
|
798
|
-
const { target, picker } = this;
|
|
799
|
-
if (Platform.backgrounder)
|
|
800
|
-
target && target.updateLayout();
|
|
810
|
+
const {target: target, picker: picker} = this;
|
|
811
|
+
if (Platform.backgrounder) target && target.updateLayout();
|
|
801
812
|
return picker.getByPoint(hitPoint, hitRadius, options);
|
|
802
813
|
}
|
|
814
|
+
hitPoint(hitPoint, hitRadius, options) {
|
|
815
|
+
return this.picker.hitPoint(hitPoint, hitRadius, options);
|
|
816
|
+
}
|
|
803
817
|
getBy(condition, branch, one, options) {
|
|
804
|
-
return this.finder ? this.finder.getBy(condition, branch, one, options) : Plugin.need(
|
|
818
|
+
return this.finder ? this.finder.getBy(condition, branch, one, options) : Plugin.need("find");
|
|
805
819
|
}
|
|
806
820
|
destroy() {
|
|
807
821
|
this.picker.destroy();
|
|
808
|
-
if (this.finder)
|
|
809
|
-
this.finder.destroy();
|
|
822
|
+
if (this.finder) this.finder.destroy();
|
|
810
823
|
}
|
|
811
824
|
}
|
|
812
825
|
|
|
@@ -816,24 +829,22 @@ Object.assign(Creator, {
|
|
|
816
829
|
renderer: (target, canvas, options) => new Renderer(target, canvas, options),
|
|
817
830
|
selector: (target, options) => new Selector(target, options)
|
|
818
831
|
});
|
|
832
|
+
|
|
819
833
|
Platform.layout = Layouter.fullLayout;
|
|
820
834
|
|
|
821
835
|
function fillText(ui, canvas) {
|
|
822
|
-
const data = ui.__, { rows, decorationY } = data.__textDrawData;
|
|
823
|
-
if (data.__isPlacehold && data.placeholderColor)
|
|
824
|
-
canvas.fillStyle = data.placeholderColor;
|
|
836
|
+
const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
|
|
837
|
+
if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
|
|
825
838
|
let row;
|
|
826
839
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
827
840
|
row = rows[i];
|
|
828
|
-
if (row.text)
|
|
829
|
-
canvas.fillText(
|
|
830
|
-
|
|
831
|
-
row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
|
|
841
|
+
if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
|
|
842
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
843
|
+
});
|
|
832
844
|
}
|
|
833
845
|
if (decorationY) {
|
|
834
|
-
const { decorationColor, decorationHeight } = data.__textDrawData;
|
|
835
|
-
if (decorationColor)
|
|
836
|
-
canvas.fillStyle = decorationColor;
|
|
846
|
+
const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
|
|
847
|
+
if (decorationColor) canvas.fillStyle = decorationColor;
|
|
837
848
|
rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
|
|
838
849
|
}
|
|
839
850
|
}
|
|
@@ -842,106 +853,112 @@ function fill(fill, ui, canvas) {
|
|
|
842
853
|
canvas.fillStyle = fill;
|
|
843
854
|
fillPathOrText(ui, canvas);
|
|
844
855
|
}
|
|
856
|
+
|
|
845
857
|
function fills(fills, ui, canvas) {
|
|
846
858
|
let item;
|
|
847
859
|
for (let i = 0, len = fills.length; i < len; i++) {
|
|
848
860
|
item = fills[i];
|
|
849
861
|
if (item.image) {
|
|
850
|
-
if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
|
|
851
|
-
continue;
|
|
862
|
+
if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
|
|
852
863
|
if (!item.style) {
|
|
853
|
-
if (!i && item.image.isPlacehold)
|
|
854
|
-
ui.drawImagePlaceholder(canvas, item.image);
|
|
864
|
+
if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
|
|
855
865
|
continue;
|
|
856
866
|
}
|
|
857
867
|
}
|
|
858
868
|
canvas.fillStyle = item.style;
|
|
859
|
-
if (item.transform) {
|
|
869
|
+
if (item.transform || item.scaleFixed) {
|
|
860
870
|
canvas.save();
|
|
861
|
-
canvas.transform(item.transform);
|
|
862
|
-
if (item.
|
|
863
|
-
|
|
871
|
+
if (item.transform) canvas.transform(item.transform);
|
|
872
|
+
if (item.scaleFixed) {
|
|
873
|
+
const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
|
|
874
|
+
if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
|
|
875
|
+
}
|
|
876
|
+
if (item.blendMode) canvas.blendMode = item.blendMode;
|
|
864
877
|
fillPathOrText(ui, canvas);
|
|
865
878
|
canvas.restore();
|
|
866
|
-
}
|
|
867
|
-
else {
|
|
879
|
+
} else {
|
|
868
880
|
if (item.blendMode) {
|
|
869
881
|
canvas.saveBlendMode(item.blendMode);
|
|
870
882
|
fillPathOrText(ui, canvas);
|
|
871
883
|
canvas.restoreBlendMode();
|
|
872
|
-
}
|
|
873
|
-
else
|
|
874
|
-
fillPathOrText(ui, canvas);
|
|
884
|
+
} else fillPathOrText(ui, canvas);
|
|
875
885
|
}
|
|
876
886
|
}
|
|
877
887
|
}
|
|
888
|
+
|
|
878
889
|
function fillPathOrText(ui, canvas) {
|
|
879
|
-
ui.__.__font ? fillText(ui, canvas) :
|
|
890
|
+
ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
|
|
880
891
|
}
|
|
881
892
|
|
|
882
893
|
function strokeText(stroke, ui, canvas) {
|
|
883
894
|
switch (ui.__.strokeAlign) {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
895
|
+
case "center":
|
|
896
|
+
drawCenter$1(stroke, 1, ui, canvas);
|
|
897
|
+
break;
|
|
898
|
+
|
|
899
|
+
case "inside":
|
|
900
|
+
drawAlign(stroke, "inside", ui, canvas);
|
|
901
|
+
break;
|
|
902
|
+
|
|
903
|
+
case "outside":
|
|
904
|
+
ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
|
|
905
|
+
break;
|
|
893
906
|
}
|
|
894
907
|
}
|
|
908
|
+
|
|
895
909
|
function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
|
|
896
910
|
const data = ui.__;
|
|
897
|
-
|
|
898
|
-
|
|
911
|
+
if (isObject(stroke)) {
|
|
912
|
+
drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
|
|
913
|
+
} else {
|
|
914
|
+
canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
|
|
915
|
+
drawTextStroke(ui, canvas);
|
|
916
|
+
}
|
|
899
917
|
}
|
|
918
|
+
|
|
900
919
|
function drawAlign(stroke, align, ui, canvas) {
|
|
901
920
|
const out = canvas.getSameCanvas(true, true);
|
|
902
921
|
out.font = ui.__.__font;
|
|
903
922
|
drawCenter$1(stroke, 2, ui, out);
|
|
904
|
-
out.blendMode = align ===
|
|
923
|
+
out.blendMode = align === "outside" ? "destination-out" : "destination-in";
|
|
905
924
|
fillText(ui, out);
|
|
906
|
-
out.blendMode =
|
|
907
|
-
|
|
925
|
+
out.blendMode = "normal";
|
|
926
|
+
LeafHelper.copyCanvasByWorld(ui, canvas, out);
|
|
908
927
|
out.recycle(ui.__nowWorld);
|
|
909
928
|
}
|
|
910
|
-
|
|
911
|
-
if (ui.__worldFlipped || Platform.fullImageShadow)
|
|
912
|
-
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
913
|
-
else
|
|
914
|
-
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
915
|
-
}
|
|
929
|
+
|
|
916
930
|
function drawTextStroke(ui, canvas) {
|
|
917
931
|
let row, data = ui.__.__textDrawData;
|
|
918
|
-
const { rows, decorationY } = data;
|
|
932
|
+
const {rows: rows, decorationY: decorationY} = data;
|
|
919
933
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
920
934
|
row = rows[i];
|
|
921
|
-
if (row.text)
|
|
922
|
-
canvas.strokeText(
|
|
923
|
-
|
|
924
|
-
row.data.forEach(charData => { canvas.strokeText(charData.char, charData.x, row.y); });
|
|
935
|
+
if (row.text) canvas.strokeText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
|
|
936
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
937
|
+
});
|
|
925
938
|
}
|
|
926
939
|
if (decorationY) {
|
|
927
|
-
const { decorationHeight
|
|
940
|
+
const {decorationHeight: decorationHeight} = data;
|
|
928
941
|
rows.forEach(row => decorationY.forEach(value => canvas.strokeRect(row.x, row.y + value, row.width, decorationHeight)));
|
|
929
942
|
}
|
|
930
943
|
}
|
|
931
|
-
|
|
944
|
+
|
|
945
|
+
function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
|
|
932
946
|
let item;
|
|
947
|
+
const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
|
|
948
|
+
__hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
|
|
933
949
|
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
934
950
|
item = strokes[i];
|
|
935
|
-
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
936
|
-
continue;
|
|
951
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false)) continue;
|
|
937
952
|
if (item.style) {
|
|
938
|
-
|
|
953
|
+
if (__hasMultiStrokeStyle) {
|
|
954
|
+
const {strokeStyle: strokeStyle} = item;
|
|
955
|
+
strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
|
|
956
|
+
} else canvas.strokeStyle = item.style;
|
|
939
957
|
if (item.blendMode) {
|
|
940
958
|
canvas.saveBlendMode(item.blendMode);
|
|
941
959
|
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
942
960
|
canvas.restoreBlendMode();
|
|
943
|
-
}
|
|
944
|
-
else {
|
|
961
|
+
} else {
|
|
945
962
|
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
946
963
|
}
|
|
947
964
|
}
|
|
@@ -950,77 +967,81 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
|
950
967
|
|
|
951
968
|
function stroke(stroke, ui, canvas) {
|
|
952
969
|
const data = ui.__;
|
|
953
|
-
if (!data.__strokeWidth)
|
|
954
|
-
return;
|
|
970
|
+
if (!data.__strokeWidth) return;
|
|
955
971
|
if (data.__font) {
|
|
956
972
|
strokeText(stroke, ui, canvas);
|
|
957
|
-
}
|
|
958
|
-
else {
|
|
973
|
+
} else {
|
|
959
974
|
switch (data.strokeAlign) {
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
975
|
+
case "center":
|
|
976
|
+
drawCenter(stroke, 1, ui, canvas);
|
|
977
|
+
break;
|
|
978
|
+
|
|
979
|
+
case "inside":
|
|
980
|
+
drawInside(stroke, ui, canvas);
|
|
981
|
+
break;
|
|
982
|
+
|
|
983
|
+
case "outside":
|
|
984
|
+
drawOutside(stroke, ui, canvas);
|
|
985
|
+
break;
|
|
969
986
|
}
|
|
970
987
|
}
|
|
971
988
|
}
|
|
989
|
+
|
|
972
990
|
function strokes(strokes, ui, canvas) {
|
|
973
991
|
stroke(strokes, ui, canvas);
|
|
974
992
|
}
|
|
993
|
+
|
|
975
994
|
function drawCenter(stroke, strokeWidthScale, ui, canvas) {
|
|
976
995
|
const data = ui.__;
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
996
|
+
if (isObject(stroke)) {
|
|
997
|
+
drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
|
|
998
|
+
} else {
|
|
999
|
+
canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
|
|
1000
|
+
canvas.stroke();
|
|
1001
|
+
}
|
|
1002
|
+
if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas);
|
|
981
1003
|
}
|
|
1004
|
+
|
|
982
1005
|
function drawInside(stroke, ui, canvas) {
|
|
983
1006
|
canvas.save();
|
|
984
1007
|
canvas.clipUI(ui);
|
|
985
1008
|
drawCenter(stroke, 2, ui, canvas);
|
|
986
1009
|
canvas.restore();
|
|
987
1010
|
}
|
|
1011
|
+
|
|
988
1012
|
function drawOutside(stroke, ui, canvas) {
|
|
989
1013
|
const data = ui.__;
|
|
990
1014
|
if (data.__fillAfterStroke) {
|
|
991
1015
|
drawCenter(stroke, 2, ui, canvas);
|
|
992
|
-
}
|
|
993
|
-
|
|
994
|
-
const { renderBounds } = ui.__layout;
|
|
1016
|
+
} else {
|
|
1017
|
+
const {renderBounds: renderBounds} = ui.__layout;
|
|
995
1018
|
const out = canvas.getSameCanvas(true, true);
|
|
996
1019
|
ui.__drawRenderPath(out);
|
|
997
1020
|
drawCenter(stroke, 2, ui, out);
|
|
998
1021
|
out.clipUI(data);
|
|
999
1022
|
out.clearWorld(renderBounds);
|
|
1000
|
-
|
|
1023
|
+
LeafHelper.copyCanvasByWorld(ui, canvas, out);
|
|
1001
1024
|
out.recycle(ui.__nowWorld);
|
|
1002
1025
|
}
|
|
1003
1026
|
}
|
|
1004
1027
|
|
|
1005
|
-
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1028
|
+
const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = BoundsHelper;
|
|
1029
|
+
|
|
1006
1030
|
function shape(ui, current, options) {
|
|
1007
1031
|
const canvas = current.getSameCanvas();
|
|
1008
1032
|
const nowWorld = ui.__nowWorld;
|
|
1009
|
-
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1010
|
-
let { scaleX, scaleY } = nowWorld;
|
|
1011
|
-
if (scaleX < 0)
|
|
1012
|
-
|
|
1013
|
-
if (scaleY < 0)
|
|
1014
|
-
scaleY = -scaleY;
|
|
1033
|
+
let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
|
|
1034
|
+
let {scaleX: scaleX, scaleY: scaleY} = nowWorld;
|
|
1035
|
+
if (scaleX < 0) scaleX = -scaleX;
|
|
1036
|
+
if (scaleY < 0) scaleY = -scaleY;
|
|
1015
1037
|
if (current.bounds.includes(nowWorld)) {
|
|
1016
1038
|
worldCanvas = canvas;
|
|
1017
1039
|
bounds = shapeBounds = nowWorld;
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
const
|
|
1021
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1040
|
+
} else {
|
|
1041
|
+
const {renderShapeSpread: spread} = ui.__layout;
|
|
1042
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : current.bounds, nowWorld);
|
|
1022
1043
|
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1023
|
-
let {
|
|
1044
|
+
let {a: fitScaleX, d: fitScaleY} = fitMatrix;
|
|
1024
1045
|
if (fitMatrix.a < 1) {
|
|
1025
1046
|
worldCanvas = current.getSameCanvas();
|
|
1026
1047
|
ui.__renderShape(worldCanvas, options);
|
|
@@ -1029,215 +1050,262 @@ function shape(ui, current, options) {
|
|
|
1029
1050
|
}
|
|
1030
1051
|
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1031
1052
|
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
fitMatrix
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1053
|
+
const userMatrix = options.matrix;
|
|
1054
|
+
if (userMatrix) {
|
|
1055
|
+
matrix = new Matrix(fitMatrix);
|
|
1056
|
+
matrix.multiply(userMatrix);
|
|
1057
|
+
fitScaleX *= userMatrix.scaleX;
|
|
1058
|
+
fitScaleY *= userMatrix.scaleY;
|
|
1059
|
+
} else matrix = fitMatrix;
|
|
1060
|
+
matrix.withScale(fitScaleX, fitScaleY);
|
|
1061
|
+
options = Object.assign(Object.assign({}, options), {
|
|
1062
|
+
matrix: matrix
|
|
1063
|
+
});
|
|
1039
1064
|
}
|
|
1040
1065
|
ui.__renderShape(canvas, options);
|
|
1041
1066
|
return {
|
|
1042
|
-
canvas
|
|
1043
|
-
|
|
1067
|
+
canvas: canvas,
|
|
1068
|
+
matrix: matrix,
|
|
1069
|
+
fitMatrix: fitMatrix,
|
|
1070
|
+
bounds: bounds,
|
|
1071
|
+
worldCanvas: worldCanvas,
|
|
1072
|
+
shapeBounds: shapeBounds,
|
|
1073
|
+
scaleX: scaleX,
|
|
1074
|
+
scaleY: scaleY
|
|
1044
1075
|
};
|
|
1045
1076
|
}
|
|
1046
1077
|
|
|
1047
1078
|
let recycleMap;
|
|
1048
|
-
|
|
1079
|
+
|
|
1080
|
+
const {stintSet: stintSet} = DataHelper, {hasTransparent: hasTransparent$1} = ColorConvert;
|
|
1081
|
+
|
|
1049
1082
|
function compute(attrName, ui) {
|
|
1050
1083
|
const data = ui.__, leafPaints = [];
|
|
1051
1084
|
let paints = data.__input[attrName], isAlphaPixel, isTransparent;
|
|
1052
|
-
if (!(paints
|
|
1053
|
-
paints = [paints];
|
|
1085
|
+
if (!isArray(paints)) paints = [ paints ];
|
|
1054
1086
|
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1087
|
+
let maxChildStrokeWidth;
|
|
1055
1088
|
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1056
|
-
(item = getLeafPaint(attrName, paints[i], ui))
|
|
1089
|
+
if (item = getLeafPaint(attrName, paints[i], ui)) {
|
|
1090
|
+
leafPaints.push(item);
|
|
1091
|
+
if (item.strokeStyle) {
|
|
1092
|
+
maxChildStrokeWidth || (maxChildStrokeWidth = 1);
|
|
1093
|
+
if (item.strokeStyle.strokeWidth) maxChildStrokeWidth = Math.max(maxChildStrokeWidth, item.strokeStyle.strokeWidth);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1057
1096
|
}
|
|
1058
|
-
data[
|
|
1097
|
+
data["_" + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1059
1098
|
if (leafPaints.length) {
|
|
1060
1099
|
if (leafPaints.every(item => item.isTransparent)) {
|
|
1061
|
-
if (leafPaints.some(item => item.image))
|
|
1062
|
-
isAlphaPixel = true;
|
|
1100
|
+
if (leafPaints.some(item => item.image)) isAlphaPixel = true;
|
|
1063
1101
|
isTransparent = true;
|
|
1064
1102
|
}
|
|
1065
1103
|
}
|
|
1066
|
-
if (attrName ===
|
|
1067
|
-
stintSet(data,
|
|
1068
|
-
stintSet(data,
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
stintSet(data,
|
|
1072
|
-
stintSet(data,
|
|
1104
|
+
if (attrName === "fill") {
|
|
1105
|
+
stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
|
|
1106
|
+
stintSet(data, "__isTransparentFill", isTransparent);
|
|
1107
|
+
} else {
|
|
1108
|
+
stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
|
|
1109
|
+
stintSet(data, "__isTransparentStroke", isTransparent);
|
|
1110
|
+
stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
|
|
1073
1111
|
}
|
|
1074
1112
|
}
|
|
1113
|
+
|
|
1075
1114
|
function getLeafPaint(attrName, paint, ui) {
|
|
1076
|
-
if (
|
|
1077
|
-
return undefined;
|
|
1115
|
+
if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
|
|
1078
1116
|
let data;
|
|
1079
|
-
const { boxBounds
|
|
1117
|
+
const {boxBounds: boxBounds} = ui.__layout;
|
|
1080
1118
|
switch (paint.type) {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1119
|
+
case "image":
|
|
1120
|
+
data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1121
|
+
break;
|
|
1122
|
+
|
|
1123
|
+
case "linear":
|
|
1124
|
+
data = PaintGradient.linearGradient(paint, boxBounds);
|
|
1125
|
+
break;
|
|
1126
|
+
|
|
1127
|
+
case "radial":
|
|
1128
|
+
data = PaintGradient.radialGradient(paint, boxBounds);
|
|
1129
|
+
break;
|
|
1130
|
+
|
|
1131
|
+
case "angular":
|
|
1132
|
+
data = PaintGradient.conicGradient(paint, boxBounds);
|
|
1133
|
+
break;
|
|
1134
|
+
|
|
1135
|
+
case "solid":
|
|
1136
|
+
const {type: type, color: color, opacity: opacity} = paint;
|
|
1137
|
+
data = {
|
|
1138
|
+
type: type,
|
|
1139
|
+
style: ColorConvert.string(color, opacity)
|
|
1140
|
+
};
|
|
1141
|
+
break;
|
|
1142
|
+
|
|
1143
|
+
default:
|
|
1144
|
+
if (!isUndefined(paint.r)) data = {
|
|
1145
|
+
type: "solid",
|
|
1146
|
+
style: ColorConvert.string(paint)
|
|
1147
|
+
};
|
|
1100
1148
|
}
|
|
1101
1149
|
if (data) {
|
|
1102
|
-
if (
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
data.
|
|
1150
|
+
if (isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
|
|
1151
|
+
if (paint.style) {
|
|
1152
|
+
if (paint.style.strokeWidth === 0) return undefined;
|
|
1153
|
+
data.strokeStyle = paint.style;
|
|
1154
|
+
}
|
|
1155
|
+
if (paint.editing) data.editing = paint.editing;
|
|
1156
|
+
if (paint.blendMode) data.blendMode = paint.blendMode;
|
|
1106
1157
|
}
|
|
1107
1158
|
return data;
|
|
1108
1159
|
}
|
|
1109
1160
|
|
|
1110
1161
|
const PaintModule = {
|
|
1111
|
-
compute,
|
|
1112
|
-
fill,
|
|
1113
|
-
fills,
|
|
1114
|
-
fillPathOrText,
|
|
1115
|
-
fillText,
|
|
1116
|
-
stroke,
|
|
1117
|
-
strokes,
|
|
1118
|
-
strokeText,
|
|
1119
|
-
drawTextStroke,
|
|
1120
|
-
shape
|
|
1162
|
+
compute: compute,
|
|
1163
|
+
fill: fill,
|
|
1164
|
+
fills: fills,
|
|
1165
|
+
fillPathOrText: fillPathOrText,
|
|
1166
|
+
fillText: fillText,
|
|
1167
|
+
stroke: stroke,
|
|
1168
|
+
strokes: strokes,
|
|
1169
|
+
strokeText: strokeText,
|
|
1170
|
+
drawTextStroke: drawTextStroke,
|
|
1171
|
+
shape: shape
|
|
1121
1172
|
};
|
|
1122
1173
|
|
|
1123
|
-
let origin = {};
|
|
1124
|
-
|
|
1174
|
+
let origin = {}, tempMatrix = getMatrixData();
|
|
1175
|
+
|
|
1176
|
+
const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
|
|
1177
|
+
|
|
1125
1178
|
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1126
1179
|
const transform = get$3();
|
|
1127
1180
|
translate$1(transform, box.x + x, box.y + y);
|
|
1128
1181
|
scaleHelper(transform, scaleX, scaleY);
|
|
1129
|
-
if (rotation)
|
|
1130
|
-
|
|
1182
|
+
if (rotation) rotateOfOuter$1(transform, {
|
|
1183
|
+
x: box.x + box.width / 2,
|
|
1184
|
+
y: box.y + box.height / 2
|
|
1185
|
+
}, rotation);
|
|
1131
1186
|
data.transform = transform;
|
|
1132
1187
|
}
|
|
1133
|
-
|
|
1188
|
+
|
|
1189
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
|
|
1134
1190
|
const transform = get$3();
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
scaleHelper(transform, scaleX, scaleY);
|
|
1141
|
-
translate$1(transform, box.x + x, box.y + y);
|
|
1191
|
+
layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
|
|
1192
|
+
if (clipSize) {
|
|
1193
|
+
tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
|
|
1194
|
+
multiplyParent(transform, tempMatrix);
|
|
1195
|
+
}
|
|
1142
1196
|
data.transform = transform;
|
|
1143
1197
|
}
|
|
1144
|
-
|
|
1198
|
+
|
|
1199
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
|
|
1145
1200
|
const transform = get$3();
|
|
1146
|
-
if (
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1201
|
+
if (freeTransform) {
|
|
1202
|
+
layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
|
|
1203
|
+
} else {
|
|
1204
|
+
if (rotation) {
|
|
1205
|
+
if (align === "center") {
|
|
1206
|
+
rotateOfOuter$1(transform, {
|
|
1207
|
+
x: width / 2,
|
|
1208
|
+
y: height / 2
|
|
1209
|
+
}, rotation);
|
|
1210
|
+
} else {
|
|
1211
|
+
rotate(transform, rotation);
|
|
1212
|
+
switch (rotation) {
|
|
1213
|
+
case 90:
|
|
1154
1214
|
translate$1(transform, height, 0);
|
|
1155
1215
|
break;
|
|
1156
|
-
|
|
1216
|
+
|
|
1217
|
+
case 180:
|
|
1157
1218
|
translate$1(transform, width, height);
|
|
1158
1219
|
break;
|
|
1159
|
-
|
|
1220
|
+
|
|
1221
|
+
case 270:
|
|
1160
1222
|
translate$1(transform, 0, width);
|
|
1161
1223
|
break;
|
|
1224
|
+
}
|
|
1162
1225
|
}
|
|
1163
1226
|
}
|
|
1227
|
+
origin.x = box.x + x;
|
|
1228
|
+
origin.y = box.y + y;
|
|
1229
|
+
translate$1(transform, origin.x, origin.y);
|
|
1230
|
+
if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1164
1231
|
}
|
|
1165
|
-
origin.x = box.x + x;
|
|
1166
|
-
origin.y = box.y + y;
|
|
1167
|
-
translate$1(transform, origin.x, origin.y);
|
|
1168
|
-
if (scaleX)
|
|
1169
|
-
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1170
1232
|
data.transform = transform;
|
|
1171
1233
|
}
|
|
1172
1234
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1235
|
+
function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
|
|
1236
|
+
if (rotation) rotate(transform, rotation);
|
|
1237
|
+
if (skew) skewHelper(transform, skew.x, skew.y);
|
|
1238
|
+
if (scaleX) scaleHelper(transform, scaleX, scaleY);
|
|
1239
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
const {get: get$2, translate: translate} = MatrixHelper;
|
|
1243
|
+
|
|
1244
|
+
const tempBox = new Bounds;
|
|
1245
|
+
|
|
1175
1246
|
const tempScaleData = {};
|
|
1247
|
+
|
|
1176
1248
|
const tempImage = {};
|
|
1249
|
+
|
|
1177
1250
|
function createData(leafPaint, image, paint, box) {
|
|
1178
|
-
const { changeful, sync,
|
|
1179
|
-
if (changeful)
|
|
1180
|
-
|
|
1181
|
-
if (
|
|
1182
|
-
leafPaint.sync = sync;
|
|
1183
|
-
if (editing)
|
|
1184
|
-
leafPaint.editing = editing;
|
|
1251
|
+
const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
|
|
1252
|
+
if (changeful) leafPaint.changeful = changeful;
|
|
1253
|
+
if (sync) leafPaint.sync = sync;
|
|
1254
|
+
if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
|
|
1185
1255
|
leafPaint.data = getPatternData(paint, box, image);
|
|
1186
1256
|
}
|
|
1257
|
+
|
|
1187
1258
|
function getPatternData(paint, box, image) {
|
|
1188
|
-
if (paint.padding)
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
let { width, height } = image;
|
|
1193
|
-
const { opacity, mode, align, offset, scale, size, rotation, skew, repeat, filters } = paint;
|
|
1259
|
+
if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
|
|
1260
|
+
if (paint.mode === "strench") paint.mode = "stretch";
|
|
1261
|
+
let {width: width, height: height} = image;
|
|
1262
|
+
const {opacity: opacity, mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, filters: filters} = paint;
|
|
1194
1263
|
const sameBox = box.width === width && box.height === height;
|
|
1195
|
-
const data = {
|
|
1196
|
-
|
|
1264
|
+
const data = {
|
|
1265
|
+
mode: mode
|
|
1266
|
+
};
|
|
1267
|
+
const swapSize = align !== "center" && (rotation || 0) % 180 === 90;
|
|
1197
1268
|
BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
|
|
1198
1269
|
let scaleX, scaleY;
|
|
1199
|
-
if (!mode || mode ===
|
|
1270
|
+
if (!mode || mode === "cover" || mode === "fit") {
|
|
1200
1271
|
if (!sameBox || rotation) {
|
|
1201
|
-
scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !==
|
|
1272
|
+
scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== "fit");
|
|
1202
1273
|
BoundsHelper.put(box, image, align, scaleX, false, tempImage);
|
|
1203
1274
|
BoundsHelper.scale(tempImage, scaleX, scaleY, true);
|
|
1204
1275
|
}
|
|
1205
|
-
}
|
|
1206
|
-
else {
|
|
1276
|
+
} else {
|
|
1207
1277
|
if (scale || size) {
|
|
1208
1278
|
MathHelper.getScaleData(scale, size, image, tempScaleData);
|
|
1209
1279
|
scaleX = tempScaleData.scaleX;
|
|
1210
1280
|
scaleY = tempScaleData.scaleY;
|
|
1211
1281
|
}
|
|
1212
|
-
if (align) {
|
|
1213
|
-
if (scaleX)
|
|
1214
|
-
|
|
1215
|
-
AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
|
|
1282
|
+
if (align || gap || repeat) {
|
|
1283
|
+
if (scaleX) BoundsHelper.scale(tempImage, scaleX, scaleY, true);
|
|
1284
|
+
if (align) AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
|
|
1216
1285
|
}
|
|
1217
1286
|
}
|
|
1218
|
-
if (offset)
|
|
1219
|
-
PointHelper.move(tempImage, offset);
|
|
1287
|
+
if (offset) PointHelper.move(tempImage, offset);
|
|
1220
1288
|
switch (mode) {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1289
|
+
case "stretch":
|
|
1290
|
+
if (!sameBox) width = box.width, height = box.height;
|
|
1291
|
+
break;
|
|
1292
|
+
|
|
1293
|
+
case "normal":
|
|
1294
|
+
case "clip":
|
|
1295
|
+
if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
|
|
1296
|
+
break;
|
|
1297
|
+
|
|
1298
|
+
case "repeat":
|
|
1299
|
+
if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
|
|
1300
|
+
if (!repeat) data.repeat = "repeat";
|
|
1301
|
+
const count = isObject(repeat);
|
|
1302
|
+
if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
|
|
1303
|
+
break;
|
|
1304
|
+
|
|
1305
|
+
case "fit":
|
|
1306
|
+
case "cover":
|
|
1307
|
+
default:
|
|
1308
|
+
if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
|
|
1241
1309
|
}
|
|
1242
1310
|
if (!data.transform) {
|
|
1243
1311
|
if (box.x || box.y) {
|
|
@@ -1245,49 +1313,69 @@ function getPatternData(paint, box, image) {
|
|
|
1245
1313
|
translate(data.transform, box.x, box.y);
|
|
1246
1314
|
}
|
|
1247
1315
|
}
|
|
1248
|
-
if (scaleX && mode !==
|
|
1316
|
+
if (scaleX && mode !== "stretch") {
|
|
1249
1317
|
data.scaleX = scaleX;
|
|
1250
1318
|
data.scaleY = scaleY;
|
|
1251
1319
|
}
|
|
1252
1320
|
data.width = width;
|
|
1253
1321
|
data.height = height;
|
|
1254
|
-
if (opacity)
|
|
1255
|
-
|
|
1256
|
-
if (
|
|
1257
|
-
data.filters = filters;
|
|
1258
|
-
if (repeat)
|
|
1259
|
-
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1322
|
+
if (opacity) data.opacity = opacity;
|
|
1323
|
+
if (filters) data.filters = filters;
|
|
1324
|
+
if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
|
|
1260
1325
|
return data;
|
|
1261
1326
|
}
|
|
1262
1327
|
|
|
1263
|
-
|
|
1264
|
-
|
|
1328
|
+
function getGapData(gap, repeat, width, height, box) {
|
|
1329
|
+
let xGap, yGap;
|
|
1330
|
+
if (isObject(gap)) xGap = gap.x, yGap = gap.y; else xGap = yGap = gap;
|
|
1331
|
+
return {
|
|
1332
|
+
x: getGapValue(xGap, width, box.width, repeat && repeat.x),
|
|
1333
|
+
y: getGapValue(yGap, height, box.height, repeat && repeat.y)
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
function getGapValue(gap, size, totalSize, rows) {
|
|
1338
|
+
const auto = isString(gap) || rows;
|
|
1339
|
+
const remain = rows ? totalSize - rows * size : totalSize % size;
|
|
1340
|
+
const value = auto ? remain / ((rows || Math.floor(totalSize / size)) - 1) : gap;
|
|
1341
|
+
return gap === "auto" ? value < 0 ? 0 : value : value;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
let cache, box = new Bounds;
|
|
1345
|
+
|
|
1346
|
+
const {isSame: isSame} = BoundsHelper;
|
|
1347
|
+
|
|
1265
1348
|
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1266
1349
|
let leafPaint, event;
|
|
1267
1350
|
const image = ImageManager.get(paint);
|
|
1268
1351
|
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1269
1352
|
leafPaint = cache.leafPaint;
|
|
1270
|
-
}
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1353
|
+
} else {
|
|
1354
|
+
leafPaint = {
|
|
1355
|
+
type: paint.type,
|
|
1356
|
+
image: image
|
|
1357
|
+
};
|
|
1358
|
+
if (image.hasAlphaPixel) leafPaint.isTransparent = true;
|
|
1359
|
+
cache = image.use > 1 ? {
|
|
1360
|
+
leafPaint: leafPaint,
|
|
1361
|
+
paint: paint,
|
|
1362
|
+
boxBounds: box.set(boxBounds)
|
|
1363
|
+
} : null;
|
|
1364
|
+
}
|
|
1365
|
+
if (firstUse || image.loading) event = {
|
|
1366
|
+
image: image,
|
|
1367
|
+
attrName: attrName,
|
|
1368
|
+
attrValue: paint
|
|
1369
|
+
};
|
|
1279
1370
|
if (image.ready) {
|
|
1280
1371
|
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1281
1372
|
if (firstUse) {
|
|
1282
1373
|
onLoad(ui, event);
|
|
1283
1374
|
onLoadSuccess(ui, event);
|
|
1284
1375
|
}
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
onLoadError(ui, event, image.error);
|
|
1289
|
-
}
|
|
1290
|
-
else {
|
|
1376
|
+
} else if (image.error) {
|
|
1377
|
+
if (firstUse) onLoadError(ui, event, image.error);
|
|
1378
|
+
} else {
|
|
1291
1379
|
if (firstUse) {
|
|
1292
1380
|
ignoreRender(ui, true);
|
|
1293
1381
|
onLoad(ui, event);
|
|
@@ -1296,107 +1384,105 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
|
1296
1384
|
ignoreRender(ui, false);
|
|
1297
1385
|
if (!ui.destroyed) {
|
|
1298
1386
|
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1299
|
-
if (image.hasAlphaPixel)
|
|
1300
|
-
|
|
1301
|
-
ui.forceUpdate('surface');
|
|
1387
|
+
if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
|
|
1388
|
+
ui.forceUpdate("surface");
|
|
1302
1389
|
}
|
|
1303
1390
|
onLoadSuccess(ui, event);
|
|
1304
1391
|
}
|
|
1305
1392
|
leafPaint.loadId = undefined;
|
|
1306
|
-
},
|
|
1393
|
+
}, error => {
|
|
1307
1394
|
ignoreRender(ui, false);
|
|
1308
1395
|
onLoadError(ui, event, error);
|
|
1309
1396
|
leafPaint.loadId = undefined;
|
|
1310
1397
|
});
|
|
1311
1398
|
if (ui.placeholderColor) {
|
|
1312
|
-
if (!ui.placeholderDelay)
|
|
1313
|
-
image.
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
ui.forceUpdate('surface');
|
|
1319
|
-
}
|
|
1320
|
-
}, ui.placeholderDelay);
|
|
1399
|
+
if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
|
|
1400
|
+
if (!image.ready) {
|
|
1401
|
+
image.isPlacehold = true;
|
|
1402
|
+
ui.forceUpdate("surface");
|
|
1403
|
+
}
|
|
1404
|
+
}, ui.placeholderDelay);
|
|
1321
1405
|
}
|
|
1322
1406
|
}
|
|
1323
1407
|
return leafPaint;
|
|
1324
1408
|
}
|
|
1409
|
+
|
|
1325
1410
|
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1326
|
-
if (attrName ===
|
|
1411
|
+
if (attrName === "fill" && !ui.__.__naturalWidth) {
|
|
1327
1412
|
const data = ui.__;
|
|
1328
1413
|
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1329
1414
|
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1330
1415
|
if (data.__autoSide) {
|
|
1331
|
-
ui.forceUpdate(
|
|
1416
|
+
ui.forceUpdate("width");
|
|
1332
1417
|
if (ui.__proxyData) {
|
|
1333
|
-
ui.setProxyAttr(
|
|
1334
|
-
ui.setProxyAttr(
|
|
1418
|
+
ui.setProxyAttr("width", data.width);
|
|
1419
|
+
ui.setProxyAttr("height", data.height);
|
|
1335
1420
|
}
|
|
1336
1421
|
return false;
|
|
1337
1422
|
}
|
|
1338
1423
|
}
|
|
1339
|
-
if (!leafPaint.data)
|
|
1340
|
-
createData(leafPaint, image, paint, boxBounds);
|
|
1424
|
+
if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
|
|
1341
1425
|
return true;
|
|
1342
1426
|
}
|
|
1427
|
+
|
|
1343
1428
|
function onLoad(ui, event) {
|
|
1344
1429
|
emit(ui, ImageEvent.LOAD, event);
|
|
1345
1430
|
}
|
|
1431
|
+
|
|
1346
1432
|
function onLoadSuccess(ui, event) {
|
|
1347
1433
|
emit(ui, ImageEvent.LOADED, event);
|
|
1348
1434
|
}
|
|
1435
|
+
|
|
1349
1436
|
function onLoadError(ui, event, error) {
|
|
1350
1437
|
event.error = error;
|
|
1351
|
-
ui.forceUpdate(
|
|
1438
|
+
ui.forceUpdate("surface");
|
|
1352
1439
|
emit(ui, ImageEvent.ERROR, event);
|
|
1353
1440
|
}
|
|
1441
|
+
|
|
1354
1442
|
function emit(ui, type, data) {
|
|
1355
|
-
if (ui.hasEvent(type))
|
|
1356
|
-
ui.emitEvent(new ImageEvent(type, data));
|
|
1443
|
+
if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
|
|
1357
1444
|
}
|
|
1445
|
+
|
|
1358
1446
|
function ignoreRender(ui, value) {
|
|
1359
|
-
const { leafer
|
|
1360
|
-
if (leafer && leafer.viewReady)
|
|
1361
|
-
leafer.renderer.ignore = value;
|
|
1447
|
+
const {leafer: leafer} = ui;
|
|
1448
|
+
if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
|
|
1362
1449
|
}
|
|
1363
1450
|
|
|
1364
|
-
const {
|
|
1365
|
-
|
|
1451
|
+
const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
|
|
1452
|
+
|
|
1453
|
+
const {floor: floor, max: max, abs: abs} = Math;
|
|
1454
|
+
|
|
1366
1455
|
function createPattern(ui, paint, pixelRatio) {
|
|
1367
|
-
let { scaleX, scaleY } =
|
|
1368
|
-
const id = scaleX +
|
|
1456
|
+
let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
|
|
1457
|
+
const id = scaleX + "-" + scaleY + "-" + pixelRatio;
|
|
1369
1458
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1370
|
-
|
|
1371
|
-
scaleY =
|
|
1372
|
-
|
|
1373
|
-
|
|
1459
|
+
const {image: image, data: data} = paint;
|
|
1460
|
+
let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
|
|
1461
|
+
scaleX *= pixelRatio;
|
|
1462
|
+
scaleY *= pixelRatio;
|
|
1463
|
+
const xGap = gap && gap.x * scaleX;
|
|
1464
|
+
const yGap = gap && gap.y * scaleY;
|
|
1374
1465
|
if (sx) {
|
|
1375
|
-
sx = abs
|
|
1376
|
-
sy = abs
|
|
1466
|
+
sx = abs(sx);
|
|
1467
|
+
sy = abs(sy);
|
|
1377
1468
|
imageMatrix = get$1();
|
|
1378
1469
|
copy$1(imageMatrix, transform);
|
|
1379
1470
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1380
1471
|
scaleX *= sx;
|
|
1381
1472
|
scaleY *= sy;
|
|
1382
1473
|
}
|
|
1383
|
-
scaleX *= pixelRatio;
|
|
1384
|
-
scaleY *= pixelRatio;
|
|
1385
1474
|
width *= scaleX;
|
|
1386
1475
|
height *= scaleY;
|
|
1387
1476
|
const size = width * height;
|
|
1388
1477
|
if (!repeat) {
|
|
1389
|
-
if (size > Platform.image.maxCacheSize)
|
|
1390
|
-
return false;
|
|
1478
|
+
if (size > Platform.image.maxCacheSize) return false;
|
|
1391
1479
|
}
|
|
1392
1480
|
let maxSize = Platform.image.maxPatternSize;
|
|
1393
1481
|
if (!image.isSVG) {
|
|
1394
1482
|
const imageSize = image.width * image.height;
|
|
1395
|
-
if (maxSize > imageSize)
|
|
1396
|
-
maxSize = imageSize;
|
|
1483
|
+
if (maxSize > imageSize) maxSize = imageSize;
|
|
1397
1484
|
}
|
|
1398
|
-
if (size > maxSize)
|
|
1399
|
-
imageScale = Math.sqrt(size / maxSize);
|
|
1485
|
+
if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
|
|
1400
1486
|
if (imageScale) {
|
|
1401
1487
|
scaleX /= imageScale;
|
|
1402
1488
|
scaleY /= imageScale;
|
|
@@ -1410,94 +1496,95 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1410
1496
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1411
1497
|
if (!imageMatrix) {
|
|
1412
1498
|
imageMatrix = get$1();
|
|
1413
|
-
if (transform)
|
|
1414
|
-
copy$1(imageMatrix, transform);
|
|
1499
|
+
if (transform) copy$1(imageMatrix, transform);
|
|
1415
1500
|
}
|
|
1416
1501
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1417
1502
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1503
|
+
if (imageMatrix) {
|
|
1504
|
+
const canvasWidth = width + (xGap || 0), canvasHeight = height + (yGap || 0);
|
|
1505
|
+
scale(imageMatrix, canvasWidth / max(floor(canvasWidth), 1), canvasHeight / max(floor(canvasHeight), 1));
|
|
1506
|
+
}
|
|
1507
|
+
const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap);
|
|
1508
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
|
|
1420
1509
|
paint.style = pattern;
|
|
1421
1510
|
paint.patternId = id;
|
|
1422
1511
|
return true;
|
|
1423
|
-
}
|
|
1424
|
-
else {
|
|
1512
|
+
} else {
|
|
1425
1513
|
return false;
|
|
1426
1514
|
}
|
|
1427
1515
|
}
|
|
1428
1516
|
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
function
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1517
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1518
|
+
function adopt(value) {
|
|
1519
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
1520
|
+
resolve(value);
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
1524
|
+
function fulfilled(value) {
|
|
1525
|
+
try {
|
|
1526
|
+
step(generator.next(value));
|
|
1527
|
+
} catch (e) {
|
|
1528
|
+
reject(e);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
function rejected(value) {
|
|
1532
|
+
try {
|
|
1533
|
+
step(generator["throw"](value));
|
|
1534
|
+
} catch (e) {
|
|
1535
|
+
reject(e);
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
function step(result) {
|
|
1539
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
1540
|
+
}
|
|
1541
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1542
|
+
});
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
|
|
1546
|
+
var e = new Error(message);
|
|
1547
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1459
1548
|
};
|
|
1460
1549
|
|
|
1461
|
-
const { abs } = Math;
|
|
1462
1550
|
function checkImage(ui, canvas, paint, allowDraw) {
|
|
1463
|
-
const { scaleX, scaleY } =
|
|
1464
|
-
const { pixelRatio
|
|
1465
|
-
if (!data ||
|
|
1551
|
+
const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
|
|
1552
|
+
const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
|
|
1553
|
+
if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !Export.running) {
|
|
1466
1554
|
return false;
|
|
1467
|
-
}
|
|
1468
|
-
else {
|
|
1555
|
+
} else {
|
|
1469
1556
|
if (allowDraw) {
|
|
1470
1557
|
if (data.repeat) {
|
|
1471
1558
|
allowDraw = false;
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
height *= abs(scaleY) * pixelRatio;
|
|
1559
|
+
} else {
|
|
1560
|
+
if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
|
|
1561
|
+
let {width: width, height: height} = data;
|
|
1562
|
+
width *= scaleX * pixelRatio;
|
|
1563
|
+
height *= scaleY * pixelRatio;
|
|
1478
1564
|
if (data.scaleX) {
|
|
1479
1565
|
width *= data.scaleX;
|
|
1480
1566
|
height *= data.scaleY;
|
|
1481
1567
|
}
|
|
1482
|
-
allowDraw =
|
|
1568
|
+
allowDraw = width * height > Platform.image.maxCacheSize;
|
|
1483
1569
|
}
|
|
1484
1570
|
}
|
|
1485
1571
|
}
|
|
1486
1572
|
if (allowDraw) {
|
|
1573
|
+
if (ui.__.__isFastShadow) {
|
|
1574
|
+
canvas.fillStyle = paint.style || "#000";
|
|
1575
|
+
canvas.fill();
|
|
1576
|
+
}
|
|
1487
1577
|
drawImage(ui, canvas, paint, data);
|
|
1488
1578
|
return true;
|
|
1489
|
-
}
|
|
1490
|
-
else {
|
|
1579
|
+
} else {
|
|
1491
1580
|
if (!paint.style || paint.sync || Export.running) {
|
|
1492
1581
|
createPattern(ui, paint, pixelRatio);
|
|
1493
|
-
}
|
|
1494
|
-
else {
|
|
1582
|
+
} else {
|
|
1495
1583
|
if (!paint.patternTask) {
|
|
1496
|
-
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*
|
|
1584
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
|
|
1497
1585
|
paint.patternTask = null;
|
|
1498
|
-
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1499
|
-
|
|
1500
|
-
ui.forceUpdate('surface');
|
|
1586
|
+
if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
|
|
1587
|
+
ui.forceUpdate("surface");
|
|
1501
1588
|
}), 300);
|
|
1502
1589
|
}
|
|
1503
1590
|
}
|
|
@@ -1505,39 +1592,35 @@ function checkImage(ui, canvas, paint, allowDraw) {
|
|
|
1505
1592
|
}
|
|
1506
1593
|
}
|
|
1507
1594
|
}
|
|
1595
|
+
|
|
1508
1596
|
function drawImage(ui, canvas, paint, data) {
|
|
1509
1597
|
canvas.save();
|
|
1510
1598
|
canvas.clipUI(ui);
|
|
1511
|
-
if (paint.blendMode)
|
|
1512
|
-
|
|
1513
|
-
if (data.
|
|
1514
|
-
canvas.opacity *= data.opacity;
|
|
1515
|
-
if (data.transform)
|
|
1516
|
-
canvas.transform(data.transform);
|
|
1599
|
+
if (paint.blendMode) canvas.blendMode = paint.blendMode;
|
|
1600
|
+
if (data.opacity) canvas.opacity *= data.opacity;
|
|
1601
|
+
if (data.transform) canvas.transform(data.transform);
|
|
1517
1602
|
canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
|
|
1518
1603
|
canvas.restore();
|
|
1519
1604
|
}
|
|
1520
1605
|
|
|
1521
1606
|
function recycleImage(attrName, data) {
|
|
1522
|
-
const paints = data[
|
|
1523
|
-
if (paints
|
|
1607
|
+
const paints = data["_" + attrName];
|
|
1608
|
+
if (isArray(paints)) {
|
|
1524
1609
|
let paint, image, recycleMap, input, url;
|
|
1525
1610
|
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1526
1611
|
paint = paints[i];
|
|
1527
1612
|
image = paint.image;
|
|
1528
1613
|
url = image && image.url;
|
|
1529
1614
|
if (url) {
|
|
1530
|
-
if (!recycleMap)
|
|
1531
|
-
recycleMap = {};
|
|
1615
|
+
if (!recycleMap) recycleMap = {};
|
|
1532
1616
|
recycleMap[url] = true;
|
|
1533
1617
|
ImageManager.recycle(image);
|
|
1534
1618
|
if (image.loading) {
|
|
1535
1619
|
if (!input) {
|
|
1536
|
-
input =
|
|
1537
|
-
if (!(input
|
|
1538
|
-
input = [input];
|
|
1620
|
+
input = data.__input && data.__input[attrName] || [];
|
|
1621
|
+
if (!isArray(input)) input = [ input ];
|
|
1539
1622
|
}
|
|
1540
|
-
image.unload(paints[i].loadId, !input.some(
|
|
1623
|
+
image.unload(paints[i].loadId, !input.some(item => item.url === url));
|
|
1541
1624
|
}
|
|
1542
1625
|
}
|
|
1543
1626
|
}
|
|
@@ -1547,75 +1630,85 @@ function recycleImage(attrName, data) {
|
|
|
1547
1630
|
}
|
|
1548
1631
|
|
|
1549
1632
|
const PaintImageModule = {
|
|
1550
|
-
image,
|
|
1551
|
-
checkImage,
|
|
1552
|
-
createPattern,
|
|
1553
|
-
recycleImage,
|
|
1554
|
-
createData,
|
|
1555
|
-
getPatternData,
|
|
1556
|
-
fillOrFitMode,
|
|
1557
|
-
clipMode,
|
|
1558
|
-
repeatMode
|
|
1633
|
+
image: image,
|
|
1634
|
+
checkImage: checkImage,
|
|
1635
|
+
createPattern: createPattern,
|
|
1636
|
+
recycleImage: recycleImage,
|
|
1637
|
+
createData: createData,
|
|
1638
|
+
getPatternData: getPatternData,
|
|
1639
|
+
fillOrFitMode: fillOrFitMode,
|
|
1640
|
+
clipMode: clipMode,
|
|
1641
|
+
repeatMode: repeatMode
|
|
1559
1642
|
};
|
|
1560
1643
|
|
|
1561
|
-
const {
|
|
1644
|
+
const {toPoint: toPoint$2} = AroundHelper, {hasTransparent: hasTransparent} = ColorConvert;
|
|
1645
|
+
|
|
1562
1646
|
const realFrom$2 = {};
|
|
1647
|
+
|
|
1563
1648
|
const realTo$2 = {};
|
|
1649
|
+
|
|
1564
1650
|
function linearGradient(paint, box) {
|
|
1565
|
-
let { from, to, type, opacity } = paint;
|
|
1566
|
-
toPoint$2(from ||
|
|
1567
|
-
toPoint$2(to ||
|
|
1651
|
+
let {from: from, to: to, type: type, opacity: opacity} = paint;
|
|
1652
|
+
toPoint$2(from || "top", box, realFrom$2);
|
|
1653
|
+
toPoint$2(to || "bottom", box, realTo$2);
|
|
1568
1654
|
const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1569
|
-
const data = {
|
|
1655
|
+
const data = {
|
|
1656
|
+
type: type,
|
|
1657
|
+
style: style
|
|
1658
|
+
};
|
|
1570
1659
|
applyStops(data, style, paint.stops, opacity);
|
|
1571
1660
|
return data;
|
|
1572
1661
|
}
|
|
1662
|
+
|
|
1573
1663
|
function applyStops(data, gradient, stops, opacity) {
|
|
1574
1664
|
if (stops) {
|
|
1575
1665
|
let stop, color, offset, isTransparent;
|
|
1576
1666
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1577
1667
|
stop = stops[i];
|
|
1578
|
-
if (
|
|
1579
|
-
|
|
1580
|
-
else
|
|
1581
|
-
offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
|
|
1668
|
+
if (isString(stop)) offset = i / (len - 1), color = ColorConvert.string(stop, opacity); else offset = stop.offset,
|
|
1669
|
+
color = ColorConvert.string(stop.color, opacity);
|
|
1582
1670
|
gradient.addColorStop(offset, color);
|
|
1583
|
-
if (!isTransparent && hasTransparent(color))
|
|
1584
|
-
isTransparent = true;
|
|
1671
|
+
if (!isTransparent && hasTransparent(color)) isTransparent = true;
|
|
1585
1672
|
}
|
|
1586
|
-
if (isTransparent)
|
|
1587
|
-
data.isTransparent = true;
|
|
1673
|
+
if (isTransparent) data.isTransparent = true;
|
|
1588
1674
|
}
|
|
1589
1675
|
}
|
|
1590
1676
|
|
|
1591
|
-
const { getAngle, getDistance: getDistance$1
|
|
1592
|
-
|
|
1593
|
-
const {
|
|
1677
|
+
const {getAngle: getAngle, getDistance: getDistance$1} = PointHelper;
|
|
1678
|
+
|
|
1679
|
+
const {get: get, rotateOfOuter: rotateOfOuter, scaleOfOuter: scaleOfOuter} = MatrixHelper;
|
|
1680
|
+
|
|
1681
|
+
const {toPoint: toPoint$1} = AroundHelper;
|
|
1682
|
+
|
|
1594
1683
|
const realFrom$1 = {};
|
|
1684
|
+
|
|
1595
1685
|
const realTo$1 = {};
|
|
1686
|
+
|
|
1596
1687
|
function radialGradient(paint, box) {
|
|
1597
|
-
let { from, to, type, opacity, stretch } = paint;
|
|
1598
|
-
toPoint$1(from ||
|
|
1599
|
-
toPoint$1(to ||
|
|
1688
|
+
let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
|
|
1689
|
+
toPoint$1(from || "center", box, realFrom$1);
|
|
1690
|
+
toPoint$1(to || "bottom", box, realTo$1);
|
|
1600
1691
|
const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
1601
|
-
const data = {
|
|
1692
|
+
const data = {
|
|
1693
|
+
type: type,
|
|
1694
|
+
style: style
|
|
1695
|
+
};
|
|
1602
1696
|
applyStops(data, style, paint.stops, opacity);
|
|
1603
1697
|
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
1604
|
-
if (transform)
|
|
1605
|
-
data.transform = transform;
|
|
1698
|
+
if (transform) data.transform = transform;
|
|
1606
1699
|
return data;
|
|
1607
1700
|
}
|
|
1701
|
+
|
|
1608
1702
|
function getTransform(box, from, to, stretch, rotate90) {
|
|
1609
1703
|
let transform;
|
|
1610
|
-
const { width, height } = box;
|
|
1704
|
+
const {width: width, height: height} = box;
|
|
1611
1705
|
if (width !== height || stretch) {
|
|
1612
1706
|
const angle = getAngle(from, to);
|
|
1613
1707
|
transform = get();
|
|
1614
1708
|
if (rotate90) {
|
|
1615
1709
|
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
1616
1710
|
rotateOfOuter(transform, from, angle + 90);
|
|
1617
|
-
}
|
|
1618
|
-
else {
|
|
1711
|
+
} else {
|
|
1619
1712
|
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
1620
1713
|
rotateOfOuter(transform, from, angle);
|
|
1621
1714
|
}
|
|
@@ -1623,84 +1716,94 @@ function getTransform(box, from, to, stretch, rotate90) {
|
|
|
1623
1716
|
return transform;
|
|
1624
1717
|
}
|
|
1625
1718
|
|
|
1626
|
-
const { getDistance
|
|
1627
|
-
|
|
1719
|
+
const {getDistance: getDistance} = PointHelper;
|
|
1720
|
+
|
|
1721
|
+
const {toPoint: toPoint} = AroundHelper;
|
|
1722
|
+
|
|
1628
1723
|
const realFrom = {};
|
|
1724
|
+
|
|
1629
1725
|
const realTo = {};
|
|
1726
|
+
|
|
1630
1727
|
function conicGradient(paint, box) {
|
|
1631
|
-
let { from, to, type, opacity, stretch } = paint;
|
|
1632
|
-
toPoint(from ||
|
|
1633
|
-
toPoint(to ||
|
|
1728
|
+
let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
|
|
1729
|
+
toPoint(from || "center", box, realFrom);
|
|
1730
|
+
toPoint(to || "bottom", box, realTo);
|
|
1634
1731
|
const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
|
|
1635
|
-
const data = {
|
|
1732
|
+
const data = {
|
|
1733
|
+
type: type,
|
|
1734
|
+
style: style
|
|
1735
|
+
};
|
|
1636
1736
|
applyStops(data, style, paint.stops, opacity);
|
|
1637
1737
|
const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
|
|
1638
|
-
if (transform)
|
|
1639
|
-
data.transform = transform;
|
|
1738
|
+
if (transform) data.transform = transform;
|
|
1640
1739
|
return data;
|
|
1641
1740
|
}
|
|
1642
1741
|
|
|
1643
1742
|
const PaintGradientModule = {
|
|
1644
|
-
linearGradient,
|
|
1645
|
-
radialGradient,
|
|
1646
|
-
conicGradient,
|
|
1647
|
-
getTransform
|
|
1743
|
+
linearGradient: linearGradient,
|
|
1744
|
+
radialGradient: radialGradient,
|
|
1745
|
+
conicGradient: conicGradient,
|
|
1746
|
+
getTransform: getTransform
|
|
1648
1747
|
};
|
|
1649
1748
|
|
|
1650
|
-
const { copy, toOffsetOutBounds: toOffsetOutBounds$1
|
|
1749
|
+
const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = BoundsHelper;
|
|
1750
|
+
|
|
1651
1751
|
const tempBounds = {};
|
|
1752
|
+
|
|
1652
1753
|
const offsetOutBounds$1 = {};
|
|
1754
|
+
|
|
1653
1755
|
function shadow(ui, current, shape) {
|
|
1654
1756
|
let copyBounds, spreadScale;
|
|
1655
|
-
const {
|
|
1656
|
-
const { shadow
|
|
1657
|
-
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1757
|
+
const {__nowWorld: nowWorld, __layout: __layout} = ui;
|
|
1758
|
+
const {shadow: shadow} = ui.__;
|
|
1759
|
+
const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
|
|
1658
1760
|
const other = current.getSameCanvas();
|
|
1659
1761
|
const end = shadow.length - 1;
|
|
1660
1762
|
toOffsetOutBounds$1(bounds, offsetOutBounds$1);
|
|
1661
1763
|
shadow.forEach((item, index) => {
|
|
1662
|
-
|
|
1663
|
-
|
|
1764
|
+
let otherScale = 1;
|
|
1765
|
+
if (item.scaleFixed) {
|
|
1766
|
+
const sx = Math.abs(nowWorld.scaleX);
|
|
1767
|
+
if (sx > 1) otherScale = 1 / sx;
|
|
1768
|
+
}
|
|
1769
|
+
other.setWorldShadow(offsetOutBounds$1.offsetX + item.x * scaleX * otherScale, offsetOutBounds$1.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale, ColorConvert.string(item.color));
|
|
1770
|
+
spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
|
|
1664
1771
|
drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
|
|
1665
1772
|
copyBounds = bounds;
|
|
1666
1773
|
if (item.box) {
|
|
1667
1774
|
other.restore();
|
|
1668
1775
|
other.save();
|
|
1669
1776
|
if (worldCanvas) {
|
|
1670
|
-
other.copyWorld(other, bounds, nowWorld,
|
|
1777
|
+
other.copyWorld(other, bounds, nowWorld, "copy");
|
|
1671
1778
|
copyBounds = nowWorld;
|
|
1672
1779
|
}
|
|
1673
|
-
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld,
|
|
1674
|
-
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
else
|
|
1678
|
-
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1679
|
-
if (end && index < end)
|
|
1680
|
-
other.clearWorld(copyBounds, true);
|
|
1780
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
|
|
1781
|
+
}
|
|
1782
|
+
LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
|
|
1783
|
+
if (end && index < end) other.clearWorld(copyBounds, true);
|
|
1681
1784
|
});
|
|
1682
1785
|
other.recycle(copyBounds);
|
|
1683
1786
|
}
|
|
1787
|
+
|
|
1684
1788
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1685
|
-
const { bounds, shapeBounds } = shape;
|
|
1789
|
+
const {bounds: bounds, shapeBounds: shapeBounds} = shape;
|
|
1686
1790
|
if (Platform.fullImageShadow) {
|
|
1687
1791
|
copy(tempBounds, canvas.bounds);
|
|
1688
|
-
tempBounds.x +=
|
|
1689
|
-
tempBounds.y +=
|
|
1792
|
+
tempBounds.x += outBounds.x - shapeBounds.x;
|
|
1793
|
+
tempBounds.y += outBounds.y - shapeBounds.y;
|
|
1690
1794
|
if (spreadScale) {
|
|
1691
|
-
const {
|
|
1692
|
-
tempBounds.x -= (bounds.x + (
|
|
1693
|
-
tempBounds.y -= (bounds.y + (
|
|
1795
|
+
const {fitMatrix: fitMatrix} = shape;
|
|
1796
|
+
tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
|
|
1797
|
+
tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
|
|
1694
1798
|
tempBounds.width *= spreadScale;
|
|
1695
1799
|
tempBounds.height *= spreadScale;
|
|
1696
1800
|
}
|
|
1697
1801
|
canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
|
|
1698
|
-
}
|
|
1699
|
-
else {
|
|
1802
|
+
} else {
|
|
1700
1803
|
if (spreadScale) {
|
|
1701
1804
|
copy(tempBounds, outBounds);
|
|
1702
|
-
tempBounds.x -=
|
|
1703
|
-
tempBounds.y -=
|
|
1805
|
+
tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
|
|
1806
|
+
tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
|
|
1704
1807
|
tempBounds.width *= spreadScale;
|
|
1705
1808
|
tempBounds.height *= spreadScale;
|
|
1706
1809
|
}
|
|
@@ -1708,178 +1811,184 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1708
1811
|
}
|
|
1709
1812
|
}
|
|
1710
1813
|
|
|
1711
|
-
const { toOffsetOutBounds
|
|
1814
|
+
const {toOffsetOutBounds: toOffsetOutBounds} = BoundsHelper;
|
|
1815
|
+
|
|
1712
1816
|
const offsetOutBounds = {};
|
|
1817
|
+
|
|
1713
1818
|
function innerShadow(ui, current, shape) {
|
|
1714
1819
|
let copyBounds, spreadScale;
|
|
1715
|
-
const {
|
|
1716
|
-
const { innerShadow
|
|
1717
|
-
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1820
|
+
const {__nowWorld: nowWorld, __layout: __layout} = ui;
|
|
1821
|
+
const {innerShadow: innerShadow} = ui.__;
|
|
1822
|
+
const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
|
|
1718
1823
|
const other = current.getSameCanvas();
|
|
1719
1824
|
const end = innerShadow.length - 1;
|
|
1720
1825
|
toOffsetOutBounds(bounds, offsetOutBounds);
|
|
1721
1826
|
innerShadow.forEach((item, index) => {
|
|
1827
|
+
let otherScale = 1;
|
|
1828
|
+
if (item.scaleFixed) {
|
|
1829
|
+
const sx = Math.abs(nowWorld.scaleX);
|
|
1830
|
+
if (sx > 1) otherScale = 1 / sx;
|
|
1831
|
+
}
|
|
1722
1832
|
other.save();
|
|
1723
|
-
other.setWorldShadow(
|
|
1724
|
-
spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
|
|
1833
|
+
other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
|
|
1834
|
+
spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
|
|
1725
1835
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1726
1836
|
other.restore();
|
|
1727
1837
|
if (worldCanvas) {
|
|
1728
|
-
other.copyWorld(other, bounds, nowWorld,
|
|
1729
|
-
other.copyWorld(worldCanvas, nowWorld, nowWorld,
|
|
1838
|
+
other.copyWorld(other, bounds, nowWorld, "copy");
|
|
1839
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
|
|
1730
1840
|
copyBounds = nowWorld;
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1841
|
+
} else {
|
|
1842
|
+
other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
|
|
1734
1843
|
copyBounds = bounds;
|
|
1735
1844
|
}
|
|
1736
|
-
other.fillWorld(copyBounds, ColorConvert.string(item.color),
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
else
|
|
1740
|
-
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1741
|
-
if (end && index < end)
|
|
1742
|
-
other.clearWorld(copyBounds, true);
|
|
1845
|
+
other.fillWorld(copyBounds, ColorConvert.string(item.color), "source-in");
|
|
1846
|
+
LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
|
|
1847
|
+
if (end && index < end) other.clearWorld(copyBounds, true);
|
|
1743
1848
|
});
|
|
1744
1849
|
other.recycle(copyBounds);
|
|
1745
1850
|
}
|
|
1746
1851
|
|
|
1747
1852
|
function blur(ui, current, origin) {
|
|
1748
|
-
const { blur
|
|
1853
|
+
const {blur: blur} = ui.__;
|
|
1749
1854
|
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1750
1855
|
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1751
|
-
origin.filter =
|
|
1856
|
+
origin.filter = "none";
|
|
1752
1857
|
}
|
|
1753
1858
|
|
|
1754
|
-
function backgroundBlur(_ui, _current, _shape) {
|
|
1755
|
-
}
|
|
1859
|
+
function backgroundBlur(_ui, _current, _shape) {}
|
|
1756
1860
|
|
|
1757
1861
|
const EffectModule = {
|
|
1758
|
-
shadow,
|
|
1759
|
-
innerShadow,
|
|
1760
|
-
blur,
|
|
1761
|
-
backgroundBlur
|
|
1862
|
+
shadow: shadow,
|
|
1863
|
+
innerShadow: innerShadow,
|
|
1864
|
+
blur: blur,
|
|
1865
|
+
backgroundBlur: backgroundBlur
|
|
1762
1866
|
};
|
|
1763
1867
|
|
|
1764
|
-
const { excludeRenderBounds
|
|
1765
|
-
|
|
1868
|
+
const {excludeRenderBounds: excludeRenderBounds} = LeafBoundsHelper;
|
|
1869
|
+
|
|
1870
|
+
let usedGrayscaleAlpha;
|
|
1871
|
+
|
|
1872
|
+
Group.prototype.__renderMask = function(canvas, options) {
|
|
1766
1873
|
let child, maskCanvas, contentCanvas, maskOpacity, currentMask, mask;
|
|
1767
|
-
const { children
|
|
1874
|
+
const {children: children} = this;
|
|
1768
1875
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
1769
1876
|
child = children[i], mask = child.__.mask;
|
|
1770
1877
|
if (mask) {
|
|
1771
1878
|
if (currentMask) {
|
|
1772
|
-
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1879
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
|
|
1773
1880
|
maskCanvas = contentCanvas = null;
|
|
1774
1881
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
currentMask = 'path';
|
|
1882
|
+
maskOpacity = child.__.opacity;
|
|
1883
|
+
usedGrayscaleAlpha = false;
|
|
1884
|
+
if (mask === "path" || mask === "clipping-path") {
|
|
1885
|
+
if (maskOpacity < 1) {
|
|
1886
|
+
currentMask = "opacity-path";
|
|
1887
|
+
if (!contentCanvas) contentCanvas = getCanvas(canvas);
|
|
1888
|
+
} else {
|
|
1889
|
+
currentMask = "path";
|
|
1784
1890
|
canvas.save();
|
|
1785
1891
|
}
|
|
1786
1892
|
child.__clip(contentCanvas || canvas, options);
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
if (!
|
|
1791
|
-
maskCanvas = getCanvas(canvas);
|
|
1792
|
-
if (!contentCanvas)
|
|
1793
|
-
contentCanvas = getCanvas(canvas);
|
|
1893
|
+
} else {
|
|
1894
|
+
currentMask = mask === "grayscale" ? "grayscale" : "alpha";
|
|
1895
|
+
if (!maskCanvas) maskCanvas = getCanvas(canvas);
|
|
1896
|
+
if (!contentCanvas) contentCanvas = getCanvas(canvas);
|
|
1794
1897
|
child.__render(maskCanvas, options);
|
|
1795
1898
|
}
|
|
1796
|
-
if (
|
|
1797
|
-
continue;
|
|
1798
|
-
}
|
|
1799
|
-
if (excludeRenderBounds(child, options))
|
|
1899
|
+
if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
|
|
1800
1900
|
continue;
|
|
1801
|
-
|
|
1901
|
+
}
|
|
1902
|
+
const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
|
|
1903
|
+
if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, false);
|
|
1904
|
+
excludeRenderBounds(child, options) || child.__render(contentCanvas || canvas, options);
|
|
1905
|
+
if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, childBlendMode, false);
|
|
1802
1906
|
}
|
|
1803
|
-
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1907
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
|
|
1804
1908
|
};
|
|
1805
|
-
|
|
1909
|
+
|
|
1910
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity, blendMode, recycle) {
|
|
1806
1911
|
switch (maskMode) {
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1912
|
+
case "grayscale":
|
|
1913
|
+
if (!usedGrayscaleAlpha) usedGrayscaleAlpha = true, maskCanvas.useGrayscaleAlpha(leaf.__nowWorld);
|
|
1914
|
+
|
|
1915
|
+
case "alpha":
|
|
1916
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas, blendMode, recycle);
|
|
1917
|
+
break;
|
|
1918
|
+
|
|
1919
|
+
case "opacity-path":
|
|
1920
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity, blendMode, recycle);
|
|
1921
|
+
break;
|
|
1922
|
+
|
|
1923
|
+
case "path":
|
|
1924
|
+
if (recycle) canvas.restore();
|
|
1817
1925
|
}
|
|
1818
1926
|
}
|
|
1927
|
+
|
|
1819
1928
|
function getCanvas(canvas) {
|
|
1820
1929
|
return canvas.getSameCanvas(false, true);
|
|
1821
1930
|
}
|
|
1822
|
-
|
|
1931
|
+
|
|
1932
|
+
function usePixelMask(leaf, canvas, content, mask, blendMode, recycle) {
|
|
1823
1933
|
const realBounds = leaf.__nowWorld;
|
|
1824
1934
|
content.resetTransform();
|
|
1825
1935
|
content.opacity = 1;
|
|
1826
1936
|
content.useMask(mask, realBounds);
|
|
1827
|
-
mask.recycle(realBounds);
|
|
1828
|
-
copyContent(leaf, canvas, content, 1);
|
|
1937
|
+
if (recycle) mask.recycle(realBounds);
|
|
1938
|
+
copyContent(leaf, canvas, content, 1, blendMode, recycle);
|
|
1829
1939
|
}
|
|
1830
|
-
|
|
1940
|
+
|
|
1941
|
+
function copyContent(leaf, canvas, content, maskOpacity, blendMode, recycle) {
|
|
1831
1942
|
const realBounds = leaf.__nowWorld;
|
|
1832
1943
|
canvas.resetTransform();
|
|
1833
1944
|
canvas.opacity = maskOpacity;
|
|
1834
|
-
canvas.copyWorld(content, realBounds);
|
|
1835
|
-
content.recycle(realBounds);
|
|
1836
|
-
}
|
|
1837
|
-
|
|
1838
|
-
const money =
|
|
1839
|
-
|
|
1840
|
-
const
|
|
1841
|
-
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
const
|
|
1845
|
-
|
|
1846
|
-
const
|
|
1847
|
-
|
|
1848
|
-
const
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
[0x31C0, 0x31EF],
|
|
1863
|
-
[0x3200, 0x32FF],
|
|
1864
|
-
[0x3300, 0x33FF],
|
|
1865
|
-
[0xF900, 0xFAFF],
|
|
1866
|
-
[0xFE30, 0xFE4F],
|
|
1867
|
-
[0x1F200, 0x1F2FF],
|
|
1868
|
-
[0x2F800, 0x2FA1F],
|
|
1869
|
-
];
|
|
1870
|
-
const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join('|'));
|
|
1945
|
+
canvas.copyWorld(content, realBounds, undefined, blendMode);
|
|
1946
|
+
recycle ? content.recycle(realBounds) : content.clearWorld(realBounds, true);
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
const money = "¥¥$€££¢¢";
|
|
1950
|
+
|
|
1951
|
+
const letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
|
|
1952
|
+
|
|
1953
|
+
const langBefore = "《(「〈『〖【〔{┌<‘“=" + money;
|
|
1954
|
+
|
|
1955
|
+
const langAfter = "》)」〉』〗】〕}┐>’”!?,、。:;‰";
|
|
1956
|
+
|
|
1957
|
+
const langSymbol = "≮≯≈≠=…";
|
|
1958
|
+
|
|
1959
|
+
const langBreak$1 = "—/~|┆·";
|
|
1960
|
+
|
|
1961
|
+
const beforeChar = "{[(<'\"" + langBefore;
|
|
1962
|
+
|
|
1963
|
+
const afterChar = ">)]}%!?,.:;'\"" + langAfter;
|
|
1964
|
+
|
|
1965
|
+
const symbolChar = afterChar + "_#~&*+\\=|" + langSymbol;
|
|
1966
|
+
|
|
1967
|
+
const breakChar = "- " + langBreak$1;
|
|
1968
|
+
|
|
1969
|
+
const cjkRangeList = [ [ 19968, 40959 ], [ 13312, 19903 ], [ 131072, 173791 ], [ 173824, 177983 ], [ 177984, 178207 ], [ 178208, 183983 ], [ 183984, 191471 ], [ 196608, 201551 ], [ 201552, 205743 ], [ 11904, 12031 ], [ 12032, 12255 ], [ 12272, 12287 ], [ 12288, 12351 ], [ 12736, 12783 ], [ 12800, 13055 ], [ 13056, 13311 ], [ 63744, 64255 ], [ 65072, 65103 ], [ 127488, 127743 ], [ 194560, 195103 ] ];
|
|
1970
|
+
|
|
1971
|
+
const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join("|"));
|
|
1972
|
+
|
|
1871
1973
|
function mapChar(str) {
|
|
1872
1974
|
const map = {};
|
|
1873
|
-
str.split(
|
|
1975
|
+
str.split("").forEach(char => map[char] = true);
|
|
1874
1976
|
return map;
|
|
1875
1977
|
}
|
|
1978
|
+
|
|
1876
1979
|
const letterMap = mapChar(letter);
|
|
1980
|
+
|
|
1877
1981
|
const beforeMap = mapChar(beforeChar);
|
|
1982
|
+
|
|
1878
1983
|
const afterMap = mapChar(afterChar);
|
|
1984
|
+
|
|
1879
1985
|
const symbolMap = mapChar(symbolChar);
|
|
1986
|
+
|
|
1880
1987
|
const breakMap = mapChar(breakChar);
|
|
1988
|
+
|
|
1881
1989
|
var CharType;
|
|
1882
|
-
|
|
1990
|
+
|
|
1991
|
+
(function(CharType) {
|
|
1883
1992
|
CharType[CharType["Letter"] = 0] = "Letter";
|
|
1884
1993
|
CharType[CharType["Single"] = 1] = "Single";
|
|
1885
1994
|
CharType[CharType["Before"] = 2] = "Before";
|
|
@@ -1887,179 +1996,175 @@ var CharType;
|
|
|
1887
1996
|
CharType[CharType["Symbol"] = 4] = "Symbol";
|
|
1888
1997
|
CharType[CharType["Break"] = 5] = "Break";
|
|
1889
1998
|
})(CharType || (CharType = {}));
|
|
1890
|
-
|
|
1999
|
+
|
|
2000
|
+
const {Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1} = CharType;
|
|
2001
|
+
|
|
1891
2002
|
function getCharType(char) {
|
|
1892
2003
|
if (letterMap[char]) {
|
|
1893
2004
|
return Letter$1;
|
|
1894
|
-
}
|
|
1895
|
-
else if (breakMap[char]) {
|
|
2005
|
+
} else if (breakMap[char]) {
|
|
1896
2006
|
return Break$1;
|
|
1897
|
-
}
|
|
1898
|
-
else if (beforeMap[char]) {
|
|
2007
|
+
} else if (beforeMap[char]) {
|
|
1899
2008
|
return Before$1;
|
|
1900
|
-
}
|
|
1901
|
-
else if (afterMap[char]) {
|
|
2009
|
+
} else if (afterMap[char]) {
|
|
1902
2010
|
return After$1;
|
|
1903
|
-
}
|
|
1904
|
-
else if (symbolMap[char]) {
|
|
2011
|
+
} else if (symbolMap[char]) {
|
|
1905
2012
|
return Symbol$1;
|
|
1906
|
-
}
|
|
1907
|
-
else if (cjkReg.test(char)) {
|
|
2013
|
+
} else if (cjkReg.test(char)) {
|
|
1908
2014
|
return Single$1;
|
|
1909
|
-
}
|
|
1910
|
-
else {
|
|
2015
|
+
} else {
|
|
1911
2016
|
return Letter$1;
|
|
1912
2017
|
}
|
|
1913
2018
|
}
|
|
1914
2019
|
|
|
1915
2020
|
const TextRowHelper = {
|
|
1916
2021
|
trimRight(row) {
|
|
1917
|
-
const { words
|
|
2022
|
+
const {words: words} = row;
|
|
1918
2023
|
let trimRight = 0, len = words.length, char;
|
|
1919
2024
|
for (let i = len - 1; i > -1; i--) {
|
|
1920
2025
|
char = words[i].data[0];
|
|
1921
|
-
if (char.char ===
|
|
2026
|
+
if (char.char === " ") {
|
|
1922
2027
|
trimRight++;
|
|
1923
2028
|
row.width -= char.width;
|
|
1924
|
-
}
|
|
1925
|
-
else {
|
|
2029
|
+
} else {
|
|
1926
2030
|
break;
|
|
1927
2031
|
}
|
|
1928
2032
|
}
|
|
1929
|
-
if (trimRight)
|
|
1930
|
-
words.splice(len - trimRight, trimRight);
|
|
2033
|
+
if (trimRight) words.splice(len - trimRight, trimRight);
|
|
1931
2034
|
}
|
|
1932
2035
|
};
|
|
1933
2036
|
|
|
1934
2037
|
function getTextCase(char, textCase, firstChar) {
|
|
1935
2038
|
switch (textCase) {
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2039
|
+
case "title":
|
|
2040
|
+
return firstChar ? char.toUpperCase() : char;
|
|
2041
|
+
|
|
2042
|
+
case "upper":
|
|
2043
|
+
return char.toUpperCase();
|
|
2044
|
+
|
|
2045
|
+
case "lower":
|
|
2046
|
+
return char.toLowerCase();
|
|
2047
|
+
|
|
2048
|
+
default:
|
|
2049
|
+
return char;
|
|
1944
2050
|
}
|
|
1945
2051
|
}
|
|
1946
2052
|
|
|
1947
|
-
const { trimRight
|
|
1948
|
-
|
|
2053
|
+
const {trimRight: trimRight} = TextRowHelper;
|
|
2054
|
+
|
|
2055
|
+
const {Letter: Letter, Single: Single, Before: Before, After: After, Symbol: Symbol, Break: Break} = CharType;
|
|
2056
|
+
|
|
1949
2057
|
let word, row, wordWidth, rowWidth, realWidth;
|
|
2058
|
+
|
|
1950
2059
|
let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
2060
|
+
|
|
1951
2061
|
let textDrawData, rows = [], bounds, findMaxWidth;
|
|
2062
|
+
|
|
1952
2063
|
function createRows(drawData, content, style) {
|
|
1953
2064
|
textDrawData = drawData;
|
|
1954
2065
|
rows = drawData.rows;
|
|
1955
2066
|
bounds = drawData.bounds;
|
|
1956
2067
|
findMaxWidth = !bounds.width && !style.autoSizeAlign;
|
|
1957
|
-
const { __letterSpacing, paraIndent, textCase } = style;
|
|
1958
|
-
const { canvas
|
|
1959
|
-
const { width, height } = bounds;
|
|
1960
|
-
const charMode = width || height || __letterSpacing ||
|
|
2068
|
+
const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
|
|
2069
|
+
const {canvas: canvas} = Platform;
|
|
2070
|
+
const {width: width, height: height} = bounds;
|
|
2071
|
+
const charMode = width || height || __letterSpacing || textCase !== "none";
|
|
1961
2072
|
if (charMode) {
|
|
1962
|
-
const wrap = style.textWrap !==
|
|
1963
|
-
const breakAll = style.textWrap ===
|
|
2073
|
+
const wrap = style.textWrap !== "none";
|
|
2074
|
+
const breakAll = style.textWrap === "break";
|
|
1964
2075
|
paraStart = true;
|
|
1965
2076
|
lastCharType = null;
|
|
1966
2077
|
startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
|
|
1967
|
-
word = {
|
|
1968
|
-
|
|
1969
|
-
|
|
2078
|
+
word = {
|
|
2079
|
+
data: []
|
|
2080
|
+
}, row = {
|
|
2081
|
+
words: []
|
|
2082
|
+
};
|
|
2083
|
+
if (__letterSpacing) content = [ ...content ];
|
|
1970
2084
|
for (let i = 0, len = content.length; i < len; i++) {
|
|
1971
2085
|
char = content[i];
|
|
1972
|
-
if (char ===
|
|
1973
|
-
if (wordWidth)
|
|
1974
|
-
addWord();
|
|
2086
|
+
if (char === "\n") {
|
|
2087
|
+
if (wordWidth) addWord();
|
|
1975
2088
|
row.paraEnd = true;
|
|
1976
2089
|
addRow();
|
|
1977
2090
|
paraStart = true;
|
|
1978
|
-
}
|
|
1979
|
-
else {
|
|
2091
|
+
} else {
|
|
1980
2092
|
charType = getCharType(char);
|
|
1981
|
-
if (charType === Letter && textCase !==
|
|
1982
|
-
char = getTextCase(char, textCase, !wordWidth);
|
|
2093
|
+
if (charType === Letter && textCase !== "none") char = getTextCase(char, textCase, !wordWidth);
|
|
1983
2094
|
charWidth = canvas.measureText(char).width;
|
|
1984
2095
|
if (__letterSpacing) {
|
|
1985
|
-
if (__letterSpacing < 0)
|
|
1986
|
-
charSize = charWidth;
|
|
2096
|
+
if (__letterSpacing < 0) charSize = charWidth;
|
|
1987
2097
|
charWidth += __letterSpacing;
|
|
1988
2098
|
}
|
|
1989
|
-
langBreak =
|
|
1990
|
-
afterBreak = (
|
|
2099
|
+
langBreak = charType === Single && (lastCharType === Single || lastCharType === Letter) || lastCharType === Single && charType !== After;
|
|
2100
|
+
afterBreak = (charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After);
|
|
1991
2101
|
realWidth = paraStart && paraIndent ? width - paraIndent : width;
|
|
1992
2102
|
if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
|
|
1993
2103
|
if (breakAll) {
|
|
1994
|
-
if (wordWidth)
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
if (wordWidth)
|
|
2004
|
-
addWord();
|
|
2005
|
-
if (rowWidth)
|
|
2006
|
-
addRow();
|
|
2007
|
-
}
|
|
2008
|
-
else {
|
|
2009
|
-
if (rowWidth)
|
|
2010
|
-
addRow();
|
|
2104
|
+
if (wordWidth) addWord();
|
|
2105
|
+
if (rowWidth) addRow();
|
|
2106
|
+
} else {
|
|
2107
|
+
if (!afterBreak) afterBreak = charType === Letter && lastCharType == After;
|
|
2108
|
+
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || wordWidth + charWidth > realWidth) {
|
|
2109
|
+
if (wordWidth) addWord();
|
|
2110
|
+
if (rowWidth) addRow();
|
|
2111
|
+
} else {
|
|
2112
|
+
if (rowWidth) addRow();
|
|
2011
2113
|
}
|
|
2012
2114
|
}
|
|
2013
2115
|
}
|
|
2014
|
-
if (char ===
|
|
2015
|
-
else {
|
|
2116
|
+
if (char === " " && paraStart !== true && rowWidth + wordWidth === 0) ; else {
|
|
2016
2117
|
if (charType === Break) {
|
|
2017
|
-
if (char ===
|
|
2018
|
-
addWord();
|
|
2118
|
+
if (char === " " && wordWidth) addWord();
|
|
2019
2119
|
addChar(char, charWidth);
|
|
2020
2120
|
addWord();
|
|
2021
|
-
}
|
|
2022
|
-
|
|
2023
|
-
if (wordWidth)
|
|
2024
|
-
addWord();
|
|
2121
|
+
} else if (langBreak || afterBreak) {
|
|
2122
|
+
if (wordWidth) addWord();
|
|
2025
2123
|
addChar(char, charWidth);
|
|
2026
|
-
}
|
|
2027
|
-
else {
|
|
2124
|
+
} else {
|
|
2028
2125
|
addChar(char, charWidth);
|
|
2029
2126
|
}
|
|
2030
2127
|
}
|
|
2031
2128
|
lastCharType = charType;
|
|
2032
2129
|
}
|
|
2033
2130
|
}
|
|
2034
|
-
if (wordWidth)
|
|
2035
|
-
|
|
2036
|
-
if (rowWidth)
|
|
2037
|
-
addRow();
|
|
2131
|
+
if (wordWidth) addWord();
|
|
2132
|
+
if (rowWidth) addRow();
|
|
2038
2133
|
rows.length > 0 && (rows[rows.length - 1].paraEnd = true);
|
|
2039
|
-
}
|
|
2040
|
-
|
|
2041
|
-
content.split('\n').forEach(content => {
|
|
2134
|
+
} else {
|
|
2135
|
+
content.split("\n").forEach(content => {
|
|
2042
2136
|
textDrawData.paraNumber++;
|
|
2043
2137
|
rowWidth = canvas.measureText(content).width;
|
|
2044
|
-
rows.push({
|
|
2045
|
-
|
|
2046
|
-
|
|
2138
|
+
rows.push({
|
|
2139
|
+
x: paraIndent || 0,
|
|
2140
|
+
text: content,
|
|
2141
|
+
width: rowWidth,
|
|
2142
|
+
paraStart: true
|
|
2143
|
+
});
|
|
2144
|
+
if (findMaxWidth) setMaxWidth();
|
|
2047
2145
|
});
|
|
2048
2146
|
}
|
|
2049
2147
|
}
|
|
2148
|
+
|
|
2050
2149
|
function addChar(char, width) {
|
|
2051
|
-
if (charSize && !startCharSize)
|
|
2052
|
-
|
|
2053
|
-
|
|
2150
|
+
if (charSize && !startCharSize) startCharSize = charSize;
|
|
2151
|
+
word.data.push({
|
|
2152
|
+
char: char,
|
|
2153
|
+
width: width
|
|
2154
|
+
});
|
|
2054
2155
|
wordWidth += width;
|
|
2055
2156
|
}
|
|
2157
|
+
|
|
2056
2158
|
function addWord() {
|
|
2057
2159
|
rowWidth += wordWidth;
|
|
2058
2160
|
word.width = wordWidth;
|
|
2059
2161
|
row.words.push(word);
|
|
2060
|
-
word = {
|
|
2162
|
+
word = {
|
|
2163
|
+
data: []
|
|
2164
|
+
};
|
|
2061
2165
|
wordWidth = 0;
|
|
2062
2166
|
}
|
|
2167
|
+
|
|
2063
2168
|
function addRow() {
|
|
2064
2169
|
if (paraStart) {
|
|
2065
2170
|
textDrawData.paraNumber++;
|
|
@@ -2072,52 +2177,53 @@ function addRow() {
|
|
|
2072
2177
|
startCharSize = 0;
|
|
2073
2178
|
}
|
|
2074
2179
|
row.width = rowWidth;
|
|
2075
|
-
if (bounds.width)
|
|
2076
|
-
trimRight(row);
|
|
2077
|
-
else if (findMaxWidth)
|
|
2078
|
-
setMaxWidth();
|
|
2180
|
+
if (bounds.width) trimRight(row); else if (findMaxWidth) setMaxWidth();
|
|
2079
2181
|
rows.push(row);
|
|
2080
|
-
row = {
|
|
2182
|
+
row = {
|
|
2183
|
+
words: []
|
|
2184
|
+
};
|
|
2081
2185
|
rowWidth = 0;
|
|
2082
2186
|
}
|
|
2187
|
+
|
|
2083
2188
|
function setMaxWidth() {
|
|
2084
|
-
if (rowWidth > (textDrawData.maxWidth || 0))
|
|
2085
|
-
textDrawData.maxWidth = rowWidth;
|
|
2189
|
+
if (rowWidth > (textDrawData.maxWidth || 0)) textDrawData.maxWidth = rowWidth;
|
|
2086
2190
|
}
|
|
2087
2191
|
|
|
2088
2192
|
const CharMode = 0;
|
|
2193
|
+
|
|
2089
2194
|
const WordMode = 1;
|
|
2195
|
+
|
|
2090
2196
|
const TextMode = 2;
|
|
2197
|
+
|
|
2091
2198
|
function layoutChar(drawData, style, width, _height) {
|
|
2092
|
-
const { rows
|
|
2093
|
-
const { textAlign, paraIndent, letterSpacing } = style;
|
|
2199
|
+
const {rows: rows} = drawData;
|
|
2200
|
+
const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
|
|
2094
2201
|
let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
|
|
2095
2202
|
rows.forEach(row => {
|
|
2096
2203
|
if (row.words) {
|
|
2097
2204
|
indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
|
|
2098
|
-
addWordWidth =
|
|
2099
|
-
mode =
|
|
2100
|
-
if (row.isOverflow && !letterSpacing)
|
|
2101
|
-
row.textMode = true;
|
|
2205
|
+
addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
|
|
2206
|
+
mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
|
|
2207
|
+
if (row.isOverflow && !letterSpacing) row.textMode = true;
|
|
2102
2208
|
if (mode === TextMode) {
|
|
2103
2209
|
row.x += indentWidth;
|
|
2104
2210
|
toTextChar$1(row);
|
|
2105
|
-
}
|
|
2106
|
-
else {
|
|
2211
|
+
} else {
|
|
2107
2212
|
row.x += indentWidth;
|
|
2108
2213
|
charX = row.x;
|
|
2109
2214
|
row.data = [];
|
|
2110
2215
|
row.words.forEach((word, index) => {
|
|
2111
2216
|
if (mode === WordMode) {
|
|
2112
|
-
wordChar = {
|
|
2217
|
+
wordChar = {
|
|
2218
|
+
char: "",
|
|
2219
|
+
x: charX
|
|
2220
|
+
};
|
|
2113
2221
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2114
|
-
if (row.isOverflow || wordChar.char !==
|
|
2115
|
-
|
|
2116
|
-
}
|
|
2117
|
-
else {
|
|
2222
|
+
if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
|
|
2223
|
+
} else {
|
|
2118
2224
|
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2119
2225
|
}
|
|
2120
|
-
if (addWordWidth && (!row.paraEnd || textAlign ===
|
|
2226
|
+
if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
|
|
2121
2227
|
charX += addWordWidth;
|
|
2122
2228
|
row.width += addWordWidth;
|
|
2123
2229
|
}
|
|
@@ -2127,14 +2233,16 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2127
2233
|
}
|
|
2128
2234
|
});
|
|
2129
2235
|
}
|
|
2236
|
+
|
|
2130
2237
|
function toTextChar$1(row) {
|
|
2131
|
-
row.text =
|
|
2238
|
+
row.text = "";
|
|
2132
2239
|
row.words.forEach(word => {
|
|
2133
2240
|
word.data.forEach(char => {
|
|
2134
2241
|
row.text += char.char;
|
|
2135
2242
|
});
|
|
2136
2243
|
});
|
|
2137
2244
|
}
|
|
2245
|
+
|
|
2138
2246
|
function toWordChar(data, charX, wordChar) {
|
|
2139
2247
|
data.forEach(char => {
|
|
2140
2248
|
wordChar.char += char.char;
|
|
@@ -2142,9 +2250,10 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2142
2250
|
});
|
|
2143
2251
|
return charX;
|
|
2144
2252
|
}
|
|
2253
|
+
|
|
2145
2254
|
function toChar(data, charX, rowData, isOverflow) {
|
|
2146
2255
|
data.forEach(char => {
|
|
2147
|
-
if (isOverflow || char.char !==
|
|
2256
|
+
if (isOverflow || char.char !== " ") {
|
|
2148
2257
|
char.x = charX;
|
|
2149
2258
|
rowData.push(char);
|
|
2150
2259
|
}
|
|
@@ -2154,38 +2263,39 @@ function toChar(data, charX, rowData, isOverflow) {
|
|
|
2154
2263
|
}
|
|
2155
2264
|
|
|
2156
2265
|
function layoutText(drawData, style) {
|
|
2157
|
-
const { rows, bounds } = drawData, countRows = rows.length;
|
|
2158
|
-
const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
|
|
2159
|
-
let { x, y, width, height } = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
2266
|
+
const {rows: rows, bounds: bounds} = drawData, countRows = rows.length;
|
|
2267
|
+
const {__lineHeight: __lineHeight, __baseLine: __baseLine, __letterSpacing: __letterSpacing, __clipText: __clipText, textAlign: textAlign, verticalAlign: verticalAlign, paraSpacing: paraSpacing, autoSizeAlign: autoSizeAlign} = style;
|
|
2268
|
+
let {x: x, y: y, width: width, height: height} = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
2160
2269
|
let starY = __baseLine;
|
|
2161
2270
|
if (__clipText && realHeight > height) {
|
|
2162
2271
|
realHeight = Math.max(height, __lineHeight);
|
|
2163
|
-
if (countRows > 1)
|
|
2164
|
-
|
|
2165
|
-
}
|
|
2166
|
-
else if (height || autoSizeAlign) {
|
|
2272
|
+
if (countRows > 1) drawData.overflow = countRows;
|
|
2273
|
+
} else if (height || autoSizeAlign) {
|
|
2167
2274
|
switch (verticalAlign) {
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2275
|
+
case "middle":
|
|
2276
|
+
y += (height - realHeight) / 2;
|
|
2277
|
+
break;
|
|
2278
|
+
|
|
2279
|
+
case "bottom":
|
|
2280
|
+
y += height - realHeight;
|
|
2172
2281
|
}
|
|
2173
2282
|
}
|
|
2174
2283
|
starY += y;
|
|
2175
|
-
let row, rowX, rowWidth, layoutWidth =
|
|
2284
|
+
let row, rowX, rowWidth, layoutWidth = width || autoSizeAlign ? width : drawData.maxWidth;
|
|
2176
2285
|
for (let i = 0, len = countRows; i < len; i++) {
|
|
2177
2286
|
row = rows[i];
|
|
2178
2287
|
row.x = x;
|
|
2179
|
-
if (row.width < width ||
|
|
2288
|
+
if (row.width < width || row.width > width && !__clipText) {
|
|
2180
2289
|
switch (textAlign) {
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2290
|
+
case "center":
|
|
2291
|
+
row.x += (layoutWidth - row.width) / 2;
|
|
2292
|
+
break;
|
|
2293
|
+
|
|
2294
|
+
case "right":
|
|
2295
|
+
row.x += layoutWidth - row.width;
|
|
2185
2296
|
}
|
|
2186
2297
|
}
|
|
2187
|
-
if (row.paraStart && paraSpacing && i > 0)
|
|
2188
|
-
starY += paraSpacing;
|
|
2298
|
+
if (row.paraStart && paraSpacing && i > 0) starY += paraSpacing;
|
|
2189
2299
|
row.y = starY;
|
|
2190
2300
|
starY += __lineHeight;
|
|
2191
2301
|
if (drawData.overflow > i && starY > realHeight) {
|
|
@@ -2199,19 +2309,15 @@ function layoutText(drawData, style) {
|
|
|
2199
2309
|
rowWidth = -row.width + style.fontSize + __letterSpacing;
|
|
2200
2310
|
rowX -= rowWidth;
|
|
2201
2311
|
rowWidth += style.fontSize;
|
|
2202
|
-
}
|
|
2203
|
-
else {
|
|
2312
|
+
} else {
|
|
2204
2313
|
rowWidth -= __letterSpacing;
|
|
2205
2314
|
}
|
|
2206
2315
|
}
|
|
2207
|
-
if (rowX < bounds.x)
|
|
2208
|
-
|
|
2209
|
-
if (rowWidth > bounds.width)
|
|
2210
|
-
bounds.width = rowWidth;
|
|
2316
|
+
if (rowX < bounds.x) bounds.x = rowX;
|
|
2317
|
+
if (rowWidth > bounds.width) bounds.width = rowWidth;
|
|
2211
2318
|
if (__clipText && width && width < rowWidth) {
|
|
2212
2319
|
row.isOverflow = true;
|
|
2213
|
-
if (!drawData.overflow)
|
|
2214
|
-
drawData.overflow = rows.length;
|
|
2320
|
+
if (!drawData.overflow) drawData.overflow = rows.length;
|
|
2215
2321
|
}
|
|
2216
2322
|
}
|
|
2217
2323
|
bounds.y = y;
|
|
@@ -2219,20 +2325,16 @@ function layoutText(drawData, style) {
|
|
|
2219
2325
|
}
|
|
2220
2326
|
|
|
2221
2327
|
function clipText(drawData, style, x, width) {
|
|
2222
|
-
if (!width)
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
let { textOverflow } = style;
|
|
2328
|
+
if (!width) return;
|
|
2329
|
+
const {rows: rows, overflow: overflow} = drawData;
|
|
2330
|
+
let {textOverflow: textOverflow} = style;
|
|
2226
2331
|
rows.splice(overflow);
|
|
2227
|
-
if (textOverflow && textOverflow !==
|
|
2228
|
-
if (textOverflow ===
|
|
2229
|
-
textOverflow = '';
|
|
2230
|
-
else if (textOverflow === 'ellipsis')
|
|
2231
|
-
textOverflow = '...';
|
|
2332
|
+
if (textOverflow && textOverflow !== "show") {
|
|
2333
|
+
if (textOverflow === "hide") textOverflow = ""; else if (textOverflow === "ellipsis") textOverflow = "...";
|
|
2232
2334
|
let char, charRight;
|
|
2233
2335
|
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2234
2336
|
const right = x + width - ellipsisWidth;
|
|
2235
|
-
const list = style.textWrap ===
|
|
2337
|
+
const list = style.textWrap === "none" ? rows : [ rows[overflow - 1] ];
|
|
2236
2338
|
list.forEach(row => {
|
|
2237
2339
|
if (row.isOverflow && row.data) {
|
|
2238
2340
|
let end = row.data.length - 1;
|
|
@@ -2241,8 +2343,7 @@ function clipText(drawData, style, x, width) {
|
|
|
2241
2343
|
charRight = char.x + char.width;
|
|
2242
2344
|
if (i === end && charRight < right) {
|
|
2243
2345
|
break;
|
|
2244
|
-
}
|
|
2245
|
-
else if ((charRight < right && char.char !== ' ') || !i) {
|
|
2346
|
+
} else if (charRight < right && char.char !== " " || !i) {
|
|
2246
2347
|
row.data.splice(i + 1);
|
|
2247
2348
|
row.width -= char.width;
|
|
2248
2349
|
break;
|
|
@@ -2250,15 +2351,18 @@ function clipText(drawData, style, x, width) {
|
|
|
2250
2351
|
row.width -= char.width;
|
|
2251
2352
|
}
|
|
2252
2353
|
row.width += ellipsisWidth;
|
|
2253
|
-
row.data.push({
|
|
2254
|
-
|
|
2255
|
-
|
|
2354
|
+
row.data.push({
|
|
2355
|
+
char: textOverflow,
|
|
2356
|
+
x: charRight
|
|
2357
|
+
});
|
|
2358
|
+
if (row.textMode) toTextChar(row);
|
|
2256
2359
|
}
|
|
2257
2360
|
});
|
|
2258
2361
|
}
|
|
2259
2362
|
}
|
|
2363
|
+
|
|
2260
2364
|
function toTextChar(row) {
|
|
2261
|
-
row.text =
|
|
2365
|
+
row.text = "";
|
|
2262
2366
|
row.data.forEach(char => {
|
|
2263
2367
|
row.text += char.char;
|
|
2264
2368
|
});
|
|
@@ -2267,122 +2371,124 @@ function toTextChar(row) {
|
|
|
2267
2371
|
|
|
2268
2372
|
function decorationText(drawData, style) {
|
|
2269
2373
|
let type;
|
|
2270
|
-
const { fontSize, textDecoration } = style;
|
|
2374
|
+
const {fontSize: fontSize, textDecoration: textDecoration} = style;
|
|
2271
2375
|
drawData.decorationHeight = fontSize / 11;
|
|
2272
|
-
if (
|
|
2376
|
+
if (isObject(textDecoration)) {
|
|
2273
2377
|
type = textDecoration.type;
|
|
2274
|
-
if (textDecoration.color)
|
|
2275
|
-
|
|
2276
|
-
}
|
|
2277
|
-
else
|
|
2278
|
-
type = textDecoration;
|
|
2378
|
+
if (textDecoration.color) drawData.decorationColor = ColorConvert.string(textDecoration.color);
|
|
2379
|
+
} else type = textDecoration;
|
|
2279
2380
|
switch (type) {
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2381
|
+
case "under":
|
|
2382
|
+
drawData.decorationY = [ fontSize * .15 ];
|
|
2383
|
+
break;
|
|
2384
|
+
|
|
2385
|
+
case "delete":
|
|
2386
|
+
drawData.decorationY = [ -fontSize * .35 ];
|
|
2387
|
+
break;
|
|
2388
|
+
|
|
2389
|
+
case "under-delete":
|
|
2390
|
+
drawData.decorationY = [ fontSize * .15, -fontSize * .35 ];
|
|
2288
2391
|
}
|
|
2289
2392
|
}
|
|
2290
2393
|
|
|
2291
|
-
const { top, right, bottom, left } = Direction4;
|
|
2394
|
+
const {top: top, right: right, bottom: bottom, left: left} = Direction4;
|
|
2395
|
+
|
|
2292
2396
|
function getDrawData(content, style) {
|
|
2293
|
-
if (
|
|
2294
|
-
content = String(content);
|
|
2397
|
+
if (!isString(content)) content = String(content);
|
|
2295
2398
|
let x = 0, y = 0;
|
|
2296
|
-
let width = style.__getInput(
|
|
2297
|
-
let height = style.__getInput(
|
|
2298
|
-
const { textDecoration, __font, __padding: padding
|
|
2399
|
+
let width = style.__getInput("width") || 0;
|
|
2400
|
+
let height = style.__getInput("height") || 0;
|
|
2401
|
+
const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
|
|
2299
2402
|
if (padding) {
|
|
2300
|
-
if (width)
|
|
2301
|
-
|
|
2302
|
-
else if (!style.autoSizeAlign)
|
|
2303
|
-
x = padding[left];
|
|
2304
|
-
if (height)
|
|
2305
|
-
y = padding[top], height -= (padding[top] + padding[bottom]);
|
|
2306
|
-
else if (!style.autoSizeAlign)
|
|
2307
|
-
y = padding[top];
|
|
2403
|
+
if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
|
|
2404
|
+
if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
|
|
2308
2405
|
}
|
|
2309
2406
|
const drawData = {
|
|
2310
|
-
bounds: {
|
|
2407
|
+
bounds: {
|
|
2408
|
+
x: x,
|
|
2409
|
+
y: y,
|
|
2410
|
+
width: width,
|
|
2411
|
+
height: height
|
|
2412
|
+
},
|
|
2311
2413
|
rows: [],
|
|
2312
2414
|
paraNumber: 0,
|
|
2313
2415
|
font: Platform.canvas.font = __font
|
|
2314
2416
|
};
|
|
2315
2417
|
createRows(drawData, content, style);
|
|
2316
|
-
if (padding)
|
|
2317
|
-
padAutoText(padding, drawData, style, width, height);
|
|
2418
|
+
if (padding) padAutoText(padding, drawData, style, width, height);
|
|
2318
2419
|
layoutText(drawData, style);
|
|
2319
2420
|
layoutChar(drawData, style, width);
|
|
2320
|
-
if (drawData.overflow)
|
|
2321
|
-
|
|
2322
|
-
if (textDecoration !== 'none')
|
|
2323
|
-
decorationText(drawData, style);
|
|
2421
|
+
if (drawData.overflow) clipText(drawData, style, x, width);
|
|
2422
|
+
if (textDecoration !== "none") decorationText(drawData, style);
|
|
2324
2423
|
return drawData;
|
|
2325
2424
|
}
|
|
2425
|
+
|
|
2326
2426
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2327
2427
|
if (!width && style.autoSizeAlign) {
|
|
2328
2428
|
switch (style.textAlign) {
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2429
|
+
case "left":
|
|
2430
|
+
offsetText(drawData, "x", padding[left]);
|
|
2431
|
+
break;
|
|
2432
|
+
|
|
2433
|
+
case "right":
|
|
2434
|
+
offsetText(drawData, "x", -padding[right]);
|
|
2333
2435
|
}
|
|
2334
2436
|
}
|
|
2335
2437
|
if (!height && style.autoSizeAlign) {
|
|
2336
2438
|
switch (style.verticalAlign) {
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2439
|
+
case "top":
|
|
2440
|
+
offsetText(drawData, "y", padding[top]);
|
|
2441
|
+
break;
|
|
2442
|
+
|
|
2443
|
+
case "bottom":
|
|
2444
|
+
offsetText(drawData, "y", -padding[bottom]);
|
|
2341
2445
|
}
|
|
2342
2446
|
}
|
|
2343
2447
|
}
|
|
2448
|
+
|
|
2344
2449
|
function offsetText(drawData, attrName, value) {
|
|
2345
|
-
const { bounds, rows } = drawData;
|
|
2450
|
+
const {bounds: bounds, rows: rows} = drawData;
|
|
2346
2451
|
bounds[attrName] += value;
|
|
2347
|
-
for (let i = 0; i < rows.length; i++)
|
|
2348
|
-
rows[i][attrName] += value;
|
|
2452
|
+
for (let i = 0; i < rows.length; i++) rows[i][attrName] += value;
|
|
2349
2453
|
}
|
|
2350
2454
|
|
|
2351
2455
|
const TextConvertModule = {
|
|
2352
|
-
getDrawData
|
|
2456
|
+
getDrawData: getDrawData
|
|
2353
2457
|
};
|
|
2354
2458
|
|
|
2355
2459
|
function string(color, opacity) {
|
|
2356
|
-
const doOpacity =
|
|
2357
|
-
if (
|
|
2358
|
-
if (doOpacity && ColorConvert.object)
|
|
2359
|
-
color = ColorConvert.object(color);
|
|
2360
|
-
else
|
|
2361
|
-
return color;
|
|
2460
|
+
const doOpacity = isNumber(opacity) && opacity < 1;
|
|
2461
|
+
if (isString(color)) {
|
|
2462
|
+
if (doOpacity && ColorConvert.object) color = ColorConvert.object(color); else return color;
|
|
2362
2463
|
}
|
|
2363
|
-
let a = color.a
|
|
2364
|
-
if (doOpacity)
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2464
|
+
let a = isUndefined(color.a) ? 1 : color.a;
|
|
2465
|
+
if (doOpacity) a *= opacity;
|
|
2466
|
+
const rgb = color.r + "," + color.g + "," + color.b;
|
|
2467
|
+
return a === 1 ? "rgb(" + rgb + ")" : "rgba(" + rgb + "," + a + ")";
|
|
2368
2468
|
}
|
|
2369
2469
|
|
|
2370
2470
|
const ColorConvertModule = {
|
|
2371
|
-
string
|
|
2471
|
+
string: string
|
|
2372
2472
|
};
|
|
2373
2473
|
|
|
2374
2474
|
Object.assign(TextConvert, TextConvertModule);
|
|
2475
|
+
|
|
2375
2476
|
Object.assign(ColorConvert, ColorConvertModule);
|
|
2477
|
+
|
|
2376
2478
|
Object.assign(Paint, PaintModule);
|
|
2479
|
+
|
|
2377
2480
|
Object.assign(PaintImage, PaintImageModule);
|
|
2481
|
+
|
|
2378
2482
|
Object.assign(PaintGradient, PaintGradientModule);
|
|
2483
|
+
|
|
2379
2484
|
Object.assign(Effect, EffectModule);
|
|
2380
2485
|
|
|
2381
2486
|
Object.assign(Creator, {
|
|
2382
2487
|
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
2383
2488
|
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2384
|
-
hitCanvasManager: () => new HitCanvasManager
|
|
2489
|
+
hitCanvasManager: () => new HitCanvasManager
|
|
2385
2490
|
});
|
|
2491
|
+
|
|
2386
2492
|
useCanvas();
|
|
2387
2493
|
|
|
2388
2494
|
export { Layouter, LeaferCanvas, Picker, Renderer, Selector, Watcher, useCanvas };
|