@leafer-ui/worker 1.0.0-beta.17 → 1.0.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/worker.esm.js +1129 -849
- package/dist/worker.esm.min.js +1 -1
- package/dist/worker.js +5916 -4861
- package/dist/worker.min.js +1 -1
- package/dist/worker.module.js +10965 -0
- package/dist/worker.module.min.js +1 -0
- package/package.json +7 -7
- package/src/index.ts +12 -4
- package/types/index.d.ts +4 -8
package/dist/worker.esm.js
CHANGED
|
@@ -1,8 +1,97 @@
|
|
|
1
|
-
import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper,
|
|
1
|
+
import { LeaferCanvasBase, Platform, canvasPatch, Creator, LeaferImage, FileHelper, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, ResizeEvent, BoundsHelper, Answer, MatrixHelper, ImageEvent, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
|
|
2
2
|
export * from '@leafer/core';
|
|
3
3
|
export { LeaferImage } from '@leafer/core';
|
|
4
|
-
import {
|
|
4
|
+
import { InteractionBase, HitCanvasManager } from '@leafer-ui/core';
|
|
5
5
|
export * from '@leafer-ui/core';
|
|
6
|
+
import { ColorConvert, Export, Group, TextConvert, Paint, PaintImage as PaintImage$1, PaintGradient as PaintGradient$1, Effect } from '@leafer-ui/draw';
|
|
7
|
+
|
|
8
|
+
class LeaferCanvas extends LeaferCanvasBase {
|
|
9
|
+
get allowBackgroundColor() { return true; }
|
|
10
|
+
init() {
|
|
11
|
+
this.__createView();
|
|
12
|
+
this.__createContext();
|
|
13
|
+
this.resize(this.config);
|
|
14
|
+
}
|
|
15
|
+
__createView() {
|
|
16
|
+
this.view = Platform.origin.createCanvas(1, 1);
|
|
17
|
+
}
|
|
18
|
+
updateViewSize() {
|
|
19
|
+
const { width, height, pixelRatio } = this;
|
|
20
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
21
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
22
|
+
this.clientBounds = this.bounds;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
canvasPatch(OffscreenCanvasRenderingContext2D.prototype);
|
|
27
|
+
canvasPatch(Path2D.prototype);
|
|
28
|
+
|
|
29
|
+
const { mineType } = FileHelper;
|
|
30
|
+
Object.assign(Creator, {
|
|
31
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
32
|
+
image: (options) => new LeaferImage(options)
|
|
33
|
+
});
|
|
34
|
+
function useCanvas(_canvasType, _power) {
|
|
35
|
+
Platform.origin = {
|
|
36
|
+
createCanvas: (width, height) => new OffscreenCanvas(width, height),
|
|
37
|
+
canvasToDataURL: (canvas, type, quality) => {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
canvas.convertToBlob({ type: mineType(type), quality }).then((blob) => {
|
|
40
|
+
var reader = new FileReader();
|
|
41
|
+
reader.onload = (e) => resolve(e.target.result);
|
|
42
|
+
reader.onerror = (e) => reject(e);
|
|
43
|
+
reader.readAsDataURL(blob);
|
|
44
|
+
}).catch((e) => {
|
|
45
|
+
reject(e);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({ type: mineType(type), quality }),
|
|
50
|
+
canvasSaveAs: (_canvas, _filename, _quality) => new Promise((resolve) => resolve()),
|
|
51
|
+
loadImage(src) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
if (!src.startsWith('data:') && Platform.image.suffix)
|
|
54
|
+
src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
|
|
55
|
+
let req = new XMLHttpRequest();
|
|
56
|
+
req.open('GET', src, true);
|
|
57
|
+
req.responseType = "blob";
|
|
58
|
+
req.onload = () => {
|
|
59
|
+
createImageBitmap(req.response).then(img => {
|
|
60
|
+
resolve(img);
|
|
61
|
+
}).catch(e => {
|
|
62
|
+
reject(e);
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
req.onerror = (e) => reject(e);
|
|
66
|
+
req.send();
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
Platform.canvas = Creator.canvas();
|
|
71
|
+
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
72
|
+
}
|
|
73
|
+
Platform.name = 'web';
|
|
74
|
+
Platform.isWorker = true;
|
|
75
|
+
Platform.requestRender = function (render) { requestAnimationFrame(render); };
|
|
76
|
+
Platform.devicePixelRatio = 1;
|
|
77
|
+
const { userAgent } = navigator;
|
|
78
|
+
if (userAgent.indexOf("Firefox") > -1) {
|
|
79
|
+
Platform.conicGradientRotate90 = true;
|
|
80
|
+
Platform.intWheelDeltaY = true;
|
|
81
|
+
}
|
|
82
|
+
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
83
|
+
Platform.fullImageShadow = true;
|
|
84
|
+
}
|
|
85
|
+
if (userAgent.indexOf('Windows') > -1) {
|
|
86
|
+
Platform.os = 'Windows';
|
|
87
|
+
Platform.intWheelDeltaY = true;
|
|
88
|
+
}
|
|
89
|
+
else if (userAgent.indexOf('Mac') > -1) {
|
|
90
|
+
Platform.os = 'Mac';
|
|
91
|
+
}
|
|
92
|
+
else if (userAgent.indexOf('Linux') > -1) {
|
|
93
|
+
Platform.os = 'Linux';
|
|
94
|
+
}
|
|
6
95
|
|
|
7
96
|
class Watcher {
|
|
8
97
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -10,7 +99,7 @@ class Watcher {
|
|
|
10
99
|
if (this.hasRemove) {
|
|
11
100
|
const updatedList = new LeafList();
|
|
12
101
|
this.__updatedList.list.forEach(item => { if (item.leafer)
|
|
13
|
-
updatedList.
|
|
102
|
+
updatedList.add(item); });
|
|
14
103
|
return updatedList;
|
|
15
104
|
}
|
|
16
105
|
else {
|
|
@@ -45,7 +134,7 @@ class Watcher {
|
|
|
45
134
|
this.target.emit(RenderEvent.REQUEST);
|
|
46
135
|
}
|
|
47
136
|
__onAttrChange(event) {
|
|
48
|
-
this.__updatedList.
|
|
137
|
+
this.__updatedList.add(event.target);
|
|
49
138
|
this.update();
|
|
50
139
|
}
|
|
51
140
|
__onChildEvent(event) {
|
|
@@ -55,12 +144,12 @@ class Watcher {
|
|
|
55
144
|
}
|
|
56
145
|
else {
|
|
57
146
|
this.hasRemove = true;
|
|
58
|
-
this.__updatedList.
|
|
147
|
+
this.__updatedList.add(event.parent);
|
|
59
148
|
}
|
|
60
149
|
this.update();
|
|
61
150
|
}
|
|
62
151
|
__pushChild(child) {
|
|
63
|
-
this.__updatedList.
|
|
152
|
+
this.__updatedList.add(child);
|
|
64
153
|
if (child.isBranch)
|
|
65
154
|
this.__loopChildren(child);
|
|
66
155
|
}
|
|
@@ -99,22 +188,22 @@ class Watcher {
|
|
|
99
188
|
}
|
|
100
189
|
}
|
|
101
190
|
|
|
102
|
-
const {
|
|
191
|
+
const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
|
|
103
192
|
const { pushAllChildBranch, pushAllParent } = BranchHelper;
|
|
104
193
|
function updateMatrix(updateList, levelList) {
|
|
105
194
|
let layout;
|
|
106
195
|
updateList.list.forEach(leaf => {
|
|
107
196
|
layout = leaf.__layout;
|
|
108
|
-
if (levelList.without(leaf) && !layout.
|
|
197
|
+
if (levelList.without(leaf) && !layout.proxyZoom) {
|
|
109
198
|
if (layout.matrixChanged) {
|
|
110
|
-
|
|
111
|
-
levelList.
|
|
199
|
+
updateAllMatrix$1(leaf, true);
|
|
200
|
+
levelList.add(leaf);
|
|
112
201
|
if (leaf.isBranch)
|
|
113
202
|
pushAllChildBranch(leaf, levelList);
|
|
114
203
|
pushAllParent(leaf, levelList);
|
|
115
204
|
}
|
|
116
205
|
else if (layout.boundsChanged) {
|
|
117
|
-
levelList.
|
|
206
|
+
levelList.add(leaf);
|
|
118
207
|
if (leaf.isBranch)
|
|
119
208
|
leaf.__tempNumber = 0;
|
|
120
209
|
pushAllParent(leaf, levelList);
|
|
@@ -123,20 +212,21 @@ function updateMatrix(updateList, levelList) {
|
|
|
123
212
|
});
|
|
124
213
|
}
|
|
125
214
|
function updateBounds(boundsList) {
|
|
126
|
-
let
|
|
215
|
+
let list, branch, children;
|
|
127
216
|
boundsList.sort(true);
|
|
128
217
|
boundsList.levels.forEach(level => {
|
|
129
|
-
|
|
130
|
-
for (let i = 0, len =
|
|
131
|
-
branch =
|
|
218
|
+
list = boundsList.levelMap[level];
|
|
219
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
220
|
+
branch = list[i];
|
|
132
221
|
if (branch.isBranch && branch.__tempNumber) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
222
|
+
children = branch.children;
|
|
223
|
+
for (let j = 0, jLen = children.length; j < jLen; j++) {
|
|
224
|
+
if (!children[j].isBranch) {
|
|
225
|
+
updateOneBounds(children[j]);
|
|
136
226
|
}
|
|
137
227
|
}
|
|
138
228
|
}
|
|
139
|
-
branch
|
|
229
|
+
updateOneBounds(branch);
|
|
140
230
|
}
|
|
141
231
|
});
|
|
142
232
|
}
|
|
@@ -149,7 +239,7 @@ function updateChange(updateList) {
|
|
|
149
239
|
}
|
|
150
240
|
|
|
151
241
|
const { worldBounds } = LeafBoundsHelper;
|
|
152
|
-
const {
|
|
242
|
+
const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
|
|
153
243
|
class LayoutBlockData {
|
|
154
244
|
constructor(list) {
|
|
155
245
|
this.updatedBounds = new Bounds();
|
|
@@ -160,14 +250,20 @@ class LayoutBlockData {
|
|
|
160
250
|
this.updatedList = list;
|
|
161
251
|
}
|
|
162
252
|
setBefore() {
|
|
163
|
-
|
|
253
|
+
this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
164
254
|
}
|
|
165
255
|
setAfter() {
|
|
166
|
-
|
|
167
|
-
|
|
256
|
+
const { list } = this.updatedList;
|
|
257
|
+
if (list.some(leaf => leaf.noBounds)) {
|
|
258
|
+
this.afterBounds.set(bigBounds);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
this.afterBounds.setListWithFn(list, worldBounds);
|
|
262
|
+
}
|
|
263
|
+
this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
|
|
168
264
|
}
|
|
169
265
|
merge(data) {
|
|
170
|
-
this.updatedList.
|
|
266
|
+
this.updatedList.addList(data.updatedList.list);
|
|
171
267
|
this.beforeBounds.add(data.beforeBounds);
|
|
172
268
|
this.afterBounds.add(data.afterBounds);
|
|
173
269
|
this.updatedBounds.add(data.updatedBounds);
|
|
@@ -177,8 +273,7 @@ class LayoutBlockData {
|
|
|
177
273
|
}
|
|
178
274
|
}
|
|
179
275
|
|
|
180
|
-
const {
|
|
181
|
-
const { pushAllBranchStack, updateWorldBoundsByBranchStack } = BranchHelper;
|
|
276
|
+
const { updateAllMatrix, updateAllChange } = LeafHelper;
|
|
182
277
|
const debug$1 = Debug.get('Layouter');
|
|
183
278
|
class Layouter {
|
|
184
279
|
constructor(target, userConfig) {
|
|
@@ -255,12 +350,15 @@ class Layouter {
|
|
|
255
350
|
const { target, __updatedList: updateList } = this;
|
|
256
351
|
const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
|
|
257
352
|
const blocks = this.getBlocks(updateList);
|
|
258
|
-
blocks.forEach(item =>
|
|
353
|
+
blocks.forEach(item => item.setBefore());
|
|
259
354
|
target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
|
|
355
|
+
this.extraBlock = null;
|
|
260
356
|
updateList.sort();
|
|
261
357
|
updateMatrix(updateList, this.__levelList);
|
|
262
358
|
updateBounds(this.__levelList);
|
|
263
359
|
updateChange(updateList);
|
|
360
|
+
if (this.extraBlock)
|
|
361
|
+
blocks.push(this.extraBlock);
|
|
264
362
|
blocks.forEach(item => item.setAfter());
|
|
265
363
|
target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
|
|
266
364
|
target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
|
|
@@ -283,17 +381,20 @@ class Layouter {
|
|
|
283
381
|
Run.end(t);
|
|
284
382
|
}
|
|
285
383
|
static fullLayout(target) {
|
|
286
|
-
|
|
384
|
+
updateAllMatrix(target, true);
|
|
287
385
|
if (target.isBranch) {
|
|
288
|
-
|
|
289
|
-
pushAllBranchStack(target, branchStack);
|
|
290
|
-
updateWorldBoundsByBranchStack(branchStack);
|
|
386
|
+
BranchHelper.updateBounds(target);
|
|
291
387
|
}
|
|
292
388
|
else {
|
|
293
|
-
|
|
389
|
+
LeafHelper.updateBounds(target);
|
|
294
390
|
}
|
|
295
391
|
updateAllChange(target);
|
|
296
392
|
}
|
|
393
|
+
addExtra(leaf) {
|
|
394
|
+
const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
395
|
+
block.updatedList.add(leaf);
|
|
396
|
+
block.beforeBounds.add(leaf.__world);
|
|
397
|
+
}
|
|
297
398
|
createBlock(data) {
|
|
298
399
|
return new LayoutBlockData(data);
|
|
299
400
|
}
|
|
@@ -321,8 +422,7 @@ class Layouter {
|
|
|
321
422
|
if (this.target) {
|
|
322
423
|
this.stop();
|
|
323
424
|
this.__removeListenEvents();
|
|
324
|
-
this.target = null;
|
|
325
|
-
this.config = null;
|
|
425
|
+
this.target = this.config = null;
|
|
326
426
|
}
|
|
327
427
|
}
|
|
328
428
|
}
|
|
@@ -424,8 +524,7 @@ class Renderer {
|
|
|
424
524
|
const { canvas, updateBlocks: list } = this;
|
|
425
525
|
if (!list)
|
|
426
526
|
return debug.warn('PartRender: need update attr');
|
|
427
|
-
|
|
428
|
-
this.mergeBlocks();
|
|
527
|
+
this.mergeBlocks();
|
|
429
528
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
430
529
|
this.clipRender(block); });
|
|
431
530
|
}
|
|
@@ -434,7 +533,7 @@ class Renderer {
|
|
|
434
533
|
const { canvas } = this;
|
|
435
534
|
const bounds = block.getIntersect(canvas.bounds);
|
|
436
535
|
const includes = block.includes(this.target.__world);
|
|
437
|
-
const realBounds = new Bounds(
|
|
536
|
+
const realBounds = new Bounds(bounds);
|
|
438
537
|
canvas.save();
|
|
439
538
|
if (includes && !Debug.showRepaint) {
|
|
440
539
|
canvas.clear();
|
|
@@ -444,7 +543,7 @@ class Renderer {
|
|
|
444
543
|
canvas.clearWorld(bounds, true);
|
|
445
544
|
canvas.clipWorld(bounds, true);
|
|
446
545
|
}
|
|
447
|
-
this.__render(bounds, realBounds);
|
|
546
|
+
this.__render(bounds, includes, realBounds);
|
|
448
547
|
canvas.restore();
|
|
449
548
|
Run.end(t);
|
|
450
549
|
}
|
|
@@ -453,12 +552,12 @@ class Renderer {
|
|
|
453
552
|
const { canvas } = this;
|
|
454
553
|
canvas.save();
|
|
455
554
|
canvas.clear();
|
|
456
|
-
this.__render(canvas.bounds);
|
|
555
|
+
this.__render(canvas.bounds, true);
|
|
457
556
|
canvas.restore();
|
|
458
557
|
Run.end(t);
|
|
459
558
|
}
|
|
460
|
-
__render(bounds, realBounds) {
|
|
461
|
-
const options =
|
|
559
|
+
__render(bounds, includes, realBounds) {
|
|
560
|
+
const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
|
|
462
561
|
if (this.needFill)
|
|
463
562
|
this.canvas.fillWorld(bounds, this.config.fill);
|
|
464
563
|
if (Debug.showRepaint)
|
|
@@ -484,7 +583,7 @@ class Renderer {
|
|
|
484
583
|
const { updateBlocks: list } = this;
|
|
485
584
|
if (list) {
|
|
486
585
|
const bounds = new Bounds();
|
|
487
|
-
bounds.
|
|
586
|
+
bounds.setList(list);
|
|
488
587
|
list.length = 0;
|
|
489
588
|
list.push(bounds);
|
|
490
589
|
}
|
|
@@ -493,12 +592,12 @@ class Renderer {
|
|
|
493
592
|
const startTime = Date.now();
|
|
494
593
|
Platform.requestRender(() => {
|
|
495
594
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
496
|
-
if (this.
|
|
497
|
-
|
|
595
|
+
if (this.running) {
|
|
596
|
+
this.target.emit(AnimateEvent.FRAME);
|
|
597
|
+
if (this.changed && this.canvas.view)
|
|
498
598
|
this.render();
|
|
599
|
+
this.target.emit(RenderEvent.NEXT);
|
|
499
600
|
}
|
|
500
|
-
if (this.running)
|
|
501
|
-
this.target.emit(AnimateEvent.FRAME);
|
|
502
601
|
if (this.target)
|
|
503
602
|
this.__requestRender();
|
|
504
603
|
});
|
|
@@ -511,7 +610,7 @@ class Renderer {
|
|
|
511
610
|
const bounds = new Bounds(0, 0, width, height);
|
|
512
611
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
513
612
|
this.addBlock(this.canvas.bounds);
|
|
514
|
-
this.target.forceUpdate('
|
|
613
|
+
this.target.forceUpdate('surface');
|
|
515
614
|
}
|
|
516
615
|
}
|
|
517
616
|
}
|
|
@@ -524,7 +623,7 @@ class Renderer {
|
|
|
524
623
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
525
624
|
if (empty) {
|
|
526
625
|
if (!leaf.isLeafer)
|
|
527
|
-
debug.
|
|
626
|
+
debug.tip(leaf.innerName, ': empty');
|
|
528
627
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
529
628
|
}
|
|
530
629
|
return empty;
|
|
@@ -559,7 +658,7 @@ class Renderer {
|
|
|
559
658
|
}
|
|
560
659
|
|
|
561
660
|
const { hitRadiusPoint } = BoundsHelper;
|
|
562
|
-
class
|
|
661
|
+
class Picker {
|
|
563
662
|
constructor(target, selector) {
|
|
564
663
|
this.target = target;
|
|
565
664
|
this.selector = selector;
|
|
@@ -571,15 +670,17 @@ class FindPath {
|
|
|
571
670
|
options = {};
|
|
572
671
|
const through = options.through || false;
|
|
573
672
|
const ignoreHittable = options.ignoreHittable || false;
|
|
673
|
+
const target = options.target || this.target;
|
|
574
674
|
this.exclude = options.exclude || null;
|
|
575
675
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
576
|
-
this.findList = [];
|
|
577
|
-
|
|
676
|
+
this.findList = options.findList || [];
|
|
677
|
+
if (!options.findList)
|
|
678
|
+
this.eachFind(target.children, target.__onlyHitMask);
|
|
578
679
|
const list = this.findList;
|
|
579
680
|
const leaf = this.getBestMatchLeaf();
|
|
580
681
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
581
682
|
this.clear();
|
|
582
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
683
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
583
684
|
}
|
|
584
685
|
getBestMatchLeaf() {
|
|
585
686
|
const { findList: targets } = this;
|
|
@@ -602,10 +703,10 @@ class FindPath {
|
|
|
602
703
|
getPath(leaf) {
|
|
603
704
|
const path = new LeafList();
|
|
604
705
|
while (leaf) {
|
|
605
|
-
path.
|
|
706
|
+
path.add(leaf);
|
|
606
707
|
leaf = leaf.parent;
|
|
607
708
|
}
|
|
608
|
-
path.
|
|
709
|
+
path.add(this.target);
|
|
609
710
|
return path;
|
|
610
711
|
}
|
|
611
712
|
getHitablePath(leaf) {
|
|
@@ -615,7 +716,7 @@ class FindPath {
|
|
|
615
716
|
item = path.list[i];
|
|
616
717
|
if (!item.__.hittable)
|
|
617
718
|
break;
|
|
618
|
-
hittablePath.
|
|
719
|
+
hittablePath.addAt(item, 0);
|
|
619
720
|
if (!item.__.hitChildren)
|
|
620
721
|
break;
|
|
621
722
|
}
|
|
@@ -634,7 +735,7 @@ class FindPath {
|
|
|
634
735
|
leaf = path.list[j];
|
|
635
736
|
if (nextPath && nextPath.has(leaf))
|
|
636
737
|
break;
|
|
637
|
-
throughPath.
|
|
738
|
+
throughPath.add(leaf);
|
|
638
739
|
}
|
|
639
740
|
}
|
|
640
741
|
return throughPath;
|
|
@@ -644,7 +745,7 @@ class FindPath {
|
|
|
644
745
|
const { point } = this, len = children.length;
|
|
645
746
|
for (let i = len - 1; i > -1; i--) {
|
|
646
747
|
child = children[i];
|
|
647
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
748
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
648
749
|
continue;
|
|
649
750
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
650
751
|
if (child.isBranch) {
|
|
@@ -676,120 +777,113 @@ class FindPath {
|
|
|
676
777
|
}
|
|
677
778
|
}
|
|
678
779
|
|
|
780
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer;
|
|
679
781
|
class Selector {
|
|
680
782
|
constructor(target, userConfig) {
|
|
681
783
|
this.config = {};
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
this.
|
|
685
|
-
|
|
784
|
+
this.innerIdMap = {};
|
|
785
|
+
this.idMap = {};
|
|
786
|
+
this.methods = {
|
|
787
|
+
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
788
|
+
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
789
|
+
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
790
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
791
|
+
};
|
|
686
792
|
this.target = target;
|
|
687
793
|
if (userConfig)
|
|
688
794
|
this.config = DataHelper.default(userConfig, this.config);
|
|
689
|
-
this.
|
|
795
|
+
this.picker = new Picker(target, this);
|
|
690
796
|
this.__listenEvents();
|
|
691
797
|
}
|
|
798
|
+
getBy(condition, branch, one, options) {
|
|
799
|
+
switch (typeof condition) {
|
|
800
|
+
case 'number':
|
|
801
|
+
const leaf = this.getByInnerId(condition, branch);
|
|
802
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
803
|
+
case 'string':
|
|
804
|
+
switch (condition[0]) {
|
|
805
|
+
case '#':
|
|
806
|
+
const leaf = this.getById(condition.substring(1), branch);
|
|
807
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
808
|
+
case '.':
|
|
809
|
+
return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
|
|
810
|
+
default:
|
|
811
|
+
return this.getByMethod(this.methods.tag, branch, one, condition);
|
|
812
|
+
}
|
|
813
|
+
case 'function':
|
|
814
|
+
return this.getByMethod(condition, branch, one, options);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
692
817
|
getByPoint(hitPoint, hitRadius, options) {
|
|
693
818
|
if (Platform.name === 'node')
|
|
694
819
|
this.target.emit(LayoutEvent.CHECK_UPDATE);
|
|
695
|
-
return this.
|
|
696
|
-
}
|
|
697
|
-
find(name, branch) {
|
|
698
|
-
if (typeof name === 'number') {
|
|
699
|
-
return this.getByInnerId(name, branch);
|
|
700
|
-
}
|
|
701
|
-
else if (name.startsWith('#')) {
|
|
702
|
-
return this.getById(name.substring(1), branch);
|
|
703
|
-
}
|
|
704
|
-
else if (name.startsWith('.')) {
|
|
705
|
-
return this.getByClassName(name.substring(1), branch);
|
|
706
|
-
}
|
|
707
|
-
else {
|
|
708
|
-
return this.getByTagName(name, branch);
|
|
709
|
-
}
|
|
820
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
710
821
|
}
|
|
711
|
-
getByInnerId(
|
|
712
|
-
|
|
822
|
+
getByInnerId(innerId, branch) {
|
|
823
|
+
const cache = this.innerIdMap[innerId];
|
|
713
824
|
if (cache)
|
|
714
825
|
return cache;
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
let find;
|
|
718
|
-
this.loopFind(branch, (leaf) => {
|
|
719
|
-
if (leaf.innerId === name) {
|
|
720
|
-
find = leaf;
|
|
721
|
-
this.innerIdList[name] = find;
|
|
722
|
-
return true;
|
|
723
|
-
}
|
|
724
|
-
else {
|
|
725
|
-
return false;
|
|
726
|
-
}
|
|
727
|
-
});
|
|
728
|
-
return find;
|
|
826
|
+
this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
|
|
827
|
+
return this.findLeaf;
|
|
729
828
|
}
|
|
730
|
-
getById(
|
|
731
|
-
|
|
732
|
-
if (cache)
|
|
829
|
+
getById(id, branch) {
|
|
830
|
+
const cache = this.idMap[id];
|
|
831
|
+
if (cache && LeafHelper.hasParent(cache, branch || this.target))
|
|
733
832
|
return cache;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
let find;
|
|
737
|
-
this.loopFind(branch, (leaf) => {
|
|
738
|
-
if (leaf.id === name) {
|
|
739
|
-
find = leaf;
|
|
740
|
-
this.idList[name] = find;
|
|
741
|
-
return true;
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
return false;
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
return find;
|
|
748
|
-
}
|
|
749
|
-
getByClassName(name, branch) {
|
|
750
|
-
if (!branch)
|
|
751
|
-
branch = this.target;
|
|
752
|
-
let find = [];
|
|
753
|
-
this.loopFind(branch, (leaf) => {
|
|
754
|
-
if (leaf.className === name)
|
|
755
|
-
find.push(leaf);
|
|
756
|
-
return false;
|
|
757
|
-
});
|
|
758
|
-
return find;
|
|
759
|
-
}
|
|
760
|
-
getByTagName(name, branch) {
|
|
761
|
-
if (!branch)
|
|
762
|
-
branch = this.target;
|
|
763
|
-
let find = [];
|
|
764
|
-
this.loopFind(branch, (leaf) => {
|
|
765
|
-
if (leaf.__tag === name)
|
|
766
|
-
find.push(leaf);
|
|
767
|
-
return false;
|
|
768
|
-
});
|
|
769
|
-
return find;
|
|
833
|
+
this.eachFind(this.toChildren(branch), this.methods.id, null, id);
|
|
834
|
+
return this.findLeaf;
|
|
770
835
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
836
|
+
getByClassName(className, branch) {
|
|
837
|
+
return this.getByMethod(this.methods.className, branch, false, className);
|
|
838
|
+
}
|
|
839
|
+
getByTag(tag, branch) {
|
|
840
|
+
return this.getByMethod(this.methods.tag, branch, false, tag);
|
|
841
|
+
}
|
|
842
|
+
getByMethod(method, branch, one, options) {
|
|
843
|
+
const list = one ? null : [];
|
|
844
|
+
this.eachFind(this.toChildren(branch), method, list, options);
|
|
845
|
+
return list || this.findLeaf;
|
|
846
|
+
}
|
|
847
|
+
eachFind(children, method, list, options) {
|
|
848
|
+
let child, result;
|
|
775
849
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
850
|
+
child = children[i];
|
|
851
|
+
result = method(child, options);
|
|
852
|
+
if (result === Yes || result === YesAndSkip) {
|
|
853
|
+
if (list) {
|
|
854
|
+
list.push(child);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
this.findLeaf = child;
|
|
858
|
+
return;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
if (child.isBranch && result < NoAndSkip)
|
|
862
|
+
this.eachFind(child.children, method, list, options);
|
|
781
863
|
}
|
|
782
864
|
}
|
|
865
|
+
toChildren(branch) {
|
|
866
|
+
this.findLeaf = null;
|
|
867
|
+
return [branch || this.target];
|
|
868
|
+
}
|
|
783
869
|
__onRemoveChild(event) {
|
|
784
|
-
const
|
|
785
|
-
if (this.
|
|
786
|
-
this.
|
|
787
|
-
if (this.
|
|
788
|
-
this.
|
|
870
|
+
const { id, innerId } = event.child;
|
|
871
|
+
if (this.idMap[id])
|
|
872
|
+
delete this.idMap[id];
|
|
873
|
+
if (this.innerIdMap[innerId])
|
|
874
|
+
delete this.innerIdMap[innerId];
|
|
875
|
+
}
|
|
876
|
+
__checkIdChange(event) {
|
|
877
|
+
if (event.attrName === 'id') {
|
|
878
|
+
const id = event.oldValue;
|
|
879
|
+
if (this.idMap[id])
|
|
880
|
+
delete this.idMap[id];
|
|
881
|
+
}
|
|
789
882
|
}
|
|
790
883
|
__listenEvents() {
|
|
791
884
|
this.__eventIds = [
|
|
792
|
-
this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this)
|
|
885
|
+
this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
|
|
886
|
+
this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
|
|
793
887
|
];
|
|
794
888
|
}
|
|
795
889
|
__removeListenEvents() {
|
|
@@ -799,11 +893,10 @@ class Selector {
|
|
|
799
893
|
destroy() {
|
|
800
894
|
if (this.__eventIds.length) {
|
|
801
895
|
this.__removeListenEvents();
|
|
802
|
-
this.
|
|
803
|
-
this.
|
|
804
|
-
this.
|
|
805
|
-
this.
|
|
806
|
-
this.tagNameList = {};
|
|
896
|
+
this.picker.destroy();
|
|
897
|
+
this.findLeaf = null;
|
|
898
|
+
this.innerIdMap = {};
|
|
899
|
+
this.idMap = {};
|
|
807
900
|
}
|
|
808
901
|
}
|
|
809
902
|
}
|
|
@@ -816,120 +909,333 @@ Object.assign(Creator, {
|
|
|
816
909
|
});
|
|
817
910
|
Platform.layout = Layouter.fullLayout;
|
|
818
911
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
init() {
|
|
822
|
-
this.__createView();
|
|
823
|
-
this.__createContext();
|
|
824
|
-
this.resize(this.config);
|
|
825
|
-
}
|
|
826
|
-
__createView() {
|
|
827
|
-
this.view = Platform.origin.createCanvas(1, 1);
|
|
828
|
-
}
|
|
829
|
-
updateViewSize() {
|
|
830
|
-
const { width, height, pixelRatio } = this;
|
|
831
|
-
this.view.width = width * pixelRatio;
|
|
832
|
-
this.view.height = height * pixelRatio;
|
|
833
|
-
this.clientBounds = this.bounds;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
canvasPatch(OffscreenCanvasRenderingContext2D.prototype);
|
|
838
|
-
canvasPatch(Path2D.prototype);
|
|
912
|
+
const PaintImage = {};
|
|
913
|
+
const PaintGradient = {};
|
|
839
914
|
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
return new Promise((resolve, reject) => {
|
|
852
|
-
canvas.convertToBlob({ type: mineType(type), quality }).then((blob) => {
|
|
853
|
-
var reader = new FileReader();
|
|
854
|
-
reader.onload = (e) => resolve(e.target.result);
|
|
855
|
-
reader.onerror = (e) => reject(e);
|
|
856
|
-
reader.readAsDataURL(blob);
|
|
857
|
-
}).catch((e) => {
|
|
858
|
-
reject(e);
|
|
859
|
-
});
|
|
860
|
-
});
|
|
861
|
-
},
|
|
862
|
-
canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({ type: mineType(type), quality }),
|
|
863
|
-
canvasSaveAs: (_canvas, _filename, _quality) => new Promise((resolve) => resolve()),
|
|
864
|
-
loadImage(src) {
|
|
865
|
-
return new Promise((resolve, reject) => {
|
|
866
|
-
if (!src.startsWith('data:') && Platform.imageSuffix)
|
|
867
|
-
src += (src.includes("?") ? "&" : "?") + Platform.imageSuffix;
|
|
868
|
-
let req = new XMLHttpRequest();
|
|
869
|
-
req.open('GET', src, true);
|
|
870
|
-
req.responseType = "blob";
|
|
871
|
-
req.onload = () => {
|
|
872
|
-
createImageBitmap(req.response).then(img => {
|
|
873
|
-
resolve(img);
|
|
874
|
-
}).catch(e => {
|
|
875
|
-
reject(e);
|
|
876
|
-
});
|
|
877
|
-
};
|
|
878
|
-
req.onerror = (e) => reject(e);
|
|
879
|
-
req.send();
|
|
915
|
+
function fillText(ui, canvas) {
|
|
916
|
+
let row;
|
|
917
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
918
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
919
|
+
row = rows[i];
|
|
920
|
+
if (row.text) {
|
|
921
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
922
|
+
}
|
|
923
|
+
else if (row.data) {
|
|
924
|
+
row.data.forEach(charData => {
|
|
925
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
880
926
|
});
|
|
881
927
|
}
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
}
|
|
886
|
-
Platform.name = 'web';
|
|
887
|
-
Platform.isWorker = true;
|
|
888
|
-
Platform.requestRender = function (render) { requestAnimationFrame(render); };
|
|
889
|
-
Platform.devicePixelRatio = 1;
|
|
890
|
-
Platform.realtimeLayout = true;
|
|
891
|
-
const { userAgent } = navigator;
|
|
892
|
-
if (userAgent.indexOf("Firefox") > -1) {
|
|
893
|
-
Platform.conicGradientRotate90 = true;
|
|
894
|
-
Platform.intWheelDeltaY = true;
|
|
895
|
-
}
|
|
896
|
-
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
897
|
-
Platform.fullImageShadow = true;
|
|
898
|
-
}
|
|
899
|
-
if (userAgent.indexOf('Windows') > -1) {
|
|
900
|
-
Platform.os = 'Windows';
|
|
901
|
-
Platform.intWheelDeltaY = true;
|
|
928
|
+
if (decorationY)
|
|
929
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
930
|
+
}
|
|
902
931
|
}
|
|
903
|
-
|
|
904
|
-
|
|
932
|
+
|
|
933
|
+
function fill(fill, ui, canvas) {
|
|
934
|
+
canvas.fillStyle = fill;
|
|
935
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
905
936
|
}
|
|
906
|
-
|
|
907
|
-
|
|
937
|
+
function fills(fills, ui, canvas) {
|
|
938
|
+
let item;
|
|
939
|
+
const { windingRule, __font } = ui.__;
|
|
940
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
941
|
+
item = fills[i];
|
|
942
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
943
|
+
continue;
|
|
944
|
+
if (item.style) {
|
|
945
|
+
canvas.fillStyle = item.style;
|
|
946
|
+
if (item.transform) {
|
|
947
|
+
canvas.save();
|
|
948
|
+
canvas.transform(item.transform);
|
|
949
|
+
if (item.blendMode)
|
|
950
|
+
canvas.blendMode = item.blendMode;
|
|
951
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
952
|
+
canvas.restore();
|
|
953
|
+
}
|
|
954
|
+
else {
|
|
955
|
+
if (item.blendMode) {
|
|
956
|
+
canvas.saveBlendMode(item.blendMode);
|
|
957
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
958
|
+
canvas.restoreBlendMode();
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
908
966
|
}
|
|
909
967
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
968
|
+
function strokeText(stroke, ui, canvas) {
|
|
969
|
+
const { strokeAlign } = ui.__;
|
|
970
|
+
const isStrokes = typeof stroke !== 'string';
|
|
971
|
+
switch (strokeAlign) {
|
|
972
|
+
case 'center':
|
|
973
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
974
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
975
|
+
break;
|
|
976
|
+
case 'inside':
|
|
977
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
978
|
+
break;
|
|
979
|
+
case 'outside':
|
|
980
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
981
|
+
break;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
985
|
+
const { __strokeWidth, __font } = ui.__;
|
|
986
|
+
const out = canvas.getSameCanvas(true, true);
|
|
987
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
988
|
+
out.font = __font;
|
|
989
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
990
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
991
|
+
fillText(ui, out);
|
|
992
|
+
out.blendMode = 'normal';
|
|
993
|
+
if (ui.__worldFlipped) {
|
|
994
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
995
|
+
}
|
|
996
|
+
else {
|
|
997
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
998
|
+
}
|
|
999
|
+
out.recycle(ui.__nowWorld);
|
|
1000
|
+
}
|
|
1001
|
+
function drawTextStroke(ui, canvas) {
|
|
1002
|
+
let row;
|
|
1003
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1004
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1005
|
+
row = rows[i];
|
|
1006
|
+
if (row.text) {
|
|
1007
|
+
canvas.strokeText(row.text, row.x, row.y);
|
|
1008
|
+
}
|
|
1009
|
+
else if (row.data) {
|
|
1010
|
+
row.data.forEach(charData => {
|
|
1011
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
if (decorationY)
|
|
1015
|
+
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1019
|
+
let item;
|
|
1020
|
+
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1021
|
+
item = strokes[i];
|
|
1022
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1023
|
+
continue;
|
|
1024
|
+
if (item.style) {
|
|
1025
|
+
canvas.strokeStyle = item.style;
|
|
1026
|
+
if (item.blendMode) {
|
|
1027
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1028
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1029
|
+
canvas.restoreBlendMode();
|
|
1030
|
+
}
|
|
1031
|
+
else {
|
|
1032
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
function stroke(stroke, ui, canvas) {
|
|
1039
|
+
const options = ui.__;
|
|
1040
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1041
|
+
if (!__strokeWidth)
|
|
1042
|
+
return;
|
|
1043
|
+
if (__font) {
|
|
1044
|
+
strokeText(stroke, ui, canvas);
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
switch (strokeAlign) {
|
|
1048
|
+
case 'center':
|
|
1049
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1050
|
+
canvas.stroke();
|
|
1051
|
+
break;
|
|
1052
|
+
case 'inside':
|
|
1053
|
+
canvas.save();
|
|
1054
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1055
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1056
|
+
canvas.stroke();
|
|
1057
|
+
canvas.restore();
|
|
1058
|
+
break;
|
|
1059
|
+
case 'outside':
|
|
1060
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1061
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1062
|
+
ui.__drawRenderPath(out);
|
|
1063
|
+
out.stroke();
|
|
1064
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1065
|
+
out.clearWorld(ui.__layout.renderBounds);
|
|
1066
|
+
if (ui.__worldFlipped) {
|
|
1067
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1068
|
+
}
|
|
1069
|
+
else {
|
|
1070
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1071
|
+
}
|
|
1072
|
+
out.recycle(ui.__nowWorld);
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function strokes(strokes, ui, canvas) {
|
|
1078
|
+
const options = ui.__;
|
|
1079
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1080
|
+
if (!__strokeWidth)
|
|
1081
|
+
return;
|
|
1082
|
+
if (__font) {
|
|
1083
|
+
strokeText(strokes, ui, canvas);
|
|
1084
|
+
}
|
|
1085
|
+
else {
|
|
1086
|
+
switch (strokeAlign) {
|
|
1087
|
+
case 'center':
|
|
1088
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1089
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1090
|
+
break;
|
|
1091
|
+
case 'inside':
|
|
1092
|
+
canvas.save();
|
|
1093
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1094
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1095
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1096
|
+
canvas.restore();
|
|
1097
|
+
break;
|
|
1098
|
+
case 'outside':
|
|
1099
|
+
const { renderBounds } = ui.__layout;
|
|
1100
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1101
|
+
ui.__drawRenderPath(out);
|
|
1102
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1103
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1104
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1105
|
+
out.clearWorld(renderBounds);
|
|
1106
|
+
if (ui.__worldFlipped) {
|
|
1107
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1108
|
+
}
|
|
1109
|
+
else {
|
|
1110
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1111
|
+
}
|
|
1112
|
+
out.recycle(ui.__nowWorld);
|
|
1113
|
+
break;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1119
|
+
function shape(ui, current, options) {
|
|
1120
|
+
const canvas = current.getSameCanvas();
|
|
1121
|
+
const nowWorld = ui.__nowWorld;
|
|
1122
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1123
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1124
|
+
if (scaleX < 0)
|
|
1125
|
+
scaleX = -scaleX;
|
|
1126
|
+
if (scaleY < 0)
|
|
1127
|
+
scaleY = -scaleY;
|
|
1128
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1129
|
+
worldCanvas = canvas;
|
|
1130
|
+
bounds = shapeBounds = nowWorld;
|
|
1131
|
+
}
|
|
1132
|
+
else {
|
|
1133
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1134
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, nowWorld);
|
|
1135
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1136
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1137
|
+
if (fitMatrix.a < 1) {
|
|
1138
|
+
worldCanvas = current.getSameCanvas();
|
|
1139
|
+
ui.__renderShape(worldCanvas, options);
|
|
1140
|
+
scaleX *= fitScaleX;
|
|
1141
|
+
scaleY *= fitScaleY;
|
|
1142
|
+
}
|
|
1143
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1144
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1145
|
+
if (options.matrix) {
|
|
1146
|
+
const { matrix } = options;
|
|
1147
|
+
fitMatrix.multiply(matrix);
|
|
1148
|
+
fitScaleX *= matrix.scaleX;
|
|
1149
|
+
fitScaleY *= matrix.scaleY;
|
|
1150
|
+
}
|
|
1151
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1152
|
+
}
|
|
1153
|
+
ui.__renderShape(canvas, options);
|
|
1154
|
+
return {
|
|
1155
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1156
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
let recycleMap;
|
|
1161
|
+
function compute(attrName, ui) {
|
|
1162
|
+
const data = ui.__, leafPaints = [];
|
|
1163
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1164
|
+
if (!(paints instanceof Array))
|
|
1165
|
+
paints = [paints];
|
|
1166
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1167
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1168
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1169
|
+
if (item)
|
|
1170
|
+
leafPaints.push(item);
|
|
1171
|
+
}
|
|
1172
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1173
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1174
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1175
|
+
if (attrName === 'fill') {
|
|
1176
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1177
|
+
}
|
|
1178
|
+
else {
|
|
1179
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1183
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1184
|
+
return undefined;
|
|
1185
|
+
const { boxBounds } = ui.__layout;
|
|
1186
|
+
switch (paint.type) {
|
|
1187
|
+
case 'solid':
|
|
1188
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1189
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1190
|
+
case 'image':
|
|
1191
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1192
|
+
case 'linear':
|
|
1193
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1194
|
+
case 'radial':
|
|
1195
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1196
|
+
case 'angular':
|
|
1197
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1198
|
+
default:
|
|
1199
|
+
return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
const PaintModule = {
|
|
1204
|
+
compute,
|
|
1205
|
+
fill,
|
|
1206
|
+
fills,
|
|
1207
|
+
fillText,
|
|
1208
|
+
stroke,
|
|
1209
|
+
strokes,
|
|
1210
|
+
strokeText,
|
|
1211
|
+
drawTextStroke,
|
|
1212
|
+
shape
|
|
1213
|
+
};
|
|
1214
|
+
|
|
1215
|
+
let origin = {};
|
|
1216
|
+
const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1217
|
+
function fillOrFitMode(data, mode, box, width, height, rotation) {
|
|
1218
|
+
const transform = get$4();
|
|
1219
|
+
const swap = rotation && rotation !== 180;
|
|
1220
|
+
const sw = box.width / (swap ? height : width);
|
|
1221
|
+
const sh = box.height / (swap ? width : height);
|
|
1222
|
+
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
917
1223
|
const x = box.x + (box.width - width * scale) / 2;
|
|
918
1224
|
const y = box.y + (box.height - height * scale) / 2;
|
|
919
1225
|
translate$1(transform, x, y);
|
|
920
|
-
scaleHelper
|
|
1226
|
+
scaleHelper(transform, scale);
|
|
921
1227
|
if (rotation)
|
|
922
1228
|
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
923
1229
|
data.scaleX = data.scaleY = scale;
|
|
924
1230
|
data.transform = transform;
|
|
925
1231
|
}
|
|
926
|
-
function clipMode(data, box,
|
|
1232
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
927
1233
|
const transform = get$4();
|
|
928
1234
|
translate$1(transform, box.x, box.y);
|
|
929
|
-
if (
|
|
930
|
-
translate$1(transform,
|
|
931
|
-
if (
|
|
932
|
-
|
|
1235
|
+
if (x || y)
|
|
1236
|
+
translate$1(transform, x, y);
|
|
1237
|
+
if (scaleX) {
|
|
1238
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
933
1239
|
data.scaleX = transform.a;
|
|
934
1240
|
data.scaleY = transform.d;
|
|
935
1241
|
}
|
|
@@ -937,7 +1243,7 @@ function clipMode(data, box, offset, scale, rotation) {
|
|
|
937
1243
|
rotate(transform, rotation);
|
|
938
1244
|
data.transform = transform;
|
|
939
1245
|
}
|
|
940
|
-
function repeatMode(data, box, width, height,
|
|
1246
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
|
|
941
1247
|
const transform = get$4();
|
|
942
1248
|
if (rotation) {
|
|
943
1249
|
rotate(transform, rotation);
|
|
@@ -953,10 +1259,15 @@ function repeatMode(data, box, width, height, scale, rotation) {
|
|
|
953
1259
|
break;
|
|
954
1260
|
}
|
|
955
1261
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1262
|
+
origin.x = box.x;
|
|
1263
|
+
origin.y = box.y;
|
|
1264
|
+
if (x || y)
|
|
1265
|
+
origin.x += x, origin.y += y;
|
|
1266
|
+
translate$1(transform, origin.x, origin.y);
|
|
1267
|
+
if (scaleX) {
|
|
1268
|
+
scaleOfOuter$2(transform, origin, scaleX, scaleY);
|
|
1269
|
+
data.scaleX = scaleX;
|
|
1270
|
+
data.scaleY = scaleY;
|
|
960
1271
|
}
|
|
961
1272
|
data.transform = transform;
|
|
962
1273
|
}
|
|
@@ -964,11 +1275,22 @@ function repeatMode(data, box, width, height, scale, rotation) {
|
|
|
964
1275
|
const { get: get$3, translate } = MatrixHelper;
|
|
965
1276
|
function createData(leafPaint, image, paint, box) {
|
|
966
1277
|
let { width, height } = image;
|
|
967
|
-
const { opacity, mode, offset, scale, rotation, blendMode } = paint;
|
|
1278
|
+
const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
|
|
968
1279
|
const sameBox = box.width === width && box.height === height;
|
|
969
1280
|
if (blendMode)
|
|
970
1281
|
leafPaint.blendMode = blendMode;
|
|
971
1282
|
const data = leafPaint.data = { mode };
|
|
1283
|
+
let x, y, scaleX, scaleY;
|
|
1284
|
+
if (offset)
|
|
1285
|
+
x = offset.x, y = offset.y;
|
|
1286
|
+
if (size) {
|
|
1287
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1288
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1289
|
+
}
|
|
1290
|
+
else if (scale) {
|
|
1291
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1292
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1293
|
+
}
|
|
972
1294
|
switch (mode) {
|
|
973
1295
|
case 'strench':
|
|
974
1296
|
if (!sameBox)
|
|
@@ -979,12 +1301,14 @@ function createData(leafPaint, image, paint, box) {
|
|
|
979
1301
|
}
|
|
980
1302
|
break;
|
|
981
1303
|
case 'clip':
|
|
982
|
-
if (offset ||
|
|
983
|
-
clipMode(data, box,
|
|
1304
|
+
if (offset || scaleX || rotation)
|
|
1305
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
984
1306
|
break;
|
|
985
1307
|
case 'repeat':
|
|
986
|
-
if (!sameBox ||
|
|
987
|
-
repeatMode(data, box, width, height,
|
|
1308
|
+
if (!sameBox || scaleX || rotation)
|
|
1309
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1310
|
+
if (!repeat)
|
|
1311
|
+
data.repeat = 'repeat';
|
|
988
1312
|
break;
|
|
989
1313
|
case 'fit':
|
|
990
1314
|
case 'cover':
|
|
@@ -996,111 +1320,101 @@ function createData(leafPaint, image, paint, box) {
|
|
|
996
1320
|
data.height = height;
|
|
997
1321
|
if (opacity)
|
|
998
1322
|
data.opacity = opacity;
|
|
1323
|
+
if (repeat)
|
|
1324
|
+
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
999
1325
|
}
|
|
1000
1326
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1327
|
+
let cache, box = new Bounds();
|
|
1328
|
+
const { isSame } = BoundsHelper;
|
|
1329
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1330
|
+
let leafPaint, event;
|
|
1331
|
+
const image = ImageManager.get(paint);
|
|
1332
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1333
|
+
leafPaint = cache.leafPaint;
|
|
1334
|
+
}
|
|
1335
|
+
else {
|
|
1336
|
+
leafPaint = { type: paint.type };
|
|
1337
|
+
leafPaint.image = image;
|
|
1338
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1339
|
+
}
|
|
1340
|
+
if (firstUse || image.loading)
|
|
1341
|
+
event = { image, attrName, attrValue: paint };
|
|
1005
1342
|
if (image.ready) {
|
|
1006
|
-
|
|
1007
|
-
createData(leafPaint, image, attrValue, box);
|
|
1343
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1008
1344
|
if (firstUse) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1345
|
+
onLoad(ui, event);
|
|
1346
|
+
onLoadSuccess(ui, event);
|
|
1011
1347
|
}
|
|
1012
1348
|
}
|
|
1013
1349
|
else if (image.error) {
|
|
1014
|
-
if (firstUse)
|
|
1015
|
-
ui.
|
|
1016
|
-
event.error = image.error;
|
|
1017
|
-
emit(ImageEvent.ERROR, event);
|
|
1018
|
-
}
|
|
1350
|
+
if (firstUse)
|
|
1351
|
+
onLoadError(ui, event, image.error);
|
|
1019
1352
|
}
|
|
1020
1353
|
else {
|
|
1021
1354
|
if (firstUse)
|
|
1022
|
-
|
|
1355
|
+
onLoad(ui, event);
|
|
1023
1356
|
leafPaint.loadId = image.load(() => {
|
|
1024
1357
|
if (!ui.destroyed) {
|
|
1025
|
-
if (
|
|
1026
|
-
createData(leafPaint, image, attrValue, box);
|
|
1358
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds))
|
|
1027
1359
|
ui.forceUpdate('surface');
|
|
1028
|
-
|
|
1029
|
-
emit(ImageEvent.LOADED, event);
|
|
1360
|
+
onLoadSuccess(ui, event);
|
|
1030
1361
|
}
|
|
1362
|
+
leafPaint.loadId = null;
|
|
1031
1363
|
}, (error) => {
|
|
1032
|
-
ui
|
|
1033
|
-
|
|
1034
|
-
emit(ImageEvent.ERROR, event);
|
|
1364
|
+
onLoadError(ui, event, error);
|
|
1365
|
+
leafPaint.loadId = null;
|
|
1035
1366
|
});
|
|
1036
1367
|
}
|
|
1037
1368
|
return leafPaint;
|
|
1038
1369
|
}
|
|
1039
|
-
function
|
|
1370
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1040
1371
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
if (
|
|
1372
|
+
const data = ui.__;
|
|
1373
|
+
data.__naturalWidth = image.width;
|
|
1374
|
+
data.__naturalHeight = image.height;
|
|
1375
|
+
if (data.__autoWidth || data.__autoHeight) {
|
|
1045
1376
|
ui.forceUpdate('width');
|
|
1377
|
+
if (ui.__proxyData) {
|
|
1378
|
+
ui.setProxyAttr('width', data.width);
|
|
1379
|
+
ui.setProxyAttr('height', data.height);
|
|
1380
|
+
}
|
|
1046
1381
|
return false;
|
|
1047
1382
|
}
|
|
1048
1383
|
}
|
|
1384
|
+
if (!leafPaint.data)
|
|
1385
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1049
1386
|
return true;
|
|
1050
1387
|
}
|
|
1051
|
-
function
|
|
1052
|
-
|
|
1053
|
-
|
|
1388
|
+
function onLoad(ui, event) {
|
|
1389
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1390
|
+
}
|
|
1391
|
+
function onLoadSuccess(ui, event) {
|
|
1392
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1393
|
+
}
|
|
1394
|
+
function onLoadError(ui, event, error) {
|
|
1395
|
+
event.error = error;
|
|
1396
|
+
ui.forceUpdate('surface');
|
|
1397
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1398
|
+
}
|
|
1399
|
+
function emit(ui, type, data) {
|
|
1400
|
+
if (ui.hasEvent(type))
|
|
1401
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1054
1402
|
}
|
|
1055
1403
|
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1060
|
-
purpose with or without fee is hereby granted.
|
|
1061
|
-
|
|
1062
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1063
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1064
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1065
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1066
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1067
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1068
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1069
|
-
***************************************************************************** */
|
|
1070
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1074
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1075
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1076
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1077
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1078
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1079
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1080
|
-
});
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1084
|
-
var e = new Error(message);
|
|
1085
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
const { get: get$2, scale: scaleHelper, copy: copy$1 } = MatrixHelper;
|
|
1404
|
+
const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
|
|
1405
|
+
const { round, abs: abs$1 } = Math;
|
|
1089
1406
|
function createPattern(ui, paint, pixelRatio) {
|
|
1090
1407
|
let { scaleX, scaleY } = ui.__world;
|
|
1091
1408
|
const id = scaleX + '-' + scaleY;
|
|
1092
1409
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
scaleY = Math.abs(scaleY);
|
|
1410
|
+
scaleX = abs$1(scaleX);
|
|
1411
|
+
scaleY = abs$1(scaleY);
|
|
1096
1412
|
const { image, data } = paint;
|
|
1097
|
-
|
|
1098
|
-
const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096);
|
|
1099
|
-
let scale, matrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data;
|
|
1413
|
+
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1100
1414
|
if (sx) {
|
|
1101
|
-
|
|
1102
|
-
copy$1(
|
|
1103
|
-
|
|
1415
|
+
imageMatrix = get$2();
|
|
1416
|
+
copy$1(imageMatrix, transform);
|
|
1417
|
+
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1104
1418
|
scaleX *= sx;
|
|
1105
1419
|
scaleY *= sy;
|
|
1106
1420
|
}
|
|
@@ -1108,38 +1422,41 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1108
1422
|
scaleY *= pixelRatio;
|
|
1109
1423
|
width *= scaleX;
|
|
1110
1424
|
height *= scaleY;
|
|
1111
|
-
|
|
1112
|
-
|
|
1425
|
+
const size = width * height;
|
|
1426
|
+
if (!repeat) {
|
|
1427
|
+
if (size > Platform.image.maxCacheSize)
|
|
1428
|
+
return false;
|
|
1429
|
+
}
|
|
1430
|
+
let maxSize = Platform.image.maxPatternSize;
|
|
1431
|
+
if (!image.isSVG) {
|
|
1432
|
+
const imageSize = image.width * image.height;
|
|
1433
|
+
if (maxSize > imageSize)
|
|
1434
|
+
maxSize = imageSize;
|
|
1113
1435
|
}
|
|
1114
|
-
if (
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1436
|
+
if (size > maxSize)
|
|
1437
|
+
imageScale = Math.sqrt(size / maxSize);
|
|
1438
|
+
if (imageScale) {
|
|
1439
|
+
scaleX /= imageScale;
|
|
1440
|
+
scaleY /= imageScale;
|
|
1441
|
+
width /= imageScale;
|
|
1442
|
+
height /= imageScale;
|
|
1119
1443
|
}
|
|
1120
1444
|
if (sx) {
|
|
1121
1445
|
scaleX /= sx;
|
|
1122
1446
|
scaleY /= sy;
|
|
1123
1447
|
}
|
|
1124
1448
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1125
|
-
if (!
|
|
1126
|
-
|
|
1449
|
+
if (!imageMatrix) {
|
|
1450
|
+
imageMatrix = get$2();
|
|
1127
1451
|
if (transform)
|
|
1128
|
-
copy$1(
|
|
1452
|
+
copy$1(imageMatrix, transform);
|
|
1129
1453
|
}
|
|
1130
|
-
|
|
1454
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1131
1455
|
}
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (matrix)
|
|
1137
|
-
style.setTransform ? style.setTransform(matrix) : paint.transform = matrix;
|
|
1138
|
-
}
|
|
1139
|
-
catch (_a) {
|
|
1140
|
-
paint.transform = matrix;
|
|
1141
|
-
}
|
|
1142
|
-
paint.style = style;
|
|
1456
|
+
const canvas = image.getCanvas(width < 1 ? 1 : round(width), height < 1 ? 1 : round(height), opacity);
|
|
1457
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1458
|
+
paint.style = pattern;
|
|
1459
|
+
paint.patternId = id;
|
|
1143
1460
|
return true;
|
|
1144
1461
|
}
|
|
1145
1462
|
else {
|
|
@@ -1147,311 +1464,130 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1147
1464
|
}
|
|
1148
1465
|
}
|
|
1149
1466
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
|
|
1188
|
-
ui.forceUpdate('surface');
|
|
1189
|
-
}), 300);
|
|
1190
|
-
}
|
|
1191
|
-
return false;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
function recycleImage(data, attrName) {
|
|
1197
|
-
const paints = (attrName === 'fill' ? data._fill : data._stroke);
|
|
1198
|
-
if (paints instanceof Array) {
|
|
1199
|
-
let image, recycleMap, input, url;
|
|
1200
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1201
|
-
image = paints[i].image;
|
|
1202
|
-
url = image && image.url;
|
|
1203
|
-
if (url) {
|
|
1204
|
-
if (!recycleMap)
|
|
1205
|
-
recycleMap = {};
|
|
1206
|
-
recycleMap[url] = true;
|
|
1207
|
-
ImageManager.recycle(image);
|
|
1208
|
-
if (image.loading) {
|
|
1209
|
-
if (!input) {
|
|
1210
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1211
|
-
if (!(input instanceof Array))
|
|
1212
|
-
input = [input];
|
|
1213
|
-
}
|
|
1214
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
return recycleMap;
|
|
1219
|
-
}
|
|
1220
|
-
return null;
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
function fillText(ui, canvas) {
|
|
1224
|
-
let row;
|
|
1225
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1226
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1227
|
-
row = rows[i];
|
|
1228
|
-
if (row.text) {
|
|
1229
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1230
|
-
}
|
|
1231
|
-
else if (row.data) {
|
|
1232
|
-
row.data.forEach(charData => {
|
|
1233
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
if (decorationY)
|
|
1237
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
function fill(ui, canvas, fill) {
|
|
1242
|
-
canvas.fillStyle = fill;
|
|
1243
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1244
|
-
}
|
|
1245
|
-
function fills(ui, canvas, fills) {
|
|
1246
|
-
let item;
|
|
1247
|
-
const { windingRule, __font } = ui.__;
|
|
1248
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1249
|
-
item = fills[i];
|
|
1250
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1251
|
-
continue;
|
|
1252
|
-
if (item.style) {
|
|
1253
|
-
canvas.fillStyle = item.style;
|
|
1254
|
-
if (item.transform) {
|
|
1255
|
-
canvas.save();
|
|
1256
|
-
canvas.transform(item.transform);
|
|
1257
|
-
if (item.blendMode)
|
|
1258
|
-
canvas.blendMode = item.blendMode;
|
|
1259
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1260
|
-
canvas.restore();
|
|
1261
|
-
}
|
|
1262
|
-
else {
|
|
1263
|
-
if (item.blendMode) {
|
|
1264
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1265
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1266
|
-
canvas.restoreBlendMode();
|
|
1267
|
-
}
|
|
1268
|
-
else {
|
|
1269
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
function strokeText(ui, canvas, stroke) {
|
|
1277
|
-
const { strokeAlign } = ui.__;
|
|
1278
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1279
|
-
switch (strokeAlign) {
|
|
1280
|
-
case 'center':
|
|
1281
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1282
|
-
isStrokes ? drawStrokesStyle(ui, stroke, canvas, true) : drawTextStroke(ui, canvas);
|
|
1283
|
-
break;
|
|
1284
|
-
case 'inside':
|
|
1285
|
-
drawAlignStroke(ui, canvas, stroke, 'inside', isStrokes);
|
|
1286
|
-
break;
|
|
1287
|
-
case 'outside':
|
|
1288
|
-
drawAlignStroke(ui, canvas, stroke, 'outside', isStrokes);
|
|
1289
|
-
break;
|
|
1467
|
+
/******************************************************************************
|
|
1468
|
+
Copyright (c) Microsoft Corporation.
|
|
1469
|
+
|
|
1470
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
1471
|
+
purpose with or without fee is hereby granted.
|
|
1472
|
+
|
|
1473
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1474
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1475
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1476
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1477
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1478
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1479
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
1480
|
+
***************************************************************************** */
|
|
1481
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1482
|
+
|
|
1483
|
+
|
|
1484
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1485
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1486
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1487
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1488
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1489
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1490
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1491
|
+
});
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1495
|
+
var e = new Error(message);
|
|
1496
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1497
|
+
};
|
|
1498
|
+
|
|
1499
|
+
const { abs } = Math;
|
|
1500
|
+
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1501
|
+
const { scaleX, scaleY } = ui.__world;
|
|
1502
|
+
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1503
|
+
return false;
|
|
1290
1504
|
}
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1308
|
-
row = rows[i];
|
|
1309
|
-
if (row.text) {
|
|
1310
|
-
canvas.strokeText(row.text, row.x, row.y);
|
|
1505
|
+
else {
|
|
1506
|
+
const { data } = paint;
|
|
1507
|
+
if (allowPaint) {
|
|
1508
|
+
if (!data.repeat) {
|
|
1509
|
+
let { width, height } = data;
|
|
1510
|
+
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1511
|
+
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1512
|
+
if (data.scaleX) {
|
|
1513
|
+
width *= data.scaleX;
|
|
1514
|
+
height *= data.scaleY;
|
|
1515
|
+
}
|
|
1516
|
+
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
1517
|
+
}
|
|
1518
|
+
else {
|
|
1519
|
+
allowPaint = false;
|
|
1520
|
+
}
|
|
1311
1521
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1522
|
+
if (allowPaint) {
|
|
1523
|
+
canvas.save();
|
|
1524
|
+
canvas.clip();
|
|
1525
|
+
if (paint.blendMode)
|
|
1526
|
+
canvas.blendMode = paint.blendMode;
|
|
1527
|
+
if (data.opacity)
|
|
1528
|
+
canvas.opacity *= data.opacity;
|
|
1529
|
+
if (data.transform)
|
|
1530
|
+
canvas.transform(data.transform);
|
|
1531
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1532
|
+
canvas.restore();
|
|
1533
|
+
return true;
|
|
1316
1534
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
}
|
|
1321
|
-
function drawStrokesStyle(ui, strokes, canvas, isText) {
|
|
1322
|
-
let item;
|
|
1323
|
-
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1324
|
-
item = strokes[i];
|
|
1325
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1326
|
-
continue;
|
|
1327
|
-
if (item.style) {
|
|
1328
|
-
canvas.strokeStyle = item.style;
|
|
1329
|
-
if (item.blendMode) {
|
|
1330
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1331
|
-
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1332
|
-
canvas.restoreBlendMode();
|
|
1535
|
+
else {
|
|
1536
|
+
if (!paint.style || Export.running) {
|
|
1537
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1333
1538
|
}
|
|
1334
1539
|
else {
|
|
1335
|
-
|
|
1540
|
+
if (!paint.patternTask) {
|
|
1541
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1542
|
+
paint.patternTask = null;
|
|
1543
|
+
if (canvas.bounds.hit(ui.__world))
|
|
1544
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1545
|
+
ui.forceUpdate('surface');
|
|
1546
|
+
}), 300);
|
|
1547
|
+
}
|
|
1336
1548
|
}
|
|
1549
|
+
return false;
|
|
1337
1550
|
}
|
|
1338
1551
|
}
|
|
1339
1552
|
}
|
|
1340
1553
|
|
|
1341
|
-
function
|
|
1342
|
-
const
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
case 'outside':
|
|
1363
|
-
const out = canvas.getSameCanvas(true);
|
|
1364
|
-
out.setStroke(stroke, strokeWidth * 2, ui.__);
|
|
1365
|
-
ui.__drawRenderPath(out);
|
|
1366
|
-
out.stroke();
|
|
1367
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1368
|
-
out.clearWorld(ui.__layout.renderBounds);
|
|
1369
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1370
|
-
out.recycle();
|
|
1371
|
-
break;
|
|
1372
|
-
}
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
function strokes(ui, canvas, strokes) {
|
|
1376
|
-
const options = ui.__;
|
|
1377
|
-
const { strokeWidth, strokeAlign, __font } = options;
|
|
1378
|
-
if (!strokeWidth)
|
|
1379
|
-
return;
|
|
1380
|
-
if (__font) {
|
|
1381
|
-
strokeText(ui, canvas, strokes);
|
|
1382
|
-
}
|
|
1383
|
-
else {
|
|
1384
|
-
switch (strokeAlign) {
|
|
1385
|
-
case 'center':
|
|
1386
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1387
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1388
|
-
break;
|
|
1389
|
-
case 'inside':
|
|
1390
|
-
canvas.save();
|
|
1391
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1392
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1393
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1394
|
-
canvas.restore();
|
|
1395
|
-
break;
|
|
1396
|
-
case 'outside':
|
|
1397
|
-
const { renderBounds } = ui.__layout;
|
|
1398
|
-
const out = canvas.getSameCanvas(true);
|
|
1399
|
-
ui.__drawRenderPath(out);
|
|
1400
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1401
|
-
drawStrokesStyle(ui, strokes, out);
|
|
1402
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1403
|
-
out.clearWorld(renderBounds);
|
|
1404
|
-
canvas.copyWorldToInner(out, ui.__world, renderBounds);
|
|
1405
|
-
out.recycle();
|
|
1406
|
-
break;
|
|
1554
|
+
function recycleImage(attrName, data) {
|
|
1555
|
+
const paints = data['_' + attrName];
|
|
1556
|
+
if (paints instanceof Array) {
|
|
1557
|
+
let image, recycleMap, input, url;
|
|
1558
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1559
|
+
image = paints[i].image;
|
|
1560
|
+
url = image && image.url;
|
|
1561
|
+
if (url) {
|
|
1562
|
+
if (!recycleMap)
|
|
1563
|
+
recycleMap = {};
|
|
1564
|
+
recycleMap[url] = true;
|
|
1565
|
+
ImageManager.recycle(image);
|
|
1566
|
+
if (image.loading) {
|
|
1567
|
+
if (!input) {
|
|
1568
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1569
|
+
if (!(input instanceof Array))
|
|
1570
|
+
input = [input];
|
|
1571
|
+
}
|
|
1572
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1407
1575
|
}
|
|
1576
|
+
return recycleMap;
|
|
1408
1577
|
}
|
|
1578
|
+
return null;
|
|
1409
1579
|
}
|
|
1410
1580
|
|
|
1411
|
-
const
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
scaleY = -scaleY;
|
|
1422
|
-
if (!current.bounds.includes(__world, options.matrix)) {
|
|
1423
|
-
const { renderShapeSpread: spread } = ui.__layout;
|
|
1424
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
|
|
1425
|
-
matrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1426
|
-
if (matrix.a < 1) {
|
|
1427
|
-
worldCanvas = current.getSameCanvas();
|
|
1428
|
-
ui.__renderShape(worldCanvas, options);
|
|
1429
|
-
scaleX *= matrix.a;
|
|
1430
|
-
scaleY *= matrix.d;
|
|
1431
|
-
}
|
|
1432
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1433
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1434
|
-
if (options.matrix)
|
|
1435
|
-
matrix.multiply(options.matrix);
|
|
1436
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1437
|
-
}
|
|
1438
|
-
else {
|
|
1439
|
-
if (options.matrix) {
|
|
1440
|
-
scaleX *= options.matrix.a;
|
|
1441
|
-
scaleY *= options.matrix.d;
|
|
1442
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1443
|
-
}
|
|
1444
|
-
else {
|
|
1445
|
-
bounds = shapeBounds = __world;
|
|
1446
|
-
}
|
|
1447
|
-
worldCanvas = canvas;
|
|
1448
|
-
}
|
|
1449
|
-
ui.__renderShape(canvas, options);
|
|
1450
|
-
return {
|
|
1451
|
-
canvas, matrix, bounds,
|
|
1452
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1453
|
-
};
|
|
1454
|
-
}
|
|
1581
|
+
const PaintImageModule = {
|
|
1582
|
+
image,
|
|
1583
|
+
createData,
|
|
1584
|
+
fillOrFitMode,
|
|
1585
|
+
clipMode,
|
|
1586
|
+
repeatMode,
|
|
1587
|
+
createPattern,
|
|
1588
|
+
checkImage,
|
|
1589
|
+
recycleImage
|
|
1590
|
+
};
|
|
1455
1591
|
|
|
1456
1592
|
const defaultFrom$2 = { x: 0.5, y: 0 };
|
|
1457
1593
|
const defaultTo$2 = { x: 0.5, y: 1 };
|
|
@@ -1470,7 +1606,7 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1470
1606
|
let stop;
|
|
1471
1607
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1472
1608
|
stop = stops[i];
|
|
1473
|
-
gradient.addColorStop(stop.offset, ColorConvert
|
|
1609
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
1474
1610
|
}
|
|
1475
1611
|
}
|
|
1476
1612
|
|
|
@@ -1532,62 +1668,18 @@ function conicGradient(paint, box) {
|
|
|
1532
1668
|
return data;
|
|
1533
1669
|
}
|
|
1534
1670
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
if (!(paints instanceof Array))
|
|
1541
|
-
paints = [paints];
|
|
1542
|
-
recycleMap = recycleImage(ui.__, attrName);
|
|
1543
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1544
|
-
item = getLeafPaint(ui, paints[i], attrName);
|
|
1545
|
-
if (item)
|
|
1546
|
-
value.push(item);
|
|
1547
|
-
}
|
|
1548
|
-
ui.__['_' + attrName] = value.length ? value : undefined;
|
|
1549
|
-
}
|
|
1550
|
-
function getLeafPaint(ui, paint, attrName) {
|
|
1551
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1552
|
-
return undefined;
|
|
1553
|
-
const { boxBounds } = ui.__layout;
|
|
1554
|
-
switch (paint.type) {
|
|
1555
|
-
case 'solid':
|
|
1556
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1557
|
-
return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
|
|
1558
|
-
case 'image':
|
|
1559
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1560
|
-
case 'linear':
|
|
1561
|
-
return linearGradient(paint, boxBounds);
|
|
1562
|
-
case 'radial':
|
|
1563
|
-
return radialGradient(paint, boxBounds);
|
|
1564
|
-
case 'angular':
|
|
1565
|
-
return conicGradient(paint, boxBounds);
|
|
1566
|
-
default:
|
|
1567
|
-
return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
|
|
1571
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1572
|
-
__proto__: null,
|
|
1573
|
-
compute: compute,
|
|
1574
|
-
drawTextStroke: drawTextStroke,
|
|
1575
|
-
fill: fill,
|
|
1576
|
-
fillText: fillText,
|
|
1577
|
-
fills: fills,
|
|
1578
|
-
recycleImage: recycleImage,
|
|
1579
|
-
shape: shape,
|
|
1580
|
-
stroke: stroke,
|
|
1581
|
-
strokeText: strokeText,
|
|
1582
|
-
strokes: strokes
|
|
1583
|
-
});
|
|
1671
|
+
const PaintGradientModule = {
|
|
1672
|
+
linearGradient,
|
|
1673
|
+
radialGradient,
|
|
1674
|
+
conicGradient
|
|
1675
|
+
};
|
|
1584
1676
|
|
|
1585
1677
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
1586
1678
|
const tempBounds = {};
|
|
1587
1679
|
const offsetOutBounds$1 = {};
|
|
1588
|
-
function shadow(ui, current, shape
|
|
1680
|
+
function shadow(ui, current, shape) {
|
|
1589
1681
|
let copyBounds, spreadScale;
|
|
1590
|
-
const {
|
|
1682
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1591
1683
|
const { shadow } = ui.__;
|
|
1592
1684
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1593
1685
|
const other = current.getSameCanvas();
|
|
@@ -1602,21 +1694,21 @@ function shadow(ui, current, shape, _options) {
|
|
|
1602
1694
|
other.restore();
|
|
1603
1695
|
other.save();
|
|
1604
1696
|
if (worldCanvas) {
|
|
1605
|
-
other.copyWorld(other, bounds,
|
|
1606
|
-
copyBounds =
|
|
1697
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1698
|
+
copyBounds = nowWorld;
|
|
1607
1699
|
}
|
|
1608
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1700
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1609
1701
|
}
|
|
1610
|
-
if (ui.
|
|
1611
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1702
|
+
if (ui.__worldFlipped) {
|
|
1703
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1612
1704
|
}
|
|
1613
1705
|
else {
|
|
1614
1706
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1615
1707
|
}
|
|
1616
1708
|
if (end && index < end)
|
|
1617
|
-
other.
|
|
1709
|
+
other.clearWorld(copyBounds, true);
|
|
1618
1710
|
});
|
|
1619
|
-
other.recycle();
|
|
1711
|
+
other.recycle(copyBounds);
|
|
1620
1712
|
}
|
|
1621
1713
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1622
1714
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1647,9 +1739,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1647
1739
|
|
|
1648
1740
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
1649
1741
|
const offsetOutBounds = {};
|
|
1650
|
-
function innerShadow(ui, current, shape
|
|
1742
|
+
function innerShadow(ui, current, shape) {
|
|
1651
1743
|
let copyBounds, spreadScale;
|
|
1652
|
-
const {
|
|
1744
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1653
1745
|
const { innerShadow } = ui.__;
|
|
1654
1746
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1655
1747
|
const other = current.getSameCanvas();
|
|
@@ -1662,25 +1754,25 @@ function innerShadow(ui, current, shape, _options) {
|
|
|
1662
1754
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1663
1755
|
other.restore();
|
|
1664
1756
|
if (worldCanvas) {
|
|
1665
|
-
other.copyWorld(other, bounds,
|
|
1666
|
-
other.copyWorld(worldCanvas,
|
|
1667
|
-
copyBounds =
|
|
1757
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1758
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1759
|
+
copyBounds = nowWorld;
|
|
1668
1760
|
}
|
|
1669
1761
|
else {
|
|
1670
1762
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1671
1763
|
copyBounds = bounds;
|
|
1672
1764
|
}
|
|
1673
1765
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1674
|
-
if (ui.
|
|
1675
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1766
|
+
if (ui.__worldFlipped) {
|
|
1767
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1676
1768
|
}
|
|
1677
1769
|
else {
|
|
1678
1770
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1679
1771
|
}
|
|
1680
1772
|
if (end && index < end)
|
|
1681
|
-
other.
|
|
1773
|
+
other.clearWorld(copyBounds, true);
|
|
1682
1774
|
});
|
|
1683
|
-
other.recycle();
|
|
1775
|
+
other.recycle(copyBounds);
|
|
1684
1776
|
}
|
|
1685
1777
|
|
|
1686
1778
|
function blur(ui, current, origin) {
|
|
@@ -1690,12 +1782,87 @@ function blur(ui, current, origin) {
|
|
|
1690
1782
|
origin.filter = 'none';
|
|
1691
1783
|
}
|
|
1692
1784
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
shadow
|
|
1698
|
-
|
|
1785
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
const EffectModule = {
|
|
1789
|
+
shadow,
|
|
1790
|
+
innerShadow,
|
|
1791
|
+
blur,
|
|
1792
|
+
backgroundBlur
|
|
1793
|
+
};
|
|
1794
|
+
|
|
1795
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
1796
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
1797
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
1798
|
+
const { children } = this;
|
|
1799
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
1800
|
+
child = children[i];
|
|
1801
|
+
if (child.__.mask) {
|
|
1802
|
+
if (currentMask) {
|
|
1803
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1804
|
+
maskCanvas = contentCanvas = null;
|
|
1805
|
+
}
|
|
1806
|
+
if (child.__.maskType === 'path') {
|
|
1807
|
+
if (child.opacity < 1) {
|
|
1808
|
+
currentMask = 'opacity-path';
|
|
1809
|
+
maskOpacity = child.opacity;
|
|
1810
|
+
if (!contentCanvas)
|
|
1811
|
+
contentCanvas = getCanvas(canvas);
|
|
1812
|
+
}
|
|
1813
|
+
else {
|
|
1814
|
+
currentMask = 'path';
|
|
1815
|
+
canvas.save();
|
|
1816
|
+
}
|
|
1817
|
+
child.__clip(contentCanvas || canvas, options);
|
|
1818
|
+
}
|
|
1819
|
+
else {
|
|
1820
|
+
currentMask = 'alpha';
|
|
1821
|
+
if (!maskCanvas)
|
|
1822
|
+
maskCanvas = getCanvas(canvas);
|
|
1823
|
+
if (!contentCanvas)
|
|
1824
|
+
contentCanvas = getCanvas(canvas);
|
|
1825
|
+
child.__render(maskCanvas, options);
|
|
1826
|
+
}
|
|
1827
|
+
if (child.__.maskType !== 'clipping')
|
|
1828
|
+
continue;
|
|
1829
|
+
}
|
|
1830
|
+
if (excludeRenderBounds(child, options))
|
|
1831
|
+
continue;
|
|
1832
|
+
child.__render(contentCanvas || canvas, options);
|
|
1833
|
+
}
|
|
1834
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1835
|
+
};
|
|
1836
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
1837
|
+
switch (maskMode) {
|
|
1838
|
+
case 'alpha':
|
|
1839
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
1840
|
+
break;
|
|
1841
|
+
case 'opacity-path':
|
|
1842
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
1843
|
+
break;
|
|
1844
|
+
case 'path':
|
|
1845
|
+
canvas.restore();
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
function getCanvas(canvas) {
|
|
1849
|
+
return canvas.getSameCanvas(false, true);
|
|
1850
|
+
}
|
|
1851
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
1852
|
+
const realBounds = leaf.__nowWorld;
|
|
1853
|
+
content.resetTransform();
|
|
1854
|
+
content.opacity = 1;
|
|
1855
|
+
content.useMask(mask, realBounds);
|
|
1856
|
+
mask.recycle(realBounds);
|
|
1857
|
+
copyContent(leaf, canvas, content, 1);
|
|
1858
|
+
}
|
|
1859
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
1860
|
+
const realBounds = leaf.__nowWorld;
|
|
1861
|
+
canvas.resetTransform();
|
|
1862
|
+
canvas.opacity = maskOpacity;
|
|
1863
|
+
canvas.copyWorld(content, realBounds);
|
|
1864
|
+
content.recycle(realBounds);
|
|
1865
|
+
}
|
|
1699
1866
|
|
|
1700
1867
|
const money = '¥¥$€££¢¢';
|
|
1701
1868
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1809,7 +1976,7 @@ function getTextCase(char, textCase, firstChar) {
|
|
|
1809
1976
|
const { trimRight } = TextRowHelper;
|
|
1810
1977
|
const { Letter, Single, Before, After, Symbol, Break } = CharType;
|
|
1811
1978
|
let word, row, wordWidth, rowWidth, realWidth;
|
|
1812
|
-
let char, charWidth, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
1979
|
+
let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
1813
1980
|
let textDrawData, rows = [], bounds;
|
|
1814
1981
|
function createRows(drawData, content, style) {
|
|
1815
1982
|
textDrawData = drawData;
|
|
@@ -1820,9 +1987,11 @@ function createRows(drawData, content, style) {
|
|
|
1820
1987
|
const { width, height } = bounds;
|
|
1821
1988
|
const charMode = width || height || __letterSpacing || (textCase !== 'none');
|
|
1822
1989
|
if (charMode) {
|
|
1990
|
+
const wrap = style.textWrap !== 'none';
|
|
1991
|
+
const breakAll = style.textWrap === 'break';
|
|
1823
1992
|
paraStart = true;
|
|
1824
1993
|
lastCharType = null;
|
|
1825
|
-
wordWidth = rowWidth = 0;
|
|
1994
|
+
startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
|
|
1826
1995
|
word = { data: [] }, row = { words: [] };
|
|
1827
1996
|
for (let i = 0, len = content.length; i < len; i++) {
|
|
1828
1997
|
char = content[i];
|
|
@@ -1838,21 +2007,31 @@ function createRows(drawData, content, style) {
|
|
|
1838
2007
|
if (charType === Letter && textCase !== 'none')
|
|
1839
2008
|
char = getTextCase(char, textCase, !wordWidth);
|
|
1840
2009
|
charWidth = canvas.measureText(char).width;
|
|
1841
|
-
if (__letterSpacing)
|
|
2010
|
+
if (__letterSpacing) {
|
|
2011
|
+
if (__letterSpacing < 0)
|
|
2012
|
+
charSize = charWidth;
|
|
1842
2013
|
charWidth += __letterSpacing;
|
|
2014
|
+
}
|
|
1843
2015
|
langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
|
|
1844
2016
|
afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
|
|
1845
2017
|
realWidth = paraStart && paraIndent ? width - paraIndent : width;
|
|
1846
|
-
if (width && rowWidth + wordWidth + charWidth > realWidth) {
|
|
1847
|
-
if (
|
|
1848
|
-
afterBreak = charType === Letter && lastCharType == After;
|
|
1849
|
-
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2018
|
+
if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
|
|
2019
|
+
if (breakAll) {
|
|
1850
2020
|
if (wordWidth)
|
|
1851
2021
|
addWord();
|
|
1852
2022
|
addRow();
|
|
1853
2023
|
}
|
|
1854
2024
|
else {
|
|
1855
|
-
|
|
2025
|
+
if (!afterBreak)
|
|
2026
|
+
afterBreak = charType === Letter && lastCharType == After;
|
|
2027
|
+
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2028
|
+
if (wordWidth)
|
|
2029
|
+
addWord();
|
|
2030
|
+
addRow();
|
|
2031
|
+
}
|
|
2032
|
+
else {
|
|
2033
|
+
addRow();
|
|
2034
|
+
}
|
|
1856
2035
|
}
|
|
1857
2036
|
}
|
|
1858
2037
|
if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
|
|
@@ -1889,6 +2068,8 @@ function createRows(drawData, content, style) {
|
|
|
1889
2068
|
}
|
|
1890
2069
|
}
|
|
1891
2070
|
function addChar(char, width) {
|
|
2071
|
+
if (charSize && !startCharSize)
|
|
2072
|
+
startCharSize = charSize;
|
|
1892
2073
|
word.data.push({ char, width });
|
|
1893
2074
|
wordWidth += width;
|
|
1894
2075
|
}
|
|
@@ -1905,6 +2086,11 @@ function addRow() {
|
|
|
1905
2086
|
row.paraStart = true;
|
|
1906
2087
|
paraStart = false;
|
|
1907
2088
|
}
|
|
2089
|
+
if (charSize) {
|
|
2090
|
+
row.startCharSize = startCharSize;
|
|
2091
|
+
row.endCharSize = charSize;
|
|
2092
|
+
startCharSize = 0;
|
|
2093
|
+
}
|
|
1908
2094
|
row.width = rowWidth;
|
|
1909
2095
|
if (bounds.width)
|
|
1910
2096
|
trimRight(row);
|
|
@@ -1915,7 +2101,7 @@ function addRow() {
|
|
|
1915
2101
|
|
|
1916
2102
|
const CharMode = 0;
|
|
1917
2103
|
const WordMode = 1;
|
|
1918
|
-
const
|
|
2104
|
+
const TextMode = 2;
|
|
1919
2105
|
function layoutChar(drawData, style, width, _height) {
|
|
1920
2106
|
const { rows } = drawData;
|
|
1921
2107
|
const { textAlign, paraIndent, letterSpacing } = style;
|
|
@@ -1924,15 +2110,12 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1924
2110
|
if (row.words) {
|
|
1925
2111
|
indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
|
|
1926
2112
|
addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
|
|
1927
|
-
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode :
|
|
1928
|
-
if (
|
|
1929
|
-
row.
|
|
2113
|
+
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
|
|
2114
|
+
if (row.isOverflow && !letterSpacing)
|
|
2115
|
+
row.textMode = true;
|
|
2116
|
+
if (mode === TextMode) {
|
|
1930
2117
|
row.x += indentWidth;
|
|
1931
|
-
row
|
|
1932
|
-
word.data.forEach(char => {
|
|
1933
|
-
row.text += char.char;
|
|
1934
|
-
});
|
|
1935
|
-
});
|
|
2118
|
+
toTextChar$1(row);
|
|
1936
2119
|
}
|
|
1937
2120
|
else {
|
|
1938
2121
|
row.x += indentWidth;
|
|
@@ -1958,6 +2141,14 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1958
2141
|
}
|
|
1959
2142
|
});
|
|
1960
2143
|
}
|
|
2144
|
+
function toTextChar$1(row) {
|
|
2145
|
+
row.text = '';
|
|
2146
|
+
row.words.forEach(word => {
|
|
2147
|
+
word.data.forEach(char => {
|
|
2148
|
+
row.text += char.char;
|
|
2149
|
+
});
|
|
2150
|
+
});
|
|
2151
|
+
}
|
|
1961
2152
|
function toWordChar(data, charX, wordChar) {
|
|
1962
2153
|
data.forEach(char => {
|
|
1963
2154
|
wordChar.char += char.char;
|
|
@@ -1978,10 +2169,10 @@ function toChar(data, charX, rowData) {
|
|
|
1978
2169
|
|
|
1979
2170
|
function layoutText(drawData, style) {
|
|
1980
2171
|
const { rows, bounds } = drawData;
|
|
1981
|
-
const { __lineHeight, __baseLine, textAlign, verticalAlign, paraSpacing
|
|
2172
|
+
const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
|
|
1982
2173
|
let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
1983
2174
|
let starY = __baseLine;
|
|
1984
|
-
if (
|
|
2175
|
+
if (__clipText && realHeight > height) {
|
|
1985
2176
|
realHeight = Math.max(height, __lineHeight);
|
|
1986
2177
|
drawData.overflow = rows.length;
|
|
1987
2178
|
}
|
|
@@ -1995,7 +2186,7 @@ function layoutText(drawData, style) {
|
|
|
1995
2186
|
}
|
|
1996
2187
|
}
|
|
1997
2188
|
starY += y;
|
|
1998
|
-
let row;
|
|
2189
|
+
let row, rowX, rowWidth;
|
|
1999
2190
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2000
2191
|
row = rows[i];
|
|
2001
2192
|
row.x = x;
|
|
@@ -2014,53 +2205,74 @@ function layoutText(drawData, style) {
|
|
|
2014
2205
|
row.isOverflow = true;
|
|
2015
2206
|
drawData.overflow = i + 1;
|
|
2016
2207
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2208
|
+
rowX = row.x;
|
|
2209
|
+
rowWidth = row.width;
|
|
2210
|
+
if (__letterSpacing < 0) {
|
|
2211
|
+
if (row.width < 0) {
|
|
2212
|
+
rowWidth = -row.width + style.fontSize + __letterSpacing;
|
|
2213
|
+
rowX -= rowWidth;
|
|
2214
|
+
rowWidth += style.fontSize;
|
|
2215
|
+
}
|
|
2216
|
+
else {
|
|
2217
|
+
rowWidth -= __letterSpacing;
|
|
2218
|
+
}
|
|
2024
2219
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2220
|
+
if (rowX < bounds.x)
|
|
2221
|
+
bounds.x = rowX;
|
|
2222
|
+
if (rowWidth > bounds.width)
|
|
2223
|
+
bounds.width = rowWidth;
|
|
2224
|
+
if (__clipText && width && width < rowWidth) {
|
|
2225
|
+
row.isOverflow = true;
|
|
2226
|
+
if (!drawData.overflow)
|
|
2227
|
+
drawData.overflow = rows.length;
|
|
2030
2228
|
}
|
|
2031
2229
|
}
|
|
2032
2230
|
bounds.y = y;
|
|
2033
2231
|
bounds.height = realHeight;
|
|
2034
2232
|
}
|
|
2035
2233
|
|
|
2036
|
-
function clipText(drawData,
|
|
2234
|
+
function clipText(drawData, style) {
|
|
2037
2235
|
const { rows, overflow } = drawData;
|
|
2236
|
+
let { textOverflow } = style;
|
|
2038
2237
|
rows.splice(overflow);
|
|
2039
2238
|
if (textOverflow !== 'hide') {
|
|
2040
2239
|
if (textOverflow === 'ellipsis')
|
|
2041
2240
|
textOverflow = '...';
|
|
2241
|
+
let char, charRight;
|
|
2042
2242
|
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2043
|
-
const
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2243
|
+
const right = style.x + style.width - ellipsisWidth;
|
|
2244
|
+
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2245
|
+
list.forEach(row => {
|
|
2246
|
+
if (row.isOverflow && row.data) {
|
|
2247
|
+
let end = row.data.length - 1;
|
|
2248
|
+
for (let i = end; i > -1; i--) {
|
|
2249
|
+
char = row.data[i];
|
|
2250
|
+
charRight = char.x + char.width;
|
|
2251
|
+
if (i === end && charRight < right) {
|
|
2252
|
+
break;
|
|
2253
|
+
}
|
|
2254
|
+
else if (charRight < right && char.char !== ' ') {
|
|
2255
|
+
row.data.splice(i + 1);
|
|
2256
|
+
row.width -= char.width;
|
|
2257
|
+
break;
|
|
2258
|
+
}
|
|
2259
|
+
row.width -= char.width;
|
|
2260
|
+
}
|
|
2261
|
+
row.width += ellipsisWidth;
|
|
2262
|
+
row.data.push({ char: textOverflow, x: charRight });
|
|
2263
|
+
if (row.textMode)
|
|
2264
|
+
toTextChar(row);
|
|
2057
2265
|
}
|
|
2058
|
-
|
|
2059
|
-
}
|
|
2060
|
-
row.width += ellipsisWidth;
|
|
2061
|
-
row.data.push({ char: textOverflow, x: charRight });
|
|
2266
|
+
});
|
|
2062
2267
|
}
|
|
2063
2268
|
}
|
|
2269
|
+
function toTextChar(row) {
|
|
2270
|
+
row.text = '';
|
|
2271
|
+
row.data.forEach(char => {
|
|
2272
|
+
row.text += char.char;
|
|
2273
|
+
});
|
|
2274
|
+
row.data = null;
|
|
2275
|
+
}
|
|
2064
2276
|
|
|
2065
2277
|
function decorationText(drawData, style) {
|
|
2066
2278
|
const { fontSize } = style;
|
|
@@ -2074,101 +2286,162 @@ function decorationText(drawData, style) {
|
|
|
2074
2286
|
}
|
|
2075
2287
|
}
|
|
2076
2288
|
|
|
2077
|
-
const
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
if (
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2289
|
+
const { top, right, bottom, left } = Direction4;
|
|
2290
|
+
function getDrawData(content, style) {
|
|
2291
|
+
if (typeof content !== 'string')
|
|
2292
|
+
content = String(content);
|
|
2293
|
+
let x = 0, y = 0;
|
|
2294
|
+
let width = style.__getInput('width') || 0;
|
|
2295
|
+
let height = style.__getInput('height') || 0;
|
|
2296
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2297
|
+
if (padding) {
|
|
2298
|
+
if (width) {
|
|
2299
|
+
x = padding[left];
|
|
2300
|
+
width -= (padding[right] + padding[left]);
|
|
2301
|
+
}
|
|
2302
|
+
if (height) {
|
|
2303
|
+
y = padding[top];
|
|
2304
|
+
height -= (padding[top] + padding[bottom]);
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
const drawData = {
|
|
2308
|
+
bounds: { x, y, width, height },
|
|
2309
|
+
rows: [],
|
|
2310
|
+
paraNumber: 0,
|
|
2311
|
+
font: Platform.canvas.font = __font
|
|
2312
|
+
};
|
|
2313
|
+
createRows(drawData, content, style);
|
|
2314
|
+
if (padding)
|
|
2315
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2316
|
+
layoutText(drawData, style);
|
|
2317
|
+
layoutChar(drawData, style, width);
|
|
2318
|
+
if (drawData.overflow)
|
|
2319
|
+
clipText(drawData, style);
|
|
2320
|
+
if (textDecoration !== 'none')
|
|
2321
|
+
decorationText(drawData, style);
|
|
2322
|
+
return drawData;
|
|
2323
|
+
}
|
|
2324
|
+
function padAutoText(padding, drawData, style, width, height) {
|
|
2325
|
+
if (!width) {
|
|
2326
|
+
switch (style.textAlign) {
|
|
2327
|
+
case 'left':
|
|
2328
|
+
offsetText(drawData, 'x', padding[left]);
|
|
2329
|
+
break;
|
|
2330
|
+
case 'right':
|
|
2331
|
+
offsetText(drawData, 'x', -padding[right]);
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
if (!height) {
|
|
2335
|
+
switch (style.verticalAlign) {
|
|
2336
|
+
case 'top':
|
|
2337
|
+
offsetText(drawData, 'y', padding[top]);
|
|
2338
|
+
break;
|
|
2339
|
+
case 'bottom':
|
|
2340
|
+
offsetText(drawData, 'y', -padding[bottom]);
|
|
2096
2341
|
}
|
|
2097
|
-
const drawData = {
|
|
2098
|
-
bounds: { x, y, width, height },
|
|
2099
|
-
rows: [],
|
|
2100
|
-
paraNumber: 0,
|
|
2101
|
-
font: Platform.canvas.font = __font
|
|
2102
|
-
};
|
|
2103
|
-
createRows(drawData, content, style);
|
|
2104
|
-
layoutText(drawData, style);
|
|
2105
|
-
layoutChar(drawData, style, width);
|
|
2106
|
-
if (drawData.overflow)
|
|
2107
|
-
clipText(drawData, textOverflow);
|
|
2108
|
-
if (textDecoration !== 'none')
|
|
2109
|
-
decorationText(drawData, style);
|
|
2110
|
-
return drawData;
|
|
2111
2342
|
}
|
|
2343
|
+
}
|
|
2344
|
+
function offsetText(drawData, attrName, value) {
|
|
2345
|
+
const { bounds, rows } = drawData;
|
|
2346
|
+
bounds[attrName] += value;
|
|
2347
|
+
for (let i = 0; i < rows.length; i++)
|
|
2348
|
+
rows[i][attrName] += value;
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
const TextConvertModule = {
|
|
2352
|
+
getDrawData
|
|
2112
2353
|
};
|
|
2113
2354
|
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2355
|
+
function string(color, opacity) {
|
|
2356
|
+
if (typeof color === 'string')
|
|
2357
|
+
return color;
|
|
2358
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2359
|
+
if (opacity)
|
|
2360
|
+
a *= opacity;
|
|
2361
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2362
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
const ColorConvertModule = {
|
|
2366
|
+
string
|
|
2124
2367
|
};
|
|
2125
2368
|
|
|
2126
|
-
const
|
|
2369
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2370
|
+
function getTrimBounds(canvas) {
|
|
2371
|
+
const { width, height } = canvas.view;
|
|
2372
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2373
|
+
let x, y, pointBounds, index = 0;
|
|
2374
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2375
|
+
if (data[i + 3] !== 0) {
|
|
2376
|
+
x = index % width;
|
|
2377
|
+
y = (index - x) / width;
|
|
2378
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2379
|
+
}
|
|
2380
|
+
index++;
|
|
2381
|
+
}
|
|
2382
|
+
const bounds = new Bounds();
|
|
2383
|
+
toBounds(pointBounds, bounds);
|
|
2384
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2385
|
+
}
|
|
2386
|
+
|
|
2387
|
+
const ExportModule = {
|
|
2127
2388
|
export(leaf, filename, options) {
|
|
2389
|
+
this.running = true;
|
|
2128
2390
|
return addTask((success) => new Promise((resolve) => {
|
|
2391
|
+
const over = (result) => {
|
|
2392
|
+
success(result);
|
|
2393
|
+
resolve();
|
|
2394
|
+
this.running = false;
|
|
2395
|
+
};
|
|
2129
2396
|
const { leafer } = leaf;
|
|
2130
2397
|
if (leafer) {
|
|
2131
2398
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2132
|
-
let
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2399
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2400
|
+
options = FileHelper.getExportOptions(options);
|
|
2401
|
+
const { scale, pixelRatio, slice, trim } = options;
|
|
2402
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2403
|
+
const fill = options.fill === undefined ? ((leaf.isLeafer && screenshot) ? leaf.fill : '') : options.fill;
|
|
2404
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
2405
|
+
if (screenshot) {
|
|
2406
|
+
renderBounds = screenshot === true ? (leaf.isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2139
2407
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
break;
|
|
2147
|
-
case 'number':
|
|
2148
|
-
quality = options;
|
|
2149
|
-
break;
|
|
2150
|
-
case 'boolean':
|
|
2151
|
-
blob = options;
|
|
2408
|
+
else {
|
|
2409
|
+
const { localTransform, __world: world } = leaf;
|
|
2410
|
+
matrix.set(world).divide(localTransform).invert();
|
|
2411
|
+
scaleX = 1 / (world.scaleX / leaf.scaleX);
|
|
2412
|
+
scaleY = 1 / (world.scaleY / leaf.scaleY);
|
|
2413
|
+
renderBounds = leaf.getBounds('render', 'local');
|
|
2152
2414
|
}
|
|
2153
|
-
let
|
|
2154
|
-
if (
|
|
2155
|
-
|
|
2415
|
+
let { x, y, width, height } = renderBounds;
|
|
2416
|
+
if (scale) {
|
|
2417
|
+
matrix.scale(scale);
|
|
2418
|
+
width *= scale, height *= scale;
|
|
2419
|
+
scaleX *= scale, scaleY *= scale;
|
|
2156
2420
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2421
|
+
let canvas = Creator.canvas({ width, height, pixelRatio });
|
|
2422
|
+
const renderOptions = { matrix: matrix.translate(-x, -y).withScale(scaleX, scaleY) };
|
|
2423
|
+
if (slice) {
|
|
2424
|
+
leaf = leafer;
|
|
2425
|
+
renderOptions.bounds = canvas.bounds;
|
|
2159
2426
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2427
|
+
canvas.save();
|
|
2428
|
+
leaf.__render(canvas, renderOptions);
|
|
2429
|
+
canvas.restore();
|
|
2430
|
+
if (trim) {
|
|
2431
|
+
trimBounds = getTrimBounds(canvas);
|
|
2432
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2433
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2434
|
+
canvas = Creator.canvas(config);
|
|
2435
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2162
2436
|
}
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2437
|
+
if (needFill)
|
|
2438
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2439
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2440
|
+
over({ data, renderBounds, trimBounds });
|
|
2167
2441
|
}));
|
|
2168
2442
|
}
|
|
2169
2443
|
else {
|
|
2170
|
-
|
|
2171
|
-
resolve();
|
|
2444
|
+
over({ data: false });
|
|
2172
2445
|
}
|
|
2173
2446
|
}));
|
|
2174
2447
|
}
|
|
@@ -2182,12 +2455,19 @@ function addTask(task) {
|
|
|
2182
2455
|
});
|
|
2183
2456
|
}
|
|
2184
2457
|
|
|
2185
|
-
Object.assign(
|
|
2186
|
-
Object.assign(
|
|
2187
|
-
Object.assign(
|
|
2188
|
-
Object.assign(
|
|
2189
|
-
Object.assign(
|
|
2458
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
2459
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
2460
|
+
Object.assign(Paint, PaintModule);
|
|
2461
|
+
Object.assign(PaintImage$1, PaintImageModule);
|
|
2462
|
+
Object.assign(PaintGradient$1, PaintGradientModule);
|
|
2463
|
+
Object.assign(Effect, EffectModule);
|
|
2464
|
+
Object.assign(Export, ExportModule);
|
|
2190
2465
|
|
|
2466
|
+
Object.assign(Creator, {
|
|
2467
|
+
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
2468
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2469
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
2470
|
+
});
|
|
2191
2471
|
useCanvas();
|
|
2192
2472
|
|
|
2193
2473
|
export { Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|