@leafer-ui/worker 1.0.0-beta.18 → 1.0.0-rc.11
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 +1127 -849
- package/dist/worker.esm.min.js +1 -1
- package/dist/worker.js +5917 -4861
- package/dist/worker.min.js +1 -1
- package/dist/worker.module.js +5891 -4849
- package/dist/worker.module.min.js +1 -1
- package/package.json +7 -6
- package/src/index.ts +12 -1
- package/types/index.d.ts +4 -3
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 { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, 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,330 @@ Object.assign(Creator, {
|
|
|
816
909
|
});
|
|
817
910
|
Platform.layout = Layouter.fullLayout;
|
|
818
911
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
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);
|
|
839
|
-
|
|
840
|
-
const { mineType } = FileHelper;
|
|
841
|
-
Object.assign(Creator, {
|
|
842
|
-
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
843
|
-
image: (options) => new LeaferImage(options),
|
|
844
|
-
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
845
|
-
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
846
|
-
});
|
|
847
|
-
function useCanvas(_canvasType, _power) {
|
|
848
|
-
Platform.origin = {
|
|
849
|
-
createCanvas: (width, height) => new OffscreenCanvas(width, height),
|
|
850
|
-
canvasToDataURL: (canvas, type, quality) => {
|
|
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();
|
|
912
|
+
function fillText(ui, canvas) {
|
|
913
|
+
let row;
|
|
914
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
915
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
916
|
+
row = rows[i];
|
|
917
|
+
if (row.text) {
|
|
918
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
919
|
+
}
|
|
920
|
+
else if (row.data) {
|
|
921
|
+
row.data.forEach(charData => {
|
|
922
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
880
923
|
});
|
|
881
924
|
}
|
|
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;
|
|
925
|
+
if (decorationY)
|
|
926
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
927
|
+
}
|
|
902
928
|
}
|
|
903
|
-
|
|
904
|
-
|
|
929
|
+
|
|
930
|
+
function fill(fill, ui, canvas) {
|
|
931
|
+
canvas.fillStyle = fill;
|
|
932
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
905
933
|
}
|
|
906
|
-
|
|
907
|
-
|
|
934
|
+
function fills(fills, ui, canvas) {
|
|
935
|
+
let item;
|
|
936
|
+
const { windingRule, __font } = ui.__;
|
|
937
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
938
|
+
item = fills[i];
|
|
939
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
940
|
+
continue;
|
|
941
|
+
if (item.style) {
|
|
942
|
+
canvas.fillStyle = item.style;
|
|
943
|
+
if (item.transform) {
|
|
944
|
+
canvas.save();
|
|
945
|
+
canvas.transform(item.transform);
|
|
946
|
+
if (item.blendMode)
|
|
947
|
+
canvas.blendMode = item.blendMode;
|
|
948
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
949
|
+
canvas.restore();
|
|
950
|
+
}
|
|
951
|
+
else {
|
|
952
|
+
if (item.blendMode) {
|
|
953
|
+
canvas.saveBlendMode(item.blendMode);
|
|
954
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
955
|
+
canvas.restoreBlendMode();
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
908
963
|
}
|
|
909
964
|
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
const
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
965
|
+
function strokeText(stroke, ui, canvas) {
|
|
966
|
+
const { strokeAlign } = ui.__;
|
|
967
|
+
const isStrokes = typeof stroke !== 'string';
|
|
968
|
+
switch (strokeAlign) {
|
|
969
|
+
case 'center':
|
|
970
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
971
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
972
|
+
break;
|
|
973
|
+
case 'inside':
|
|
974
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
975
|
+
break;
|
|
976
|
+
case 'outside':
|
|
977
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
978
|
+
break;
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
982
|
+
const { __strokeWidth, __font } = ui.__;
|
|
983
|
+
const out = canvas.getSameCanvas(true, true);
|
|
984
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
985
|
+
out.font = __font;
|
|
986
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
987
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
988
|
+
fillText(ui, out);
|
|
989
|
+
out.blendMode = 'normal';
|
|
990
|
+
if (ui.__worldFlipped) {
|
|
991
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
992
|
+
}
|
|
993
|
+
else {
|
|
994
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
995
|
+
}
|
|
996
|
+
out.recycle(ui.__nowWorld);
|
|
997
|
+
}
|
|
998
|
+
function drawTextStroke(ui, canvas) {
|
|
999
|
+
let row;
|
|
1000
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1001
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1002
|
+
row = rows[i];
|
|
1003
|
+
if (row.text) {
|
|
1004
|
+
canvas.strokeText(row.text, row.x, row.y);
|
|
1005
|
+
}
|
|
1006
|
+
else if (row.data) {
|
|
1007
|
+
row.data.forEach(charData => {
|
|
1008
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
1011
|
+
if (decorationY)
|
|
1012
|
+
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1016
|
+
let item;
|
|
1017
|
+
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1018
|
+
item = strokes[i];
|
|
1019
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1020
|
+
continue;
|
|
1021
|
+
if (item.style) {
|
|
1022
|
+
canvas.strokeStyle = item.style;
|
|
1023
|
+
if (item.blendMode) {
|
|
1024
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1025
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1026
|
+
canvas.restoreBlendMode();
|
|
1027
|
+
}
|
|
1028
|
+
else {
|
|
1029
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
function stroke(stroke, ui, canvas) {
|
|
1036
|
+
const options = ui.__;
|
|
1037
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1038
|
+
if (!__strokeWidth)
|
|
1039
|
+
return;
|
|
1040
|
+
if (__font) {
|
|
1041
|
+
strokeText(stroke, ui, canvas);
|
|
1042
|
+
}
|
|
1043
|
+
else {
|
|
1044
|
+
switch (strokeAlign) {
|
|
1045
|
+
case 'center':
|
|
1046
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1047
|
+
canvas.stroke();
|
|
1048
|
+
break;
|
|
1049
|
+
case 'inside':
|
|
1050
|
+
canvas.save();
|
|
1051
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1052
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1053
|
+
canvas.stroke();
|
|
1054
|
+
canvas.restore();
|
|
1055
|
+
break;
|
|
1056
|
+
case 'outside':
|
|
1057
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1058
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1059
|
+
ui.__drawRenderPath(out);
|
|
1060
|
+
out.stroke();
|
|
1061
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1062
|
+
out.clearWorld(ui.__layout.renderBounds);
|
|
1063
|
+
if (ui.__worldFlipped) {
|
|
1064
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1065
|
+
}
|
|
1066
|
+
else {
|
|
1067
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1068
|
+
}
|
|
1069
|
+
out.recycle(ui.__nowWorld);
|
|
1070
|
+
break;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
function strokes(strokes, ui, canvas) {
|
|
1075
|
+
const options = ui.__;
|
|
1076
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1077
|
+
if (!__strokeWidth)
|
|
1078
|
+
return;
|
|
1079
|
+
if (__font) {
|
|
1080
|
+
strokeText(strokes, ui, canvas);
|
|
1081
|
+
}
|
|
1082
|
+
else {
|
|
1083
|
+
switch (strokeAlign) {
|
|
1084
|
+
case 'center':
|
|
1085
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1086
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1087
|
+
break;
|
|
1088
|
+
case 'inside':
|
|
1089
|
+
canvas.save();
|
|
1090
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1091
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1092
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1093
|
+
canvas.restore();
|
|
1094
|
+
break;
|
|
1095
|
+
case 'outside':
|
|
1096
|
+
const { renderBounds } = ui.__layout;
|
|
1097
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1098
|
+
ui.__drawRenderPath(out);
|
|
1099
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1100
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1101
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1102
|
+
out.clearWorld(renderBounds);
|
|
1103
|
+
if (ui.__worldFlipped) {
|
|
1104
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1108
|
+
}
|
|
1109
|
+
out.recycle(ui.__nowWorld);
|
|
1110
|
+
break;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1116
|
+
function shape(ui, current, options) {
|
|
1117
|
+
const canvas = current.getSameCanvas();
|
|
1118
|
+
const nowWorld = ui.__nowWorld;
|
|
1119
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1120
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1121
|
+
if (scaleX < 0)
|
|
1122
|
+
scaleX = -scaleX;
|
|
1123
|
+
if (scaleY < 0)
|
|
1124
|
+
scaleY = -scaleY;
|
|
1125
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1126
|
+
worldCanvas = canvas;
|
|
1127
|
+
bounds = shapeBounds = nowWorld;
|
|
1128
|
+
}
|
|
1129
|
+
else {
|
|
1130
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1131
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, nowWorld);
|
|
1132
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1133
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1134
|
+
if (fitMatrix.a < 1) {
|
|
1135
|
+
worldCanvas = current.getSameCanvas();
|
|
1136
|
+
ui.__renderShape(worldCanvas, options);
|
|
1137
|
+
scaleX *= fitScaleX;
|
|
1138
|
+
scaleY *= fitScaleY;
|
|
1139
|
+
}
|
|
1140
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1141
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1142
|
+
if (options.matrix) {
|
|
1143
|
+
const { matrix } = options;
|
|
1144
|
+
fitMatrix.multiply(matrix);
|
|
1145
|
+
fitScaleX *= matrix.scaleX;
|
|
1146
|
+
fitScaleY *= matrix.scaleY;
|
|
1147
|
+
}
|
|
1148
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1149
|
+
}
|
|
1150
|
+
ui.__renderShape(canvas, options);
|
|
1151
|
+
return {
|
|
1152
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1153
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1154
|
+
};
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
let recycleMap;
|
|
1158
|
+
function compute(attrName, ui) {
|
|
1159
|
+
const data = ui.__, leafPaints = [];
|
|
1160
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1161
|
+
if (!(paints instanceof Array))
|
|
1162
|
+
paints = [paints];
|
|
1163
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1164
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1165
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1166
|
+
if (item)
|
|
1167
|
+
leafPaints.push(item);
|
|
1168
|
+
}
|
|
1169
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1170
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1171
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1172
|
+
if (attrName === 'fill') {
|
|
1173
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1180
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1181
|
+
return undefined;
|
|
1182
|
+
const { boxBounds } = ui.__layout;
|
|
1183
|
+
switch (paint.type) {
|
|
1184
|
+
case 'solid':
|
|
1185
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1186
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1187
|
+
case 'image':
|
|
1188
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1189
|
+
case 'linear':
|
|
1190
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1191
|
+
case 'radial':
|
|
1192
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1193
|
+
case 'angular':
|
|
1194
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1195
|
+
default:
|
|
1196
|
+
return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
const PaintModule = {
|
|
1201
|
+
compute,
|
|
1202
|
+
fill,
|
|
1203
|
+
fills,
|
|
1204
|
+
fillText,
|
|
1205
|
+
stroke,
|
|
1206
|
+
strokes,
|
|
1207
|
+
strokeText,
|
|
1208
|
+
drawTextStroke,
|
|
1209
|
+
shape
|
|
1210
|
+
};
|
|
1211
|
+
|
|
1212
|
+
let origin = {};
|
|
1213
|
+
const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1214
|
+
function fillOrFitMode(data, mode, box, width, height, rotation) {
|
|
1215
|
+
const transform = get$4();
|
|
1216
|
+
const swap = rotation && rotation !== 180;
|
|
1217
|
+
const sw = box.width / (swap ? height : width);
|
|
1218
|
+
const sh = box.height / (swap ? width : height);
|
|
916
1219
|
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
917
1220
|
const x = box.x + (box.width - width * scale) / 2;
|
|
918
1221
|
const y = box.y + (box.height - height * scale) / 2;
|
|
919
1222
|
translate$1(transform, x, y);
|
|
920
|
-
scaleHelper
|
|
1223
|
+
scaleHelper(transform, scale);
|
|
921
1224
|
if (rotation)
|
|
922
1225
|
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
923
1226
|
data.scaleX = data.scaleY = scale;
|
|
924
1227
|
data.transform = transform;
|
|
925
1228
|
}
|
|
926
|
-
function clipMode(data, box,
|
|
1229
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
927
1230
|
const transform = get$4();
|
|
928
1231
|
translate$1(transform, box.x, box.y);
|
|
929
|
-
if (
|
|
930
|
-
translate$1(transform,
|
|
931
|
-
if (
|
|
932
|
-
|
|
1232
|
+
if (x || y)
|
|
1233
|
+
translate$1(transform, x, y);
|
|
1234
|
+
if (scaleX) {
|
|
1235
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
933
1236
|
data.scaleX = transform.a;
|
|
934
1237
|
data.scaleY = transform.d;
|
|
935
1238
|
}
|
|
@@ -937,7 +1240,7 @@ function clipMode(data, box, offset, scale, rotation) {
|
|
|
937
1240
|
rotate(transform, rotation);
|
|
938
1241
|
data.transform = transform;
|
|
939
1242
|
}
|
|
940
|
-
function repeatMode(data, box, width, height,
|
|
1243
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
|
|
941
1244
|
const transform = get$4();
|
|
942
1245
|
if (rotation) {
|
|
943
1246
|
rotate(transform, rotation);
|
|
@@ -953,10 +1256,15 @@ function repeatMode(data, box, width, height, scale, rotation) {
|
|
|
953
1256
|
break;
|
|
954
1257
|
}
|
|
955
1258
|
}
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1259
|
+
origin.x = box.x;
|
|
1260
|
+
origin.y = box.y;
|
|
1261
|
+
if (x || y)
|
|
1262
|
+
origin.x += x, origin.y += y;
|
|
1263
|
+
translate$1(transform, origin.x, origin.y);
|
|
1264
|
+
if (scaleX) {
|
|
1265
|
+
scaleOfOuter$2(transform, origin, scaleX, scaleY);
|
|
1266
|
+
data.scaleX = scaleX;
|
|
1267
|
+
data.scaleY = scaleY;
|
|
960
1268
|
}
|
|
961
1269
|
data.transform = transform;
|
|
962
1270
|
}
|
|
@@ -964,11 +1272,22 @@ function repeatMode(data, box, width, height, scale, rotation) {
|
|
|
964
1272
|
const { get: get$3, translate } = MatrixHelper;
|
|
965
1273
|
function createData(leafPaint, image, paint, box) {
|
|
966
1274
|
let { width, height } = image;
|
|
967
|
-
const { opacity, mode, offset, scale, rotation, blendMode } = paint;
|
|
1275
|
+
const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
|
|
968
1276
|
const sameBox = box.width === width && box.height === height;
|
|
969
1277
|
if (blendMode)
|
|
970
1278
|
leafPaint.blendMode = blendMode;
|
|
971
1279
|
const data = leafPaint.data = { mode };
|
|
1280
|
+
let x, y, scaleX, scaleY;
|
|
1281
|
+
if (offset)
|
|
1282
|
+
x = offset.x, y = offset.y;
|
|
1283
|
+
if (size) {
|
|
1284
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1285
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1286
|
+
}
|
|
1287
|
+
else if (scale) {
|
|
1288
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1289
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1290
|
+
}
|
|
972
1291
|
switch (mode) {
|
|
973
1292
|
case 'strench':
|
|
974
1293
|
if (!sameBox)
|
|
@@ -979,12 +1298,14 @@ function createData(leafPaint, image, paint, box) {
|
|
|
979
1298
|
}
|
|
980
1299
|
break;
|
|
981
1300
|
case 'clip':
|
|
982
|
-
if (offset ||
|
|
983
|
-
clipMode(data, box,
|
|
1301
|
+
if (offset || scaleX || rotation)
|
|
1302
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
984
1303
|
break;
|
|
985
1304
|
case 'repeat':
|
|
986
|
-
if (!sameBox ||
|
|
987
|
-
repeatMode(data, box, width, height,
|
|
1305
|
+
if (!sameBox || scaleX || rotation)
|
|
1306
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1307
|
+
if (!repeat)
|
|
1308
|
+
data.repeat = 'repeat';
|
|
988
1309
|
break;
|
|
989
1310
|
case 'fit':
|
|
990
1311
|
case 'cover':
|
|
@@ -996,111 +1317,101 @@ function createData(leafPaint, image, paint, box) {
|
|
|
996
1317
|
data.height = height;
|
|
997
1318
|
if (opacity)
|
|
998
1319
|
data.opacity = opacity;
|
|
1320
|
+
if (repeat)
|
|
1321
|
+
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
999
1322
|
}
|
|
1000
1323
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1324
|
+
let cache, box = new Bounds();
|
|
1325
|
+
const { isSame } = BoundsHelper;
|
|
1326
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1327
|
+
let leafPaint, event;
|
|
1328
|
+
const image = ImageManager.get(paint);
|
|
1329
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1330
|
+
leafPaint = cache.leafPaint;
|
|
1331
|
+
}
|
|
1332
|
+
else {
|
|
1333
|
+
leafPaint = { type: paint.type };
|
|
1334
|
+
leafPaint.image = image;
|
|
1335
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1336
|
+
}
|
|
1337
|
+
if (firstUse || image.loading)
|
|
1338
|
+
event = { image, attrName, attrValue: paint };
|
|
1005
1339
|
if (image.ready) {
|
|
1006
|
-
|
|
1007
|
-
createData(leafPaint, image, attrValue, box);
|
|
1340
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1008
1341
|
if (firstUse) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1342
|
+
onLoad(ui, event);
|
|
1343
|
+
onLoadSuccess(ui, event);
|
|
1011
1344
|
}
|
|
1012
1345
|
}
|
|
1013
1346
|
else if (image.error) {
|
|
1014
|
-
if (firstUse)
|
|
1015
|
-
ui.
|
|
1016
|
-
event.error = image.error;
|
|
1017
|
-
emit(ImageEvent.ERROR, event);
|
|
1018
|
-
}
|
|
1347
|
+
if (firstUse)
|
|
1348
|
+
onLoadError(ui, event, image.error);
|
|
1019
1349
|
}
|
|
1020
1350
|
else {
|
|
1021
1351
|
if (firstUse)
|
|
1022
|
-
|
|
1352
|
+
onLoad(ui, event);
|
|
1023
1353
|
leafPaint.loadId = image.load(() => {
|
|
1024
1354
|
if (!ui.destroyed) {
|
|
1025
|
-
if (
|
|
1026
|
-
createData(leafPaint, image, attrValue, box);
|
|
1355
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds))
|
|
1027
1356
|
ui.forceUpdate('surface');
|
|
1028
|
-
|
|
1029
|
-
emit(ImageEvent.LOADED, event);
|
|
1357
|
+
onLoadSuccess(ui, event);
|
|
1030
1358
|
}
|
|
1359
|
+
leafPaint.loadId = null;
|
|
1031
1360
|
}, (error) => {
|
|
1032
|
-
ui
|
|
1033
|
-
|
|
1034
|
-
emit(ImageEvent.ERROR, event);
|
|
1361
|
+
onLoadError(ui, event, error);
|
|
1362
|
+
leafPaint.loadId = null;
|
|
1035
1363
|
});
|
|
1036
1364
|
}
|
|
1037
1365
|
return leafPaint;
|
|
1038
1366
|
}
|
|
1039
|
-
function
|
|
1367
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1040
1368
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
if (
|
|
1369
|
+
const data = ui.__;
|
|
1370
|
+
data.__naturalWidth = image.width;
|
|
1371
|
+
data.__naturalHeight = image.height;
|
|
1372
|
+
if (data.__autoWidth || data.__autoHeight) {
|
|
1045
1373
|
ui.forceUpdate('width');
|
|
1374
|
+
if (ui.__proxyData) {
|
|
1375
|
+
ui.setProxyAttr('width', data.width);
|
|
1376
|
+
ui.setProxyAttr('height', data.height);
|
|
1377
|
+
}
|
|
1046
1378
|
return false;
|
|
1047
1379
|
}
|
|
1048
1380
|
}
|
|
1381
|
+
if (!leafPaint.data)
|
|
1382
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1049
1383
|
return true;
|
|
1050
1384
|
}
|
|
1051
|
-
function
|
|
1052
|
-
|
|
1053
|
-
|
|
1385
|
+
function onLoad(ui, event) {
|
|
1386
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1387
|
+
}
|
|
1388
|
+
function onLoadSuccess(ui, event) {
|
|
1389
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1390
|
+
}
|
|
1391
|
+
function onLoadError(ui, event, error) {
|
|
1392
|
+
event.error = error;
|
|
1393
|
+
ui.forceUpdate('surface');
|
|
1394
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1395
|
+
}
|
|
1396
|
+
function emit(ui, type, data) {
|
|
1397
|
+
if (ui.hasEvent(type))
|
|
1398
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1054
1399
|
}
|
|
1055
1400
|
|
|
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;
|
|
1401
|
+
const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
|
|
1402
|
+
const { round, abs: abs$1 } = Math;
|
|
1089
1403
|
function createPattern(ui, paint, pixelRatio) {
|
|
1090
1404
|
let { scaleX, scaleY } = ui.__world;
|
|
1091
1405
|
const id = scaleX + '-' + scaleY;
|
|
1092
1406
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
scaleY = Math.abs(scaleY);
|
|
1407
|
+
scaleX = abs$1(scaleX);
|
|
1408
|
+
scaleY = abs$1(scaleY);
|
|
1096
1409
|
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;
|
|
1410
|
+
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1100
1411
|
if (sx) {
|
|
1101
|
-
|
|
1102
|
-
copy$1(
|
|
1103
|
-
|
|
1412
|
+
imageMatrix = get$2();
|
|
1413
|
+
copy$1(imageMatrix, transform);
|
|
1414
|
+
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1104
1415
|
scaleX *= sx;
|
|
1105
1416
|
scaleY *= sy;
|
|
1106
1417
|
}
|
|
@@ -1108,38 +1419,41 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1108
1419
|
scaleY *= pixelRatio;
|
|
1109
1420
|
width *= scaleX;
|
|
1110
1421
|
height *= scaleY;
|
|
1111
|
-
|
|
1112
|
-
|
|
1422
|
+
const size = width * height;
|
|
1423
|
+
if (!repeat) {
|
|
1424
|
+
if (size > Platform.image.maxCacheSize)
|
|
1425
|
+
return false;
|
|
1426
|
+
}
|
|
1427
|
+
let maxSize = Platform.image.maxPatternSize;
|
|
1428
|
+
if (!image.isSVG) {
|
|
1429
|
+
const imageSize = image.width * image.height;
|
|
1430
|
+
if (maxSize > imageSize)
|
|
1431
|
+
maxSize = imageSize;
|
|
1113
1432
|
}
|
|
1114
|
-
if (
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1433
|
+
if (size > maxSize)
|
|
1434
|
+
imageScale = Math.sqrt(size / maxSize);
|
|
1435
|
+
if (imageScale) {
|
|
1436
|
+
scaleX /= imageScale;
|
|
1437
|
+
scaleY /= imageScale;
|
|
1438
|
+
width /= imageScale;
|
|
1439
|
+
height /= imageScale;
|
|
1119
1440
|
}
|
|
1120
1441
|
if (sx) {
|
|
1121
1442
|
scaleX /= sx;
|
|
1122
1443
|
scaleY /= sy;
|
|
1123
1444
|
}
|
|
1124
1445
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1125
|
-
if (!
|
|
1126
|
-
|
|
1446
|
+
if (!imageMatrix) {
|
|
1447
|
+
imageMatrix = get$2();
|
|
1127
1448
|
if (transform)
|
|
1128
|
-
copy$1(
|
|
1449
|
+
copy$1(imageMatrix, transform);
|
|
1129
1450
|
}
|
|
1130
|
-
|
|
1131
|
-
}
|
|
1132
|
-
const style = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'));
|
|
1133
|
-
try {
|
|
1134
|
-
if (paint.transform)
|
|
1135
|
-
paint.transform = null;
|
|
1136
|
-
if (matrix)
|
|
1137
|
-
style.setTransform ? style.setTransform(matrix) : paint.transform = matrix;
|
|
1138
|
-
}
|
|
1139
|
-
catch (_a) {
|
|
1140
|
-
paint.transform = matrix;
|
|
1451
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1141
1452
|
}
|
|
1142
|
-
|
|
1453
|
+
const canvas = image.getCanvas(width < 1 ? 1 : round(width), height < 1 ? 1 : round(height), opacity);
|
|
1454
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1455
|
+
paint.style = pattern;
|
|
1456
|
+
paint.patternId = id;
|
|
1143
1457
|
return true;
|
|
1144
1458
|
}
|
|
1145
1459
|
else {
|
|
@@ -1147,311 +1461,130 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1147
1461
|
}
|
|
1148
1462
|
}
|
|
1149
1463
|
|
|
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;
|
|
1464
|
+
/******************************************************************************
|
|
1465
|
+
Copyright (c) Microsoft Corporation.
|
|
1466
|
+
|
|
1467
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
1468
|
+
purpose with or without fee is hereby granted.
|
|
1469
|
+
|
|
1470
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1471
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1472
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1473
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1474
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1475
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1476
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
1477
|
+
***************************************************************************** */
|
|
1478
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1479
|
+
|
|
1480
|
+
|
|
1481
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1482
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1483
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1484
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1485
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1486
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1487
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1492
|
+
var e = new Error(message);
|
|
1493
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1494
|
+
};
|
|
1495
|
+
|
|
1496
|
+
const { abs } = Math;
|
|
1497
|
+
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1498
|
+
const { scaleX, scaleY } = ui.__world;
|
|
1499
|
+
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1500
|
+
return false;
|
|
1290
1501
|
}
|
|
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);
|
|
1502
|
+
else {
|
|
1503
|
+
const { data } = paint;
|
|
1504
|
+
if (allowPaint) {
|
|
1505
|
+
if (!data.repeat) {
|
|
1506
|
+
let { width, height } = data;
|
|
1507
|
+
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1508
|
+
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1509
|
+
if (data.scaleX) {
|
|
1510
|
+
width *= data.scaleX;
|
|
1511
|
+
height *= data.scaleY;
|
|
1512
|
+
}
|
|
1513
|
+
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
1514
|
+
}
|
|
1515
|
+
else {
|
|
1516
|
+
allowPaint = false;
|
|
1517
|
+
}
|
|
1311
1518
|
}
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1519
|
+
if (allowPaint) {
|
|
1520
|
+
canvas.save();
|
|
1521
|
+
canvas.clip();
|
|
1522
|
+
if (paint.blendMode)
|
|
1523
|
+
canvas.blendMode = paint.blendMode;
|
|
1524
|
+
if (data.opacity)
|
|
1525
|
+
canvas.opacity *= data.opacity;
|
|
1526
|
+
if (data.transform)
|
|
1527
|
+
canvas.transform(data.transform);
|
|
1528
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1529
|
+
canvas.restore();
|
|
1530
|
+
return true;
|
|
1316
1531
|
}
|
|
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();
|
|
1532
|
+
else {
|
|
1533
|
+
if (!paint.style || Export.running) {
|
|
1534
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1333
1535
|
}
|
|
1334
1536
|
else {
|
|
1335
|
-
|
|
1537
|
+
if (!paint.patternTask) {
|
|
1538
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1539
|
+
paint.patternTask = null;
|
|
1540
|
+
if (canvas.bounds.hit(ui.__world))
|
|
1541
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1542
|
+
ui.forceUpdate('surface');
|
|
1543
|
+
}), 300);
|
|
1544
|
+
}
|
|
1336
1545
|
}
|
|
1546
|
+
return false;
|
|
1337
1547
|
}
|
|
1338
1548
|
}
|
|
1339
1549
|
}
|
|
1340
1550
|
|
|
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;
|
|
1551
|
+
function recycleImage(attrName, data) {
|
|
1552
|
+
const paints = data['_' + attrName];
|
|
1553
|
+
if (paints instanceof Array) {
|
|
1554
|
+
let image, recycleMap, input, url;
|
|
1555
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1556
|
+
image = paints[i].image;
|
|
1557
|
+
url = image && image.url;
|
|
1558
|
+
if (url) {
|
|
1559
|
+
if (!recycleMap)
|
|
1560
|
+
recycleMap = {};
|
|
1561
|
+
recycleMap[url] = true;
|
|
1562
|
+
ImageManager.recycle(image);
|
|
1563
|
+
if (image.loading) {
|
|
1564
|
+
if (!input) {
|
|
1565
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1566
|
+
if (!(input instanceof Array))
|
|
1567
|
+
input = [input];
|
|
1568
|
+
}
|
|
1569
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1407
1572
|
}
|
|
1573
|
+
return recycleMap;
|
|
1408
1574
|
}
|
|
1575
|
+
return null;
|
|
1409
1576
|
}
|
|
1410
1577
|
|
|
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
|
-
}
|
|
1578
|
+
const PaintImageModule = {
|
|
1579
|
+
image,
|
|
1580
|
+
createData,
|
|
1581
|
+
fillOrFitMode,
|
|
1582
|
+
clipMode,
|
|
1583
|
+
repeatMode,
|
|
1584
|
+
createPattern,
|
|
1585
|
+
checkImage,
|
|
1586
|
+
recycleImage
|
|
1587
|
+
};
|
|
1455
1588
|
|
|
1456
1589
|
const defaultFrom$2 = { x: 0.5, y: 0 };
|
|
1457
1590
|
const defaultTo$2 = { x: 0.5, y: 1 };
|
|
@@ -1470,7 +1603,7 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1470
1603
|
let stop;
|
|
1471
1604
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1472
1605
|
stop = stops[i];
|
|
1473
|
-
gradient.addColorStop(stop.offset, ColorConvert
|
|
1606
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
1474
1607
|
}
|
|
1475
1608
|
}
|
|
1476
1609
|
|
|
@@ -1532,62 +1665,18 @@ function conicGradient(paint, box) {
|
|
|
1532
1665
|
return data;
|
|
1533
1666
|
}
|
|
1534
1667
|
|
|
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
|
-
});
|
|
1668
|
+
const PaintGradientModule = {
|
|
1669
|
+
linearGradient,
|
|
1670
|
+
radialGradient,
|
|
1671
|
+
conicGradient
|
|
1672
|
+
};
|
|
1584
1673
|
|
|
1585
1674
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
1586
1675
|
const tempBounds = {};
|
|
1587
1676
|
const offsetOutBounds$1 = {};
|
|
1588
|
-
function shadow(ui, current, shape
|
|
1677
|
+
function shadow(ui, current, shape) {
|
|
1589
1678
|
let copyBounds, spreadScale;
|
|
1590
|
-
const {
|
|
1679
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1591
1680
|
const { shadow } = ui.__;
|
|
1592
1681
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1593
1682
|
const other = current.getSameCanvas();
|
|
@@ -1602,21 +1691,21 @@ function shadow(ui, current, shape, _options) {
|
|
|
1602
1691
|
other.restore();
|
|
1603
1692
|
other.save();
|
|
1604
1693
|
if (worldCanvas) {
|
|
1605
|
-
other.copyWorld(other, bounds,
|
|
1606
|
-
copyBounds =
|
|
1694
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1695
|
+
copyBounds = nowWorld;
|
|
1607
1696
|
}
|
|
1608
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1697
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1609
1698
|
}
|
|
1610
|
-
if (ui.
|
|
1611
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1699
|
+
if (ui.__worldFlipped) {
|
|
1700
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1612
1701
|
}
|
|
1613
1702
|
else {
|
|
1614
1703
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1615
1704
|
}
|
|
1616
1705
|
if (end && index < end)
|
|
1617
|
-
other.
|
|
1706
|
+
other.clearWorld(copyBounds, true);
|
|
1618
1707
|
});
|
|
1619
|
-
other.recycle();
|
|
1708
|
+
other.recycle(copyBounds);
|
|
1620
1709
|
}
|
|
1621
1710
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1622
1711
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1647,9 +1736,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1647
1736
|
|
|
1648
1737
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
1649
1738
|
const offsetOutBounds = {};
|
|
1650
|
-
function innerShadow(ui, current, shape
|
|
1739
|
+
function innerShadow(ui, current, shape) {
|
|
1651
1740
|
let copyBounds, spreadScale;
|
|
1652
|
-
const {
|
|
1741
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1653
1742
|
const { innerShadow } = ui.__;
|
|
1654
1743
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1655
1744
|
const other = current.getSameCanvas();
|
|
@@ -1662,25 +1751,25 @@ function innerShadow(ui, current, shape, _options) {
|
|
|
1662
1751
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1663
1752
|
other.restore();
|
|
1664
1753
|
if (worldCanvas) {
|
|
1665
|
-
other.copyWorld(other, bounds,
|
|
1666
|
-
other.copyWorld(worldCanvas,
|
|
1667
|
-
copyBounds =
|
|
1754
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1755
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1756
|
+
copyBounds = nowWorld;
|
|
1668
1757
|
}
|
|
1669
1758
|
else {
|
|
1670
1759
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1671
1760
|
copyBounds = bounds;
|
|
1672
1761
|
}
|
|
1673
1762
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1674
|
-
if (ui.
|
|
1675
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1763
|
+
if (ui.__worldFlipped) {
|
|
1764
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1676
1765
|
}
|
|
1677
1766
|
else {
|
|
1678
1767
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1679
1768
|
}
|
|
1680
1769
|
if (end && index < end)
|
|
1681
|
-
other.
|
|
1770
|
+
other.clearWorld(copyBounds, true);
|
|
1682
1771
|
});
|
|
1683
|
-
other.recycle();
|
|
1772
|
+
other.recycle(copyBounds);
|
|
1684
1773
|
}
|
|
1685
1774
|
|
|
1686
1775
|
function blur(ui, current, origin) {
|
|
@@ -1690,12 +1779,87 @@ function blur(ui, current, origin) {
|
|
|
1690
1779
|
origin.filter = 'none';
|
|
1691
1780
|
}
|
|
1692
1781
|
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
shadow
|
|
1698
|
-
|
|
1782
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
const EffectModule = {
|
|
1786
|
+
shadow,
|
|
1787
|
+
innerShadow,
|
|
1788
|
+
blur,
|
|
1789
|
+
backgroundBlur
|
|
1790
|
+
};
|
|
1791
|
+
|
|
1792
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
1793
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
1794
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
1795
|
+
const { children } = this;
|
|
1796
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
1797
|
+
child = children[i];
|
|
1798
|
+
if (child.__.mask) {
|
|
1799
|
+
if (currentMask) {
|
|
1800
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1801
|
+
maskCanvas = contentCanvas = null;
|
|
1802
|
+
}
|
|
1803
|
+
if (child.__.maskType === 'path') {
|
|
1804
|
+
if (child.opacity < 1) {
|
|
1805
|
+
currentMask = 'opacity-path';
|
|
1806
|
+
maskOpacity = child.opacity;
|
|
1807
|
+
if (!contentCanvas)
|
|
1808
|
+
contentCanvas = getCanvas(canvas);
|
|
1809
|
+
}
|
|
1810
|
+
else {
|
|
1811
|
+
currentMask = 'path';
|
|
1812
|
+
canvas.save();
|
|
1813
|
+
}
|
|
1814
|
+
child.__clip(contentCanvas || canvas, options);
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
currentMask = 'alpha';
|
|
1818
|
+
if (!maskCanvas)
|
|
1819
|
+
maskCanvas = getCanvas(canvas);
|
|
1820
|
+
if (!contentCanvas)
|
|
1821
|
+
contentCanvas = getCanvas(canvas);
|
|
1822
|
+
child.__render(maskCanvas, options);
|
|
1823
|
+
}
|
|
1824
|
+
if (child.__.maskType !== 'clipping')
|
|
1825
|
+
continue;
|
|
1826
|
+
}
|
|
1827
|
+
if (excludeRenderBounds(child, options))
|
|
1828
|
+
continue;
|
|
1829
|
+
child.__render(contentCanvas || canvas, options);
|
|
1830
|
+
}
|
|
1831
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1832
|
+
};
|
|
1833
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
1834
|
+
switch (maskMode) {
|
|
1835
|
+
case 'alpha':
|
|
1836
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
1837
|
+
break;
|
|
1838
|
+
case 'opacity-path':
|
|
1839
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
1840
|
+
break;
|
|
1841
|
+
case 'path':
|
|
1842
|
+
canvas.restore();
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
function getCanvas(canvas) {
|
|
1846
|
+
return canvas.getSameCanvas(false, true);
|
|
1847
|
+
}
|
|
1848
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
1849
|
+
const realBounds = leaf.__nowWorld;
|
|
1850
|
+
content.resetTransform();
|
|
1851
|
+
content.opacity = 1;
|
|
1852
|
+
content.useMask(mask, realBounds);
|
|
1853
|
+
mask.recycle(realBounds);
|
|
1854
|
+
copyContent(leaf, canvas, content, 1);
|
|
1855
|
+
}
|
|
1856
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
1857
|
+
const realBounds = leaf.__nowWorld;
|
|
1858
|
+
canvas.resetTransform();
|
|
1859
|
+
canvas.opacity = maskOpacity;
|
|
1860
|
+
canvas.copyWorld(content, realBounds);
|
|
1861
|
+
content.recycle(realBounds);
|
|
1862
|
+
}
|
|
1699
1863
|
|
|
1700
1864
|
const money = '¥¥$€££¢¢';
|
|
1701
1865
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1809,7 +1973,7 @@ function getTextCase(char, textCase, firstChar) {
|
|
|
1809
1973
|
const { trimRight } = TextRowHelper;
|
|
1810
1974
|
const { Letter, Single, Before, After, Symbol, Break } = CharType;
|
|
1811
1975
|
let word, row, wordWidth, rowWidth, realWidth;
|
|
1812
|
-
let char, charWidth, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
1976
|
+
let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
1813
1977
|
let textDrawData, rows = [], bounds;
|
|
1814
1978
|
function createRows(drawData, content, style) {
|
|
1815
1979
|
textDrawData = drawData;
|
|
@@ -1820,9 +1984,11 @@ function createRows(drawData, content, style) {
|
|
|
1820
1984
|
const { width, height } = bounds;
|
|
1821
1985
|
const charMode = width || height || __letterSpacing || (textCase !== 'none');
|
|
1822
1986
|
if (charMode) {
|
|
1987
|
+
const wrap = style.textWrap !== 'none';
|
|
1988
|
+
const breakAll = style.textWrap === 'break';
|
|
1823
1989
|
paraStart = true;
|
|
1824
1990
|
lastCharType = null;
|
|
1825
|
-
wordWidth = rowWidth = 0;
|
|
1991
|
+
startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
|
|
1826
1992
|
word = { data: [] }, row = { words: [] };
|
|
1827
1993
|
for (let i = 0, len = content.length; i < len; i++) {
|
|
1828
1994
|
char = content[i];
|
|
@@ -1838,21 +2004,31 @@ function createRows(drawData, content, style) {
|
|
|
1838
2004
|
if (charType === Letter && textCase !== 'none')
|
|
1839
2005
|
char = getTextCase(char, textCase, !wordWidth);
|
|
1840
2006
|
charWidth = canvas.measureText(char).width;
|
|
1841
|
-
if (__letterSpacing)
|
|
2007
|
+
if (__letterSpacing) {
|
|
2008
|
+
if (__letterSpacing < 0)
|
|
2009
|
+
charSize = charWidth;
|
|
1842
2010
|
charWidth += __letterSpacing;
|
|
2011
|
+
}
|
|
1843
2012
|
langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
|
|
1844
2013
|
afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
|
|
1845
2014
|
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)) {
|
|
2015
|
+
if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
|
|
2016
|
+
if (breakAll) {
|
|
1850
2017
|
if (wordWidth)
|
|
1851
2018
|
addWord();
|
|
1852
2019
|
addRow();
|
|
1853
2020
|
}
|
|
1854
2021
|
else {
|
|
1855
|
-
|
|
2022
|
+
if (!afterBreak)
|
|
2023
|
+
afterBreak = charType === Letter && lastCharType == After;
|
|
2024
|
+
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2025
|
+
if (wordWidth)
|
|
2026
|
+
addWord();
|
|
2027
|
+
addRow();
|
|
2028
|
+
}
|
|
2029
|
+
else {
|
|
2030
|
+
addRow();
|
|
2031
|
+
}
|
|
1856
2032
|
}
|
|
1857
2033
|
}
|
|
1858
2034
|
if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
|
|
@@ -1889,6 +2065,8 @@ function createRows(drawData, content, style) {
|
|
|
1889
2065
|
}
|
|
1890
2066
|
}
|
|
1891
2067
|
function addChar(char, width) {
|
|
2068
|
+
if (charSize && !startCharSize)
|
|
2069
|
+
startCharSize = charSize;
|
|
1892
2070
|
word.data.push({ char, width });
|
|
1893
2071
|
wordWidth += width;
|
|
1894
2072
|
}
|
|
@@ -1905,6 +2083,11 @@ function addRow() {
|
|
|
1905
2083
|
row.paraStart = true;
|
|
1906
2084
|
paraStart = false;
|
|
1907
2085
|
}
|
|
2086
|
+
if (charSize) {
|
|
2087
|
+
row.startCharSize = startCharSize;
|
|
2088
|
+
row.endCharSize = charSize;
|
|
2089
|
+
startCharSize = 0;
|
|
2090
|
+
}
|
|
1908
2091
|
row.width = rowWidth;
|
|
1909
2092
|
if (bounds.width)
|
|
1910
2093
|
trimRight(row);
|
|
@@ -1915,7 +2098,7 @@ function addRow() {
|
|
|
1915
2098
|
|
|
1916
2099
|
const CharMode = 0;
|
|
1917
2100
|
const WordMode = 1;
|
|
1918
|
-
const
|
|
2101
|
+
const TextMode = 2;
|
|
1919
2102
|
function layoutChar(drawData, style, width, _height) {
|
|
1920
2103
|
const { rows } = drawData;
|
|
1921
2104
|
const { textAlign, paraIndent, letterSpacing } = style;
|
|
@@ -1924,15 +2107,12 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1924
2107
|
if (row.words) {
|
|
1925
2108
|
indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
|
|
1926
2109
|
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.
|
|
2110
|
+
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
|
|
2111
|
+
if (row.isOverflow && !letterSpacing)
|
|
2112
|
+
row.textMode = true;
|
|
2113
|
+
if (mode === TextMode) {
|
|
1930
2114
|
row.x += indentWidth;
|
|
1931
|
-
row
|
|
1932
|
-
word.data.forEach(char => {
|
|
1933
|
-
row.text += char.char;
|
|
1934
|
-
});
|
|
1935
|
-
});
|
|
2115
|
+
toTextChar$1(row);
|
|
1936
2116
|
}
|
|
1937
2117
|
else {
|
|
1938
2118
|
row.x += indentWidth;
|
|
@@ -1958,6 +2138,14 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1958
2138
|
}
|
|
1959
2139
|
});
|
|
1960
2140
|
}
|
|
2141
|
+
function toTextChar$1(row) {
|
|
2142
|
+
row.text = '';
|
|
2143
|
+
row.words.forEach(word => {
|
|
2144
|
+
word.data.forEach(char => {
|
|
2145
|
+
row.text += char.char;
|
|
2146
|
+
});
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
1961
2149
|
function toWordChar(data, charX, wordChar) {
|
|
1962
2150
|
data.forEach(char => {
|
|
1963
2151
|
wordChar.char += char.char;
|
|
@@ -1978,10 +2166,10 @@ function toChar(data, charX, rowData) {
|
|
|
1978
2166
|
|
|
1979
2167
|
function layoutText(drawData, style) {
|
|
1980
2168
|
const { rows, bounds } = drawData;
|
|
1981
|
-
const { __lineHeight, __baseLine, textAlign, verticalAlign, paraSpacing
|
|
2169
|
+
const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
|
|
1982
2170
|
let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
1983
2171
|
let starY = __baseLine;
|
|
1984
|
-
if (
|
|
2172
|
+
if (__clipText && realHeight > height) {
|
|
1985
2173
|
realHeight = Math.max(height, __lineHeight);
|
|
1986
2174
|
drawData.overflow = rows.length;
|
|
1987
2175
|
}
|
|
@@ -1995,7 +2183,7 @@ function layoutText(drawData, style) {
|
|
|
1995
2183
|
}
|
|
1996
2184
|
}
|
|
1997
2185
|
starY += y;
|
|
1998
|
-
let row;
|
|
2186
|
+
let row, rowX, rowWidth;
|
|
1999
2187
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2000
2188
|
row = rows[i];
|
|
2001
2189
|
row.x = x;
|
|
@@ -2014,53 +2202,74 @@ function layoutText(drawData, style) {
|
|
|
2014
2202
|
row.isOverflow = true;
|
|
2015
2203
|
drawData.overflow = i + 1;
|
|
2016
2204
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2205
|
+
rowX = row.x;
|
|
2206
|
+
rowWidth = row.width;
|
|
2207
|
+
if (__letterSpacing < 0) {
|
|
2208
|
+
if (row.width < 0) {
|
|
2209
|
+
rowWidth = -row.width + style.fontSize + __letterSpacing;
|
|
2210
|
+
rowX -= rowWidth;
|
|
2211
|
+
rowWidth += style.fontSize;
|
|
2212
|
+
}
|
|
2213
|
+
else {
|
|
2214
|
+
rowWidth -= __letterSpacing;
|
|
2215
|
+
}
|
|
2024
2216
|
}
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2217
|
+
if (rowX < bounds.x)
|
|
2218
|
+
bounds.x = rowX;
|
|
2219
|
+
if (rowWidth > bounds.width)
|
|
2220
|
+
bounds.width = rowWidth;
|
|
2221
|
+
if (__clipText && width && width < rowWidth) {
|
|
2222
|
+
row.isOverflow = true;
|
|
2223
|
+
if (!drawData.overflow)
|
|
2224
|
+
drawData.overflow = rows.length;
|
|
2030
2225
|
}
|
|
2031
2226
|
}
|
|
2032
2227
|
bounds.y = y;
|
|
2033
2228
|
bounds.height = realHeight;
|
|
2034
2229
|
}
|
|
2035
2230
|
|
|
2036
|
-
function clipText(drawData,
|
|
2231
|
+
function clipText(drawData, style) {
|
|
2037
2232
|
const { rows, overflow } = drawData;
|
|
2233
|
+
let { textOverflow } = style;
|
|
2038
2234
|
rows.splice(overflow);
|
|
2039
2235
|
if (textOverflow !== 'hide') {
|
|
2040
2236
|
if (textOverflow === 'ellipsis')
|
|
2041
2237
|
textOverflow = '...';
|
|
2238
|
+
let char, charRight;
|
|
2042
2239
|
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2043
|
-
const
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2240
|
+
const right = style.x + style.width - ellipsisWidth;
|
|
2241
|
+
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2242
|
+
list.forEach(row => {
|
|
2243
|
+
if (row.isOverflow && row.data) {
|
|
2244
|
+
let end = row.data.length - 1;
|
|
2245
|
+
for (let i = end; i > -1; i--) {
|
|
2246
|
+
char = row.data[i];
|
|
2247
|
+
charRight = char.x + char.width;
|
|
2248
|
+
if (i === end && charRight < right) {
|
|
2249
|
+
break;
|
|
2250
|
+
}
|
|
2251
|
+
else if (charRight < right && char.char !== ' ') {
|
|
2252
|
+
row.data.splice(i + 1);
|
|
2253
|
+
row.width -= char.width;
|
|
2254
|
+
break;
|
|
2255
|
+
}
|
|
2256
|
+
row.width -= char.width;
|
|
2257
|
+
}
|
|
2258
|
+
row.width += ellipsisWidth;
|
|
2259
|
+
row.data.push({ char: textOverflow, x: charRight });
|
|
2260
|
+
if (row.textMode)
|
|
2261
|
+
toTextChar(row);
|
|
2057
2262
|
}
|
|
2058
|
-
|
|
2059
|
-
}
|
|
2060
|
-
row.width += ellipsisWidth;
|
|
2061
|
-
row.data.push({ char: textOverflow, x: charRight });
|
|
2263
|
+
});
|
|
2062
2264
|
}
|
|
2063
2265
|
}
|
|
2266
|
+
function toTextChar(row) {
|
|
2267
|
+
row.text = '';
|
|
2268
|
+
row.data.forEach(char => {
|
|
2269
|
+
row.text += char.char;
|
|
2270
|
+
});
|
|
2271
|
+
row.data = null;
|
|
2272
|
+
}
|
|
2064
2273
|
|
|
2065
2274
|
function decorationText(drawData, style) {
|
|
2066
2275
|
const { fontSize } = style;
|
|
@@ -2074,101 +2283,163 @@ function decorationText(drawData, style) {
|
|
|
2074
2283
|
}
|
|
2075
2284
|
}
|
|
2076
2285
|
|
|
2077
|
-
const
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
if (
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2286
|
+
const { top, right, bottom, left } = Direction4;
|
|
2287
|
+
function getDrawData(content, style) {
|
|
2288
|
+
if (typeof content !== 'string')
|
|
2289
|
+
content = String(content);
|
|
2290
|
+
let x = 0, y = 0;
|
|
2291
|
+
let width = style.__getInput('width') || 0;
|
|
2292
|
+
let height = style.__getInput('height') || 0;
|
|
2293
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2294
|
+
if (padding) {
|
|
2295
|
+
if (width) {
|
|
2296
|
+
x = padding[left];
|
|
2297
|
+
width -= (padding[right] + padding[left]);
|
|
2298
|
+
}
|
|
2299
|
+
if (height) {
|
|
2300
|
+
y = padding[top];
|
|
2301
|
+
height -= (padding[top] + padding[bottom]);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
const drawData = {
|
|
2305
|
+
bounds: { x, y, width, height },
|
|
2306
|
+
rows: [],
|
|
2307
|
+
paraNumber: 0,
|
|
2308
|
+
font: Platform.canvas.font = __font
|
|
2309
|
+
};
|
|
2310
|
+
createRows(drawData, content, style);
|
|
2311
|
+
if (padding)
|
|
2312
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2313
|
+
layoutText(drawData, style);
|
|
2314
|
+
layoutChar(drawData, style, width);
|
|
2315
|
+
if (drawData.overflow)
|
|
2316
|
+
clipText(drawData, style);
|
|
2317
|
+
if (textDecoration !== 'none')
|
|
2318
|
+
decorationText(drawData, style);
|
|
2319
|
+
return drawData;
|
|
2320
|
+
}
|
|
2321
|
+
function padAutoText(padding, drawData, style, width, height) {
|
|
2322
|
+
if (!width) {
|
|
2323
|
+
switch (style.textAlign) {
|
|
2324
|
+
case 'left':
|
|
2325
|
+
offsetText(drawData, 'x', padding[left]);
|
|
2326
|
+
break;
|
|
2327
|
+
case 'right':
|
|
2328
|
+
offsetText(drawData, 'x', -padding[right]);
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
if (!height) {
|
|
2332
|
+
switch (style.verticalAlign) {
|
|
2333
|
+
case 'top':
|
|
2334
|
+
offsetText(drawData, 'y', padding[top]);
|
|
2335
|
+
break;
|
|
2336
|
+
case 'bottom':
|
|
2337
|
+
offsetText(drawData, 'y', -padding[bottom]);
|
|
2096
2338
|
}
|
|
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
2339
|
}
|
|
2340
|
+
}
|
|
2341
|
+
function offsetText(drawData, attrName, value) {
|
|
2342
|
+
const { bounds, rows } = drawData;
|
|
2343
|
+
bounds[attrName] += value;
|
|
2344
|
+
for (let i = 0; i < rows.length; i++)
|
|
2345
|
+
rows[i][attrName] += value;
|
|
2346
|
+
}
|
|
2347
|
+
|
|
2348
|
+
const TextConvertModule = {
|
|
2349
|
+
getDrawData
|
|
2112
2350
|
};
|
|
2113
2351
|
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2352
|
+
function string(color, opacity) {
|
|
2353
|
+
if (typeof color === 'string')
|
|
2354
|
+
return color;
|
|
2355
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2356
|
+
if (opacity)
|
|
2357
|
+
a *= opacity;
|
|
2358
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2359
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
const ColorConvertModule = {
|
|
2363
|
+
string
|
|
2124
2364
|
};
|
|
2125
2365
|
|
|
2126
|
-
const
|
|
2366
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2367
|
+
function getTrimBounds(canvas) {
|
|
2368
|
+
const { width, height } = canvas.view;
|
|
2369
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2370
|
+
let x, y, pointBounds, index = 0;
|
|
2371
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2372
|
+
if (data[i + 3] !== 0) {
|
|
2373
|
+
x = index % width;
|
|
2374
|
+
y = (index - x) / width;
|
|
2375
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2376
|
+
}
|
|
2377
|
+
index++;
|
|
2378
|
+
}
|
|
2379
|
+
const bounds = new Bounds();
|
|
2380
|
+
toBounds(pointBounds, bounds);
|
|
2381
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2382
|
+
}
|
|
2383
|
+
|
|
2384
|
+
const ExportModule = {
|
|
2127
2385
|
export(leaf, filename, options) {
|
|
2386
|
+
this.running = true;
|
|
2128
2387
|
return addTask((success) => new Promise((resolve) => {
|
|
2388
|
+
const over = (result) => {
|
|
2389
|
+
success(result);
|
|
2390
|
+
resolve();
|
|
2391
|
+
this.running = false;
|
|
2392
|
+
};
|
|
2129
2393
|
const { leafer } = leaf;
|
|
2130
2394
|
if (leafer) {
|
|
2131
2395
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2132
|
-
let
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2396
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2397
|
+
options = FileHelper.getExportOptions(options);
|
|
2398
|
+
const { scale, slice, trim } = options;
|
|
2399
|
+
const pixelRatio = options.pixelRatio || 1;
|
|
2400
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2401
|
+
const fill = options.fill === undefined ? ((leaf.isLeafer && screenshot) ? leaf.fill : '') : options.fill;
|
|
2402
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
2403
|
+
if (screenshot) {
|
|
2404
|
+
renderBounds = screenshot === true ? (leaf.isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2139
2405
|
}
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
break;
|
|
2147
|
-
case 'number':
|
|
2148
|
-
quality = options;
|
|
2149
|
-
break;
|
|
2150
|
-
case 'boolean':
|
|
2151
|
-
blob = options;
|
|
2406
|
+
else {
|
|
2407
|
+
const { localTransform, __world: world } = leaf;
|
|
2408
|
+
matrix.set(world).divide(localTransform).invert();
|
|
2409
|
+
scaleX = 1 / (world.scaleX / leaf.scaleX);
|
|
2410
|
+
scaleY = 1 / (world.scaleY / leaf.scaleY);
|
|
2411
|
+
renderBounds = leaf.getBounds('render', 'local');
|
|
2152
2412
|
}
|
|
2153
|
-
let
|
|
2154
|
-
if (
|
|
2155
|
-
|
|
2413
|
+
let { x, y, width, height } = renderBounds;
|
|
2414
|
+
if (scale) {
|
|
2415
|
+
matrix.scale(scale);
|
|
2416
|
+
width *= scale, height *= scale;
|
|
2417
|
+
scaleX *= scale, scaleY *= scale;
|
|
2156
2418
|
}
|
|
2157
|
-
|
|
2158
|
-
|
|
2419
|
+
let canvas = Creator.canvas({ width: Math.ceil(width), height: Math.ceil(width), pixelRatio });
|
|
2420
|
+
const renderOptions = { matrix: matrix.translate(-x, -y).withScale(scaleX, scaleY) };
|
|
2421
|
+
if (slice) {
|
|
2422
|
+
leaf = leafer;
|
|
2423
|
+
renderOptions.bounds = canvas.bounds;
|
|
2159
2424
|
}
|
|
2160
|
-
|
|
2161
|
-
|
|
2425
|
+
canvas.save();
|
|
2426
|
+
leaf.__render(canvas, renderOptions);
|
|
2427
|
+
canvas.restore();
|
|
2428
|
+
if (trim) {
|
|
2429
|
+
trimBounds = getTrimBounds(canvas);
|
|
2430
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2431
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2432
|
+
canvas = Creator.canvas(config);
|
|
2433
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2162
2434
|
}
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2435
|
+
if (needFill)
|
|
2436
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2437
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2438
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2167
2439
|
}));
|
|
2168
2440
|
}
|
|
2169
2441
|
else {
|
|
2170
|
-
|
|
2171
|
-
resolve();
|
|
2442
|
+
over({ data: false });
|
|
2172
2443
|
}
|
|
2173
2444
|
}));
|
|
2174
2445
|
}
|
|
@@ -2182,12 +2453,19 @@ function addTask(task) {
|
|
|
2182
2453
|
});
|
|
2183
2454
|
}
|
|
2184
2455
|
|
|
2185
|
-
Object.assign(
|
|
2186
|
-
Object.assign(
|
|
2187
|
-
Object.assign(
|
|
2188
|
-
Object.assign(
|
|
2189
|
-
Object.assign(
|
|
2456
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
2457
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
2458
|
+
Object.assign(Paint, PaintModule);
|
|
2459
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
2460
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
2461
|
+
Object.assign(Effect, EffectModule);
|
|
2462
|
+
Object.assign(Export, ExportModule);
|
|
2190
2463
|
|
|
2464
|
+
Object.assign(Creator, {
|
|
2465
|
+
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
2466
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2467
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
2468
|
+
});
|
|
2191
2469
|
useCanvas();
|
|
2192
2470
|
|
|
2193
2471
|
export { Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|