@leafer-ui/worker 1.0.0-rc.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/worker.esm.js +1143 -830
- package/dist/worker.esm.min.js +1 -1
- package/dist/worker.js +7180 -6044
- package/dist/worker.min.js +1 -1
- package/dist/worker.module.js +7152 -6035
- package/dist/worker.module.min.js +1 -1
- package/package.json +9 -6
- package/src/index.ts +12 -1
- package/types/index.d.ts +1 -0
package/dist/worker.esm.js
CHANGED
|
@@ -1,8 +1,96 @@
|
|
|
1
|
-
import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager,
|
|
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, AlignHelper, ImageEvent, AroundHelper, 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
|
+
download(_url, _filename) { return undefined; },
|
|
52
|
+
loadImage(src) {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
let req = new XMLHttpRequest();
|
|
55
|
+
req.open('GET', Platform.image.getRealURL(src), true);
|
|
56
|
+
req.responseType = "blob";
|
|
57
|
+
req.onload = () => {
|
|
58
|
+
createImageBitmap(req.response).then(img => {
|
|
59
|
+
resolve(img);
|
|
60
|
+
}).catch(e => {
|
|
61
|
+
reject(e);
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
req.onerror = (e) => reject(e);
|
|
65
|
+
req.send();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
Platform.canvas = Creator.canvas();
|
|
70
|
+
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
71
|
+
}
|
|
72
|
+
Platform.name = 'web';
|
|
73
|
+
Platform.isWorker = true;
|
|
74
|
+
Platform.requestRender = function (render) { requestAnimationFrame(render); };
|
|
75
|
+
Platform.devicePixelRatio = 1;
|
|
76
|
+
const { userAgent } = navigator;
|
|
77
|
+
if (userAgent.indexOf("Firefox") > -1) {
|
|
78
|
+
Platform.conicGradientRotate90 = true;
|
|
79
|
+
Platform.intWheelDeltaY = true;
|
|
80
|
+
}
|
|
81
|
+
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
82
|
+
Platform.fullImageShadow = true;
|
|
83
|
+
}
|
|
84
|
+
if (userAgent.indexOf('Windows') > -1) {
|
|
85
|
+
Platform.os = 'Windows';
|
|
86
|
+
Platform.intWheelDeltaY = true;
|
|
87
|
+
}
|
|
88
|
+
else if (userAgent.indexOf('Mac') > -1) {
|
|
89
|
+
Platform.os = 'Mac';
|
|
90
|
+
}
|
|
91
|
+
else if (userAgent.indexOf('Linux') > -1) {
|
|
92
|
+
Platform.os = 'Linux';
|
|
93
|
+
}
|
|
6
94
|
|
|
7
95
|
class Watcher {
|
|
8
96
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -185,7 +273,7 @@ class LayoutBlockData {
|
|
|
185
273
|
}
|
|
186
274
|
|
|
187
275
|
const { updateAllMatrix, updateAllChange } = LeafHelper;
|
|
188
|
-
const debug$
|
|
276
|
+
const debug$2 = Debug.get('Layouter');
|
|
189
277
|
class Layouter {
|
|
190
278
|
constructor(target, userConfig) {
|
|
191
279
|
this.totalTimes = 0;
|
|
@@ -220,7 +308,7 @@ class Layouter {
|
|
|
220
308
|
target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
221
309
|
}
|
|
222
310
|
catch (e) {
|
|
223
|
-
debug$
|
|
311
|
+
debug$2.error(e);
|
|
224
312
|
}
|
|
225
313
|
this.layoutedBlocks = null;
|
|
226
314
|
}
|
|
@@ -234,9 +322,9 @@ class Layouter {
|
|
|
234
322
|
}
|
|
235
323
|
layoutOnce() {
|
|
236
324
|
if (this.layouting)
|
|
237
|
-
return debug$
|
|
325
|
+
return debug$2.warn('layouting');
|
|
238
326
|
if (this.times > 3)
|
|
239
|
-
return debug$
|
|
327
|
+
return debug$2.warn('layout max times');
|
|
240
328
|
this.times++;
|
|
241
329
|
this.totalTimes++;
|
|
242
330
|
this.layouting = true;
|
|
@@ -302,9 +390,11 @@ class Layouter {
|
|
|
302
390
|
updateAllChange(target);
|
|
303
391
|
}
|
|
304
392
|
addExtra(leaf) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
393
|
+
if (!this.__updatedList.has(leaf)) {
|
|
394
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
395
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
396
|
+
updatedList.add(leaf);
|
|
397
|
+
}
|
|
308
398
|
}
|
|
309
399
|
createBlock(data) {
|
|
310
400
|
return new LayoutBlockData(data);
|
|
@@ -338,7 +428,7 @@ class Layouter {
|
|
|
338
428
|
}
|
|
339
429
|
}
|
|
340
430
|
|
|
341
|
-
const debug = Debug.get('Renderer');
|
|
431
|
+
const debug$1 = Debug.get('Renderer');
|
|
342
432
|
class Renderer {
|
|
343
433
|
get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
|
|
344
434
|
constructor(target, canvas, userConfig) {
|
|
@@ -376,7 +466,7 @@ class Renderer {
|
|
|
376
466
|
const { target } = this;
|
|
377
467
|
this.times = 0;
|
|
378
468
|
this.totalBounds = new Bounds();
|
|
379
|
-
debug.log(target.innerName, '--->');
|
|
469
|
+
debug$1.log(target.innerName, '--->');
|
|
380
470
|
try {
|
|
381
471
|
this.emitRender(RenderEvent.START);
|
|
382
472
|
this.renderOnce(callback);
|
|
@@ -385,9 +475,9 @@ class Renderer {
|
|
|
385
475
|
}
|
|
386
476
|
catch (e) {
|
|
387
477
|
this.rendering = false;
|
|
388
|
-
debug.error(e);
|
|
478
|
+
debug$1.error(e);
|
|
389
479
|
}
|
|
390
|
-
debug.log('-------------|');
|
|
480
|
+
debug$1.log('-------------|');
|
|
391
481
|
}
|
|
392
482
|
renderAgain() {
|
|
393
483
|
if (this.rendering) {
|
|
@@ -399,9 +489,9 @@ class Renderer {
|
|
|
399
489
|
}
|
|
400
490
|
renderOnce(callback) {
|
|
401
491
|
if (this.rendering)
|
|
402
|
-
return debug.warn('rendering');
|
|
492
|
+
return debug$1.warn('rendering');
|
|
403
493
|
if (this.times > 3)
|
|
404
|
-
return debug.warn('render max times');
|
|
494
|
+
return debug$1.warn('render max times');
|
|
405
495
|
this.times++;
|
|
406
496
|
this.totalTimes++;
|
|
407
497
|
this.rendering = true;
|
|
@@ -414,6 +504,10 @@ class Renderer {
|
|
|
414
504
|
}
|
|
415
505
|
else {
|
|
416
506
|
this.requestLayout();
|
|
507
|
+
if (this.ignore) {
|
|
508
|
+
this.ignore = this.rendering = false;
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
417
511
|
this.emitRender(RenderEvent.BEFORE);
|
|
418
512
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
419
513
|
this.partRender();
|
|
@@ -434,7 +528,7 @@ class Renderer {
|
|
|
434
528
|
partRender() {
|
|
435
529
|
const { canvas, updateBlocks: list } = this;
|
|
436
530
|
if (!list)
|
|
437
|
-
return debug.warn('PartRender: need update attr');
|
|
531
|
+
return debug$1.warn('PartRender: need update attr');
|
|
438
532
|
this.mergeBlocks();
|
|
439
533
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
440
534
|
this.clipRender(block); });
|
|
@@ -450,7 +544,7 @@ class Renderer {
|
|
|
450
544
|
canvas.clear();
|
|
451
545
|
}
|
|
452
546
|
else {
|
|
453
|
-
bounds.spread(
|
|
547
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
454
548
|
canvas.clearWorld(bounds, true);
|
|
455
549
|
canvas.clipWorld(bounds, true);
|
|
456
550
|
}
|
|
@@ -503,12 +597,12 @@ class Renderer {
|
|
|
503
597
|
const startTime = Date.now();
|
|
504
598
|
Platform.requestRender(() => {
|
|
505
599
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
506
|
-
if (this.
|
|
507
|
-
|
|
600
|
+
if (this.running) {
|
|
601
|
+
this.target.emit(AnimateEvent.FRAME);
|
|
602
|
+
if (this.changed && this.canvas.view)
|
|
508
603
|
this.render();
|
|
604
|
+
this.target.emit(RenderEvent.NEXT);
|
|
509
605
|
}
|
|
510
|
-
if (this.running)
|
|
511
|
-
this.target.emit(AnimateEvent.FRAME);
|
|
512
606
|
if (this.target)
|
|
513
607
|
this.__requestRender();
|
|
514
608
|
});
|
|
@@ -521,9 +615,12 @@ class Renderer {
|
|
|
521
615
|
const bounds = new Bounds(0, 0, width, height);
|
|
522
616
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
523
617
|
this.addBlock(this.canvas.bounds);
|
|
524
|
-
this.target.forceUpdate('
|
|
618
|
+
this.target.forceUpdate('surface');
|
|
619
|
+
return;
|
|
525
620
|
}
|
|
526
621
|
}
|
|
622
|
+
this.addBlock(new Bounds(0, 0, 1, 1));
|
|
623
|
+
this.changed = true;
|
|
527
624
|
}
|
|
528
625
|
__onLayoutEnd(event) {
|
|
529
626
|
if (event.data)
|
|
@@ -534,7 +631,7 @@ class Renderer {
|
|
|
534
631
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
535
632
|
if (empty) {
|
|
536
633
|
if (!leaf.isLeafer)
|
|
537
|
-
debug.tip(leaf.innerName, ': empty');
|
|
634
|
+
debug$1.tip(leaf.innerName, ': empty');
|
|
538
635
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
539
636
|
}
|
|
540
637
|
return empty;
|
|
@@ -561,23 +658,13 @@ class Renderer {
|
|
|
561
658
|
if (this.target) {
|
|
562
659
|
this.stop();
|
|
563
660
|
this.__removeListenEvents();
|
|
564
|
-
this.target = null;
|
|
565
|
-
this.canvas = null;
|
|
566
|
-
this.config = null;
|
|
661
|
+
this.target = this.canvas = this.config = null;
|
|
567
662
|
}
|
|
568
663
|
}
|
|
569
664
|
}
|
|
570
665
|
|
|
571
|
-
var AnswerType;
|
|
572
|
-
(function (AnswerType) {
|
|
573
|
-
AnswerType[AnswerType["No"] = 0] = "No";
|
|
574
|
-
AnswerType[AnswerType["Yes"] = 1] = "Yes";
|
|
575
|
-
AnswerType[AnswerType["NoAndSkip"] = 2] = "NoAndSkip";
|
|
576
|
-
AnswerType[AnswerType["YesAndSkip"] = 3] = "YesAndSkip";
|
|
577
|
-
})(AnswerType || (AnswerType = {}));
|
|
578
|
-
|
|
579
666
|
const { hitRadiusPoint } = BoundsHelper;
|
|
580
|
-
class
|
|
667
|
+
class Picker {
|
|
581
668
|
constructor(target, selector) {
|
|
582
669
|
this.target = target;
|
|
583
670
|
this.selector = selector;
|
|
@@ -589,33 +676,41 @@ class Pather {
|
|
|
589
676
|
options = {};
|
|
590
677
|
const through = options.through || false;
|
|
591
678
|
const ignoreHittable = options.ignoreHittable || false;
|
|
679
|
+
const target = options.target || this.target;
|
|
592
680
|
this.exclude = options.exclude || null;
|
|
593
681
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
594
|
-
this.findList =
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const
|
|
682
|
+
this.findList = new LeafList(options.findList);
|
|
683
|
+
if (!options.findList)
|
|
684
|
+
this.hitBranch(target);
|
|
685
|
+
const { list } = this.findList;
|
|
686
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
598
687
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
599
688
|
this.clear();
|
|
600
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
689
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
601
690
|
}
|
|
602
|
-
getBestMatchLeaf() {
|
|
603
|
-
|
|
604
|
-
if (targets.length > 1) {
|
|
691
|
+
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
692
|
+
if (list.length) {
|
|
605
693
|
let find;
|
|
606
|
-
this.findList =
|
|
694
|
+
this.findList = new LeafList();
|
|
607
695
|
const { x, y } = this.point;
|
|
608
696
|
const point = { x, y, radiusX: 0, radiusY: 0 };
|
|
609
|
-
for (let i = 0, len =
|
|
610
|
-
find =
|
|
611
|
-
if (LeafHelper.worldHittable(find)) {
|
|
697
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
698
|
+
find = list[i];
|
|
699
|
+
if (ignoreHittable || LeafHelper.worldHittable(find)) {
|
|
612
700
|
this.hitChild(find, point);
|
|
613
701
|
if (this.findList.length)
|
|
614
|
-
return this.findList[0];
|
|
702
|
+
return this.findList.list[0];
|
|
615
703
|
}
|
|
616
704
|
}
|
|
617
705
|
}
|
|
618
|
-
|
|
706
|
+
if (bottomList) {
|
|
707
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
708
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
709
|
+
if (this.findList.length)
|
|
710
|
+
return this.findList.list[0];
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
return list[0];
|
|
619
714
|
}
|
|
620
715
|
getPath(leaf) {
|
|
621
716
|
const path = new LeafList();
|
|
@@ -627,7 +722,7 @@ class Pather {
|
|
|
627
722
|
return path;
|
|
628
723
|
}
|
|
629
724
|
getHitablePath(leaf) {
|
|
630
|
-
const path = this.getPath(leaf);
|
|
725
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
631
726
|
let item, hittablePath = new LeafList();
|
|
632
727
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
633
728
|
item = path.list[i];
|
|
@@ -657,12 +752,15 @@ class Pather {
|
|
|
657
752
|
}
|
|
658
753
|
return throughPath;
|
|
659
754
|
}
|
|
755
|
+
hitBranch(branch) {
|
|
756
|
+
this.eachFind(branch.children, branch.__onlyHitMask);
|
|
757
|
+
}
|
|
660
758
|
eachFind(children, hitMask) {
|
|
661
759
|
let child, hit;
|
|
662
760
|
const { point } = this, len = children.length;
|
|
663
761
|
for (let i = len - 1; i > -1; i--) {
|
|
664
762
|
child = children[i];
|
|
665
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
763
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
666
764
|
continue;
|
|
667
765
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
668
766
|
if (child.isBranch) {
|
|
@@ -678,11 +776,15 @@ class Pather {
|
|
|
678
776
|
}
|
|
679
777
|
}
|
|
680
778
|
}
|
|
681
|
-
hitChild(child, point) {
|
|
779
|
+
hitChild(child, point, proxy) {
|
|
682
780
|
if (this.exclude && this.exclude.has(child))
|
|
683
781
|
return;
|
|
684
|
-
if (child.__hitWorld(point))
|
|
685
|
-
|
|
782
|
+
if (child.__hitWorld(point)) {
|
|
783
|
+
const { parent } = child;
|
|
784
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
|
|
785
|
+
return;
|
|
786
|
+
this.findList.add(proxy || child);
|
|
787
|
+
}
|
|
686
788
|
}
|
|
687
789
|
clear() {
|
|
688
790
|
this.point = null;
|
|
@@ -694,7 +796,8 @@ class Pather {
|
|
|
694
796
|
}
|
|
695
797
|
}
|
|
696
798
|
|
|
697
|
-
const { Yes, NoAndSkip, YesAndSkip } =
|
|
799
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer;
|
|
800
|
+
const idCondition = {}, classNameCondition = {}, tagCondition = {};
|
|
698
801
|
class Selector {
|
|
699
802
|
constructor(target, userConfig) {
|
|
700
803
|
this.config = {};
|
|
@@ -704,12 +807,13 @@ class Selector {
|
|
|
704
807
|
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
705
808
|
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
706
809
|
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
707
|
-
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
810
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
|
|
811
|
+
tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
708
812
|
};
|
|
709
813
|
this.target = target;
|
|
710
814
|
if (userConfig)
|
|
711
815
|
this.config = DataHelper.default(userConfig, this.config);
|
|
712
|
-
this.
|
|
816
|
+
this.picker = new Picker(target, this);
|
|
713
817
|
this.__listenEvents();
|
|
714
818
|
}
|
|
715
819
|
getBy(condition, branch, one, options) {
|
|
@@ -720,12 +824,25 @@ class Selector {
|
|
|
720
824
|
case 'string':
|
|
721
825
|
switch (condition[0]) {
|
|
722
826
|
case '#':
|
|
723
|
-
|
|
724
|
-
|
|
827
|
+
idCondition.id = condition.substring(1), condition = idCondition;
|
|
828
|
+
break;
|
|
725
829
|
case '.':
|
|
726
|
-
|
|
830
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition;
|
|
831
|
+
break;
|
|
727
832
|
default:
|
|
728
|
-
|
|
833
|
+
tagCondition.tag = condition, condition = tagCondition;
|
|
834
|
+
}
|
|
835
|
+
case 'object':
|
|
836
|
+
if (condition.id !== undefined) {
|
|
837
|
+
const leaf = this.getById(condition.id, branch);
|
|
838
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
839
|
+
}
|
|
840
|
+
else if (condition.tag) {
|
|
841
|
+
const { tag } = condition, isArray = tag instanceof Array;
|
|
842
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
|
|
843
|
+
}
|
|
844
|
+
else {
|
|
845
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className);
|
|
729
846
|
}
|
|
730
847
|
case 'function':
|
|
731
848
|
return this.getByMethod(condition, branch, one, options);
|
|
@@ -734,7 +851,7 @@ class Selector {
|
|
|
734
851
|
getByPoint(hitPoint, hitRadius, options) {
|
|
735
852
|
if (Platform.name === 'node')
|
|
736
853
|
this.target.emit(LayoutEvent.CHECK_UPDATE);
|
|
737
|
-
return this.
|
|
854
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
738
855
|
}
|
|
739
856
|
getByInnerId(innerId, branch) {
|
|
740
857
|
const cache = this.innerIdMap[innerId];
|
|
@@ -810,7 +927,7 @@ class Selector {
|
|
|
810
927
|
destroy() {
|
|
811
928
|
if (this.__eventIds.length) {
|
|
812
929
|
this.__removeListenEvents();
|
|
813
|
-
this.
|
|
930
|
+
this.picker.destroy();
|
|
814
931
|
this.findLeaf = null;
|
|
815
932
|
this.innerIdMap = {};
|
|
816
933
|
this.idMap = {};
|
|
@@ -826,182 +943,428 @@ Object.assign(Creator, {
|
|
|
826
943
|
});
|
|
827
944
|
Platform.layout = Layouter.fullLayout;
|
|
828
945
|
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
const { width, height, pixelRatio } = this;
|
|
841
|
-
this.view.width = width * pixelRatio;
|
|
842
|
-
this.view.height = height * pixelRatio;
|
|
843
|
-
this.clientBounds = this.bounds;
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
canvasPatch(OffscreenCanvasRenderingContext2D.prototype);
|
|
848
|
-
canvasPatch(Path2D.prototype);
|
|
849
|
-
|
|
850
|
-
const { mineType } = FileHelper;
|
|
851
|
-
Object.assign(Creator, {
|
|
852
|
-
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
853
|
-
image: (options) => new LeaferImage(options),
|
|
854
|
-
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
855
|
-
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
856
|
-
});
|
|
857
|
-
function useCanvas(_canvasType, _power) {
|
|
858
|
-
Platform.origin = {
|
|
859
|
-
createCanvas: (width, height) => new OffscreenCanvas(width, height),
|
|
860
|
-
canvasToDataURL: (canvas, type, quality) => {
|
|
861
|
-
return new Promise((resolve, reject) => {
|
|
862
|
-
canvas.convertToBlob({ type: mineType(type), quality }).then((blob) => {
|
|
863
|
-
var reader = new FileReader();
|
|
864
|
-
reader.onload = (e) => resolve(e.target.result);
|
|
865
|
-
reader.onerror = (e) => reject(e);
|
|
866
|
-
reader.readAsDataURL(blob);
|
|
867
|
-
}).catch((e) => {
|
|
868
|
-
reject(e);
|
|
869
|
-
});
|
|
870
|
-
});
|
|
871
|
-
},
|
|
872
|
-
canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({ type: mineType(type), quality }),
|
|
873
|
-
canvasSaveAs: (_canvas, _filename, _quality) => new Promise((resolve) => resolve()),
|
|
874
|
-
loadImage(src) {
|
|
875
|
-
return new Promise((resolve, reject) => {
|
|
876
|
-
if (!src.startsWith('data:') && Platform.image.suffix)
|
|
877
|
-
src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
|
|
878
|
-
let req = new XMLHttpRequest();
|
|
879
|
-
req.open('GET', src, true);
|
|
880
|
-
req.responseType = "blob";
|
|
881
|
-
req.onload = () => {
|
|
882
|
-
createImageBitmap(req.response).then(img => {
|
|
883
|
-
resolve(img);
|
|
884
|
-
}).catch(e => {
|
|
885
|
-
reject(e);
|
|
886
|
-
});
|
|
887
|
-
};
|
|
888
|
-
req.onerror = (e) => reject(e);
|
|
889
|
-
req.send();
|
|
946
|
+
function fillText(ui, canvas) {
|
|
947
|
+
let row;
|
|
948
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
949
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
950
|
+
row = rows[i];
|
|
951
|
+
if (row.text) {
|
|
952
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
953
|
+
}
|
|
954
|
+
else if (row.data) {
|
|
955
|
+
row.data.forEach(charData => {
|
|
956
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
890
957
|
});
|
|
891
958
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
}
|
|
896
|
-
Platform.name = 'web';
|
|
897
|
-
Platform.isWorker = true;
|
|
898
|
-
Platform.requestRender = function (render) { requestAnimationFrame(render); };
|
|
899
|
-
Platform.devicePixelRatio = 1;
|
|
900
|
-
const { userAgent } = navigator;
|
|
901
|
-
if (userAgent.indexOf("Firefox") > -1) {
|
|
902
|
-
Platform.conicGradientRotate90 = true;
|
|
903
|
-
Platform.intWheelDeltaY = true;
|
|
904
|
-
}
|
|
905
|
-
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
906
|
-
Platform.fullImageShadow = true;
|
|
907
|
-
}
|
|
908
|
-
if (userAgent.indexOf('Windows') > -1) {
|
|
909
|
-
Platform.os = 'Windows';
|
|
910
|
-
Platform.intWheelDeltaY = true;
|
|
911
|
-
}
|
|
912
|
-
else if (userAgent.indexOf('Mac') > -1) {
|
|
913
|
-
Platform.os = 'Mac';
|
|
914
|
-
}
|
|
915
|
-
else if (userAgent.indexOf('Linux') > -1) {
|
|
916
|
-
Platform.os = 'Linux';
|
|
959
|
+
if (decorationY)
|
|
960
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
961
|
+
}
|
|
917
962
|
}
|
|
918
963
|
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const swap = rotation && rotation !== 180;
|
|
923
|
-
const sw = box.width / (swap ? height : width);
|
|
924
|
-
const sh = box.height / (swap ? width : height);
|
|
925
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
926
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
927
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
928
|
-
translate$1(transform, x, y);
|
|
929
|
-
scaleHelper(transform, scale);
|
|
930
|
-
if (rotation)
|
|
931
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
932
|
-
data.scaleX = data.scaleY = scale;
|
|
933
|
-
data.transform = transform;
|
|
934
|
-
}
|
|
935
|
-
function clipMode(data, box, offset, scale, rotation) {
|
|
936
|
-
const transform = get$4();
|
|
937
|
-
translate$1(transform, box.x, box.y);
|
|
938
|
-
if (offset)
|
|
939
|
-
translate$1(transform, offset.x, offset.y);
|
|
940
|
-
if (scale) {
|
|
941
|
-
typeof scale === 'number' ? scaleHelper(transform, scale) : scaleHelper(transform, scale.x, scale.y);
|
|
942
|
-
data.scaleX = transform.a;
|
|
943
|
-
data.scaleY = transform.d;
|
|
944
|
-
}
|
|
945
|
-
if (rotation)
|
|
946
|
-
rotate(transform, rotation);
|
|
947
|
-
data.transform = transform;
|
|
964
|
+
function fill(fill, ui, canvas) {
|
|
965
|
+
canvas.fillStyle = fill;
|
|
966
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
948
967
|
}
|
|
949
|
-
function
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
968
|
+
function fills(fills, ui, canvas) {
|
|
969
|
+
let item;
|
|
970
|
+
const { windingRule, __font } = ui.__;
|
|
971
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
972
|
+
item = fills[i];
|
|
973
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
974
|
+
continue;
|
|
975
|
+
if (item.style) {
|
|
976
|
+
canvas.fillStyle = item.style;
|
|
977
|
+
if (item.transform) {
|
|
978
|
+
canvas.save();
|
|
979
|
+
canvas.transform(item.transform);
|
|
980
|
+
if (item.blendMode)
|
|
981
|
+
canvas.blendMode = item.blendMode;
|
|
982
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
983
|
+
canvas.restore();
|
|
984
|
+
}
|
|
985
|
+
else {
|
|
986
|
+
if (item.blendMode) {
|
|
987
|
+
canvas.saveBlendMode(item.blendMode);
|
|
988
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
989
|
+
canvas.restoreBlendMode();
|
|
990
|
+
}
|
|
991
|
+
else {
|
|
992
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
993
|
+
}
|
|
994
|
+
}
|
|
963
995
|
}
|
|
964
996
|
}
|
|
965
|
-
translate$1(transform, box.x, box.y);
|
|
966
|
-
if (scale) {
|
|
967
|
-
scaleOfOuter$2(transform, box, scale);
|
|
968
|
-
data.scaleX = data.scaleY = scale;
|
|
969
|
-
}
|
|
970
|
-
data.transform = transform;
|
|
971
997
|
}
|
|
972
998
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
const data = leafPaint.data = { mode };
|
|
981
|
-
switch (mode) {
|
|
982
|
-
case 'strench':
|
|
983
|
-
if (!sameBox)
|
|
984
|
-
width = box.width, height = box.height;
|
|
985
|
-
if (box.x || box.y) {
|
|
986
|
-
data.transform = get$3();
|
|
987
|
-
translate(data.transform, box.x, box.y);
|
|
988
|
-
}
|
|
999
|
+
function strokeText(stroke, ui, canvas) {
|
|
1000
|
+
const { strokeAlign } = ui.__;
|
|
1001
|
+
const isStrokes = typeof stroke !== 'string';
|
|
1002
|
+
switch (strokeAlign) {
|
|
1003
|
+
case 'center':
|
|
1004
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1005
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
989
1006
|
break;
|
|
1007
|
+
case 'inside':
|
|
1008
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1009
|
+
break;
|
|
1010
|
+
case 'outside':
|
|
1011
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1012
|
+
break;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1016
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1017
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1018
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1019
|
+
out.font = __font;
|
|
1020
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1021
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1022
|
+
fillText(ui, out);
|
|
1023
|
+
out.blendMode = 'normal';
|
|
1024
|
+
if (ui.__worldFlipped) {
|
|
1025
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1026
|
+
}
|
|
1027
|
+
else {
|
|
1028
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1029
|
+
}
|
|
1030
|
+
out.recycle(ui.__nowWorld);
|
|
1031
|
+
}
|
|
1032
|
+
function drawTextStroke(ui, canvas) {
|
|
1033
|
+
let row;
|
|
1034
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1035
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1036
|
+
row = rows[i];
|
|
1037
|
+
if (row.text) {
|
|
1038
|
+
canvas.strokeText(row.text, row.x, row.y);
|
|
1039
|
+
}
|
|
1040
|
+
else if (row.data) {
|
|
1041
|
+
row.data.forEach(charData => {
|
|
1042
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
if (decorationY)
|
|
1046
|
+
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1050
|
+
let item;
|
|
1051
|
+
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1052
|
+
item = strokes[i];
|
|
1053
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1054
|
+
continue;
|
|
1055
|
+
if (item.style) {
|
|
1056
|
+
canvas.strokeStyle = item.style;
|
|
1057
|
+
if (item.blendMode) {
|
|
1058
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1059
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1060
|
+
canvas.restoreBlendMode();
|
|
1061
|
+
}
|
|
1062
|
+
else {
|
|
1063
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
function stroke(stroke, ui, canvas) {
|
|
1070
|
+
const options = ui.__;
|
|
1071
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1072
|
+
if (!__strokeWidth)
|
|
1073
|
+
return;
|
|
1074
|
+
if (__font) {
|
|
1075
|
+
strokeText(stroke, ui, canvas);
|
|
1076
|
+
}
|
|
1077
|
+
else {
|
|
1078
|
+
switch (strokeAlign) {
|
|
1079
|
+
case 'center':
|
|
1080
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1081
|
+
canvas.stroke();
|
|
1082
|
+
break;
|
|
1083
|
+
case 'inside':
|
|
1084
|
+
canvas.save();
|
|
1085
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1086
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1087
|
+
canvas.stroke();
|
|
1088
|
+
canvas.restore();
|
|
1089
|
+
break;
|
|
1090
|
+
case 'outside':
|
|
1091
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1092
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1093
|
+
ui.__drawRenderPath(out);
|
|
1094
|
+
out.stroke();
|
|
1095
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1096
|
+
out.clearWorld(ui.__layout.renderBounds);
|
|
1097
|
+
if (ui.__worldFlipped) {
|
|
1098
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1102
|
+
}
|
|
1103
|
+
out.recycle(ui.__nowWorld);
|
|
1104
|
+
break;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
function strokes(strokes, ui, canvas) {
|
|
1109
|
+
const options = ui.__;
|
|
1110
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1111
|
+
if (!__strokeWidth)
|
|
1112
|
+
return;
|
|
1113
|
+
if (__font) {
|
|
1114
|
+
strokeText(strokes, ui, canvas);
|
|
1115
|
+
}
|
|
1116
|
+
else {
|
|
1117
|
+
switch (strokeAlign) {
|
|
1118
|
+
case 'center':
|
|
1119
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1120
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1121
|
+
break;
|
|
1122
|
+
case 'inside':
|
|
1123
|
+
canvas.save();
|
|
1124
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1125
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1126
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1127
|
+
canvas.restore();
|
|
1128
|
+
break;
|
|
1129
|
+
case 'outside':
|
|
1130
|
+
const { renderBounds } = ui.__layout;
|
|
1131
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1132
|
+
ui.__drawRenderPath(out);
|
|
1133
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1134
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1135
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1136
|
+
out.clearWorld(renderBounds);
|
|
1137
|
+
if (ui.__worldFlipped) {
|
|
1138
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1139
|
+
}
|
|
1140
|
+
else {
|
|
1141
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1142
|
+
}
|
|
1143
|
+
out.recycle(ui.__nowWorld);
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1150
|
+
function shape(ui, current, options) {
|
|
1151
|
+
const canvas = current.getSameCanvas();
|
|
1152
|
+
const nowWorld = ui.__nowWorld;
|
|
1153
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1154
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1155
|
+
if (scaleX < 0)
|
|
1156
|
+
scaleX = -scaleX;
|
|
1157
|
+
if (scaleY < 0)
|
|
1158
|
+
scaleY = -scaleY;
|
|
1159
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1160
|
+
worldCanvas = canvas;
|
|
1161
|
+
bounds = shapeBounds = nowWorld;
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1165
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1166
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1167
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1168
|
+
if (fitMatrix.a < 1) {
|
|
1169
|
+
worldCanvas = current.getSameCanvas();
|
|
1170
|
+
ui.__renderShape(worldCanvas, options);
|
|
1171
|
+
scaleX *= fitScaleX;
|
|
1172
|
+
scaleY *= fitScaleY;
|
|
1173
|
+
}
|
|
1174
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1175
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1176
|
+
if (options.matrix) {
|
|
1177
|
+
const { matrix } = options;
|
|
1178
|
+
fitMatrix.multiply(matrix);
|
|
1179
|
+
fitScaleX *= matrix.scaleX;
|
|
1180
|
+
fitScaleY *= matrix.scaleY;
|
|
1181
|
+
}
|
|
1182
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1183
|
+
}
|
|
1184
|
+
ui.__renderShape(canvas, options);
|
|
1185
|
+
return {
|
|
1186
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1187
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
let recycleMap;
|
|
1192
|
+
function compute(attrName, ui) {
|
|
1193
|
+
const data = ui.__, leafPaints = [];
|
|
1194
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1195
|
+
if (!(paints instanceof Array))
|
|
1196
|
+
paints = [paints];
|
|
1197
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1198
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1199
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1200
|
+
if (item)
|
|
1201
|
+
leafPaints.push(item);
|
|
1202
|
+
}
|
|
1203
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1204
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1205
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1206
|
+
if (attrName === 'fill') {
|
|
1207
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1208
|
+
}
|
|
1209
|
+
else {
|
|
1210
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1214
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1215
|
+
return undefined;
|
|
1216
|
+
const { boxBounds } = ui.__layout;
|
|
1217
|
+
switch (paint.type) {
|
|
1218
|
+
case 'solid':
|
|
1219
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1220
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1221
|
+
case 'image':
|
|
1222
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1223
|
+
case 'linear':
|
|
1224
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1225
|
+
case 'radial':
|
|
1226
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1227
|
+
case 'angular':
|
|
1228
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1229
|
+
default:
|
|
1230
|
+
return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
const PaintModule = {
|
|
1235
|
+
compute,
|
|
1236
|
+
fill,
|
|
1237
|
+
fills,
|
|
1238
|
+
fillText,
|
|
1239
|
+
stroke,
|
|
1240
|
+
strokes,
|
|
1241
|
+
strokeText,
|
|
1242
|
+
drawTextStroke,
|
|
1243
|
+
shape
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
let origin = {};
|
|
1247
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1248
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1249
|
+
const transform = get$3();
|
|
1250
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1251
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1252
|
+
if (rotation)
|
|
1253
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1254
|
+
data.transform = transform;
|
|
1255
|
+
}
|
|
1256
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1257
|
+
const transform = get$3();
|
|
1258
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1259
|
+
if (scaleX)
|
|
1260
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1261
|
+
if (rotation)
|
|
1262
|
+
rotate(transform, rotation);
|
|
1263
|
+
data.transform = transform;
|
|
1264
|
+
}
|
|
1265
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1266
|
+
const transform = get$3();
|
|
1267
|
+
if (rotation) {
|
|
1268
|
+
if (align === 'center') {
|
|
1269
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1270
|
+
}
|
|
1271
|
+
else {
|
|
1272
|
+
rotate(transform, rotation);
|
|
1273
|
+
switch (rotation) {
|
|
1274
|
+
case 90:
|
|
1275
|
+
translate$1(transform, height, 0);
|
|
1276
|
+
break;
|
|
1277
|
+
case 180:
|
|
1278
|
+
translate$1(transform, width, height);
|
|
1279
|
+
break;
|
|
1280
|
+
case 270:
|
|
1281
|
+
translate$1(transform, 0, width);
|
|
1282
|
+
break;
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
origin.x = box.x + x;
|
|
1287
|
+
origin.y = box.y + y;
|
|
1288
|
+
translate$1(transform, origin.x, origin.y);
|
|
1289
|
+
if (scaleX)
|
|
1290
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1291
|
+
data.transform = transform;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
const { get: get$2, translate } = MatrixHelper;
|
|
1295
|
+
const tempBox = new Bounds();
|
|
1296
|
+
const tempPoint = {};
|
|
1297
|
+
function createData(leafPaint, image, paint, box) {
|
|
1298
|
+
const { blendMode } = paint;
|
|
1299
|
+
if (blendMode)
|
|
1300
|
+
leafPaint.blendMode = blendMode;
|
|
1301
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1302
|
+
}
|
|
1303
|
+
function getPatternData(paint, box, image) {
|
|
1304
|
+
let { width, height } = image;
|
|
1305
|
+
if (paint.padding)
|
|
1306
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1307
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1308
|
+
const sameBox = box.width === width && box.height === height;
|
|
1309
|
+
const data = { mode };
|
|
1310
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1311
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1312
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1313
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1314
|
+
if (!sameBox || rotation) {
|
|
1315
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1316
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1317
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
else if (size) {
|
|
1321
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1322
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1323
|
+
}
|
|
1324
|
+
else if (scale) {
|
|
1325
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1326
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1327
|
+
}
|
|
1328
|
+
if (align) {
|
|
1329
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1330
|
+
if (scaleX)
|
|
1331
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1332
|
+
AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1333
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1334
|
+
}
|
|
1335
|
+
if (offset)
|
|
1336
|
+
x += offset.x, y += offset.y;
|
|
1337
|
+
switch (mode) {
|
|
1338
|
+
case 'strench':
|
|
1339
|
+
if (!sameBox)
|
|
1340
|
+
width = box.width, height = box.height;
|
|
1341
|
+
break;
|
|
1342
|
+
case 'normal':
|
|
990
1343
|
case 'clip':
|
|
991
|
-
if (
|
|
992
|
-
clipMode(data, box,
|
|
1344
|
+
if (x || y || scaleX || rotation)
|
|
1345
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
993
1346
|
break;
|
|
994
1347
|
case 'repeat':
|
|
995
|
-
if (!sameBox ||
|
|
996
|
-
repeatMode(data, box, width, height,
|
|
1348
|
+
if (!sameBox || scaleX || rotation)
|
|
1349
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
997
1350
|
if (!repeat)
|
|
998
1351
|
data.repeat = 'repeat';
|
|
999
1352
|
break;
|
|
1000
1353
|
case 'fit':
|
|
1001
1354
|
case 'cover':
|
|
1002
1355
|
default:
|
|
1003
|
-
if (
|
|
1004
|
-
fillOrFitMode(data,
|
|
1356
|
+
if (scaleX)
|
|
1357
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1358
|
+
}
|
|
1359
|
+
if (!data.transform) {
|
|
1360
|
+
if (box.x || box.y) {
|
|
1361
|
+
data.transform = get$2();
|
|
1362
|
+
translate(data.transform, box.x, box.y);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
if (scaleX && mode !== 'strench') {
|
|
1366
|
+
data.scaleX = scaleX;
|
|
1367
|
+
data.scaleY = scaleY;
|
|
1005
1368
|
}
|
|
1006
1369
|
data.width = width;
|
|
1007
1370
|
data.height = height;
|
|
@@ -1009,112 +1372,108 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1009
1372
|
data.opacity = opacity;
|
|
1010
1373
|
if (repeat)
|
|
1011
1374
|
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1375
|
+
return data;
|
|
1012
1376
|
}
|
|
1013
1377
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1378
|
+
let cache, box = new Bounds();
|
|
1379
|
+
const { isSame } = BoundsHelper;
|
|
1380
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1381
|
+
let leafPaint, event;
|
|
1382
|
+
const image = ImageManager.get(paint);
|
|
1383
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1384
|
+
leafPaint = cache.leafPaint;
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
leafPaint = { type: paint.type, image };
|
|
1388
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1389
|
+
}
|
|
1390
|
+
if (firstUse || image.loading)
|
|
1391
|
+
event = { image, attrName, attrValue: paint };
|
|
1018
1392
|
if (image.ready) {
|
|
1019
|
-
|
|
1020
|
-
createData(leafPaint, image, attrValue, box);
|
|
1393
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1021
1394
|
if (firstUse) {
|
|
1022
|
-
|
|
1023
|
-
|
|
1395
|
+
onLoad(ui, event);
|
|
1396
|
+
onLoadSuccess(ui, event);
|
|
1024
1397
|
}
|
|
1025
1398
|
}
|
|
1026
1399
|
else if (image.error) {
|
|
1027
|
-
if (firstUse)
|
|
1028
|
-
ui.
|
|
1029
|
-
event.error = image.error;
|
|
1030
|
-
emit(ImageEvent.ERROR, event);
|
|
1031
|
-
}
|
|
1400
|
+
if (firstUse)
|
|
1401
|
+
onLoadError(ui, event, image.error);
|
|
1032
1402
|
}
|
|
1033
1403
|
else {
|
|
1404
|
+
ignoreRender(ui, true);
|
|
1034
1405
|
if (firstUse)
|
|
1035
|
-
|
|
1406
|
+
onLoad(ui, event);
|
|
1036
1407
|
leafPaint.loadId = image.load(() => {
|
|
1408
|
+
ignoreRender(ui, false);
|
|
1037
1409
|
if (!ui.destroyed) {
|
|
1038
|
-
if (
|
|
1039
|
-
|
|
1410
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1411
|
+
if (image.hasOpacityPixel)
|
|
1412
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1040
1413
|
ui.forceUpdate('surface');
|
|
1041
1414
|
}
|
|
1042
|
-
|
|
1415
|
+
onLoadSuccess(ui, event);
|
|
1043
1416
|
}
|
|
1417
|
+
leafPaint.loadId = null;
|
|
1044
1418
|
}, (error) => {
|
|
1045
|
-
ui
|
|
1046
|
-
event
|
|
1047
|
-
|
|
1419
|
+
ignoreRender(ui, false);
|
|
1420
|
+
onLoadError(ui, event, error);
|
|
1421
|
+
leafPaint.loadId = null;
|
|
1048
1422
|
});
|
|
1049
1423
|
}
|
|
1050
1424
|
return leafPaint;
|
|
1051
1425
|
}
|
|
1052
|
-
function
|
|
1426
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1053
1427
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1054
|
-
const
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
if (
|
|
1428
|
+
const data = ui.__;
|
|
1429
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1430
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1431
|
+
if (data.__autoSide) {
|
|
1058
1432
|
ui.forceUpdate('width');
|
|
1059
1433
|
if (ui.__proxyData) {
|
|
1060
|
-
ui.setProxyAttr('width',
|
|
1061
|
-
ui.setProxyAttr('height',
|
|
1434
|
+
ui.setProxyAttr('width', data.width);
|
|
1435
|
+
ui.setProxyAttr('height', data.height);
|
|
1062
1436
|
}
|
|
1063
1437
|
return false;
|
|
1064
1438
|
}
|
|
1065
1439
|
}
|
|
1440
|
+
if (!leafPaint.data)
|
|
1441
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1066
1442
|
return true;
|
|
1067
1443
|
}
|
|
1068
|
-
function
|
|
1069
|
-
|
|
1070
|
-
|
|
1444
|
+
function onLoad(ui, event) {
|
|
1445
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1446
|
+
}
|
|
1447
|
+
function onLoadSuccess(ui, event) {
|
|
1448
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1449
|
+
}
|
|
1450
|
+
function onLoadError(ui, event, error) {
|
|
1451
|
+
event.error = error;
|
|
1452
|
+
ui.forceUpdate('surface');
|
|
1453
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1454
|
+
}
|
|
1455
|
+
function emit(ui, type, data) {
|
|
1456
|
+
if (ui.hasEvent(type))
|
|
1457
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1458
|
+
}
|
|
1459
|
+
function ignoreRender(ui, value) {
|
|
1460
|
+
const { leafer } = ui;
|
|
1461
|
+
if (leafer && leafer.viewReady)
|
|
1462
|
+
leafer.renderer.ignore = value;
|
|
1071
1463
|
}
|
|
1072
1464
|
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1077
|
-
purpose with or without fee is hereby granted.
|
|
1078
|
-
|
|
1079
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1080
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1081
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1082
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1083
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1084
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1085
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1086
|
-
***************************************************************************** */
|
|
1087
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1091
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1092
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1093
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1094
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1095
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1096
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1101
|
-
var e = new Error(message);
|
|
1102
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1103
|
-
};
|
|
1104
|
-
|
|
1105
|
-
const Export$1 = {};
|
|
1106
|
-
|
|
1107
|
-
const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
|
|
1465
|
+
const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
|
|
1466
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1108
1467
|
function createPattern(ui, paint, pixelRatio) {
|
|
1109
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1468
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1110
1469
|
const id = scaleX + '-' + scaleY;
|
|
1111
1470
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1112
|
-
scaleX =
|
|
1113
|
-
scaleY =
|
|
1471
|
+
scaleX = abs$1(scaleX);
|
|
1472
|
+
scaleY = abs$1(scaleY);
|
|
1114
1473
|
const { image, data } = paint;
|
|
1115
1474
|
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1116
1475
|
if (sx) {
|
|
1117
|
-
imageMatrix = get$
|
|
1476
|
+
imageMatrix = get$1();
|
|
1118
1477
|
copy$1(imageMatrix, transform);
|
|
1119
1478
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1120
1479
|
scaleX *= sx;
|
|
@@ -1149,22 +1508,14 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1149
1508
|
}
|
|
1150
1509
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1151
1510
|
if (!imageMatrix) {
|
|
1152
|
-
imageMatrix = get$
|
|
1511
|
+
imageMatrix = get$1();
|
|
1153
1512
|
if (transform)
|
|
1154
1513
|
copy$1(imageMatrix, transform);
|
|
1155
1514
|
}
|
|
1156
1515
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1157
1516
|
}
|
|
1158
|
-
const
|
|
1159
|
-
|
|
1160
|
-
if (paint.transform)
|
|
1161
|
-
paint.transform = null;
|
|
1162
|
-
if (imageMatrix)
|
|
1163
|
-
pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
|
|
1164
|
-
}
|
|
1165
|
-
catch (_a) {
|
|
1166
|
-
paint.transform = imageMatrix;
|
|
1167
|
-
}
|
|
1517
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
1518
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1168
1519
|
paint.style = pattern;
|
|
1169
1520
|
paint.patternId = id;
|
|
1170
1521
|
return true;
|
|
@@ -1174,9 +1525,41 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1174
1525
|
}
|
|
1175
1526
|
}
|
|
1176
1527
|
|
|
1528
|
+
/******************************************************************************
|
|
1529
|
+
Copyright (c) Microsoft Corporation.
|
|
1530
|
+
|
|
1531
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
1532
|
+
purpose with or without fee is hereby granted.
|
|
1533
|
+
|
|
1534
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1535
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1536
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1537
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1538
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1539
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1540
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
1541
|
+
***************************************************************************** */
|
|
1542
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1543
|
+
|
|
1544
|
+
|
|
1545
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1546
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1547
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1548
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1549
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1550
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1551
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1556
|
+
var e = new Error(message);
|
|
1557
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1558
|
+
};
|
|
1559
|
+
|
|
1177
1560
|
const { abs } = Math;
|
|
1178
1561
|
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1179
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1562
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1180
1563
|
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1181
1564
|
return false;
|
|
1182
1565
|
}
|
|
@@ -1191,326 +1574,91 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1191
1574
|
width *= data.scaleX;
|
|
1192
1575
|
height *= data.scaleY;
|
|
1193
1576
|
}
|
|
1194
|
-
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
1577
|
+
allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
|
|
1195
1578
|
}
|
|
1196
1579
|
else {
|
|
1197
1580
|
allowPaint = false;
|
|
1198
1581
|
}
|
|
1199
1582
|
}
|
|
1200
|
-
if (allowPaint) {
|
|
1201
|
-
canvas.save();
|
|
1202
|
-
canvas.clip();
|
|
1203
|
-
if (paint.blendMode)
|
|
1204
|
-
canvas.blendMode = paint.blendMode;
|
|
1205
|
-
if (data.opacity)
|
|
1206
|
-
canvas.opacity *= data.opacity;
|
|
1207
|
-
if (data.transform)
|
|
1208
|
-
canvas.transform(data.transform);
|
|
1209
|
-
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1210
|
-
canvas.restore();
|
|
1211
|
-
return true;
|
|
1212
|
-
}
|
|
1213
|
-
else {
|
|
1214
|
-
if (!paint.style || Export
|
|
1215
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1216
|
-
}
|
|
1217
|
-
else {
|
|
1218
|
-
if (!paint.patternTask) {
|
|
1219
|
-
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1220
|
-
paint.patternTask = null;
|
|
1221
|
-
if (canvas.bounds.hit(ui.__world))
|
|
1222
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1223
|
-
ui.forceUpdate('surface');
|
|
1224
|
-
}), 300);
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
return false;
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
|
|
1232
|
-
function recycleImage(attrName, data) {
|
|
1233
|
-
const paints = data['_' + attrName];
|
|
1234
|
-
if (paints instanceof Array) {
|
|
1235
|
-
let image, recycleMap, input, url;
|
|
1236
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1237
|
-
image = paints[i].image;
|
|
1238
|
-
url = image && image.url;
|
|
1239
|
-
if (url) {
|
|
1240
|
-
if (!recycleMap)
|
|
1241
|
-
recycleMap = {};
|
|
1242
|
-
recycleMap[url] = true;
|
|
1243
|
-
ImageManager.recycle(image);
|
|
1244
|
-
if (image.loading) {
|
|
1245
|
-
if (!input) {
|
|
1246
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1247
|
-
if (!(input instanceof Array))
|
|
1248
|
-
input = [input];
|
|
1249
|
-
}
|
|
1250
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
return recycleMap;
|
|
1255
|
-
}
|
|
1256
|
-
return null;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
function fillText(ui, canvas) {
|
|
1260
|
-
let row;
|
|
1261
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1262
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1263
|
-
row = rows[i];
|
|
1264
|
-
if (row.text) {
|
|
1265
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1266
|
-
}
|
|
1267
|
-
else if (row.data) {
|
|
1268
|
-
row.data.forEach(charData => {
|
|
1269
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1270
|
-
});
|
|
1271
|
-
}
|
|
1272
|
-
if (decorationY)
|
|
1273
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
|
|
1277
|
-
function fill(fill, ui, canvas) {
|
|
1278
|
-
canvas.fillStyle = fill;
|
|
1279
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1280
|
-
}
|
|
1281
|
-
function fills(fills, ui, canvas) {
|
|
1282
|
-
let item;
|
|
1283
|
-
const { windingRule, __font } = ui.__;
|
|
1284
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1285
|
-
item = fills[i];
|
|
1286
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1287
|
-
continue;
|
|
1288
|
-
if (item.style) {
|
|
1289
|
-
canvas.fillStyle = item.style;
|
|
1290
|
-
if (item.transform) {
|
|
1291
|
-
canvas.save();
|
|
1292
|
-
canvas.transform(item.transform);
|
|
1293
|
-
if (item.blendMode)
|
|
1294
|
-
canvas.blendMode = item.blendMode;
|
|
1295
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1296
|
-
canvas.restore();
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
if (item.blendMode) {
|
|
1300
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1301
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1302
|
-
canvas.restoreBlendMode();
|
|
1303
|
-
}
|
|
1304
|
-
else {
|
|
1305
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
function strokeText(stroke, ui, canvas, renderOptions) {
|
|
1313
|
-
const { strokeAlign } = ui.__;
|
|
1314
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1315
|
-
switch (strokeAlign) {
|
|
1316
|
-
case 'center':
|
|
1317
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1318
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1319
|
-
break;
|
|
1320
|
-
case 'inside':
|
|
1321
|
-
drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1322
|
-
break;
|
|
1323
|
-
case 'outside':
|
|
1324
|
-
drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1325
|
-
break;
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
|
|
1329
|
-
const { strokeWidth, __font } = ui.__;
|
|
1330
|
-
const out = canvas.getSameCanvas(true);
|
|
1331
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1332
|
-
out.font = __font;
|
|
1333
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1334
|
-
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1335
|
-
fillText(ui, out);
|
|
1336
|
-
out.blendMode = 'normal';
|
|
1337
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1338
|
-
canvas.copyWorldByReset(out);
|
|
1339
|
-
}
|
|
1340
|
-
else {
|
|
1341
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1342
|
-
}
|
|
1343
|
-
out.recycle();
|
|
1344
|
-
}
|
|
1345
|
-
function drawTextStroke(ui, canvas) {
|
|
1346
|
-
let row;
|
|
1347
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1348
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1349
|
-
row = rows[i];
|
|
1350
|
-
if (row.text) {
|
|
1351
|
-
canvas.strokeText(row.text, row.x, row.y);
|
|
1352
|
-
}
|
|
1353
|
-
else if (row.data) {
|
|
1354
|
-
row.data.forEach(charData => {
|
|
1355
|
-
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1356
|
-
});
|
|
1357
|
-
}
|
|
1358
|
-
if (decorationY)
|
|
1359
|
-
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1360
|
-
}
|
|
1361
|
-
}
|
|
1362
|
-
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1363
|
-
let item;
|
|
1364
|
-
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1365
|
-
item = strokes[i];
|
|
1366
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1367
|
-
continue;
|
|
1368
|
-
if (item.style) {
|
|
1369
|
-
canvas.strokeStyle = item.style;
|
|
1370
|
-
if (item.blendMode) {
|
|
1371
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1372
|
-
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1373
|
-
canvas.restoreBlendMode();
|
|
1583
|
+
if (allowPaint) {
|
|
1584
|
+
canvas.save();
|
|
1585
|
+
canvas.clip();
|
|
1586
|
+
if (paint.blendMode)
|
|
1587
|
+
canvas.blendMode = paint.blendMode;
|
|
1588
|
+
if (data.opacity)
|
|
1589
|
+
canvas.opacity *= data.opacity;
|
|
1590
|
+
if (data.transform)
|
|
1591
|
+
canvas.transform(data.transform);
|
|
1592
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1593
|
+
canvas.restore();
|
|
1594
|
+
return true;
|
|
1595
|
+
}
|
|
1596
|
+
else {
|
|
1597
|
+
if (!paint.style || Export.running) {
|
|
1598
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1374
1599
|
}
|
|
1375
1600
|
else {
|
|
1376
|
-
|
|
1601
|
+
if (!paint.patternTask) {
|
|
1602
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1603
|
+
paint.patternTask = null;
|
|
1604
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1605
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1606
|
+
ui.forceUpdate('surface');
|
|
1607
|
+
}), 300);
|
|
1608
|
+
}
|
|
1377
1609
|
}
|
|
1610
|
+
return false;
|
|
1378
1611
|
}
|
|
1379
1612
|
}
|
|
1380
1613
|
}
|
|
1381
1614
|
|
|
1382
|
-
function
|
|
1383
|
-
const
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
canvas.restore();
|
|
1402
|
-
break;
|
|
1403
|
-
case 'outside':
|
|
1404
|
-
const out = canvas.getSameCanvas(true);
|
|
1405
|
-
out.setStroke(stroke, strokeWidth * 2, ui.__);
|
|
1406
|
-
ui.__drawRenderPath(out);
|
|
1407
|
-
out.stroke();
|
|
1408
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1409
|
-
out.clearWorld(ui.__layout.renderBounds);
|
|
1410
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1411
|
-
canvas.copyWorldByReset(out);
|
|
1412
|
-
}
|
|
1413
|
-
else {
|
|
1414
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1415
|
-
}
|
|
1416
|
-
out.recycle();
|
|
1417
|
-
break;
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
function strokes(strokes, ui, canvas, renderOptions) {
|
|
1422
|
-
const options = ui.__;
|
|
1423
|
-
const { strokeWidth, strokeAlign, __font } = options;
|
|
1424
|
-
if (!strokeWidth)
|
|
1425
|
-
return;
|
|
1426
|
-
if (__font) {
|
|
1427
|
-
strokeText(strokes, ui, canvas, renderOptions);
|
|
1428
|
-
}
|
|
1429
|
-
else {
|
|
1430
|
-
switch (strokeAlign) {
|
|
1431
|
-
case 'center':
|
|
1432
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1433
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1434
|
-
break;
|
|
1435
|
-
case 'inside':
|
|
1436
|
-
canvas.save();
|
|
1437
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1438
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1439
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1440
|
-
canvas.restore();
|
|
1441
|
-
break;
|
|
1442
|
-
case 'outside':
|
|
1443
|
-
const { renderBounds } = ui.__layout;
|
|
1444
|
-
const out = canvas.getSameCanvas(true);
|
|
1445
|
-
ui.__drawRenderPath(out);
|
|
1446
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1447
|
-
drawStrokesStyle(strokes, false, ui, out);
|
|
1448
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1449
|
-
out.clearWorld(renderBounds);
|
|
1450
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1451
|
-
canvas.copyWorldByReset(out);
|
|
1452
|
-
}
|
|
1453
|
-
else {
|
|
1454
|
-
canvas.copyWorldToInner(out, ui.__world, renderBounds);
|
|
1615
|
+
function recycleImage(attrName, data) {
|
|
1616
|
+
const paints = data['_' + attrName];
|
|
1617
|
+
if (paints instanceof Array) {
|
|
1618
|
+
let image, recycleMap, input, url;
|
|
1619
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1620
|
+
image = paints[i].image;
|
|
1621
|
+
url = image && image.url;
|
|
1622
|
+
if (url) {
|
|
1623
|
+
if (!recycleMap)
|
|
1624
|
+
recycleMap = {};
|
|
1625
|
+
recycleMap[url] = true;
|
|
1626
|
+
ImageManager.recycle(image);
|
|
1627
|
+
if (image.loading) {
|
|
1628
|
+
if (!input) {
|
|
1629
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1630
|
+
if (!(input instanceof Array))
|
|
1631
|
+
input = [input];
|
|
1632
|
+
}
|
|
1633
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1455
1634
|
}
|
|
1456
|
-
|
|
1457
|
-
break;
|
|
1635
|
+
}
|
|
1458
1636
|
}
|
|
1637
|
+
return recycleMap;
|
|
1459
1638
|
}
|
|
1639
|
+
return null;
|
|
1460
1640
|
}
|
|
1461
1641
|
|
|
1462
|
-
const
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
if (!current.bounds.includes(__world, options.matrix)) {
|
|
1474
|
-
const { renderShapeSpread: spread } = ui.__layout;
|
|
1475
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
|
|
1476
|
-
matrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1477
|
-
if (matrix.a < 1) {
|
|
1478
|
-
worldCanvas = current.getSameCanvas();
|
|
1479
|
-
ui.__renderShape(worldCanvas, options);
|
|
1480
|
-
scaleX *= matrix.a;
|
|
1481
|
-
scaleY *= matrix.d;
|
|
1482
|
-
}
|
|
1483
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1484
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1485
|
-
if (options.matrix)
|
|
1486
|
-
matrix.multiply(options.matrix);
|
|
1487
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1488
|
-
}
|
|
1489
|
-
else {
|
|
1490
|
-
if (options.matrix) {
|
|
1491
|
-
scaleX *= options.matrix.a;
|
|
1492
|
-
scaleY *= options.matrix.d;
|
|
1493
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1494
|
-
}
|
|
1495
|
-
else {
|
|
1496
|
-
bounds = shapeBounds = __world;
|
|
1497
|
-
}
|
|
1498
|
-
worldCanvas = canvas;
|
|
1499
|
-
}
|
|
1500
|
-
ui.__renderShape(canvas, options);
|
|
1501
|
-
return {
|
|
1502
|
-
canvas, matrix, bounds,
|
|
1503
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1504
|
-
};
|
|
1505
|
-
}
|
|
1642
|
+
const PaintImageModule = {
|
|
1643
|
+
image,
|
|
1644
|
+
checkImage,
|
|
1645
|
+
createPattern,
|
|
1646
|
+
recycleImage,
|
|
1647
|
+
createData,
|
|
1648
|
+
getPatternData,
|
|
1649
|
+
fillOrFitMode,
|
|
1650
|
+
clipMode,
|
|
1651
|
+
repeatMode
|
|
1652
|
+
};
|
|
1506
1653
|
|
|
1507
|
-
const
|
|
1508
|
-
const
|
|
1654
|
+
const { toPoint: toPoint$2 } = AroundHelper;
|
|
1655
|
+
const realFrom$2 = {};
|
|
1656
|
+
const realTo$2 = {};
|
|
1509
1657
|
function linearGradient(paint, box) {
|
|
1510
1658
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1511
|
-
from ||
|
|
1512
|
-
to ||
|
|
1513
|
-
const style = Platform.canvas.createLinearGradient(
|
|
1659
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
1660
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
1661
|
+
const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1514
1662
|
applyStops(style, paint.stops, opacity);
|
|
1515
1663
|
const data = { type, style };
|
|
1516
1664
|
if (blendMode)
|
|
@@ -1521,137 +1669,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1521
1669
|
let stop;
|
|
1522
1670
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1523
1671
|
stop = stops[i];
|
|
1524
|
-
|
|
1672
|
+
if (typeof stop === 'string') {
|
|
1673
|
+
gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
1677
|
+
}
|
|
1525
1678
|
}
|
|
1526
1679
|
}
|
|
1527
1680
|
|
|
1528
|
-
const {
|
|
1529
|
-
const { get
|
|
1530
|
-
const
|
|
1531
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
1681
|
+
const { getAngle, getDistance: getDistance$1 } = PointHelper;
|
|
1682
|
+
const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
|
|
1683
|
+
const { toPoint: toPoint$1 } = AroundHelper;
|
|
1532
1684
|
const realFrom$1 = {};
|
|
1533
1685
|
const realTo$1 = {};
|
|
1534
1686
|
function radialGradient(paint, box) {
|
|
1535
1687
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1536
|
-
from ||
|
|
1537
|
-
to ||
|
|
1538
|
-
const { x, y, width, height } = box;
|
|
1539
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
1540
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
1541
|
-
let transform;
|
|
1542
|
-
if (width !== height || stretch) {
|
|
1543
|
-
transform = get$1();
|
|
1544
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
1545
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
1546
|
-
}
|
|
1688
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
1689
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
1547
1690
|
const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
1548
1691
|
applyStops(style, paint.stops, opacity);
|
|
1549
|
-
const data = { type, style
|
|
1692
|
+
const data = { type, style };
|
|
1693
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
1694
|
+
if (transform)
|
|
1695
|
+
data.transform = transform;
|
|
1550
1696
|
if (blendMode)
|
|
1551
1697
|
data.blendMode = blendMode;
|
|
1552
1698
|
return data;
|
|
1553
1699
|
}
|
|
1700
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
1701
|
+
let transform;
|
|
1702
|
+
const { width, height } = box;
|
|
1703
|
+
if (width !== height || stretch) {
|
|
1704
|
+
const angle = getAngle(from, to);
|
|
1705
|
+
transform = get();
|
|
1706
|
+
if (rotate90) {
|
|
1707
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
1708
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
1709
|
+
}
|
|
1710
|
+
else {
|
|
1711
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
1712
|
+
rotateOfOuter(transform, from, angle);
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
return transform;
|
|
1716
|
+
}
|
|
1554
1717
|
|
|
1555
|
-
const {
|
|
1556
|
-
const {
|
|
1557
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
1558
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
1718
|
+
const { getDistance } = PointHelper;
|
|
1719
|
+
const { toPoint } = AroundHelper;
|
|
1559
1720
|
const realFrom = {};
|
|
1560
1721
|
const realTo = {};
|
|
1561
1722
|
function conicGradient(paint, box) {
|
|
1562
1723
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1563
|
-
from ||
|
|
1564
|
-
to ||
|
|
1565
|
-
const { x, y, width, height } = box;
|
|
1566
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
1567
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
1568
|
-
const transform = get();
|
|
1569
|
-
const angle = getAngle(realFrom, realTo);
|
|
1570
|
-
if (Platform.conicGradientRotate90) {
|
|
1571
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
1572
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
1573
|
-
}
|
|
1574
|
-
else {
|
|
1575
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
1576
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
1577
|
-
}
|
|
1724
|
+
toPoint(from || 'center', box, realFrom);
|
|
1725
|
+
toPoint(to || 'bottom', box, realTo);
|
|
1578
1726
|
const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
|
|
1579
1727
|
applyStops(style, paint.stops, opacity);
|
|
1580
|
-
const data = { type, style
|
|
1728
|
+
const data = { type, style };
|
|
1729
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
|
|
1730
|
+
if (transform)
|
|
1731
|
+
data.transform = transform;
|
|
1581
1732
|
if (blendMode)
|
|
1582
1733
|
data.blendMode = blendMode;
|
|
1583
1734
|
return data;
|
|
1584
1735
|
}
|
|
1585
1736
|
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
if (!(paints instanceof Array))
|
|
1593
|
-
paints = [paints];
|
|
1594
|
-
recycleMap = recycleImage(attrName, data);
|
|
1595
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1596
|
-
item = getLeafPaint(attrName, paints[i], ui);
|
|
1597
|
-
if (item)
|
|
1598
|
-
value.push(item);
|
|
1599
|
-
}
|
|
1600
|
-
data['_' + attrName] = value.length ? value : undefined;
|
|
1601
|
-
let isPixel;
|
|
1602
|
-
if (paints.length === 1) {
|
|
1603
|
-
const paint = paints[0];
|
|
1604
|
-
if (paint.type === 'image')
|
|
1605
|
-
isPixel = ImageManager$1.isPixel(paint);
|
|
1606
|
-
}
|
|
1607
|
-
if (attrName === 'fill') {
|
|
1608
|
-
data.__pixelFill = isPixel;
|
|
1609
|
-
}
|
|
1610
|
-
else {
|
|
1611
|
-
data.__pixelStroke = isPixel;
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
function getLeafPaint(attrName, paint, ui) {
|
|
1615
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1616
|
-
return undefined;
|
|
1617
|
-
const { boxBounds } = ui.__layout;
|
|
1618
|
-
switch (paint.type) {
|
|
1619
|
-
case 'solid':
|
|
1620
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1621
|
-
return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
|
|
1622
|
-
case 'image':
|
|
1623
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1624
|
-
case 'linear':
|
|
1625
|
-
return linearGradient(paint, boxBounds);
|
|
1626
|
-
case 'radial':
|
|
1627
|
-
return radialGradient(paint, boxBounds);
|
|
1628
|
-
case 'angular':
|
|
1629
|
-
return conicGradient(paint, boxBounds);
|
|
1630
|
-
default:
|
|
1631
|
-
return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1636
|
-
__proto__: null,
|
|
1637
|
-
compute: compute,
|
|
1638
|
-
drawTextStroke: drawTextStroke,
|
|
1639
|
-
fill: fill,
|
|
1640
|
-
fillText: fillText,
|
|
1641
|
-
fills: fills,
|
|
1642
|
-
recycleImage: recycleImage,
|
|
1643
|
-
shape: shape,
|
|
1644
|
-
stroke: stroke,
|
|
1645
|
-
strokeText: strokeText,
|
|
1646
|
-
strokes: strokes
|
|
1647
|
-
});
|
|
1737
|
+
const PaintGradientModule = {
|
|
1738
|
+
linearGradient,
|
|
1739
|
+
radialGradient,
|
|
1740
|
+
conicGradient,
|
|
1741
|
+
getTransform
|
|
1742
|
+
};
|
|
1648
1743
|
|
|
1649
1744
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
1650
1745
|
const tempBounds = {};
|
|
1651
1746
|
const offsetOutBounds$1 = {};
|
|
1652
|
-
function shadow(ui, current, shape
|
|
1747
|
+
function shadow(ui, current, shape) {
|
|
1653
1748
|
let copyBounds, spreadScale;
|
|
1654
|
-
const {
|
|
1749
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1655
1750
|
const { shadow } = ui.__;
|
|
1656
1751
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1657
1752
|
const other = current.getSameCanvas();
|
|
@@ -1666,21 +1761,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
1666
1761
|
other.restore();
|
|
1667
1762
|
other.save();
|
|
1668
1763
|
if (worldCanvas) {
|
|
1669
|
-
other.copyWorld(other, bounds,
|
|
1670
|
-
copyBounds =
|
|
1764
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1765
|
+
copyBounds = nowWorld;
|
|
1671
1766
|
}
|
|
1672
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1767
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1673
1768
|
}
|
|
1674
|
-
if (ui.__worldFlipped
|
|
1675
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1769
|
+
if (ui.__worldFlipped) {
|
|
1770
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1676
1771
|
}
|
|
1677
1772
|
else {
|
|
1678
1773
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1679
1774
|
}
|
|
1680
1775
|
if (end && index < end)
|
|
1681
|
-
other.
|
|
1776
|
+
other.clearWorld(copyBounds, true);
|
|
1682
1777
|
});
|
|
1683
|
-
other.recycle();
|
|
1778
|
+
other.recycle(copyBounds);
|
|
1684
1779
|
}
|
|
1685
1780
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1686
1781
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1711,9 +1806,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1711
1806
|
|
|
1712
1807
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
1713
1808
|
const offsetOutBounds = {};
|
|
1714
|
-
function innerShadow(ui, current, shape
|
|
1809
|
+
function innerShadow(ui, current, shape) {
|
|
1715
1810
|
let copyBounds, spreadScale;
|
|
1716
|
-
const {
|
|
1811
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1717
1812
|
const { innerShadow } = ui.__;
|
|
1718
1813
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1719
1814
|
const other = current.getSameCanvas();
|
|
@@ -1726,40 +1821,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
1726
1821
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1727
1822
|
other.restore();
|
|
1728
1823
|
if (worldCanvas) {
|
|
1729
|
-
other.copyWorld(other, bounds,
|
|
1730
|
-
other.copyWorld(worldCanvas,
|
|
1731
|
-
copyBounds =
|
|
1824
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1825
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1826
|
+
copyBounds = nowWorld;
|
|
1732
1827
|
}
|
|
1733
1828
|
else {
|
|
1734
1829
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1735
1830
|
copyBounds = bounds;
|
|
1736
1831
|
}
|
|
1737
1832
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1738
|
-
if (ui.__worldFlipped
|
|
1739
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1833
|
+
if (ui.__worldFlipped) {
|
|
1834
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1740
1835
|
}
|
|
1741
1836
|
else {
|
|
1742
1837
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1743
1838
|
}
|
|
1744
1839
|
if (end && index < end)
|
|
1745
|
-
other.
|
|
1840
|
+
other.clearWorld(copyBounds, true);
|
|
1746
1841
|
});
|
|
1747
|
-
other.recycle();
|
|
1842
|
+
other.recycle(copyBounds);
|
|
1748
1843
|
}
|
|
1749
1844
|
|
|
1750
1845
|
function blur(ui, current, origin) {
|
|
1751
1846
|
const { blur } = ui.__;
|
|
1752
|
-
origin.setWorldBlur(blur * ui.
|
|
1753
|
-
origin.copyWorldToInner(current, ui.
|
|
1847
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1848
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1754
1849
|
origin.filter = 'none';
|
|
1755
1850
|
}
|
|
1756
1851
|
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
shadow
|
|
1762
|
-
|
|
1852
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
const EffectModule = {
|
|
1856
|
+
shadow,
|
|
1857
|
+
innerShadow,
|
|
1858
|
+
blur,
|
|
1859
|
+
backgroundBlur
|
|
1860
|
+
};
|
|
1861
|
+
|
|
1862
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
1863
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
1864
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
1865
|
+
const { children } = this;
|
|
1866
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
1867
|
+
child = children[i];
|
|
1868
|
+
if (child.__.mask) {
|
|
1869
|
+
if (currentMask) {
|
|
1870
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1871
|
+
maskCanvas = contentCanvas = null;
|
|
1872
|
+
}
|
|
1873
|
+
if (child.__.mask === 'path') {
|
|
1874
|
+
if (child.opacity < 1) {
|
|
1875
|
+
currentMask = 'opacity-path';
|
|
1876
|
+
maskOpacity = child.opacity;
|
|
1877
|
+
if (!contentCanvas)
|
|
1878
|
+
contentCanvas = getCanvas(canvas);
|
|
1879
|
+
}
|
|
1880
|
+
else {
|
|
1881
|
+
currentMask = 'path';
|
|
1882
|
+
canvas.save();
|
|
1883
|
+
}
|
|
1884
|
+
child.__clip(contentCanvas || canvas, options);
|
|
1885
|
+
}
|
|
1886
|
+
else {
|
|
1887
|
+
currentMask = 'alpha';
|
|
1888
|
+
if (!maskCanvas)
|
|
1889
|
+
maskCanvas = getCanvas(canvas);
|
|
1890
|
+
if (!contentCanvas)
|
|
1891
|
+
contentCanvas = getCanvas(canvas);
|
|
1892
|
+
child.__render(maskCanvas, options);
|
|
1893
|
+
}
|
|
1894
|
+
if (child.__.mask !== 'clipping')
|
|
1895
|
+
continue;
|
|
1896
|
+
}
|
|
1897
|
+
if (excludeRenderBounds(child, options))
|
|
1898
|
+
continue;
|
|
1899
|
+
child.__render(contentCanvas || canvas, options);
|
|
1900
|
+
}
|
|
1901
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1902
|
+
};
|
|
1903
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
1904
|
+
switch (maskMode) {
|
|
1905
|
+
case 'alpha':
|
|
1906
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
1907
|
+
break;
|
|
1908
|
+
case 'opacity-path':
|
|
1909
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
1910
|
+
break;
|
|
1911
|
+
case 'path':
|
|
1912
|
+
canvas.restore();
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
function getCanvas(canvas) {
|
|
1916
|
+
return canvas.getSameCanvas(false, true);
|
|
1917
|
+
}
|
|
1918
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
1919
|
+
const realBounds = leaf.__nowWorld;
|
|
1920
|
+
content.resetTransform();
|
|
1921
|
+
content.opacity = 1;
|
|
1922
|
+
content.useMask(mask, realBounds);
|
|
1923
|
+
mask.recycle(realBounds);
|
|
1924
|
+
copyContent(leaf, canvas, content, 1);
|
|
1925
|
+
}
|
|
1926
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
1927
|
+
const realBounds = leaf.__nowWorld;
|
|
1928
|
+
canvas.resetTransform();
|
|
1929
|
+
canvas.opacity = maskOpacity;
|
|
1930
|
+
canvas.copyWorld(content, realBounds);
|
|
1931
|
+
content.recycle(realBounds);
|
|
1932
|
+
}
|
|
1763
1933
|
|
|
1764
1934
|
const money = '¥¥$€££¢¢';
|
|
1765
1935
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1916,7 +2086,8 @@ function createRows(drawData, content, style) {
|
|
|
1916
2086
|
if (breakAll) {
|
|
1917
2087
|
if (wordWidth)
|
|
1918
2088
|
addWord();
|
|
1919
|
-
|
|
2089
|
+
if (rowWidth)
|
|
2090
|
+
addRow();
|
|
1920
2091
|
}
|
|
1921
2092
|
else {
|
|
1922
2093
|
if (!afterBreak)
|
|
@@ -1924,10 +2095,12 @@ function createRows(drawData, content, style) {
|
|
|
1924
2095
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
1925
2096
|
if (wordWidth)
|
|
1926
2097
|
addWord();
|
|
1927
|
-
|
|
2098
|
+
if (rowWidth)
|
|
2099
|
+
addRow();
|
|
1928
2100
|
}
|
|
1929
2101
|
else {
|
|
1930
|
-
|
|
2102
|
+
if (rowWidth)
|
|
2103
|
+
addRow();
|
|
1931
2104
|
}
|
|
1932
2105
|
}
|
|
1933
2106
|
}
|
|
@@ -2022,11 +2195,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2022
2195
|
if (mode === WordMode) {
|
|
2023
2196
|
wordChar = { char: '', x: charX };
|
|
2024
2197
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2025
|
-
if (wordChar.char !== ' ')
|
|
2198
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2026
2199
|
row.data.push(wordChar);
|
|
2027
2200
|
}
|
|
2028
2201
|
else {
|
|
2029
|
-
charX = toChar(word.data, charX, row.data);
|
|
2202
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2030
2203
|
}
|
|
2031
2204
|
if (!row.paraEnd && addWordWidth) {
|
|
2032
2205
|
charX += addWordWidth;
|
|
@@ -2053,9 +2226,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2053
2226
|
});
|
|
2054
2227
|
return charX;
|
|
2055
2228
|
}
|
|
2056
|
-
function toChar(data, charX, rowData) {
|
|
2229
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2057
2230
|
data.forEach(char => {
|
|
2058
|
-
if (char.char !== ' ') {
|
|
2231
|
+
if (isOverflow || char.char !== ' ') {
|
|
2059
2232
|
char.x = charX;
|
|
2060
2233
|
rowData.push(char);
|
|
2061
2234
|
}
|
|
@@ -2087,12 +2260,14 @@ function layoutText(drawData, style) {
|
|
|
2087
2260
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2088
2261
|
row = rows[i];
|
|
2089
2262
|
row.x = x;
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2263
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2264
|
+
switch (textAlign) {
|
|
2265
|
+
case 'center':
|
|
2266
|
+
row.x += (width - row.width) / 2;
|
|
2267
|
+
break;
|
|
2268
|
+
case 'right':
|
|
2269
|
+
row.x += width - row.width;
|
|
2270
|
+
}
|
|
2096
2271
|
}
|
|
2097
2272
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2098
2273
|
starY += paraSpacing;
|
|
@@ -2128,16 +2303,20 @@ function layoutText(drawData, style) {
|
|
|
2128
2303
|
bounds.height = realHeight;
|
|
2129
2304
|
}
|
|
2130
2305
|
|
|
2131
|
-
function clipText(drawData, style) {
|
|
2306
|
+
function clipText(drawData, style, x, width) {
|
|
2307
|
+
if (!width)
|
|
2308
|
+
return;
|
|
2132
2309
|
const { rows, overflow } = drawData;
|
|
2133
2310
|
let { textOverflow } = style;
|
|
2134
2311
|
rows.splice(overflow);
|
|
2135
|
-
if (textOverflow !== '
|
|
2136
|
-
if (textOverflow === '
|
|
2312
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2313
|
+
if (textOverflow === 'hide')
|
|
2314
|
+
textOverflow = '';
|
|
2315
|
+
else if (textOverflow === 'ellipsis')
|
|
2137
2316
|
textOverflow = '...';
|
|
2138
2317
|
let char, charRight;
|
|
2139
|
-
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2140
|
-
const right =
|
|
2318
|
+
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2319
|
+
const right = x + width - ellipsisWidth;
|
|
2141
2320
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2142
2321
|
list.forEach(row => {
|
|
2143
2322
|
if (row.isOverflow && row.data) {
|
|
@@ -2184,42 +2363,40 @@ function decorationText(drawData, style) {
|
|
|
2184
2363
|
}
|
|
2185
2364
|
|
|
2186
2365
|
const { top, right, bottom, left } = Direction4;
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
if (
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
}
|
|
2222
|
-
};
|
|
2366
|
+
function getDrawData(content, style) {
|
|
2367
|
+
if (typeof content !== 'string')
|
|
2368
|
+
content = String(content);
|
|
2369
|
+
let x = 0, y = 0;
|
|
2370
|
+
let width = style.__getInput('width') || 0;
|
|
2371
|
+
let height = style.__getInput('height') || 0;
|
|
2372
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2373
|
+
if (padding) {
|
|
2374
|
+
if (width) {
|
|
2375
|
+
x = padding[left];
|
|
2376
|
+
width -= (padding[right] + padding[left]);
|
|
2377
|
+
}
|
|
2378
|
+
if (height) {
|
|
2379
|
+
y = padding[top];
|
|
2380
|
+
height -= (padding[top] + padding[bottom]);
|
|
2381
|
+
}
|
|
2382
|
+
}
|
|
2383
|
+
const drawData = {
|
|
2384
|
+
bounds: { x, y, width, height },
|
|
2385
|
+
rows: [],
|
|
2386
|
+
paraNumber: 0,
|
|
2387
|
+
font: Platform.canvas.font = __font
|
|
2388
|
+
};
|
|
2389
|
+
createRows(drawData, content, style);
|
|
2390
|
+
if (padding)
|
|
2391
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2392
|
+
layoutText(drawData, style);
|
|
2393
|
+
layoutChar(drawData, style, width);
|
|
2394
|
+
if (drawData.overflow)
|
|
2395
|
+
clipText(drawData, style, x, width);
|
|
2396
|
+
if (textDecoration !== 'none')
|
|
2397
|
+
decorationText(drawData, style);
|
|
2398
|
+
return drawData;
|
|
2399
|
+
}
|
|
2223
2400
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2224
2401
|
if (!width) {
|
|
2225
2402
|
switch (style.textAlign) {
|
|
@@ -2247,67 +2424,152 @@ function offsetText(drawData, attrName, value) {
|
|
|
2247
2424
|
rows[i][attrName] += value;
|
|
2248
2425
|
}
|
|
2249
2426
|
|
|
2250
|
-
const
|
|
2251
|
-
|
|
2252
|
-
if (typeof color === 'string')
|
|
2253
|
-
return color;
|
|
2254
|
-
let a = color.a === undefined ? 1 : color.a;
|
|
2255
|
-
if (opacity)
|
|
2256
|
-
a *= opacity;
|
|
2257
|
-
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2258
|
-
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2259
|
-
}
|
|
2427
|
+
const TextConvertModule = {
|
|
2428
|
+
getDrawData
|
|
2260
2429
|
};
|
|
2261
2430
|
|
|
2262
|
-
|
|
2431
|
+
function string(color, opacity) {
|
|
2432
|
+
if (typeof color === 'string')
|
|
2433
|
+
return color;
|
|
2434
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2435
|
+
if (opacity)
|
|
2436
|
+
a *= opacity;
|
|
2437
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2438
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
const ColorConvertModule = {
|
|
2442
|
+
string
|
|
2443
|
+
};
|
|
2444
|
+
|
|
2445
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2446
|
+
function getTrimBounds(canvas) {
|
|
2447
|
+
const { width, height } = canvas.view;
|
|
2448
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2449
|
+
let x, y, pointBounds, index = 0;
|
|
2450
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2451
|
+
if (data[i + 3] !== 0) {
|
|
2452
|
+
x = index % width;
|
|
2453
|
+
y = (index - x) / width;
|
|
2454
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2455
|
+
}
|
|
2456
|
+
index++;
|
|
2457
|
+
}
|
|
2458
|
+
const bounds = new Bounds();
|
|
2459
|
+
toBounds(pointBounds, bounds);
|
|
2460
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
const ExportModule = {
|
|
2263
2464
|
export(leaf, filename, options) {
|
|
2264
|
-
|
|
2465
|
+
this.running = true;
|
|
2466
|
+
const fileType = FileHelper.fileType(filename);
|
|
2467
|
+
options = FileHelper.getExportOptions(options);
|
|
2265
2468
|
return addTask((success) => new Promise((resolve) => {
|
|
2469
|
+
const over = (result) => {
|
|
2470
|
+
success(result);
|
|
2471
|
+
resolve();
|
|
2472
|
+
this.running = false;
|
|
2473
|
+
};
|
|
2474
|
+
const { toURL } = Platform;
|
|
2475
|
+
const { download } = Platform.origin;
|
|
2476
|
+
if (filename === 'json') {
|
|
2477
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
2478
|
+
}
|
|
2479
|
+
else if (fileType === 'json') {
|
|
2480
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
2481
|
+
return over({ data: true });
|
|
2482
|
+
}
|
|
2483
|
+
if (filename === 'svg') {
|
|
2484
|
+
return over({ data: leaf.toSVG() });
|
|
2485
|
+
}
|
|
2486
|
+
else if (fileType === 'svg') {
|
|
2487
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
2488
|
+
return over({ data: true });
|
|
2489
|
+
}
|
|
2266
2490
|
const { leafer } = leaf;
|
|
2267
2491
|
if (leafer) {
|
|
2492
|
+
checkLazy(leaf);
|
|
2268
2493
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2269
|
-
let
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2494
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2495
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
2496
|
+
const { slice, trim, onCanvas } = options;
|
|
2497
|
+
let scale = options.scale || 1;
|
|
2498
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
2499
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
2500
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
2501
|
+
if (leaf.isApp) {
|
|
2502
|
+
scale *= pixelRatio;
|
|
2503
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
2504
|
+
}
|
|
2505
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2506
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
2507
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
2508
|
+
if (screenshot) {
|
|
2509
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2276
2510
|
}
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2511
|
+
else {
|
|
2512
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
2513
|
+
scaleX = worldTransform.scaleX;
|
|
2514
|
+
scaleY = worldTransform.scaleY;
|
|
2515
|
+
switch (relative) {
|
|
2516
|
+
case 'inner':
|
|
2517
|
+
matrix.set(worldTransform);
|
|
2518
|
+
break;
|
|
2519
|
+
case 'local':
|
|
2520
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
2521
|
+
scaleX /= leaf.scaleX;
|
|
2522
|
+
scaleY /= leaf.scaleY;
|
|
2523
|
+
break;
|
|
2524
|
+
case 'world':
|
|
2525
|
+
scaleX = 1;
|
|
2526
|
+
scaleY = 1;
|
|
2527
|
+
break;
|
|
2528
|
+
case 'page':
|
|
2529
|
+
relative = leaf.leafer;
|
|
2530
|
+
default:
|
|
2531
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
2532
|
+
const l = relative.worldTransform;
|
|
2533
|
+
scaleX /= scaleX / l.scaleX;
|
|
2534
|
+
scaleY /= scaleY / l.scaleY;
|
|
2535
|
+
}
|
|
2536
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2289
2537
|
}
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2538
|
+
const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
|
|
2539
|
+
let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
2540
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
2541
|
+
if (slice) {
|
|
2542
|
+
leaf = leafer;
|
|
2543
|
+
renderOptions.bounds = canvas.bounds;
|
|
2293
2544
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2545
|
+
canvas.save();
|
|
2546
|
+
if (isFrame && fill !== undefined) {
|
|
2547
|
+
const oldFill = leaf.get('fill');
|
|
2548
|
+
leaf.fill = '';
|
|
2549
|
+
leaf.__render(canvas, renderOptions);
|
|
2550
|
+
leaf.fill = oldFill;
|
|
2296
2551
|
}
|
|
2297
2552
|
else {
|
|
2298
|
-
|
|
2553
|
+
leaf.__render(canvas, renderOptions);
|
|
2299
2554
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2555
|
+
canvas.restore();
|
|
2556
|
+
if (trim) {
|
|
2557
|
+
trimBounds = getTrimBounds(canvas);
|
|
2558
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2559
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2560
|
+
canvas = Creator.canvas(config);
|
|
2561
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2562
|
+
}
|
|
2563
|
+
if (needFill)
|
|
2564
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2565
|
+
if (onCanvas)
|
|
2566
|
+
onCanvas(canvas);
|
|
2567
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2568
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2305
2569
|
}));
|
|
2306
2570
|
}
|
|
2307
2571
|
else {
|
|
2308
|
-
|
|
2309
|
-
resolve();
|
|
2310
|
-
Export.running = false;
|
|
2572
|
+
over({ data: false });
|
|
2311
2573
|
}
|
|
2312
2574
|
}));
|
|
2313
2575
|
}
|
|
@@ -2320,13 +2582,64 @@ function addTask(task) {
|
|
|
2320
2582
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2321
2583
|
});
|
|
2322
2584
|
}
|
|
2585
|
+
function checkLazy(leaf) {
|
|
2586
|
+
if (leaf.__.__needComputePaint)
|
|
2587
|
+
leaf.__.__computePaint();
|
|
2588
|
+
if (leaf.isBranch)
|
|
2589
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
const canvas = LeaferCanvasBase.prototype;
|
|
2593
|
+
const debug = Debug.get('@leafer-ui/export');
|
|
2594
|
+
canvas.export = function (filename, options) {
|
|
2595
|
+
const { quality, blob } = FileHelper.getExportOptions(options);
|
|
2596
|
+
if (filename.includes('.')) {
|
|
2597
|
+
return this.saveAs(filename, quality);
|
|
2598
|
+
}
|
|
2599
|
+
else if (blob) {
|
|
2600
|
+
return this.toBlob(filename, quality);
|
|
2601
|
+
}
|
|
2602
|
+
else {
|
|
2603
|
+
return this.toDataURL(filename, quality);
|
|
2604
|
+
}
|
|
2605
|
+
};
|
|
2606
|
+
canvas.toBlob = function (type, quality) {
|
|
2607
|
+
return new Promise((resolve) => {
|
|
2608
|
+
Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2609
|
+
resolve(blob);
|
|
2610
|
+
}).catch((e) => {
|
|
2611
|
+
debug.error(e);
|
|
2612
|
+
resolve(null);
|
|
2613
|
+
});
|
|
2614
|
+
});
|
|
2615
|
+
};
|
|
2616
|
+
canvas.toDataURL = function (type, quality) {
|
|
2617
|
+
return Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2618
|
+
};
|
|
2619
|
+
canvas.saveAs = function (filename, quality) {
|
|
2620
|
+
return new Promise((resolve) => {
|
|
2621
|
+
Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2622
|
+
resolve(true);
|
|
2623
|
+
}).catch((e) => {
|
|
2624
|
+
debug.error(e);
|
|
2625
|
+
resolve(false);
|
|
2626
|
+
});
|
|
2627
|
+
});
|
|
2628
|
+
};
|
|
2323
2629
|
|
|
2324
|
-
Object.assign(
|
|
2325
|
-
Object.assign(
|
|
2326
|
-
Object.assign(
|
|
2327
|
-
Object.assign(
|
|
2328
|
-
Object.assign(
|
|
2630
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
2631
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
2632
|
+
Object.assign(Paint, PaintModule);
|
|
2633
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
2634
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
2635
|
+
Object.assign(Effect, EffectModule);
|
|
2636
|
+
Object.assign(Export, ExportModule);
|
|
2329
2637
|
|
|
2638
|
+
Object.assign(Creator, {
|
|
2639
|
+
interaction: (target, canvas, selector, options) => new InteractionBase(target, canvas, selector, options),
|
|
2640
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2641
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
2642
|
+
});
|
|
2330
2643
|
useCanvas();
|
|
2331
2644
|
|
|
2332
2645
|
export { Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|