@leafer-ui/node 1.0.0-rc.3 → 1.0.0-rc.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/node.cjs +1396 -927
- package/dist/node.esm.js +1397 -928
- package/dist/node.esm.min.js +1 -1
- package/dist/node.min.cjs +1 -1
- package/package.json +12 -8
- package/src/index.ts +13 -0
- package/types/index.d.ts +1 -0
package/dist/node.cjs
CHANGED
|
@@ -1,7 +1,108 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var core = require('@leafer/core');
|
|
4
|
+
var fs = require('fs');
|
|
4
5
|
var core$1 = require('@leafer-ui/core');
|
|
6
|
+
var draw = require('@leafer-ui/draw');
|
|
7
|
+
|
|
8
|
+
/******************************************************************************
|
|
9
|
+
Copyright (c) Microsoft Corporation.
|
|
10
|
+
|
|
11
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
12
|
+
purpose with or without fee is hereby granted.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
15
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
16
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
17
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
18
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
19
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
20
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
21
|
+
***************************************************************************** */
|
|
22
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
36
|
+
var e = new Error(message);
|
|
37
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
class LeaferCanvas extends core.LeaferCanvasBase {
|
|
41
|
+
get allowBackgroundColor() { return true; }
|
|
42
|
+
init() {
|
|
43
|
+
this.__createView();
|
|
44
|
+
this.__createContext();
|
|
45
|
+
this.resize(this.config);
|
|
46
|
+
if (core.Platform.roundRectPatch) {
|
|
47
|
+
this.context.__proto__.roundRect = null;
|
|
48
|
+
core.canvasPatch(this.context.__proto__);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
__createView() {
|
|
52
|
+
this.view = core.Platform.origin.createCanvas(1, 1);
|
|
53
|
+
}
|
|
54
|
+
updateViewSize() {
|
|
55
|
+
const { width, height, pixelRatio } = this;
|
|
56
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
57
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
58
|
+
this.clientBounds = this.bounds;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const { mineType, fileType } = core.FileHelper;
|
|
63
|
+
Object.assign(core.Creator, {
|
|
64
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
65
|
+
image: (options) => new core.LeaferImage(options)
|
|
66
|
+
});
|
|
67
|
+
function useCanvas(canvasType, power) {
|
|
68
|
+
core.Platform.canvasType = canvasType;
|
|
69
|
+
if (!core.Platform.origin) {
|
|
70
|
+
if (canvasType === 'skia') {
|
|
71
|
+
const { Canvas, loadImage } = power;
|
|
72
|
+
core.Platform.origin = {
|
|
73
|
+
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
74
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURLSync(type, { quality }),
|
|
75
|
+
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
76
|
+
canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
|
|
77
|
+
download(_url, _filename) { return undefined; },
|
|
78
|
+
loadImage(src) { return loadImage(core.Platform.image.getRealURL(src)); }
|
|
79
|
+
};
|
|
80
|
+
core.Platform.roundRectPatch = true;
|
|
81
|
+
}
|
|
82
|
+
else if (canvasType === 'napi') {
|
|
83
|
+
const { Canvas, loadImage } = power;
|
|
84
|
+
core.Platform.origin = {
|
|
85
|
+
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
86
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
87
|
+
canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function* () { return canvas.toBuffer(mineType(type), quality); }),
|
|
88
|
+
canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function* () { return fs.writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality)); }),
|
|
89
|
+
download(_url, _filename) { return undefined; },
|
|
90
|
+
loadImage(src) { return loadImage(core.Platform.image.getRealURL(src)); }
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
core.Platform.ellipseToCurve = true;
|
|
94
|
+
core.Platform.event = {
|
|
95
|
+
stopDefault(_origin) { },
|
|
96
|
+
stopNow(_origin) { },
|
|
97
|
+
stop(_origin) { }
|
|
98
|
+
};
|
|
99
|
+
core.Platform.canvas = core.Creator.canvas();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
core.Platform.name = 'node';
|
|
103
|
+
core.Platform.requestRender = function (render) { setTimeout(render); };
|
|
104
|
+
core.Platform.devicePixelRatio = 1;
|
|
105
|
+
core.Platform.conicGradientSupport = true;
|
|
5
106
|
|
|
6
107
|
class Watcher {
|
|
7
108
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -9,7 +110,7 @@ class Watcher {
|
|
|
9
110
|
if (this.hasRemove) {
|
|
10
111
|
const updatedList = new core.LeafList();
|
|
11
112
|
this.__updatedList.list.forEach(item => { if (item.leafer)
|
|
12
|
-
updatedList.
|
|
113
|
+
updatedList.add(item); });
|
|
13
114
|
return updatedList;
|
|
14
115
|
}
|
|
15
116
|
else {
|
|
@@ -44,7 +145,7 @@ class Watcher {
|
|
|
44
145
|
this.target.emit(core.RenderEvent.REQUEST);
|
|
45
146
|
}
|
|
46
147
|
__onAttrChange(event) {
|
|
47
|
-
this.__updatedList.
|
|
148
|
+
this.__updatedList.add(event.target);
|
|
48
149
|
this.update();
|
|
49
150
|
}
|
|
50
151
|
__onChildEvent(event) {
|
|
@@ -54,12 +155,12 @@ class Watcher {
|
|
|
54
155
|
}
|
|
55
156
|
else {
|
|
56
157
|
this.hasRemove = true;
|
|
57
|
-
this.__updatedList.
|
|
158
|
+
this.__updatedList.add(event.parent);
|
|
58
159
|
}
|
|
59
160
|
this.update();
|
|
60
161
|
}
|
|
61
162
|
__pushChild(child) {
|
|
62
|
-
this.__updatedList.
|
|
163
|
+
this.__updatedList.add(child);
|
|
63
164
|
if (child.isBranch)
|
|
64
165
|
this.__loopChildren(child);
|
|
65
166
|
}
|
|
@@ -98,22 +199,22 @@ class Watcher {
|
|
|
98
199
|
}
|
|
99
200
|
}
|
|
100
201
|
|
|
101
|
-
const {
|
|
202
|
+
const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = core.LeafHelper;
|
|
102
203
|
const { pushAllChildBranch, pushAllParent } = core.BranchHelper;
|
|
103
204
|
function updateMatrix(updateList, levelList) {
|
|
104
205
|
let layout;
|
|
105
206
|
updateList.list.forEach(leaf => {
|
|
106
207
|
layout = leaf.__layout;
|
|
107
|
-
if (levelList.without(leaf) && !layout.
|
|
208
|
+
if (levelList.without(leaf) && !layout.proxyZoom) {
|
|
108
209
|
if (layout.matrixChanged) {
|
|
109
|
-
|
|
110
|
-
levelList.
|
|
210
|
+
updateAllMatrix$1(leaf, true);
|
|
211
|
+
levelList.add(leaf);
|
|
111
212
|
if (leaf.isBranch)
|
|
112
213
|
pushAllChildBranch(leaf, levelList);
|
|
113
214
|
pushAllParent(leaf, levelList);
|
|
114
215
|
}
|
|
115
216
|
else if (layout.boundsChanged) {
|
|
116
|
-
levelList.
|
|
217
|
+
levelList.add(leaf);
|
|
117
218
|
if (leaf.isBranch)
|
|
118
219
|
leaf.__tempNumber = 0;
|
|
119
220
|
pushAllParent(leaf, levelList);
|
|
@@ -122,20 +223,21 @@ function updateMatrix(updateList, levelList) {
|
|
|
122
223
|
});
|
|
123
224
|
}
|
|
124
225
|
function updateBounds(boundsList) {
|
|
125
|
-
let
|
|
226
|
+
let list, branch, children;
|
|
126
227
|
boundsList.sort(true);
|
|
127
228
|
boundsList.levels.forEach(level => {
|
|
128
|
-
|
|
129
|
-
for (let i = 0, len =
|
|
130
|
-
branch =
|
|
229
|
+
list = boundsList.levelMap[level];
|
|
230
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
231
|
+
branch = list[i];
|
|
131
232
|
if (branch.isBranch && branch.__tempNumber) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
233
|
+
children = branch.children;
|
|
234
|
+
for (let j = 0, jLen = children.length; j < jLen; j++) {
|
|
235
|
+
if (!children[j].isBranch) {
|
|
236
|
+
updateOneBounds(children[j]);
|
|
135
237
|
}
|
|
136
238
|
}
|
|
137
239
|
}
|
|
138
|
-
branch
|
|
240
|
+
updateOneBounds(branch);
|
|
139
241
|
}
|
|
140
242
|
});
|
|
141
243
|
}
|
|
@@ -148,7 +250,7 @@ function updateChange(updateList) {
|
|
|
148
250
|
}
|
|
149
251
|
|
|
150
252
|
const { worldBounds } = core.LeafBoundsHelper;
|
|
151
|
-
const {
|
|
253
|
+
const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
|
|
152
254
|
class LayoutBlockData {
|
|
153
255
|
constructor(list) {
|
|
154
256
|
this.updatedBounds = new core.Bounds();
|
|
@@ -159,14 +261,20 @@ class LayoutBlockData {
|
|
|
159
261
|
this.updatedList = list;
|
|
160
262
|
}
|
|
161
263
|
setBefore() {
|
|
162
|
-
|
|
264
|
+
this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
163
265
|
}
|
|
164
266
|
setAfter() {
|
|
165
|
-
|
|
166
|
-
|
|
267
|
+
const { list } = this.updatedList;
|
|
268
|
+
if (list.some(leaf => leaf.noBounds)) {
|
|
269
|
+
this.afterBounds.set(bigBounds);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.afterBounds.setListWithFn(list, worldBounds);
|
|
273
|
+
}
|
|
274
|
+
this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
|
|
167
275
|
}
|
|
168
276
|
merge(data) {
|
|
169
|
-
this.updatedList.
|
|
277
|
+
this.updatedList.addList(data.updatedList.list);
|
|
170
278
|
this.beforeBounds.add(data.beforeBounds);
|
|
171
279
|
this.afterBounds.add(data.afterBounds);
|
|
172
280
|
this.updatedBounds.add(data.updatedBounds);
|
|
@@ -176,9 +284,8 @@ class LayoutBlockData {
|
|
|
176
284
|
}
|
|
177
285
|
}
|
|
178
286
|
|
|
179
|
-
const {
|
|
180
|
-
const
|
|
181
|
-
const debug$1 = core.Debug.get('Layouter');
|
|
287
|
+
const { updateAllMatrix, updateAllChange } = core.LeafHelper;
|
|
288
|
+
const debug$2 = core.Debug.get('Layouter');
|
|
182
289
|
class Layouter {
|
|
183
290
|
constructor(target, userConfig) {
|
|
184
291
|
this.totalTimes = 0;
|
|
@@ -213,7 +320,7 @@ class Layouter {
|
|
|
213
320
|
target.emitEvent(new core.LayoutEvent(core.LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
214
321
|
}
|
|
215
322
|
catch (e) {
|
|
216
|
-
debug$
|
|
323
|
+
debug$2.error(e);
|
|
217
324
|
}
|
|
218
325
|
this.layoutedBlocks = null;
|
|
219
326
|
}
|
|
@@ -227,9 +334,9 @@ class Layouter {
|
|
|
227
334
|
}
|
|
228
335
|
layoutOnce() {
|
|
229
336
|
if (this.layouting)
|
|
230
|
-
return debug$
|
|
337
|
+
return debug$2.warn('layouting');
|
|
231
338
|
if (this.times > 3)
|
|
232
|
-
return debug$
|
|
339
|
+
return debug$2.warn('layout max times');
|
|
233
340
|
this.times++;
|
|
234
341
|
this.totalTimes++;
|
|
235
342
|
this.layouting = true;
|
|
@@ -254,12 +361,15 @@ class Layouter {
|
|
|
254
361
|
const { target, __updatedList: updateList } = this;
|
|
255
362
|
const { BEFORE, LAYOUT, AFTER } = core.LayoutEvent;
|
|
256
363
|
const blocks = this.getBlocks(updateList);
|
|
257
|
-
blocks.forEach(item =>
|
|
364
|
+
blocks.forEach(item => item.setBefore());
|
|
258
365
|
target.emitEvent(new core.LayoutEvent(BEFORE, blocks, this.times));
|
|
366
|
+
this.extraBlock = null;
|
|
259
367
|
updateList.sort();
|
|
260
368
|
updateMatrix(updateList, this.__levelList);
|
|
261
369
|
updateBounds(this.__levelList);
|
|
262
370
|
updateChange(updateList);
|
|
371
|
+
if (this.extraBlock)
|
|
372
|
+
blocks.push(this.extraBlock);
|
|
263
373
|
blocks.forEach(item => item.setAfter());
|
|
264
374
|
target.emitEvent(new core.LayoutEvent(LAYOUT, blocks, this.times));
|
|
265
375
|
target.emitEvent(new core.LayoutEvent(AFTER, blocks, this.times));
|
|
@@ -282,17 +392,22 @@ class Layouter {
|
|
|
282
392
|
core.Run.end(t);
|
|
283
393
|
}
|
|
284
394
|
static fullLayout(target) {
|
|
285
|
-
|
|
395
|
+
updateAllMatrix(target, true);
|
|
286
396
|
if (target.isBranch) {
|
|
287
|
-
|
|
288
|
-
pushAllBranchStack(target, branchStack);
|
|
289
|
-
updateWorldBoundsByBranchStack(branchStack);
|
|
397
|
+
core.BranchHelper.updateBounds(target);
|
|
290
398
|
}
|
|
291
399
|
else {
|
|
292
|
-
|
|
400
|
+
core.LeafHelper.updateBounds(target);
|
|
293
401
|
}
|
|
294
402
|
updateAllChange(target);
|
|
295
403
|
}
|
|
404
|
+
addExtra(leaf) {
|
|
405
|
+
if (!this.__updatedList.has(leaf)) {
|
|
406
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
407
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
408
|
+
updatedList.add(leaf);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
296
411
|
createBlock(data) {
|
|
297
412
|
return new LayoutBlockData(data);
|
|
298
413
|
}
|
|
@@ -320,13 +435,12 @@ class Layouter {
|
|
|
320
435
|
if (this.target) {
|
|
321
436
|
this.stop();
|
|
322
437
|
this.__removeListenEvents();
|
|
323
|
-
this.target = null;
|
|
324
|
-
this.config = null;
|
|
438
|
+
this.target = this.config = null;
|
|
325
439
|
}
|
|
326
440
|
}
|
|
327
441
|
}
|
|
328
442
|
|
|
329
|
-
const debug = core.Debug.get('Renderer');
|
|
443
|
+
const debug$1 = core.Debug.get('Renderer');
|
|
330
444
|
class Renderer {
|
|
331
445
|
get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
|
|
332
446
|
constructor(target, canvas, userConfig) {
|
|
@@ -364,7 +478,7 @@ class Renderer {
|
|
|
364
478
|
const { target } = this;
|
|
365
479
|
this.times = 0;
|
|
366
480
|
this.totalBounds = new core.Bounds();
|
|
367
|
-
debug.log(target.innerName, '--->');
|
|
481
|
+
debug$1.log(target.innerName, '--->');
|
|
368
482
|
try {
|
|
369
483
|
this.emitRender(core.RenderEvent.START);
|
|
370
484
|
this.renderOnce(callback);
|
|
@@ -373,9 +487,9 @@ class Renderer {
|
|
|
373
487
|
}
|
|
374
488
|
catch (e) {
|
|
375
489
|
this.rendering = false;
|
|
376
|
-
debug.error(e);
|
|
490
|
+
debug$1.error(e);
|
|
377
491
|
}
|
|
378
|
-
debug.log('-------------|');
|
|
492
|
+
debug$1.log('-------------|');
|
|
379
493
|
}
|
|
380
494
|
renderAgain() {
|
|
381
495
|
if (this.rendering) {
|
|
@@ -387,9 +501,9 @@ class Renderer {
|
|
|
387
501
|
}
|
|
388
502
|
renderOnce(callback) {
|
|
389
503
|
if (this.rendering)
|
|
390
|
-
return debug.warn('rendering');
|
|
504
|
+
return debug$1.warn('rendering');
|
|
391
505
|
if (this.times > 3)
|
|
392
|
-
return debug.warn('render max times');
|
|
506
|
+
return debug$1.warn('render max times');
|
|
393
507
|
this.times++;
|
|
394
508
|
this.totalTimes++;
|
|
395
509
|
this.rendering = true;
|
|
@@ -402,6 +516,10 @@ class Renderer {
|
|
|
402
516
|
}
|
|
403
517
|
else {
|
|
404
518
|
this.requestLayout();
|
|
519
|
+
if (this.ignore) {
|
|
520
|
+
this.ignore = this.rendering = false;
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
405
523
|
this.emitRender(core.RenderEvent.BEFORE);
|
|
406
524
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
407
525
|
this.partRender();
|
|
@@ -422,9 +540,8 @@ class Renderer {
|
|
|
422
540
|
partRender() {
|
|
423
541
|
const { canvas, updateBlocks: list } = this;
|
|
424
542
|
if (!list)
|
|
425
|
-
return debug.warn('PartRender: need update attr');
|
|
426
|
-
|
|
427
|
-
this.mergeBlocks();
|
|
543
|
+
return debug$1.warn('PartRender: need update attr');
|
|
544
|
+
this.mergeBlocks();
|
|
428
545
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
429
546
|
this.clipRender(block); });
|
|
430
547
|
}
|
|
@@ -433,17 +550,17 @@ class Renderer {
|
|
|
433
550
|
const { canvas } = this;
|
|
434
551
|
const bounds = block.getIntersect(canvas.bounds);
|
|
435
552
|
const includes = block.includes(this.target.__world);
|
|
436
|
-
const realBounds = new core.Bounds(
|
|
553
|
+
const realBounds = new core.Bounds(bounds);
|
|
437
554
|
canvas.save();
|
|
438
555
|
if (includes && !core.Debug.showRepaint) {
|
|
439
556
|
canvas.clear();
|
|
440
557
|
}
|
|
441
558
|
else {
|
|
442
|
-
bounds.spread(
|
|
559
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
443
560
|
canvas.clearWorld(bounds, true);
|
|
444
561
|
canvas.clipWorld(bounds, true);
|
|
445
562
|
}
|
|
446
|
-
this.__render(bounds, realBounds);
|
|
563
|
+
this.__render(bounds, includes, realBounds);
|
|
447
564
|
canvas.restore();
|
|
448
565
|
core.Run.end(t);
|
|
449
566
|
}
|
|
@@ -452,12 +569,12 @@ class Renderer {
|
|
|
452
569
|
const { canvas } = this;
|
|
453
570
|
canvas.save();
|
|
454
571
|
canvas.clear();
|
|
455
|
-
this.__render(canvas.bounds);
|
|
572
|
+
this.__render(canvas.bounds, true);
|
|
456
573
|
canvas.restore();
|
|
457
574
|
core.Run.end(t);
|
|
458
575
|
}
|
|
459
|
-
__render(bounds, realBounds) {
|
|
460
|
-
const options =
|
|
576
|
+
__render(bounds, includes, realBounds) {
|
|
577
|
+
const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
|
|
461
578
|
if (this.needFill)
|
|
462
579
|
this.canvas.fillWorld(bounds, this.config.fill);
|
|
463
580
|
if (core.Debug.showRepaint)
|
|
@@ -483,7 +600,7 @@ class Renderer {
|
|
|
483
600
|
const { updateBlocks: list } = this;
|
|
484
601
|
if (list) {
|
|
485
602
|
const bounds = new core.Bounds();
|
|
486
|
-
bounds.
|
|
603
|
+
bounds.setList(list);
|
|
487
604
|
list.length = 0;
|
|
488
605
|
list.push(bounds);
|
|
489
606
|
}
|
|
@@ -492,12 +609,12 @@ class Renderer {
|
|
|
492
609
|
const startTime = Date.now();
|
|
493
610
|
core.Platform.requestRender(() => {
|
|
494
611
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
495
|
-
if (this.
|
|
496
|
-
|
|
612
|
+
if (this.running) {
|
|
613
|
+
this.target.emit(core.AnimateEvent.FRAME);
|
|
614
|
+
if (this.changed && this.canvas.view)
|
|
497
615
|
this.render();
|
|
616
|
+
this.target.emit(core.RenderEvent.NEXT);
|
|
498
617
|
}
|
|
499
|
-
if (this.running)
|
|
500
|
-
this.target.emit(core.AnimateEvent.FRAME);
|
|
501
618
|
if (this.target)
|
|
502
619
|
this.__requestRender();
|
|
503
620
|
});
|
|
@@ -510,9 +627,12 @@ class Renderer {
|
|
|
510
627
|
const bounds = new core.Bounds(0, 0, width, height);
|
|
511
628
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
512
629
|
this.addBlock(this.canvas.bounds);
|
|
513
|
-
this.target.forceUpdate('
|
|
630
|
+
this.target.forceUpdate('surface');
|
|
631
|
+
return;
|
|
514
632
|
}
|
|
515
633
|
}
|
|
634
|
+
this.addBlock(new core.Bounds(0, 0, 1, 1));
|
|
635
|
+
this.changed = true;
|
|
516
636
|
}
|
|
517
637
|
__onLayoutEnd(event) {
|
|
518
638
|
if (event.data)
|
|
@@ -523,7 +643,7 @@ class Renderer {
|
|
|
523
643
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
524
644
|
if (empty) {
|
|
525
645
|
if (!leaf.isLeafer)
|
|
526
|
-
debug.
|
|
646
|
+
debug$1.tip(leaf.innerName, ': empty');
|
|
527
647
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
528
648
|
}
|
|
529
649
|
return empty;
|
|
@@ -550,15 +670,13 @@ class Renderer {
|
|
|
550
670
|
if (this.target) {
|
|
551
671
|
this.stop();
|
|
552
672
|
this.__removeListenEvents();
|
|
553
|
-
this.target = null;
|
|
554
|
-
this.canvas = null;
|
|
555
|
-
this.config = null;
|
|
673
|
+
this.target = this.canvas = this.config = null;
|
|
556
674
|
}
|
|
557
675
|
}
|
|
558
676
|
}
|
|
559
677
|
|
|
560
678
|
const { hitRadiusPoint } = core.BoundsHelper;
|
|
561
|
-
class
|
|
679
|
+
class Picker {
|
|
562
680
|
constructor(target, selector) {
|
|
563
681
|
this.target = target;
|
|
564
682
|
this.selector = selector;
|
|
@@ -570,51 +688,59 @@ class FindPath {
|
|
|
570
688
|
options = {};
|
|
571
689
|
const through = options.through || false;
|
|
572
690
|
const ignoreHittable = options.ignoreHittable || false;
|
|
691
|
+
const target = options.target || this.target;
|
|
573
692
|
this.exclude = options.exclude || null;
|
|
574
693
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
575
|
-
this.findList =
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
const
|
|
694
|
+
this.findList = new core.LeafList(options.findList);
|
|
695
|
+
if (!options.findList)
|
|
696
|
+
this.hitBranch(target);
|
|
697
|
+
const { list } = this.findList;
|
|
698
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
579
699
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
580
700
|
this.clear();
|
|
581
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
701
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
582
702
|
}
|
|
583
|
-
getBestMatchLeaf() {
|
|
584
|
-
|
|
585
|
-
if (targets.length > 1) {
|
|
703
|
+
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
704
|
+
if (list.length) {
|
|
586
705
|
let find;
|
|
587
|
-
this.findList =
|
|
706
|
+
this.findList = new core.LeafList();
|
|
588
707
|
const { x, y } = this.point;
|
|
589
708
|
const point = { x, y, radiusX: 0, radiusY: 0 };
|
|
590
|
-
for (let i = 0, len =
|
|
591
|
-
find =
|
|
592
|
-
if (core.LeafHelper.worldHittable(find)) {
|
|
709
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
710
|
+
find = list[i];
|
|
711
|
+
if (ignoreHittable || core.LeafHelper.worldHittable(find)) {
|
|
593
712
|
this.hitChild(find, point);
|
|
594
713
|
if (this.findList.length)
|
|
595
|
-
return this.findList[0];
|
|
714
|
+
return this.findList.list[0];
|
|
596
715
|
}
|
|
597
716
|
}
|
|
598
717
|
}
|
|
599
|
-
|
|
718
|
+
if (bottomList) {
|
|
719
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
720
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
721
|
+
if (this.findList.length)
|
|
722
|
+
return this.findList.list[0];
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return list[0];
|
|
600
726
|
}
|
|
601
727
|
getPath(leaf) {
|
|
602
728
|
const path = new core.LeafList();
|
|
603
729
|
while (leaf) {
|
|
604
|
-
path.
|
|
730
|
+
path.add(leaf);
|
|
605
731
|
leaf = leaf.parent;
|
|
606
732
|
}
|
|
607
|
-
path.
|
|
733
|
+
path.add(this.target);
|
|
608
734
|
return path;
|
|
609
735
|
}
|
|
610
736
|
getHitablePath(leaf) {
|
|
611
|
-
const path = this.getPath(leaf);
|
|
737
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
612
738
|
let item, hittablePath = new core.LeafList();
|
|
613
739
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
614
740
|
item = path.list[i];
|
|
615
741
|
if (!item.__.hittable)
|
|
616
742
|
break;
|
|
617
|
-
hittablePath.
|
|
743
|
+
hittablePath.addAt(item, 0);
|
|
618
744
|
if (!item.__.hitChildren)
|
|
619
745
|
break;
|
|
620
746
|
}
|
|
@@ -633,17 +759,20 @@ class FindPath {
|
|
|
633
759
|
leaf = path.list[j];
|
|
634
760
|
if (nextPath && nextPath.has(leaf))
|
|
635
761
|
break;
|
|
636
|
-
throughPath.
|
|
762
|
+
throughPath.add(leaf);
|
|
637
763
|
}
|
|
638
764
|
}
|
|
639
765
|
return throughPath;
|
|
640
766
|
}
|
|
767
|
+
hitBranch(branch) {
|
|
768
|
+
this.eachFind(branch.children, branch.__onlyHitMask);
|
|
769
|
+
}
|
|
641
770
|
eachFind(children, hitMask) {
|
|
642
771
|
let child, hit;
|
|
643
772
|
const { point } = this, len = children.length;
|
|
644
773
|
for (let i = len - 1; i > -1; i--) {
|
|
645
774
|
child = children[i];
|
|
646
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
775
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
647
776
|
continue;
|
|
648
777
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
649
778
|
if (child.isBranch) {
|
|
@@ -659,11 +788,15 @@ class FindPath {
|
|
|
659
788
|
}
|
|
660
789
|
}
|
|
661
790
|
}
|
|
662
|
-
hitChild(child, point) {
|
|
791
|
+
hitChild(child, point, proxy) {
|
|
663
792
|
if (this.exclude && this.exclude.has(child))
|
|
664
793
|
return;
|
|
665
|
-
if (child.__hitWorld(point))
|
|
666
|
-
|
|
794
|
+
if (child.__hitWorld(point)) {
|
|
795
|
+
const { parent } = child;
|
|
796
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
|
|
797
|
+
return;
|
|
798
|
+
this.findList.add(proxy || child);
|
|
799
|
+
}
|
|
667
800
|
}
|
|
668
801
|
clear() {
|
|
669
802
|
this.point = null;
|
|
@@ -675,120 +808,128 @@ class FindPath {
|
|
|
675
808
|
}
|
|
676
809
|
}
|
|
677
810
|
|
|
811
|
+
const { Yes, NoAndSkip, YesAndSkip } = core.Answer;
|
|
812
|
+
const idCondition = {}, classNameCondition = {}, tagCondition = {};
|
|
678
813
|
class Selector {
|
|
679
814
|
constructor(target, userConfig) {
|
|
680
815
|
this.config = {};
|
|
681
|
-
this.
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
|
|
816
|
+
this.innerIdMap = {};
|
|
817
|
+
this.idMap = {};
|
|
818
|
+
this.methods = {
|
|
819
|
+
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
820
|
+
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
821
|
+
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
822
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
|
|
823
|
+
tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
824
|
+
};
|
|
685
825
|
this.target = target;
|
|
686
826
|
if (userConfig)
|
|
687
827
|
this.config = core.DataHelper.default(userConfig, this.config);
|
|
688
|
-
this.
|
|
828
|
+
this.picker = new Picker(target, this);
|
|
689
829
|
this.__listenEvents();
|
|
690
830
|
}
|
|
831
|
+
getBy(condition, branch, one, options) {
|
|
832
|
+
switch (typeof condition) {
|
|
833
|
+
case 'number':
|
|
834
|
+
const leaf = this.getByInnerId(condition, branch);
|
|
835
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
836
|
+
case 'string':
|
|
837
|
+
switch (condition[0]) {
|
|
838
|
+
case '#':
|
|
839
|
+
idCondition.id = condition.substring(1), condition = idCondition;
|
|
840
|
+
break;
|
|
841
|
+
case '.':
|
|
842
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition;
|
|
843
|
+
break;
|
|
844
|
+
default:
|
|
845
|
+
tagCondition.tag = condition, condition = tagCondition;
|
|
846
|
+
}
|
|
847
|
+
case 'object':
|
|
848
|
+
if (condition.id !== undefined) {
|
|
849
|
+
const leaf = this.getById(condition.id, branch);
|
|
850
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
851
|
+
}
|
|
852
|
+
else if (condition.tag) {
|
|
853
|
+
const { tag } = condition, isArray = tag instanceof Array;
|
|
854
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? core.DataHelper.toMap(tag) : tag);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className);
|
|
858
|
+
}
|
|
859
|
+
case 'function':
|
|
860
|
+
return this.getByMethod(condition, branch, one, options);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
691
863
|
getByPoint(hitPoint, hitRadius, options) {
|
|
692
864
|
if (core.Platform.name === 'node')
|
|
693
865
|
this.target.emit(core.LayoutEvent.CHECK_UPDATE);
|
|
694
|
-
return this.
|
|
695
|
-
}
|
|
696
|
-
find(name, branch) {
|
|
697
|
-
if (typeof name === 'number') {
|
|
698
|
-
return this.getByInnerId(name, branch);
|
|
699
|
-
}
|
|
700
|
-
else if (name.startsWith('#')) {
|
|
701
|
-
return this.getById(name.substring(1), branch);
|
|
702
|
-
}
|
|
703
|
-
else if (name.startsWith('.')) {
|
|
704
|
-
return this.getByClassName(name.substring(1), branch);
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
return this.getByTagName(name, branch);
|
|
708
|
-
}
|
|
866
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
709
867
|
}
|
|
710
|
-
getByInnerId(
|
|
711
|
-
|
|
868
|
+
getByInnerId(innerId, branch) {
|
|
869
|
+
const cache = this.innerIdMap[innerId];
|
|
712
870
|
if (cache)
|
|
713
871
|
return cache;
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
let find;
|
|
717
|
-
this.loopFind(branch, (leaf) => {
|
|
718
|
-
if (leaf.innerId === name) {
|
|
719
|
-
find = leaf;
|
|
720
|
-
this.innerIdList[name] = find;
|
|
721
|
-
return true;
|
|
722
|
-
}
|
|
723
|
-
else {
|
|
724
|
-
return false;
|
|
725
|
-
}
|
|
726
|
-
});
|
|
727
|
-
return find;
|
|
872
|
+
this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
|
|
873
|
+
return this.findLeaf;
|
|
728
874
|
}
|
|
729
|
-
getById(
|
|
730
|
-
|
|
731
|
-
if (cache)
|
|
875
|
+
getById(id, branch) {
|
|
876
|
+
const cache = this.idMap[id];
|
|
877
|
+
if (cache && core.LeafHelper.hasParent(cache, branch || this.target))
|
|
732
878
|
return cache;
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
let find;
|
|
736
|
-
this.loopFind(branch, (leaf) => {
|
|
737
|
-
if (leaf.id === name) {
|
|
738
|
-
find = leaf;
|
|
739
|
-
this.idList[name] = find;
|
|
740
|
-
return true;
|
|
741
|
-
}
|
|
742
|
-
else {
|
|
743
|
-
return false;
|
|
744
|
-
}
|
|
745
|
-
});
|
|
746
|
-
return find;
|
|
747
|
-
}
|
|
748
|
-
getByClassName(name, branch) {
|
|
749
|
-
if (!branch)
|
|
750
|
-
branch = this.target;
|
|
751
|
-
let find = [];
|
|
752
|
-
this.loopFind(branch, (leaf) => {
|
|
753
|
-
if (leaf.className === name)
|
|
754
|
-
find.push(leaf);
|
|
755
|
-
return false;
|
|
756
|
-
});
|
|
757
|
-
return find;
|
|
758
|
-
}
|
|
759
|
-
getByTagName(name, branch) {
|
|
760
|
-
if (!branch)
|
|
761
|
-
branch = this.target;
|
|
762
|
-
let find = [];
|
|
763
|
-
this.loopFind(branch, (leaf) => {
|
|
764
|
-
if (leaf.__tag === name)
|
|
765
|
-
find.push(leaf);
|
|
766
|
-
return false;
|
|
767
|
-
});
|
|
768
|
-
return find;
|
|
879
|
+
this.eachFind(this.toChildren(branch), this.methods.id, null, id);
|
|
880
|
+
return this.findLeaf;
|
|
769
881
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
882
|
+
getByClassName(className, branch) {
|
|
883
|
+
return this.getByMethod(this.methods.className, branch, false, className);
|
|
884
|
+
}
|
|
885
|
+
getByTag(tag, branch) {
|
|
886
|
+
return this.getByMethod(this.methods.tag, branch, false, tag);
|
|
887
|
+
}
|
|
888
|
+
getByMethod(method, branch, one, options) {
|
|
889
|
+
const list = one ? null : [];
|
|
890
|
+
this.eachFind(this.toChildren(branch), method, list, options);
|
|
891
|
+
return list || this.findLeaf;
|
|
892
|
+
}
|
|
893
|
+
eachFind(children, method, list, options) {
|
|
894
|
+
let child, result;
|
|
774
895
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
896
|
+
child = children[i];
|
|
897
|
+
result = method(child, options);
|
|
898
|
+
if (result === Yes || result === YesAndSkip) {
|
|
899
|
+
if (list) {
|
|
900
|
+
list.push(child);
|
|
901
|
+
}
|
|
902
|
+
else {
|
|
903
|
+
this.findLeaf = child;
|
|
904
|
+
return;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
if (child.isBranch && result < NoAndSkip)
|
|
908
|
+
this.eachFind(child.children, method, list, options);
|
|
780
909
|
}
|
|
781
910
|
}
|
|
911
|
+
toChildren(branch) {
|
|
912
|
+
this.findLeaf = null;
|
|
913
|
+
return [branch || this.target];
|
|
914
|
+
}
|
|
782
915
|
__onRemoveChild(event) {
|
|
783
|
-
const
|
|
784
|
-
if (this.
|
|
785
|
-
this.
|
|
786
|
-
if (this.
|
|
787
|
-
this.
|
|
916
|
+
const { id, innerId } = event.child;
|
|
917
|
+
if (this.idMap[id])
|
|
918
|
+
delete this.idMap[id];
|
|
919
|
+
if (this.innerIdMap[innerId])
|
|
920
|
+
delete this.innerIdMap[innerId];
|
|
921
|
+
}
|
|
922
|
+
__checkIdChange(event) {
|
|
923
|
+
if (event.attrName === 'id') {
|
|
924
|
+
const id = event.oldValue;
|
|
925
|
+
if (this.idMap[id])
|
|
926
|
+
delete this.idMap[id];
|
|
927
|
+
}
|
|
788
928
|
}
|
|
789
929
|
__listenEvents() {
|
|
790
930
|
this.__eventIds = [
|
|
791
|
-
this.target.on_(core.ChildEvent.REMOVE, this.__onRemoveChild, this)
|
|
931
|
+
this.target.on_(core.ChildEvent.REMOVE, this.__onRemoveChild, this),
|
|
932
|
+
this.target.on_(core.PropertyEvent.CHANGE, this.__checkIdChange, this)
|
|
792
933
|
];
|
|
793
934
|
}
|
|
794
935
|
__removeListenEvents() {
|
|
@@ -798,11 +939,10 @@ class Selector {
|
|
|
798
939
|
destroy() {
|
|
799
940
|
if (this.__eventIds.length) {
|
|
800
941
|
this.__removeListenEvents();
|
|
801
|
-
this.
|
|
802
|
-
this.
|
|
803
|
-
this.
|
|
804
|
-
this.
|
|
805
|
-
this.tagNameList = {};
|
|
942
|
+
this.picker.destroy();
|
|
943
|
+
this.findLeaf = null;
|
|
944
|
+
this.innerIdMap = {};
|
|
945
|
+
this.idMap = {};
|
|
806
946
|
}
|
|
807
947
|
}
|
|
808
948
|
}
|
|
@@ -815,444 +955,91 @@ Object.assign(core.Creator, {
|
|
|
815
955
|
});
|
|
816
956
|
core.Platform.layout = Layouter.fullLayout;
|
|
817
957
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
__createView() {
|
|
826
|
-
this.view = core.Platform.origin.createCanvas(1, 1);
|
|
827
|
-
}
|
|
828
|
-
updateViewSize() {
|
|
829
|
-
const { width, height, pixelRatio } = this;
|
|
830
|
-
this.view.width = width * pixelRatio;
|
|
831
|
-
this.view.height = height * pixelRatio;
|
|
832
|
-
this.clientBounds = this.bounds;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
Object.assign(core.Creator, {
|
|
837
|
-
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
838
|
-
image: (options) => new core.LeaferImage(options),
|
|
839
|
-
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
840
|
-
interaction: (target, canvas, selector, options) => { return new core.InteractionBase(target, canvas, selector, options); }
|
|
841
|
-
});
|
|
842
|
-
function useCanvas(canvasType, power) {
|
|
843
|
-
if (!core.Platform.origin) {
|
|
844
|
-
if (canvasType === 'skia') {
|
|
845
|
-
const { Canvas, loadImage } = power;
|
|
846
|
-
core.Platform.origin = {
|
|
847
|
-
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
848
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURLSync(type, { quality }),
|
|
849
|
-
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
850
|
-
canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
|
|
851
|
-
loadImage
|
|
852
|
-
};
|
|
958
|
+
function fillText(ui, canvas) {
|
|
959
|
+
let row;
|
|
960
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
961
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
962
|
+
row = rows[i];
|
|
963
|
+
if (row.text) {
|
|
964
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
853
965
|
}
|
|
854
|
-
|
|
966
|
+
else if (row.data) {
|
|
967
|
+
row.data.forEach(charData => {
|
|
968
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
if (decorationY)
|
|
972
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
855
973
|
}
|
|
856
974
|
}
|
|
857
|
-
core.Platform.name = 'node';
|
|
858
|
-
core.Platform.requestRender = function (render) { setTimeout(render); };
|
|
859
|
-
core.Platform.devicePixelRatio = 1;
|
|
860
|
-
core.Platform.conicGradientSupport = true;
|
|
861
|
-
core.Platform.realtimeLayout = true;
|
|
862
975
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
const swap = rotation && rotation !== 180;
|
|
867
|
-
const sw = box.width / (swap ? height : width);
|
|
868
|
-
const sh = box.height / (swap ? width : height);
|
|
869
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
870
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
871
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
872
|
-
translate$1(transform, x, y);
|
|
873
|
-
scaleHelper$1(transform, scale);
|
|
874
|
-
if (rotation)
|
|
875
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
876
|
-
data.scaleX = data.scaleY = scale;
|
|
877
|
-
data.transform = transform;
|
|
878
|
-
}
|
|
879
|
-
function clipMode(data, box, offset, scale, rotation) {
|
|
880
|
-
const transform = get$4();
|
|
881
|
-
translate$1(transform, box.x, box.y);
|
|
882
|
-
if (offset)
|
|
883
|
-
translate$1(transform, offset.x, offset.y);
|
|
884
|
-
if (scale) {
|
|
885
|
-
typeof scale === 'number' ? scaleHelper$1(transform, scale) : scaleHelper$1(transform, scale.x, scale.y);
|
|
886
|
-
data.scaleX = transform.a;
|
|
887
|
-
data.scaleY = transform.d;
|
|
888
|
-
}
|
|
889
|
-
if (rotation)
|
|
890
|
-
rotate(transform, rotation);
|
|
891
|
-
data.transform = transform;
|
|
976
|
+
function fill(fill, ui, canvas) {
|
|
977
|
+
canvas.fillStyle = fill;
|
|
978
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
892
979
|
}
|
|
893
|
-
function
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
980
|
+
function fills(fills, ui, canvas) {
|
|
981
|
+
let item;
|
|
982
|
+
const { windingRule, __font } = ui.__;
|
|
983
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
984
|
+
item = fills[i];
|
|
985
|
+
if (item.image && draw.PaintImage.checkImage(ui, canvas, item, !__font))
|
|
986
|
+
continue;
|
|
987
|
+
if (item.style) {
|
|
988
|
+
canvas.fillStyle = item.style;
|
|
989
|
+
if (item.transform) {
|
|
990
|
+
canvas.save();
|
|
991
|
+
canvas.transform(item.transform);
|
|
992
|
+
if (item.blendMode)
|
|
993
|
+
canvas.blendMode = item.blendMode;
|
|
994
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
995
|
+
canvas.restore();
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
if (item.blendMode) {
|
|
999
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1000
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1001
|
+
canvas.restoreBlendMode();
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
907
1007
|
}
|
|
908
1008
|
}
|
|
909
|
-
translate$1(transform, box.x, box.y);
|
|
910
|
-
if (scale) {
|
|
911
|
-
scaleOfOuter$2(transform, box, scale);
|
|
912
|
-
data.scaleX = data.scaleY = scale;
|
|
913
|
-
}
|
|
914
|
-
data.transform = transform;
|
|
915
1009
|
}
|
|
916
1010
|
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
const data = leafPaint.data = { mode };
|
|
925
|
-
switch (mode) {
|
|
926
|
-
case 'strench':
|
|
927
|
-
if (!sameBox)
|
|
928
|
-
width = box.width, height = box.height;
|
|
929
|
-
if (box.x || box.y) {
|
|
930
|
-
data.transform = get$3();
|
|
931
|
-
translate(data.transform, box.x, box.y);
|
|
932
|
-
}
|
|
1011
|
+
function strokeText(stroke, ui, canvas) {
|
|
1012
|
+
const { strokeAlign } = ui.__;
|
|
1013
|
+
const isStrokes = typeof stroke !== 'string';
|
|
1014
|
+
switch (strokeAlign) {
|
|
1015
|
+
case 'center':
|
|
1016
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1017
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
933
1018
|
break;
|
|
934
|
-
case '
|
|
935
|
-
|
|
936
|
-
clipMode(data, box, offset, scale, rotation);
|
|
1019
|
+
case 'inside':
|
|
1020
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
937
1021
|
break;
|
|
938
|
-
case '
|
|
939
|
-
|
|
940
|
-
repeatMode(data, box, width, height, scale, rotation);
|
|
1022
|
+
case 'outside':
|
|
1023
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
941
1024
|
break;
|
|
942
|
-
case 'fit':
|
|
943
|
-
case 'cover':
|
|
944
|
-
default:
|
|
945
|
-
if (!sameBox || rotation)
|
|
946
|
-
fillOrFitMode(data, mode, box, width, height, rotation);
|
|
947
1025
|
}
|
|
948
|
-
data.width = width;
|
|
949
|
-
data.height = height;
|
|
950
|
-
if (opacity)
|
|
951
|
-
data.opacity = opacity;
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
function image(ui, attrName, attrValue, box, firstUse) {
|
|
955
|
-
const leafPaint = { type: attrValue.type };
|
|
956
|
-
const image = leafPaint.image = core.ImageManager.get(attrValue);
|
|
957
|
-
const event = (firstUse || image.loading) && { target: ui, image, attrName, attrValue };
|
|
958
|
-
if (image.ready) {
|
|
959
|
-
if (hasNaturalSize(ui, attrName, image))
|
|
960
|
-
createData(leafPaint, image, attrValue, box);
|
|
961
|
-
if (firstUse) {
|
|
962
|
-
emit(core.ImageEvent.LOAD, event);
|
|
963
|
-
emit(core.ImageEvent.LOADED, event);
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
else if (image.error) {
|
|
967
|
-
if (firstUse) {
|
|
968
|
-
ui.forceUpdate('surface');
|
|
969
|
-
event.error = image.error;
|
|
970
|
-
emit(core.ImageEvent.ERROR, event);
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
else {
|
|
974
|
-
if (firstUse)
|
|
975
|
-
emit(core.ImageEvent.LOAD, event);
|
|
976
|
-
leafPaint.loadId = image.load(() => {
|
|
977
|
-
if (!ui.destroyed) {
|
|
978
|
-
if (hasNaturalSize(ui, attrName, image)) {
|
|
979
|
-
createData(leafPaint, image, attrValue, box);
|
|
980
|
-
ui.forceUpdate('surface');
|
|
981
|
-
}
|
|
982
|
-
emit(core.ImageEvent.LOADED, event);
|
|
983
|
-
}
|
|
984
|
-
}, (error) => {
|
|
985
|
-
ui.forceUpdate('surface');
|
|
986
|
-
event.error = error;
|
|
987
|
-
emit(core.ImageEvent.ERROR, event);
|
|
988
|
-
});
|
|
989
|
-
}
|
|
990
|
-
return leafPaint;
|
|
991
|
-
}
|
|
992
|
-
function hasNaturalSize(ui, attrName, image) {
|
|
993
|
-
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
994
|
-
const { __: d } = ui;
|
|
995
|
-
d.__naturalWidth = image.width;
|
|
996
|
-
d.__naturalHeight = image.height;
|
|
997
|
-
if (!d.__getInput('width') || !d.__getInput('height')) {
|
|
998
|
-
ui.forceUpdate('width');
|
|
999
|
-
return false;
|
|
1000
|
-
}
|
|
1001
|
-
}
|
|
1002
|
-
return true;
|
|
1003
|
-
}
|
|
1004
|
-
function emit(type, data) {
|
|
1005
|
-
if (data.target.hasEvent(type))
|
|
1006
|
-
data.target.emitEvent(new core.ImageEvent(type, data));
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
/******************************************************************************
|
|
1010
|
-
Copyright (c) Microsoft Corporation.
|
|
1011
|
-
|
|
1012
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1013
|
-
purpose with or without fee is hereby granted.
|
|
1014
|
-
|
|
1015
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1016
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1017
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1018
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1019
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1020
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1021
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1022
|
-
***************************************************************************** */
|
|
1023
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1027
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1028
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1029
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1030
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1031
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1032
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1033
|
-
});
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1037
|
-
var e = new Error(message);
|
|
1038
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1039
|
-
};
|
|
1040
|
-
|
|
1041
|
-
const { get: get$2, scale: scaleHelper, copy: copy$1 } = core.MatrixHelper;
|
|
1042
|
-
function createPattern(ui, paint, pixelRatio) {
|
|
1043
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1044
|
-
const id = scaleX + '-' + scaleY;
|
|
1045
|
-
if (paint.patternId !== id && !ui.destroyed) {
|
|
1046
|
-
paint.patternId = id;
|
|
1047
|
-
scaleX = Math.abs(scaleX);
|
|
1048
|
-
scaleY = Math.abs(scaleY);
|
|
1049
|
-
const { image, data } = paint;
|
|
1050
|
-
const maxWidth = image.isSVG ? 4096 : Math.min(image.width, 4096);
|
|
1051
|
-
const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096);
|
|
1052
|
-
let scale, matrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data;
|
|
1053
|
-
if (sx) {
|
|
1054
|
-
matrix = get$2();
|
|
1055
|
-
copy$1(matrix, transform);
|
|
1056
|
-
scaleHelper(matrix, 1 / sx, 1 / sy);
|
|
1057
|
-
scaleX *= sx;
|
|
1058
|
-
scaleY *= sy;
|
|
1059
|
-
}
|
|
1060
|
-
scaleX *= pixelRatio;
|
|
1061
|
-
scaleY *= pixelRatio;
|
|
1062
|
-
width *= scaleX;
|
|
1063
|
-
height *= scaleY;
|
|
1064
|
-
if (width > maxWidth || height > maxHeight) {
|
|
1065
|
-
scale = Math.max(width / maxWidth, height / maxHeight);
|
|
1066
|
-
}
|
|
1067
|
-
if (scale) {
|
|
1068
|
-
scaleX /= scale;
|
|
1069
|
-
scaleY /= scale;
|
|
1070
|
-
width /= scale;
|
|
1071
|
-
height /= scale;
|
|
1072
|
-
}
|
|
1073
|
-
if (sx) {
|
|
1074
|
-
scaleX /= sx;
|
|
1075
|
-
scaleY /= sy;
|
|
1076
|
-
}
|
|
1077
|
-
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1078
|
-
if (!matrix) {
|
|
1079
|
-
matrix = get$2();
|
|
1080
|
-
if (transform)
|
|
1081
|
-
copy$1(matrix, transform);
|
|
1082
|
-
}
|
|
1083
|
-
scaleHelper(matrix, 1 / scaleX, 1 / scaleY);
|
|
1084
|
-
}
|
|
1085
|
-
const style = core.Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), mode === 'repeat' ? 'repeat' : (core.Platform.origin.noRepeat || 'no-repeat'));
|
|
1086
|
-
try {
|
|
1087
|
-
if (paint.transform)
|
|
1088
|
-
paint.transform = null;
|
|
1089
|
-
if (matrix)
|
|
1090
|
-
style.setTransform ? style.setTransform(matrix) : paint.transform = matrix;
|
|
1091
|
-
}
|
|
1092
|
-
catch (_a) {
|
|
1093
|
-
paint.transform = matrix;
|
|
1094
|
-
}
|
|
1095
|
-
paint.style = style;
|
|
1096
|
-
return true;
|
|
1097
|
-
}
|
|
1098
|
-
else {
|
|
1099
|
-
return false;
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1104
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1105
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1106
|
-
return false;
|
|
1107
|
-
}
|
|
1108
|
-
else {
|
|
1109
|
-
if (allowPaint) {
|
|
1110
|
-
if (paint.image.isSVG && paint.data.mode !== 'repeat') {
|
|
1111
|
-
let { width, height } = paint.data;
|
|
1112
|
-
width *= scaleX * canvas.pixelRatio;
|
|
1113
|
-
height *= scaleY * canvas.pixelRatio;
|
|
1114
|
-
allowPaint = width > 4096 || height > 4096;
|
|
1115
|
-
}
|
|
1116
|
-
else {
|
|
1117
|
-
allowPaint = false;
|
|
1118
|
-
}
|
|
1119
|
-
}
|
|
1120
|
-
if (allowPaint) {
|
|
1121
|
-
canvas.save();
|
|
1122
|
-
canvas.clip();
|
|
1123
|
-
const { data } = paint;
|
|
1124
|
-
if (paint.blendMode)
|
|
1125
|
-
canvas.blendMode = paint.blendMode;
|
|
1126
|
-
if (data.opacity)
|
|
1127
|
-
canvas.opacity *= data.opacity;
|
|
1128
|
-
if (data.transform)
|
|
1129
|
-
canvas.transform(data.transform);
|
|
1130
|
-
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1131
|
-
canvas.restore();
|
|
1132
|
-
return true;
|
|
1133
|
-
}
|
|
1134
|
-
else {
|
|
1135
|
-
if (!paint.style) {
|
|
1136
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1137
|
-
}
|
|
1138
|
-
else {
|
|
1139
|
-
core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1140
|
-
if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
|
|
1141
|
-
ui.forceUpdate('surface');
|
|
1142
|
-
}), 300);
|
|
1143
|
-
}
|
|
1144
|
-
return false;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
|
|
1149
|
-
function recycleImage(data, attrName) {
|
|
1150
|
-
const paints = (attrName === 'fill' ? data._fill : data._stroke);
|
|
1151
|
-
if (paints instanceof Array) {
|
|
1152
|
-
let image, recycleMap, input, url;
|
|
1153
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1154
|
-
image = paints[i].image;
|
|
1155
|
-
url = image && image.url;
|
|
1156
|
-
if (url) {
|
|
1157
|
-
if (!recycleMap)
|
|
1158
|
-
recycleMap = {};
|
|
1159
|
-
recycleMap[url] = true;
|
|
1160
|
-
core.ImageManager.recycle(image);
|
|
1161
|
-
if (image.loading) {
|
|
1162
|
-
if (!input) {
|
|
1163
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1164
|
-
if (!(input instanceof Array))
|
|
1165
|
-
input = [input];
|
|
1166
|
-
}
|
|
1167
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
return recycleMap;
|
|
1172
|
-
}
|
|
1173
|
-
return null;
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
function fillText(ui, canvas) {
|
|
1177
|
-
let row;
|
|
1178
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1179
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1180
|
-
row = rows[i];
|
|
1181
|
-
if (row.text) {
|
|
1182
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1183
|
-
}
|
|
1184
|
-
else if (row.data) {
|
|
1185
|
-
row.data.forEach(charData => {
|
|
1186
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
if (decorationY)
|
|
1190
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1191
|
-
}
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
function fill(ui, canvas, fill) {
|
|
1195
|
-
canvas.fillStyle = fill;
|
|
1196
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1197
1026
|
}
|
|
1198
|
-
function
|
|
1199
|
-
|
|
1200
|
-
const
|
|
1201
|
-
|
|
1202
|
-
item = fills[i];
|
|
1203
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1204
|
-
continue;
|
|
1205
|
-
if (item.style) {
|
|
1206
|
-
canvas.fillStyle = item.style;
|
|
1207
|
-
if (item.transform) {
|
|
1208
|
-
canvas.save();
|
|
1209
|
-
canvas.transform(item.transform);
|
|
1210
|
-
if (item.blendMode)
|
|
1211
|
-
canvas.blendMode = item.blendMode;
|
|
1212
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1213
|
-
canvas.restore();
|
|
1214
|
-
}
|
|
1215
|
-
else {
|
|
1216
|
-
if (item.blendMode) {
|
|
1217
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1218
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1219
|
-
canvas.restoreBlendMode();
|
|
1220
|
-
}
|
|
1221
|
-
else {
|
|
1222
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
function strokeText(ui, canvas, stroke) {
|
|
1230
|
-
const { strokeAlign } = ui.__;
|
|
1231
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1232
|
-
switch (strokeAlign) {
|
|
1233
|
-
case 'center':
|
|
1234
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1235
|
-
isStrokes ? drawStrokesStyle(ui, stroke, canvas, true) : drawTextStroke(ui, canvas);
|
|
1236
|
-
break;
|
|
1237
|
-
case 'inside':
|
|
1238
|
-
drawAlignStroke(ui, canvas, stroke, 'inside', isStrokes);
|
|
1239
|
-
break;
|
|
1240
|
-
case 'outside':
|
|
1241
|
-
drawAlignStroke(ui, canvas, stroke, 'outside', isStrokes);
|
|
1242
|
-
break;
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
function drawAlignStroke(ui, canvas, stroke, align, isStrokes) {
|
|
1246
|
-
const { strokeWidth, __font } = ui.__;
|
|
1247
|
-
const out = canvas.getSameCanvas(true);
|
|
1248
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1027
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1028
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1029
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1030
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1249
1031
|
out.font = __font;
|
|
1250
|
-
isStrokes ? drawStrokesStyle(
|
|
1032
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1251
1033
|
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1252
1034
|
fillText(ui, out);
|
|
1253
1035
|
out.blendMode = 'normal';
|
|
1254
|
-
|
|
1255
|
-
|
|
1036
|
+
if (ui.__worldFlipped) {
|
|
1037
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1038
|
+
}
|
|
1039
|
+
else {
|
|
1040
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1041
|
+
}
|
|
1042
|
+
out.recycle(ui.__nowWorld);
|
|
1256
1043
|
}
|
|
1257
1044
|
function drawTextStroke(ui, canvas) {
|
|
1258
1045
|
let row;
|
|
@@ -1271,11 +1058,11 @@ function drawTextStroke(ui, canvas) {
|
|
|
1271
1058
|
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1272
1059
|
}
|
|
1273
1060
|
}
|
|
1274
|
-
function drawStrokesStyle(
|
|
1061
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1275
1062
|
let item;
|
|
1276
1063
|
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1277
1064
|
item = strokes[i];
|
|
1278
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1065
|
+
if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false))
|
|
1279
1066
|
continue;
|
|
1280
1067
|
if (item.style) {
|
|
1281
1068
|
canvas.strokeStyle = item.style;
|
|
@@ -1291,128 +1078,567 @@ function drawStrokesStyle(ui, strokes, canvas, isText) {
|
|
|
1291
1078
|
}
|
|
1292
1079
|
}
|
|
1293
1080
|
|
|
1294
|
-
function stroke(ui, canvas
|
|
1081
|
+
function stroke(stroke, ui, canvas) {
|
|
1295
1082
|
const options = ui.__;
|
|
1296
|
-
const {
|
|
1297
|
-
if (!
|
|
1083
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1084
|
+
if (!__strokeWidth)
|
|
1298
1085
|
return;
|
|
1299
1086
|
if (__font) {
|
|
1300
|
-
strokeText(ui, canvas
|
|
1087
|
+
strokeText(stroke, ui, canvas);
|
|
1301
1088
|
}
|
|
1302
1089
|
else {
|
|
1303
1090
|
switch (strokeAlign) {
|
|
1304
1091
|
case 'center':
|
|
1305
|
-
canvas.setStroke(stroke,
|
|
1092
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1306
1093
|
canvas.stroke();
|
|
1307
1094
|
break;
|
|
1308
1095
|
case 'inside':
|
|
1309
1096
|
canvas.save();
|
|
1310
|
-
canvas.setStroke(stroke,
|
|
1097
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1311
1098
|
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1312
1099
|
canvas.stroke();
|
|
1313
1100
|
canvas.restore();
|
|
1314
1101
|
break;
|
|
1315
1102
|
case 'outside':
|
|
1316
|
-
const out = canvas.getSameCanvas(true);
|
|
1317
|
-
out.setStroke(stroke,
|
|
1103
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1104
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1318
1105
|
ui.__drawRenderPath(out);
|
|
1319
1106
|
out.stroke();
|
|
1320
1107
|
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1321
1108
|
out.clearWorld(ui.__layout.renderBounds);
|
|
1322
|
-
|
|
1323
|
-
|
|
1109
|
+
if (ui.__worldFlipped) {
|
|
1110
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1114
|
+
}
|
|
1115
|
+
out.recycle(ui.__nowWorld);
|
|
1116
|
+
break;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
function strokes(strokes, ui, canvas) {
|
|
1121
|
+
const options = ui.__;
|
|
1122
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1123
|
+
if (!__strokeWidth)
|
|
1124
|
+
return;
|
|
1125
|
+
if (__font) {
|
|
1126
|
+
strokeText(strokes, ui, canvas);
|
|
1127
|
+
}
|
|
1128
|
+
else {
|
|
1129
|
+
switch (strokeAlign) {
|
|
1130
|
+
case 'center':
|
|
1131
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1132
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1324
1133
|
break;
|
|
1134
|
+
case 'inside':
|
|
1135
|
+
canvas.save();
|
|
1136
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1137
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1138
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1139
|
+
canvas.restore();
|
|
1140
|
+
break;
|
|
1141
|
+
case 'outside':
|
|
1142
|
+
const { renderBounds } = ui.__layout;
|
|
1143
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1144
|
+
ui.__drawRenderPath(out);
|
|
1145
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1146
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1147
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1148
|
+
out.clearWorld(renderBounds);
|
|
1149
|
+
if (ui.__worldFlipped) {
|
|
1150
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1151
|
+
}
|
|
1152
|
+
else {
|
|
1153
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1154
|
+
}
|
|
1155
|
+
out.recycle(ui.__nowWorld);
|
|
1156
|
+
break;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = core.BoundsHelper;
|
|
1162
|
+
function shape(ui, current, options) {
|
|
1163
|
+
const canvas = current.getSameCanvas();
|
|
1164
|
+
const nowWorld = ui.__nowWorld;
|
|
1165
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1166
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1167
|
+
if (scaleX < 0)
|
|
1168
|
+
scaleX = -scaleX;
|
|
1169
|
+
if (scaleY < 0)
|
|
1170
|
+
scaleY = -scaleY;
|
|
1171
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1172
|
+
worldCanvas = canvas;
|
|
1173
|
+
bounds = shapeBounds = nowWorld;
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1177
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1178
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1179
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1180
|
+
if (fitMatrix.a < 1) {
|
|
1181
|
+
worldCanvas = current.getSameCanvas();
|
|
1182
|
+
ui.__renderShape(worldCanvas, options);
|
|
1183
|
+
scaleX *= fitScaleX;
|
|
1184
|
+
scaleY *= fitScaleY;
|
|
1185
|
+
}
|
|
1186
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1187
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1188
|
+
if (options.matrix) {
|
|
1189
|
+
const { matrix } = options;
|
|
1190
|
+
fitMatrix.multiply(matrix);
|
|
1191
|
+
fitScaleX *= matrix.scaleX;
|
|
1192
|
+
fitScaleY *= matrix.scaleY;
|
|
1193
|
+
}
|
|
1194
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1195
|
+
}
|
|
1196
|
+
ui.__renderShape(canvas, options);
|
|
1197
|
+
return {
|
|
1198
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1199
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
let recycleMap;
|
|
1204
|
+
function compute(attrName, ui) {
|
|
1205
|
+
const data = ui.__, leafPaints = [];
|
|
1206
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1207
|
+
if (!(paints instanceof Array))
|
|
1208
|
+
paints = [paints];
|
|
1209
|
+
recycleMap = draw.PaintImage.recycleImage(attrName, data);
|
|
1210
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1211
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1212
|
+
if (item)
|
|
1213
|
+
leafPaints.push(item);
|
|
1214
|
+
}
|
|
1215
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1216
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1217
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1218
|
+
if (attrName === 'fill') {
|
|
1219
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1226
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1227
|
+
return undefined;
|
|
1228
|
+
const { boxBounds } = ui.__layout;
|
|
1229
|
+
switch (paint.type) {
|
|
1230
|
+
case 'solid':
|
|
1231
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1232
|
+
return { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
|
|
1233
|
+
case 'image':
|
|
1234
|
+
return draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1235
|
+
case 'linear':
|
|
1236
|
+
return draw.PaintGradient.linearGradient(paint, boxBounds);
|
|
1237
|
+
case 'radial':
|
|
1238
|
+
return draw.PaintGradient.radialGradient(paint, boxBounds);
|
|
1239
|
+
case 'angular':
|
|
1240
|
+
return draw.PaintGradient.conicGradient(paint, boxBounds);
|
|
1241
|
+
default:
|
|
1242
|
+
return paint.r !== undefined ? { type: 'solid', style: draw.ColorConvert.string(paint) } : undefined;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
const PaintModule = {
|
|
1247
|
+
compute,
|
|
1248
|
+
fill,
|
|
1249
|
+
fills,
|
|
1250
|
+
fillText,
|
|
1251
|
+
stroke,
|
|
1252
|
+
strokes,
|
|
1253
|
+
strokeText,
|
|
1254
|
+
drawTextStroke,
|
|
1255
|
+
shape
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
let origin = {};
|
|
1259
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = core.MatrixHelper;
|
|
1260
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1261
|
+
const transform = get$3();
|
|
1262
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1263
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1264
|
+
if (rotation)
|
|
1265
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1266
|
+
data.transform = transform;
|
|
1267
|
+
}
|
|
1268
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1269
|
+
const transform = get$3();
|
|
1270
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1271
|
+
if (scaleX)
|
|
1272
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1273
|
+
if (rotation)
|
|
1274
|
+
rotate(transform, rotation);
|
|
1275
|
+
data.transform = transform;
|
|
1276
|
+
}
|
|
1277
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1278
|
+
const transform = get$3();
|
|
1279
|
+
if (rotation) {
|
|
1280
|
+
if (align === 'center') {
|
|
1281
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1282
|
+
}
|
|
1283
|
+
else {
|
|
1284
|
+
rotate(transform, rotation);
|
|
1285
|
+
switch (rotation) {
|
|
1286
|
+
case 90:
|
|
1287
|
+
translate$1(transform, height, 0);
|
|
1288
|
+
break;
|
|
1289
|
+
case 180:
|
|
1290
|
+
translate$1(transform, width, height);
|
|
1291
|
+
break;
|
|
1292
|
+
case 270:
|
|
1293
|
+
translate$1(transform, 0, width);
|
|
1294
|
+
break;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
origin.x = box.x + x;
|
|
1299
|
+
origin.y = box.y + y;
|
|
1300
|
+
translate$1(transform, origin.x, origin.y);
|
|
1301
|
+
if (scaleX)
|
|
1302
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1303
|
+
data.transform = transform;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const { get: get$2, translate } = core.MatrixHelper;
|
|
1307
|
+
const tempBox = new core.Bounds();
|
|
1308
|
+
const tempPoint = {};
|
|
1309
|
+
function createData(leafPaint, image, paint, box) {
|
|
1310
|
+
const { blendMode } = paint;
|
|
1311
|
+
if (blendMode)
|
|
1312
|
+
leafPaint.blendMode = blendMode;
|
|
1313
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1314
|
+
}
|
|
1315
|
+
function getPatternData(paint, box, image) {
|
|
1316
|
+
let { width, height } = image;
|
|
1317
|
+
if (paint.padding)
|
|
1318
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1319
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1320
|
+
const sameBox = box.width === width && box.height === height;
|
|
1321
|
+
const data = { mode };
|
|
1322
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1323
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1324
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1325
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1326
|
+
if (!sameBox || rotation) {
|
|
1327
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1328
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1329
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
else if (size) {
|
|
1333
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1334
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1335
|
+
}
|
|
1336
|
+
else if (scale) {
|
|
1337
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1338
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1339
|
+
}
|
|
1340
|
+
if (align) {
|
|
1341
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1342
|
+
if (scaleX)
|
|
1343
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1344
|
+
core.AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1345
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1346
|
+
}
|
|
1347
|
+
if (offset)
|
|
1348
|
+
x += offset.x, y += offset.y;
|
|
1349
|
+
switch (mode) {
|
|
1350
|
+
case 'strench':
|
|
1351
|
+
if (!sameBox)
|
|
1352
|
+
width = box.width, height = box.height;
|
|
1353
|
+
break;
|
|
1354
|
+
case 'normal':
|
|
1355
|
+
case 'clip':
|
|
1356
|
+
if (x || y || scaleX || rotation)
|
|
1357
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1358
|
+
break;
|
|
1359
|
+
case 'repeat':
|
|
1360
|
+
if (!sameBox || scaleX || rotation)
|
|
1361
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1362
|
+
if (!repeat)
|
|
1363
|
+
data.repeat = 'repeat';
|
|
1364
|
+
break;
|
|
1365
|
+
case 'fit':
|
|
1366
|
+
case 'cover':
|
|
1367
|
+
default:
|
|
1368
|
+
if (scaleX)
|
|
1369
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1370
|
+
}
|
|
1371
|
+
if (!data.transform) {
|
|
1372
|
+
if (box.x || box.y) {
|
|
1373
|
+
data.transform = get$2();
|
|
1374
|
+
translate(data.transform, box.x, box.y);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
if (scaleX && mode !== 'strench') {
|
|
1378
|
+
data.scaleX = scaleX;
|
|
1379
|
+
data.scaleY = scaleY;
|
|
1380
|
+
}
|
|
1381
|
+
data.width = width;
|
|
1382
|
+
data.height = height;
|
|
1383
|
+
if (opacity)
|
|
1384
|
+
data.opacity = opacity;
|
|
1385
|
+
if (repeat)
|
|
1386
|
+
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1387
|
+
return data;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
let cache, box = new core.Bounds();
|
|
1391
|
+
const { isSame } = core.BoundsHelper;
|
|
1392
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1393
|
+
let leafPaint, event;
|
|
1394
|
+
const image = core.ImageManager.get(paint);
|
|
1395
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1396
|
+
leafPaint = cache.leafPaint;
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
leafPaint = { type: paint.type, image };
|
|
1400
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1401
|
+
}
|
|
1402
|
+
if (firstUse || image.loading)
|
|
1403
|
+
event = { image, attrName, attrValue: paint };
|
|
1404
|
+
if (image.ready) {
|
|
1405
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1406
|
+
if (firstUse) {
|
|
1407
|
+
onLoad(ui, event);
|
|
1408
|
+
onLoadSuccess(ui, event);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
else if (image.error) {
|
|
1412
|
+
if (firstUse)
|
|
1413
|
+
onLoadError(ui, event, image.error);
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
ignoreRender(ui, true);
|
|
1417
|
+
if (firstUse)
|
|
1418
|
+
onLoad(ui, event);
|
|
1419
|
+
leafPaint.loadId = image.load(() => {
|
|
1420
|
+
ignoreRender(ui, false);
|
|
1421
|
+
if (!ui.destroyed) {
|
|
1422
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1423
|
+
if (image.hasOpacityPixel)
|
|
1424
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1425
|
+
ui.forceUpdate('surface');
|
|
1426
|
+
}
|
|
1427
|
+
onLoadSuccess(ui, event);
|
|
1428
|
+
}
|
|
1429
|
+
leafPaint.loadId = null;
|
|
1430
|
+
}, (error) => {
|
|
1431
|
+
ignoreRender(ui, false);
|
|
1432
|
+
onLoadError(ui, event, error);
|
|
1433
|
+
leafPaint.loadId = null;
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
return leafPaint;
|
|
1437
|
+
}
|
|
1438
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1439
|
+
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1440
|
+
const data = ui.__;
|
|
1441
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1442
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1443
|
+
if (data.__autoSide) {
|
|
1444
|
+
ui.forceUpdate('width');
|
|
1445
|
+
if (ui.__proxyData) {
|
|
1446
|
+
ui.setProxyAttr('width', data.width);
|
|
1447
|
+
ui.setProxyAttr('height', data.height);
|
|
1448
|
+
}
|
|
1449
|
+
return false;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (!leafPaint.data)
|
|
1453
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1454
|
+
return true;
|
|
1455
|
+
}
|
|
1456
|
+
function onLoad(ui, event) {
|
|
1457
|
+
emit(ui, core.ImageEvent.LOAD, event);
|
|
1458
|
+
}
|
|
1459
|
+
function onLoadSuccess(ui, event) {
|
|
1460
|
+
emit(ui, core.ImageEvent.LOADED, event);
|
|
1461
|
+
}
|
|
1462
|
+
function onLoadError(ui, event, error) {
|
|
1463
|
+
event.error = error;
|
|
1464
|
+
ui.forceUpdate('surface');
|
|
1465
|
+
emit(ui, core.ImageEvent.ERROR, event);
|
|
1466
|
+
}
|
|
1467
|
+
function emit(ui, type, data) {
|
|
1468
|
+
if (ui.hasEvent(type))
|
|
1469
|
+
ui.emitEvent(new core.ImageEvent(type, data));
|
|
1470
|
+
}
|
|
1471
|
+
function ignoreRender(ui, value) {
|
|
1472
|
+
const { leafer } = ui;
|
|
1473
|
+
if (leafer && leafer.viewReady)
|
|
1474
|
+
leafer.renderer.ignore = value;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
const { get: get$1, scale, copy: copy$1 } = core.MatrixHelper;
|
|
1478
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1479
|
+
function createPattern(ui, paint, pixelRatio) {
|
|
1480
|
+
let { scaleX, scaleY } = core.ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1481
|
+
const id = scaleX + '-' + scaleY;
|
|
1482
|
+
if (paint.patternId !== id && !ui.destroyed) {
|
|
1483
|
+
scaleX = abs$1(scaleX);
|
|
1484
|
+
scaleY = abs$1(scaleY);
|
|
1485
|
+
const { image, data } = paint;
|
|
1486
|
+
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1487
|
+
if (sx) {
|
|
1488
|
+
imageMatrix = get$1();
|
|
1489
|
+
copy$1(imageMatrix, transform);
|
|
1490
|
+
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1491
|
+
scaleX *= sx;
|
|
1492
|
+
scaleY *= sy;
|
|
1493
|
+
}
|
|
1494
|
+
scaleX *= pixelRatio;
|
|
1495
|
+
scaleY *= pixelRatio;
|
|
1496
|
+
width *= scaleX;
|
|
1497
|
+
height *= scaleY;
|
|
1498
|
+
const size = width * height;
|
|
1499
|
+
if (!repeat) {
|
|
1500
|
+
if (size > core.Platform.image.maxCacheSize)
|
|
1501
|
+
return false;
|
|
1325
1502
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1503
|
+
let maxSize = core.Platform.image.maxPatternSize;
|
|
1504
|
+
if (!image.isSVG) {
|
|
1505
|
+
const imageSize = image.width * image.height;
|
|
1506
|
+
if (maxSize > imageSize)
|
|
1507
|
+
maxSize = imageSize;
|
|
1508
|
+
}
|
|
1509
|
+
if (size > maxSize)
|
|
1510
|
+
imageScale = Math.sqrt(size / maxSize);
|
|
1511
|
+
if (imageScale) {
|
|
1512
|
+
scaleX /= imageScale;
|
|
1513
|
+
scaleY /= imageScale;
|
|
1514
|
+
width /= imageScale;
|
|
1515
|
+
height /= imageScale;
|
|
1516
|
+
}
|
|
1517
|
+
if (sx) {
|
|
1518
|
+
scaleX /= sx;
|
|
1519
|
+
scaleY /= sy;
|
|
1520
|
+
}
|
|
1521
|
+
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1522
|
+
if (!imageMatrix) {
|
|
1523
|
+
imageMatrix = get$1();
|
|
1524
|
+
if (transform)
|
|
1525
|
+
copy$1(imageMatrix, transform);
|
|
1526
|
+
}
|
|
1527
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1528
|
+
}
|
|
1529
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
1530
|
+
const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1531
|
+
paint.style = pattern;
|
|
1532
|
+
paint.patternId = id;
|
|
1533
|
+
return true;
|
|
1335
1534
|
}
|
|
1336
1535
|
else {
|
|
1337
|
-
|
|
1338
|
-
case 'center':
|
|
1339
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1340
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1341
|
-
break;
|
|
1342
|
-
case 'inside':
|
|
1343
|
-
canvas.save();
|
|
1344
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1345
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1346
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1347
|
-
canvas.restore();
|
|
1348
|
-
break;
|
|
1349
|
-
case 'outside':
|
|
1350
|
-
const { renderBounds } = ui.__layout;
|
|
1351
|
-
const out = canvas.getSameCanvas(true);
|
|
1352
|
-
ui.__drawRenderPath(out);
|
|
1353
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1354
|
-
drawStrokesStyle(ui, strokes, out);
|
|
1355
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1356
|
-
out.clearWorld(renderBounds);
|
|
1357
|
-
canvas.copyWorldToInner(out, ui.__world, renderBounds);
|
|
1358
|
-
out.recycle();
|
|
1359
|
-
break;
|
|
1360
|
-
}
|
|
1536
|
+
return false;
|
|
1361
1537
|
}
|
|
1362
1538
|
}
|
|
1363
1539
|
|
|
1364
|
-
const {
|
|
1365
|
-
function
|
|
1366
|
-
const
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
const { __world } = ui;
|
|
1370
|
-
let { scaleX, scaleY } = __world;
|
|
1371
|
-
if (scaleX < 0)
|
|
1372
|
-
scaleX = -scaleX;
|
|
1373
|
-
if (scaleY < 0)
|
|
1374
|
-
scaleY = -scaleY;
|
|
1375
|
-
if (!current.bounds.includes(__world, options.matrix)) {
|
|
1376
|
-
const { renderShapeSpread: spread } = ui.__layout;
|
|
1377
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
|
|
1378
|
-
matrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1379
|
-
if (matrix.a < 1) {
|
|
1380
|
-
worldCanvas = current.getSameCanvas();
|
|
1381
|
-
ui.__renderShape(worldCanvas, options);
|
|
1382
|
-
scaleX *= matrix.a;
|
|
1383
|
-
scaleY *= matrix.d;
|
|
1384
|
-
}
|
|
1385
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1386
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1387
|
-
if (options.matrix)
|
|
1388
|
-
matrix.multiply(options.matrix);
|
|
1389
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1540
|
+
const { abs } = Math;
|
|
1541
|
+
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1542
|
+
const { scaleX, scaleY } = core.ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1543
|
+
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1544
|
+
return false;
|
|
1390
1545
|
}
|
|
1391
1546
|
else {
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1547
|
+
const { data } = paint;
|
|
1548
|
+
if (allowPaint) {
|
|
1549
|
+
if (!data.repeat) {
|
|
1550
|
+
let { width, height } = data;
|
|
1551
|
+
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1552
|
+
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1553
|
+
if (data.scaleX) {
|
|
1554
|
+
width *= data.scaleX;
|
|
1555
|
+
height *= data.scaleY;
|
|
1556
|
+
}
|
|
1557
|
+
allowPaint = (width * height > core.Platform.image.maxCacheSize) || draw.Export.running;
|
|
1558
|
+
}
|
|
1559
|
+
else {
|
|
1560
|
+
allowPaint = false;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
if (allowPaint) {
|
|
1564
|
+
canvas.save();
|
|
1565
|
+
canvas.clip();
|
|
1566
|
+
if (paint.blendMode)
|
|
1567
|
+
canvas.blendMode = paint.blendMode;
|
|
1568
|
+
if (data.opacity)
|
|
1569
|
+
canvas.opacity *= data.opacity;
|
|
1570
|
+
if (data.transform)
|
|
1571
|
+
canvas.transform(data.transform);
|
|
1572
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1573
|
+
canvas.restore();
|
|
1574
|
+
return true;
|
|
1396
1575
|
}
|
|
1397
1576
|
else {
|
|
1398
|
-
|
|
1577
|
+
if (!paint.style || draw.Export.running) {
|
|
1578
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1579
|
+
}
|
|
1580
|
+
else {
|
|
1581
|
+
if (!paint.patternTask) {
|
|
1582
|
+
paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1583
|
+
paint.patternTask = null;
|
|
1584
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1585
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1586
|
+
ui.forceUpdate('surface');
|
|
1587
|
+
}), 300);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return false;
|
|
1399
1591
|
}
|
|
1400
|
-
worldCanvas = canvas;
|
|
1401
1592
|
}
|
|
1402
|
-
ui.__renderShape(canvas, options);
|
|
1403
|
-
return {
|
|
1404
|
-
canvas, matrix, bounds,
|
|
1405
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1406
|
-
};
|
|
1407
1593
|
}
|
|
1408
1594
|
|
|
1409
|
-
|
|
1410
|
-
const
|
|
1595
|
+
function recycleImage(attrName, data) {
|
|
1596
|
+
const paints = data['_' + attrName];
|
|
1597
|
+
if (paints instanceof Array) {
|
|
1598
|
+
let image, recycleMap, input, url;
|
|
1599
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1600
|
+
image = paints[i].image;
|
|
1601
|
+
url = image && image.url;
|
|
1602
|
+
if (url) {
|
|
1603
|
+
if (!recycleMap)
|
|
1604
|
+
recycleMap = {};
|
|
1605
|
+
recycleMap[url] = true;
|
|
1606
|
+
core.ImageManager.recycle(image);
|
|
1607
|
+
if (image.loading) {
|
|
1608
|
+
if (!input) {
|
|
1609
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1610
|
+
if (!(input instanceof Array))
|
|
1611
|
+
input = [input];
|
|
1612
|
+
}
|
|
1613
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
return recycleMap;
|
|
1618
|
+
}
|
|
1619
|
+
return null;
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
const PaintImageModule = {
|
|
1623
|
+
image,
|
|
1624
|
+
checkImage,
|
|
1625
|
+
createPattern,
|
|
1626
|
+
recycleImage,
|
|
1627
|
+
createData,
|
|
1628
|
+
getPatternData,
|
|
1629
|
+
fillOrFitMode,
|
|
1630
|
+
clipMode,
|
|
1631
|
+
repeatMode
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1634
|
+
const { toPoint: toPoint$2 } = core.AroundHelper;
|
|
1635
|
+
const realFrom$2 = {};
|
|
1636
|
+
const realTo$2 = {};
|
|
1411
1637
|
function linearGradient(paint, box) {
|
|
1412
1638
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1413
|
-
from ||
|
|
1414
|
-
to ||
|
|
1415
|
-
const style = core.Platform.canvas.createLinearGradient(
|
|
1639
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
1640
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
1641
|
+
const style = core.Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1416
1642
|
applyStops(style, paint.stops, opacity);
|
|
1417
1643
|
const data = { type, style };
|
|
1418
1644
|
if (blendMode)
|
|
@@ -1423,124 +1649,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1423
1649
|
let stop;
|
|
1424
1650
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1425
1651
|
stop = stops[i];
|
|
1426
|
-
|
|
1652
|
+
if (typeof stop === 'string') {
|
|
1653
|
+
gradient.addColorStop(i / (len - 1), draw.ColorConvert.string(stop, opacity));
|
|
1654
|
+
}
|
|
1655
|
+
else {
|
|
1656
|
+
gradient.addColorStop(stop.offset, draw.ColorConvert.string(stop.color, opacity));
|
|
1657
|
+
}
|
|
1427
1658
|
}
|
|
1428
1659
|
}
|
|
1429
1660
|
|
|
1430
|
-
const {
|
|
1431
|
-
const { get
|
|
1432
|
-
const
|
|
1433
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
1661
|
+
const { getAngle, getDistance: getDistance$1 } = core.PointHelper;
|
|
1662
|
+
const { get, rotateOfOuter, scaleOfOuter } = core.MatrixHelper;
|
|
1663
|
+
const { toPoint: toPoint$1 } = core.AroundHelper;
|
|
1434
1664
|
const realFrom$1 = {};
|
|
1435
1665
|
const realTo$1 = {};
|
|
1436
1666
|
function radialGradient(paint, box) {
|
|
1437
1667
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1438
|
-
from ||
|
|
1439
|
-
to ||
|
|
1440
|
-
const { x, y, width, height } = box;
|
|
1441
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
1442
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
1443
|
-
let transform;
|
|
1444
|
-
if (width !== height || stretch) {
|
|
1445
|
-
transform = get$1();
|
|
1446
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
1447
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
1448
|
-
}
|
|
1668
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
1669
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
1449
1670
|
const style = core.Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
1450
1671
|
applyStops(style, paint.stops, opacity);
|
|
1451
|
-
const data = { type, style
|
|
1672
|
+
const data = { type, style };
|
|
1673
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
1674
|
+
if (transform)
|
|
1675
|
+
data.transform = transform;
|
|
1452
1676
|
if (blendMode)
|
|
1453
1677
|
data.blendMode = blendMode;
|
|
1454
1678
|
return data;
|
|
1455
1679
|
}
|
|
1680
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
1681
|
+
let transform;
|
|
1682
|
+
const { width, height } = box;
|
|
1683
|
+
if (width !== height || stretch) {
|
|
1684
|
+
const angle = getAngle(from, to);
|
|
1685
|
+
transform = get();
|
|
1686
|
+
if (rotate90) {
|
|
1687
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
1688
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
1692
|
+
rotateOfOuter(transform, from, angle);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return transform;
|
|
1696
|
+
}
|
|
1456
1697
|
|
|
1457
|
-
const {
|
|
1458
|
-
const {
|
|
1459
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
1460
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
1698
|
+
const { getDistance } = core.PointHelper;
|
|
1699
|
+
const { toPoint } = core.AroundHelper;
|
|
1461
1700
|
const realFrom = {};
|
|
1462
1701
|
const realTo = {};
|
|
1463
1702
|
function conicGradient(paint, box) {
|
|
1464
1703
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1465
|
-
from ||
|
|
1466
|
-
to ||
|
|
1467
|
-
const { x, y, width, height } = box;
|
|
1468
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
1469
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
1470
|
-
const transform = get();
|
|
1471
|
-
const angle = getAngle(realFrom, realTo);
|
|
1472
|
-
if (core.Platform.conicGradientRotate90) {
|
|
1473
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
1474
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
1475
|
-
}
|
|
1476
|
-
else {
|
|
1477
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
1478
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
1479
|
-
}
|
|
1704
|
+
toPoint(from || 'center', box, realFrom);
|
|
1705
|
+
toPoint(to || 'bottom', box, realTo);
|
|
1480
1706
|
const style = core.Platform.conicGradientSupport ? core.Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : core.Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
|
|
1481
1707
|
applyStops(style, paint.stops, opacity);
|
|
1482
|
-
const data = { type, style
|
|
1708
|
+
const data = { type, style };
|
|
1709
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, core.Platform.conicGradientRotate90);
|
|
1710
|
+
if (transform)
|
|
1711
|
+
data.transform = transform;
|
|
1483
1712
|
if (blendMode)
|
|
1484
1713
|
data.blendMode = blendMode;
|
|
1485
1714
|
return data;
|
|
1486
1715
|
}
|
|
1487
1716
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
paints = [paints];
|
|
1495
|
-
recycleMap = recycleImage(ui.__, attrName);
|
|
1496
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1497
|
-
item = getLeafPaint(ui, paints[i], attrName);
|
|
1498
|
-
if (item)
|
|
1499
|
-
value.push(item);
|
|
1500
|
-
}
|
|
1501
|
-
ui.__['_' + attrName] = value.length ? value : undefined;
|
|
1502
|
-
}
|
|
1503
|
-
function getLeafPaint(ui, paint, attrName) {
|
|
1504
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1505
|
-
return undefined;
|
|
1506
|
-
const { boxBounds } = ui.__layout;
|
|
1507
|
-
switch (paint.type) {
|
|
1508
|
-
case 'solid':
|
|
1509
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1510
|
-
return { type, blendMode, style: core$1.ColorConvert.string(color, opacity) };
|
|
1511
|
-
case 'image':
|
|
1512
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1513
|
-
case 'linear':
|
|
1514
|
-
return linearGradient(paint, boxBounds);
|
|
1515
|
-
case 'radial':
|
|
1516
|
-
return radialGradient(paint, boxBounds);
|
|
1517
|
-
case 'angular':
|
|
1518
|
-
return conicGradient(paint, boxBounds);
|
|
1519
|
-
default:
|
|
1520
|
-
return paint.r ? { type: 'solid', style: core$1.ColorConvert.string(paint) } : undefined;
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1525
|
-
__proto__: null,
|
|
1526
|
-
compute: compute,
|
|
1527
|
-
drawTextStroke: drawTextStroke,
|
|
1528
|
-
fill: fill,
|
|
1529
|
-
fillText: fillText,
|
|
1530
|
-
fills: fills,
|
|
1531
|
-
recycleImage: recycleImage,
|
|
1532
|
-
shape: shape,
|
|
1533
|
-
stroke: stroke,
|
|
1534
|
-
strokeText: strokeText,
|
|
1535
|
-
strokes: strokes
|
|
1536
|
-
});
|
|
1717
|
+
const PaintGradientModule = {
|
|
1718
|
+
linearGradient,
|
|
1719
|
+
radialGradient,
|
|
1720
|
+
conicGradient,
|
|
1721
|
+
getTransform
|
|
1722
|
+
};
|
|
1537
1723
|
|
|
1538
1724
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = core.BoundsHelper;
|
|
1539
1725
|
const tempBounds = {};
|
|
1540
1726
|
const offsetOutBounds$1 = {};
|
|
1541
|
-
function shadow(ui, current, shape
|
|
1727
|
+
function shadow(ui, current, shape) {
|
|
1542
1728
|
let copyBounds, spreadScale;
|
|
1543
|
-
const {
|
|
1729
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1544
1730
|
const { shadow } = ui.__;
|
|
1545
1731
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1546
1732
|
const other = current.getSameCanvas();
|
|
@@ -1555,21 +1741,21 @@ function shadow(ui, current, shape, _options) {
|
|
|
1555
1741
|
other.restore();
|
|
1556
1742
|
other.save();
|
|
1557
1743
|
if (worldCanvas) {
|
|
1558
|
-
other.copyWorld(other, bounds,
|
|
1559
|
-
copyBounds =
|
|
1744
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1745
|
+
copyBounds = nowWorld;
|
|
1560
1746
|
}
|
|
1561
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1747
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1562
1748
|
}
|
|
1563
|
-
if (ui.
|
|
1564
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1749
|
+
if (ui.__worldFlipped) {
|
|
1750
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1565
1751
|
}
|
|
1566
1752
|
else {
|
|
1567
1753
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1568
1754
|
}
|
|
1569
1755
|
if (end && index < end)
|
|
1570
|
-
other.
|
|
1756
|
+
other.clearWorld(copyBounds, true);
|
|
1571
1757
|
});
|
|
1572
|
-
other.recycle();
|
|
1758
|
+
other.recycle(copyBounds);
|
|
1573
1759
|
}
|
|
1574
1760
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1575
1761
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1600,9 +1786,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1600
1786
|
|
|
1601
1787
|
const { toOffsetOutBounds } = core.BoundsHelper;
|
|
1602
1788
|
const offsetOutBounds = {};
|
|
1603
|
-
function innerShadow(ui, current, shape
|
|
1789
|
+
function innerShadow(ui, current, shape) {
|
|
1604
1790
|
let copyBounds, spreadScale;
|
|
1605
|
-
const {
|
|
1791
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1606
1792
|
const { innerShadow } = ui.__;
|
|
1607
1793
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1608
1794
|
const other = current.getSameCanvas();
|
|
@@ -1615,40 +1801,115 @@ function innerShadow(ui, current, shape, _options) {
|
|
|
1615
1801
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1616
1802
|
other.restore();
|
|
1617
1803
|
if (worldCanvas) {
|
|
1618
|
-
other.copyWorld(other, bounds,
|
|
1619
|
-
other.copyWorld(worldCanvas,
|
|
1620
|
-
copyBounds =
|
|
1804
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1805
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1806
|
+
copyBounds = nowWorld;
|
|
1621
1807
|
}
|
|
1622
1808
|
else {
|
|
1623
1809
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1624
1810
|
copyBounds = bounds;
|
|
1625
1811
|
}
|
|
1626
1812
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1627
|
-
if (ui.
|
|
1628
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1813
|
+
if (ui.__worldFlipped) {
|
|
1814
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1629
1815
|
}
|
|
1630
1816
|
else {
|
|
1631
1817
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1632
1818
|
}
|
|
1633
1819
|
if (end && index < end)
|
|
1634
|
-
other.
|
|
1820
|
+
other.clearWorld(copyBounds, true);
|
|
1635
1821
|
});
|
|
1636
|
-
other.recycle();
|
|
1822
|
+
other.recycle(copyBounds);
|
|
1637
1823
|
}
|
|
1638
1824
|
|
|
1639
1825
|
function blur(ui, current, origin) {
|
|
1640
1826
|
const { blur } = ui.__;
|
|
1641
|
-
origin.setWorldBlur(blur * ui.
|
|
1642
|
-
origin.copyWorldToInner(current, ui.
|
|
1827
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1828
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1643
1829
|
origin.filter = 'none';
|
|
1644
1830
|
}
|
|
1645
1831
|
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
shadow
|
|
1651
|
-
|
|
1832
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
const EffectModule = {
|
|
1836
|
+
shadow,
|
|
1837
|
+
innerShadow,
|
|
1838
|
+
blur,
|
|
1839
|
+
backgroundBlur
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1842
|
+
const { excludeRenderBounds } = core.LeafBoundsHelper;
|
|
1843
|
+
draw.Group.prototype.__renderMask = function (canvas, options) {
|
|
1844
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
1845
|
+
const { children } = this;
|
|
1846
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
1847
|
+
child = children[i];
|
|
1848
|
+
if (child.__.mask) {
|
|
1849
|
+
if (currentMask) {
|
|
1850
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1851
|
+
maskCanvas = contentCanvas = null;
|
|
1852
|
+
}
|
|
1853
|
+
if (child.__.mask === 'path') {
|
|
1854
|
+
if (child.opacity < 1) {
|
|
1855
|
+
currentMask = 'opacity-path';
|
|
1856
|
+
maskOpacity = child.opacity;
|
|
1857
|
+
if (!contentCanvas)
|
|
1858
|
+
contentCanvas = getCanvas(canvas);
|
|
1859
|
+
}
|
|
1860
|
+
else {
|
|
1861
|
+
currentMask = 'path';
|
|
1862
|
+
canvas.save();
|
|
1863
|
+
}
|
|
1864
|
+
child.__clip(contentCanvas || canvas, options);
|
|
1865
|
+
}
|
|
1866
|
+
else {
|
|
1867
|
+
currentMask = 'alpha';
|
|
1868
|
+
if (!maskCanvas)
|
|
1869
|
+
maskCanvas = getCanvas(canvas);
|
|
1870
|
+
if (!contentCanvas)
|
|
1871
|
+
contentCanvas = getCanvas(canvas);
|
|
1872
|
+
child.__render(maskCanvas, options);
|
|
1873
|
+
}
|
|
1874
|
+
if (child.__.mask !== 'clipping')
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
if (excludeRenderBounds(child, options))
|
|
1878
|
+
continue;
|
|
1879
|
+
child.__render(contentCanvas || canvas, options);
|
|
1880
|
+
}
|
|
1881
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1882
|
+
};
|
|
1883
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
1884
|
+
switch (maskMode) {
|
|
1885
|
+
case 'alpha':
|
|
1886
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
1887
|
+
break;
|
|
1888
|
+
case 'opacity-path':
|
|
1889
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
1890
|
+
break;
|
|
1891
|
+
case 'path':
|
|
1892
|
+
canvas.restore();
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
function getCanvas(canvas) {
|
|
1896
|
+
return canvas.getSameCanvas(false, true);
|
|
1897
|
+
}
|
|
1898
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
1899
|
+
const realBounds = leaf.__nowWorld;
|
|
1900
|
+
content.resetTransform();
|
|
1901
|
+
content.opacity = 1;
|
|
1902
|
+
content.useMask(mask, realBounds);
|
|
1903
|
+
mask.recycle(realBounds);
|
|
1904
|
+
copyContent(leaf, canvas, content, 1);
|
|
1905
|
+
}
|
|
1906
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
1907
|
+
const realBounds = leaf.__nowWorld;
|
|
1908
|
+
canvas.resetTransform();
|
|
1909
|
+
canvas.opacity = maskOpacity;
|
|
1910
|
+
canvas.copyWorld(content, realBounds);
|
|
1911
|
+
content.recycle(realBounds);
|
|
1912
|
+
}
|
|
1652
1913
|
|
|
1653
1914
|
const money = '¥¥$€££¢¢';
|
|
1654
1915
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1773,6 +2034,8 @@ function createRows(drawData, content, style) {
|
|
|
1773
2034
|
const { width, height } = bounds;
|
|
1774
2035
|
const charMode = width || height || __letterSpacing || (textCase !== 'none');
|
|
1775
2036
|
if (charMode) {
|
|
2037
|
+
const wrap = style.textWrap !== 'none';
|
|
2038
|
+
const breakAll = style.textWrap === 'break';
|
|
1776
2039
|
paraStart = true;
|
|
1777
2040
|
lastCharType = null;
|
|
1778
2041
|
startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
|
|
@@ -1799,16 +2062,26 @@ function createRows(drawData, content, style) {
|
|
|
1799
2062
|
langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
|
|
1800
2063
|
afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
|
|
1801
2064
|
realWidth = paraStart && paraIndent ? width - paraIndent : width;
|
|
1802
|
-
if (width && rowWidth + wordWidth + charWidth > realWidth) {
|
|
1803
|
-
if (
|
|
1804
|
-
afterBreak = charType === Letter && lastCharType == After;
|
|
1805
|
-
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2065
|
+
if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
|
|
2066
|
+
if (breakAll) {
|
|
1806
2067
|
if (wordWidth)
|
|
1807
2068
|
addWord();
|
|
1808
|
-
|
|
2069
|
+
if (rowWidth)
|
|
2070
|
+
addRow();
|
|
1809
2071
|
}
|
|
1810
2072
|
else {
|
|
1811
|
-
|
|
2073
|
+
if (!afterBreak)
|
|
2074
|
+
afterBreak = charType === Letter && lastCharType == After;
|
|
2075
|
+
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2076
|
+
if (wordWidth)
|
|
2077
|
+
addWord();
|
|
2078
|
+
if (rowWidth)
|
|
2079
|
+
addRow();
|
|
2080
|
+
}
|
|
2081
|
+
else {
|
|
2082
|
+
if (rowWidth)
|
|
2083
|
+
addRow();
|
|
2084
|
+
}
|
|
1812
2085
|
}
|
|
1813
2086
|
}
|
|
1814
2087
|
if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
|
|
@@ -1878,7 +2151,7 @@ function addRow() {
|
|
|
1878
2151
|
|
|
1879
2152
|
const CharMode = 0;
|
|
1880
2153
|
const WordMode = 1;
|
|
1881
|
-
const
|
|
2154
|
+
const TextMode = 2;
|
|
1882
2155
|
function layoutChar(drawData, style, width, _height) {
|
|
1883
2156
|
const { rows } = drawData;
|
|
1884
2157
|
const { textAlign, paraIndent, letterSpacing } = style;
|
|
@@ -1887,15 +2160,12 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1887
2160
|
if (row.words) {
|
|
1888
2161
|
indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
|
|
1889
2162
|
addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
|
|
1890
|
-
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode :
|
|
1891
|
-
if (
|
|
1892
|
-
row.
|
|
2163
|
+
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
|
|
2164
|
+
if (row.isOverflow && !letterSpacing)
|
|
2165
|
+
row.textMode = true;
|
|
2166
|
+
if (mode === TextMode) {
|
|
1893
2167
|
row.x += indentWidth;
|
|
1894
|
-
row
|
|
1895
|
-
word.data.forEach(char => {
|
|
1896
|
-
row.text += char.char;
|
|
1897
|
-
});
|
|
1898
|
-
});
|
|
2168
|
+
toTextChar$1(row);
|
|
1899
2169
|
}
|
|
1900
2170
|
else {
|
|
1901
2171
|
row.x += indentWidth;
|
|
@@ -1905,11 +2175,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1905
2175
|
if (mode === WordMode) {
|
|
1906
2176
|
wordChar = { char: '', x: charX };
|
|
1907
2177
|
charX = toWordChar(word.data, charX, wordChar);
|
|
1908
|
-
if (wordChar.char !== ' ')
|
|
2178
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
1909
2179
|
row.data.push(wordChar);
|
|
1910
2180
|
}
|
|
1911
2181
|
else {
|
|
1912
|
-
charX = toChar(word.data, charX, row.data);
|
|
2182
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
1913
2183
|
}
|
|
1914
2184
|
if (!row.paraEnd && addWordWidth) {
|
|
1915
2185
|
charX += addWordWidth;
|
|
@@ -1921,6 +2191,14 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1921
2191
|
}
|
|
1922
2192
|
});
|
|
1923
2193
|
}
|
|
2194
|
+
function toTextChar$1(row) {
|
|
2195
|
+
row.text = '';
|
|
2196
|
+
row.words.forEach(word => {
|
|
2197
|
+
word.data.forEach(char => {
|
|
2198
|
+
row.text += char.char;
|
|
2199
|
+
});
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
1924
2202
|
function toWordChar(data, charX, wordChar) {
|
|
1925
2203
|
data.forEach(char => {
|
|
1926
2204
|
wordChar.char += char.char;
|
|
@@ -1928,9 +2206,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
1928
2206
|
});
|
|
1929
2207
|
return charX;
|
|
1930
2208
|
}
|
|
1931
|
-
function toChar(data, charX, rowData) {
|
|
2209
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
1932
2210
|
data.forEach(char => {
|
|
1933
|
-
if (char.char !== ' ') {
|
|
2211
|
+
if (isOverflow || char.char !== ' ') {
|
|
1934
2212
|
char.x = charX;
|
|
1935
2213
|
rowData.push(char);
|
|
1936
2214
|
}
|
|
@@ -1941,10 +2219,10 @@ function toChar(data, charX, rowData) {
|
|
|
1941
2219
|
|
|
1942
2220
|
function layoutText(drawData, style) {
|
|
1943
2221
|
const { rows, bounds } = drawData;
|
|
1944
|
-
const { __lineHeight, __baseLine, __letterSpacing, textAlign, verticalAlign, paraSpacing
|
|
2222
|
+
const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
|
|
1945
2223
|
let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
1946
2224
|
let starY = __baseLine;
|
|
1947
|
-
if (
|
|
2225
|
+
if (__clipText && realHeight > height) {
|
|
1948
2226
|
realHeight = Math.max(height, __lineHeight);
|
|
1949
2227
|
drawData.overflow = rows.length;
|
|
1950
2228
|
}
|
|
@@ -1962,12 +2240,14 @@ function layoutText(drawData, style) {
|
|
|
1962
2240
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1963
2241
|
row = rows[i];
|
|
1964
2242
|
row.x = x;
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2243
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2244
|
+
switch (textAlign) {
|
|
2245
|
+
case 'center':
|
|
2246
|
+
row.x += (width - row.width) / 2;
|
|
2247
|
+
break;
|
|
2248
|
+
case 'right':
|
|
2249
|
+
row.x += width - row.width;
|
|
2250
|
+
}
|
|
1971
2251
|
}
|
|
1972
2252
|
if (row.paraStart && paraSpacing && i > 0)
|
|
1973
2253
|
starY += paraSpacing;
|
|
@@ -1993,39 +2273,62 @@ function layoutText(drawData, style) {
|
|
|
1993
2273
|
bounds.x = rowX;
|
|
1994
2274
|
if (rowWidth > bounds.width)
|
|
1995
2275
|
bounds.width = rowWidth;
|
|
2276
|
+
if (__clipText && width && width < rowWidth) {
|
|
2277
|
+
row.isOverflow = true;
|
|
2278
|
+
if (!drawData.overflow)
|
|
2279
|
+
drawData.overflow = rows.length;
|
|
2280
|
+
}
|
|
1996
2281
|
}
|
|
1997
2282
|
bounds.y = y;
|
|
1998
2283
|
bounds.height = realHeight;
|
|
1999
2284
|
}
|
|
2000
2285
|
|
|
2001
|
-
function clipText(drawData,
|
|
2286
|
+
function clipText(drawData, style, x, width) {
|
|
2287
|
+
if (!width)
|
|
2288
|
+
return;
|
|
2002
2289
|
const { rows, overflow } = drawData;
|
|
2290
|
+
let { textOverflow } = style;
|
|
2003
2291
|
rows.splice(overflow);
|
|
2004
|
-
if (textOverflow !== '
|
|
2005
|
-
if (textOverflow === '
|
|
2292
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2293
|
+
if (textOverflow === 'hide')
|
|
2294
|
+
textOverflow = '';
|
|
2295
|
+
else if (textOverflow === 'ellipsis')
|
|
2006
2296
|
textOverflow = '...';
|
|
2007
|
-
|
|
2008
|
-
const
|
|
2009
|
-
let char, end = row.data.length - 1, charRight;
|
|
2010
|
-
const { x, width } = drawData.bounds;
|
|
2297
|
+
let char, charRight;
|
|
2298
|
+
const ellipsisWidth = textOverflow ? core.Platform.canvas.measureText(textOverflow).width : 0;
|
|
2011
2299
|
const right = x + width - ellipsisWidth;
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2300
|
+
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2301
|
+
list.forEach(row => {
|
|
2302
|
+
if (row.isOverflow && row.data) {
|
|
2303
|
+
let end = row.data.length - 1;
|
|
2304
|
+
for (let i = end; i > -1; i--) {
|
|
2305
|
+
char = row.data[i];
|
|
2306
|
+
charRight = char.x + char.width;
|
|
2307
|
+
if (i === end && charRight < right) {
|
|
2308
|
+
break;
|
|
2309
|
+
}
|
|
2310
|
+
else if (charRight < right && char.char !== ' ') {
|
|
2311
|
+
row.data.splice(i + 1);
|
|
2312
|
+
row.width -= char.width;
|
|
2313
|
+
break;
|
|
2314
|
+
}
|
|
2315
|
+
row.width -= char.width;
|
|
2316
|
+
}
|
|
2317
|
+
row.width += ellipsisWidth;
|
|
2318
|
+
row.data.push({ char: textOverflow, x: charRight });
|
|
2319
|
+
if (row.textMode)
|
|
2320
|
+
toTextChar(row);
|
|
2022
2321
|
}
|
|
2023
|
-
|
|
2024
|
-
}
|
|
2025
|
-
row.width += ellipsisWidth;
|
|
2026
|
-
row.data.push({ char: textOverflow, x: charRight });
|
|
2322
|
+
});
|
|
2027
2323
|
}
|
|
2028
2324
|
}
|
|
2325
|
+
function toTextChar(row) {
|
|
2326
|
+
row.text = '';
|
|
2327
|
+
row.data.forEach(char => {
|
|
2328
|
+
row.text += char.char;
|
|
2329
|
+
});
|
|
2330
|
+
row.data = null;
|
|
2331
|
+
}
|
|
2029
2332
|
|
|
2030
2333
|
function decorationText(drawData, style) {
|
|
2031
2334
|
const { fontSize } = style;
|
|
@@ -2039,100 +2342,214 @@ function decorationText(drawData, style) {
|
|
|
2039
2342
|
}
|
|
2040
2343
|
}
|
|
2041
2344
|
|
|
2042
|
-
const
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2345
|
+
const { top, right, bottom, left } = core.Direction4;
|
|
2346
|
+
function getDrawData(content, style) {
|
|
2347
|
+
if (typeof content !== 'string')
|
|
2348
|
+
content = String(content);
|
|
2349
|
+
let x = 0, y = 0;
|
|
2350
|
+
let width = style.__getInput('width') || 0;
|
|
2351
|
+
let height = style.__getInput('height') || 0;
|
|
2352
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2353
|
+
if (padding) {
|
|
2354
|
+
if (width) {
|
|
2355
|
+
x = padding[left];
|
|
2356
|
+
width -= (padding[right] + padding[left]);
|
|
2357
|
+
}
|
|
2358
|
+
if (height) {
|
|
2359
|
+
y = padding[top];
|
|
2360
|
+
height -= (padding[top] + padding[bottom]);
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
const drawData = {
|
|
2364
|
+
bounds: { x, y, width, height },
|
|
2365
|
+
rows: [],
|
|
2366
|
+
paraNumber: 0,
|
|
2367
|
+
font: core.Platform.canvas.font = __font
|
|
2368
|
+
};
|
|
2369
|
+
createRows(drawData, content, style);
|
|
2370
|
+
if (padding)
|
|
2371
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2372
|
+
layoutText(drawData, style);
|
|
2373
|
+
layoutChar(drawData, style, width);
|
|
2374
|
+
if (drawData.overflow)
|
|
2375
|
+
clipText(drawData, style, x, width);
|
|
2376
|
+
if (textDecoration !== 'none')
|
|
2377
|
+
decorationText(drawData, style);
|
|
2378
|
+
return drawData;
|
|
2379
|
+
}
|
|
2380
|
+
function padAutoText(padding, drawData, style, width, height) {
|
|
2381
|
+
if (!width) {
|
|
2382
|
+
switch (style.textAlign) {
|
|
2383
|
+
case 'left':
|
|
2384
|
+
offsetText(drawData, 'x', padding[left]);
|
|
2385
|
+
break;
|
|
2386
|
+
case 'right':
|
|
2387
|
+
offsetText(drawData, 'x', -padding[right]);
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
if (!height) {
|
|
2391
|
+
switch (style.verticalAlign) {
|
|
2392
|
+
case 'top':
|
|
2393
|
+
offsetText(drawData, 'y', padding[top]);
|
|
2394
|
+
break;
|
|
2395
|
+
case 'bottom':
|
|
2396
|
+
offsetText(drawData, 'y', -padding[bottom]);
|
|
2060
2397
|
}
|
|
2061
|
-
const drawData = {
|
|
2062
|
-
bounds: { x, y, width, height },
|
|
2063
|
-
rows: [],
|
|
2064
|
-
paraNumber: 0,
|
|
2065
|
-
font: core.Platform.canvas.font = __font
|
|
2066
|
-
};
|
|
2067
|
-
createRows(drawData, content, style);
|
|
2068
|
-
layoutText(drawData, style);
|
|
2069
|
-
layoutChar(drawData, style, width);
|
|
2070
|
-
if (drawData.overflow)
|
|
2071
|
-
clipText(drawData, textOverflow);
|
|
2072
|
-
if (textDecoration !== 'none')
|
|
2073
|
-
decorationText(drawData, style);
|
|
2074
|
-
return drawData;
|
|
2075
2398
|
}
|
|
2399
|
+
}
|
|
2400
|
+
function offsetText(drawData, attrName, value) {
|
|
2401
|
+
const { bounds, rows } = drawData;
|
|
2402
|
+
bounds[attrName] += value;
|
|
2403
|
+
for (let i = 0; i < rows.length; i++)
|
|
2404
|
+
rows[i][attrName] += value;
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
const TextConvertModule = {
|
|
2408
|
+
getDrawData
|
|
2076
2409
|
};
|
|
2077
2410
|
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2411
|
+
function string(color, opacity) {
|
|
2412
|
+
if (typeof color === 'string')
|
|
2413
|
+
return color;
|
|
2414
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2415
|
+
if (opacity)
|
|
2416
|
+
a *= opacity;
|
|
2417
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2418
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
const ColorConvertModule = {
|
|
2422
|
+
string
|
|
2088
2423
|
};
|
|
2089
2424
|
|
|
2090
|
-
const
|
|
2425
|
+
const { setPoint, addPoint, toBounds } = core.TwoPointBoundsHelper;
|
|
2426
|
+
function getTrimBounds(canvas) {
|
|
2427
|
+
const { width, height } = canvas.view;
|
|
2428
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2429
|
+
let x, y, pointBounds, index = 0;
|
|
2430
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2431
|
+
if (data[i + 3] !== 0) {
|
|
2432
|
+
x = index % width;
|
|
2433
|
+
y = (index - x) / width;
|
|
2434
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2435
|
+
}
|
|
2436
|
+
index++;
|
|
2437
|
+
}
|
|
2438
|
+
const bounds = new core.Bounds();
|
|
2439
|
+
toBounds(pointBounds, bounds);
|
|
2440
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
const ExportModule = {
|
|
2091
2444
|
export(leaf, filename, options) {
|
|
2445
|
+
this.running = true;
|
|
2446
|
+
const fileType = core.FileHelper.fileType(filename);
|
|
2447
|
+
options = core.FileHelper.getExportOptions(options);
|
|
2092
2448
|
return addTask((success) => new Promise((resolve) => {
|
|
2449
|
+
const over = (result) => {
|
|
2450
|
+
success(result);
|
|
2451
|
+
resolve();
|
|
2452
|
+
this.running = false;
|
|
2453
|
+
};
|
|
2454
|
+
const { toURL } = core.Platform;
|
|
2455
|
+
const { download } = core.Platform.origin;
|
|
2456
|
+
if (filename === 'json') {
|
|
2457
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
2458
|
+
}
|
|
2459
|
+
else if (fileType === 'json') {
|
|
2460
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
2461
|
+
return over({ data: true });
|
|
2462
|
+
}
|
|
2463
|
+
if (filename === 'svg') {
|
|
2464
|
+
return over({ data: leaf.toSVG() });
|
|
2465
|
+
}
|
|
2466
|
+
else if (fileType === 'svg') {
|
|
2467
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
2468
|
+
return over({ data: true });
|
|
2469
|
+
}
|
|
2093
2470
|
const { leafer } = leaf;
|
|
2094
2471
|
if (leafer) {
|
|
2472
|
+
checkLazy(leaf);
|
|
2095
2473
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2096
|
-
let
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2474
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2475
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
2476
|
+
const { slice, trim, onCanvas } = options;
|
|
2477
|
+
let scale = options.scale || 1;
|
|
2478
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
2479
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
2480
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
2481
|
+
if (leaf.isApp) {
|
|
2482
|
+
scale *= pixelRatio;
|
|
2483
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
2484
|
+
}
|
|
2485
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2486
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
2487
|
+
const needFill = core.FileHelper.isOpaqueImage(filename) || fill, matrix = new core.Matrix();
|
|
2488
|
+
if (screenshot) {
|
|
2489
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2103
2490
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2491
|
+
else {
|
|
2492
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
2493
|
+
scaleX = worldTransform.scaleX;
|
|
2494
|
+
scaleY = worldTransform.scaleY;
|
|
2495
|
+
switch (relative) {
|
|
2496
|
+
case 'inner':
|
|
2497
|
+
matrix.set(worldTransform);
|
|
2498
|
+
break;
|
|
2499
|
+
case 'local':
|
|
2500
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
2501
|
+
scaleX /= leaf.scaleX;
|
|
2502
|
+
scaleY /= leaf.scaleY;
|
|
2503
|
+
break;
|
|
2504
|
+
case 'world':
|
|
2505
|
+
scaleX = 1;
|
|
2506
|
+
scaleY = 1;
|
|
2507
|
+
break;
|
|
2508
|
+
case 'page':
|
|
2509
|
+
relative = leaf.leafer;
|
|
2510
|
+
default:
|
|
2511
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
2512
|
+
const l = relative.worldTransform;
|
|
2513
|
+
scaleX /= scaleX / l.scaleX;
|
|
2514
|
+
scaleY /= scaleY / l.scaleY;
|
|
2515
|
+
}
|
|
2516
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2116
2517
|
}
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2518
|
+
const { x, y, width, height } = new core.Bounds(renderBounds).scale(scale);
|
|
2519
|
+
let canvas = core.Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
2520
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
2521
|
+
if (slice) {
|
|
2522
|
+
leaf = leafer;
|
|
2523
|
+
renderOptions.bounds = canvas.bounds;
|
|
2120
2524
|
}
|
|
2121
|
-
|
|
2122
|
-
|
|
2525
|
+
canvas.save();
|
|
2526
|
+
if (isFrame && fill !== undefined) {
|
|
2527
|
+
const oldFill = leaf.get('fill');
|
|
2528
|
+
leaf.fill = '';
|
|
2529
|
+
leaf.__render(canvas, renderOptions);
|
|
2530
|
+
leaf.fill = oldFill;
|
|
2123
2531
|
}
|
|
2124
2532
|
else {
|
|
2125
|
-
|
|
2533
|
+
leaf.__render(canvas, renderOptions);
|
|
2126
2534
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
canvas
|
|
2535
|
+
canvas.restore();
|
|
2536
|
+
if (trim) {
|
|
2537
|
+
trimBounds = getTrimBounds(canvas);
|
|
2538
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2539
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2540
|
+
canvas = core.Creator.canvas(config);
|
|
2541
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2542
|
+
}
|
|
2543
|
+
if (needFill)
|
|
2544
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2545
|
+
if (onCanvas)
|
|
2546
|
+
onCanvas(canvas);
|
|
2547
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2548
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2131
2549
|
}));
|
|
2132
2550
|
}
|
|
2133
2551
|
else {
|
|
2134
|
-
|
|
2135
|
-
resolve();
|
|
2552
|
+
over({ data: false });
|
|
2136
2553
|
}
|
|
2137
2554
|
}));
|
|
2138
2555
|
}
|
|
@@ -2145,14 +2562,66 @@ function addTask(task) {
|
|
|
2145
2562
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2146
2563
|
});
|
|
2147
2564
|
}
|
|
2565
|
+
function checkLazy(leaf) {
|
|
2566
|
+
if (leaf.__.__needComputePaint)
|
|
2567
|
+
leaf.__.__computePaint();
|
|
2568
|
+
if (leaf.isBranch)
|
|
2569
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
const canvas = core.LeaferCanvasBase.prototype;
|
|
2573
|
+
const debug = core.Debug.get('@leafer-ui/export');
|
|
2574
|
+
canvas.export = function (filename, options) {
|
|
2575
|
+
const { quality, blob } = core.FileHelper.getExportOptions(options);
|
|
2576
|
+
if (filename.includes('.')) {
|
|
2577
|
+
return this.saveAs(filename, quality);
|
|
2578
|
+
}
|
|
2579
|
+
else if (blob) {
|
|
2580
|
+
return this.toBlob(filename, quality);
|
|
2581
|
+
}
|
|
2582
|
+
else {
|
|
2583
|
+
return this.toDataURL(filename, quality);
|
|
2584
|
+
}
|
|
2585
|
+
};
|
|
2586
|
+
canvas.toBlob = function (type, quality) {
|
|
2587
|
+
return new Promise((resolve) => {
|
|
2588
|
+
core.Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2589
|
+
resolve(blob);
|
|
2590
|
+
}).catch((e) => {
|
|
2591
|
+
debug.error(e);
|
|
2592
|
+
resolve(null);
|
|
2593
|
+
});
|
|
2594
|
+
});
|
|
2595
|
+
};
|
|
2596
|
+
canvas.toDataURL = function (type, quality) {
|
|
2597
|
+
return core.Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2598
|
+
};
|
|
2599
|
+
canvas.saveAs = function (filename, quality) {
|
|
2600
|
+
return new Promise((resolve) => {
|
|
2601
|
+
core.Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2602
|
+
resolve(true);
|
|
2603
|
+
}).catch((e) => {
|
|
2604
|
+
debug.error(e);
|
|
2605
|
+
resolve(false);
|
|
2606
|
+
});
|
|
2607
|
+
});
|
|
2608
|
+
};
|
|
2148
2609
|
|
|
2149
|
-
Object.assign(
|
|
2150
|
-
Object.assign(
|
|
2151
|
-
Object.assign(
|
|
2152
|
-
Object.assign(
|
|
2153
|
-
Object.assign(
|
|
2610
|
+
Object.assign(draw.TextConvert, TextConvertModule);
|
|
2611
|
+
Object.assign(draw.ColorConvert, ColorConvertModule);
|
|
2612
|
+
Object.assign(draw.Paint, PaintModule);
|
|
2613
|
+
Object.assign(draw.PaintImage, PaintImageModule);
|
|
2614
|
+
Object.assign(draw.PaintGradient, PaintGradientModule);
|
|
2615
|
+
Object.assign(draw.Effect, EffectModule);
|
|
2616
|
+
Object.assign(draw.Export, ExportModule);
|
|
2617
|
+
|
|
2618
|
+
Object.assign(core.Creator, {
|
|
2619
|
+
interaction: (target, canvas, selector, options) => { return new core$1.InteractionBase(target, canvas, selector, options); },
|
|
2620
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2621
|
+
hitCanvasManager: () => new core$1.HitCanvasManager()
|
|
2622
|
+
});
|
|
2154
2623
|
|
|
2155
|
-
Object.defineProperty(exports,
|
|
2624
|
+
Object.defineProperty(exports, "LeaferImage", {
|
|
2156
2625
|
enumerable: true,
|
|
2157
2626
|
get: function () { return core.LeaferImage; }
|
|
2158
2627
|
});
|