@leafer-ui/node 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/node.cjs +1142 -825
- package/dist/node.esm.js +1143 -826
- package/dist/node.esm.min.js +1 -1
- package/dist/node.min.cjs +1 -1
- package/package.json +10 -7
- package/src/index.ts +13 -0
- package/types/index.d.ts +1 -0
package/dist/node.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var core = require('@leafer/core');
|
|
4
4
|
var fs = require('fs');
|
|
5
5
|
var core$1 = require('@leafer-ui/core');
|
|
6
|
+
var draw = require('@leafer-ui/draw');
|
|
6
7
|
|
|
7
8
|
/******************************************************************************
|
|
8
9
|
Copyright (c) Microsoft Corporation.
|
|
@@ -36,6 +37,73 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
36
37
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
37
38
|
};
|
|
38
39
|
|
|
40
|
+
class LeaferCanvas extends core.LeaferCanvasBase {
|
|
41
|
+
get allowBackgroundColor() { return true; }
|
|
42
|
+
init() {
|
|
43
|
+
this.__createView();
|
|
44
|
+
this.__createContext();
|
|
45
|
+
this.resize(this.config);
|
|
46
|
+
if (core.Platform.roundRectPatch) {
|
|
47
|
+
this.context.__proto__.roundRect = null;
|
|
48
|
+
core.canvasPatch(this.context.__proto__);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
__createView() {
|
|
52
|
+
this.view = core.Platform.origin.createCanvas(1, 1);
|
|
53
|
+
}
|
|
54
|
+
updateViewSize() {
|
|
55
|
+
const { width, height, pixelRatio } = this;
|
|
56
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
57
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
58
|
+
this.clientBounds = this.bounds;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const { mineType, fileType } = core.FileHelper;
|
|
63
|
+
Object.assign(core.Creator, {
|
|
64
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
65
|
+
image: (options) => new core.LeaferImage(options)
|
|
66
|
+
});
|
|
67
|
+
function useCanvas(canvasType, power) {
|
|
68
|
+
core.Platform.canvasType = canvasType;
|
|
69
|
+
if (!core.Platform.origin) {
|
|
70
|
+
if (canvasType === 'skia') {
|
|
71
|
+
const { Canvas, loadImage } = power;
|
|
72
|
+
core.Platform.origin = {
|
|
73
|
+
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
74
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURLSync(type, { quality }),
|
|
75
|
+
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
76
|
+
canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
|
|
77
|
+
download(_url, _filename) { return undefined; },
|
|
78
|
+
loadImage(src) { return loadImage(core.Platform.image.getRealURL(src)); }
|
|
79
|
+
};
|
|
80
|
+
core.Platform.roundRectPatch = true;
|
|
81
|
+
}
|
|
82
|
+
else if (canvasType === 'napi') {
|
|
83
|
+
const { Canvas, loadImage } = power;
|
|
84
|
+
core.Platform.origin = {
|
|
85
|
+
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
86
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
87
|
+
canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function* () { return canvas.toBuffer(mineType(type), quality); }),
|
|
88
|
+
canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function* () { return fs.writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality)); }),
|
|
89
|
+
download(_url, _filename) { return undefined; },
|
|
90
|
+
loadImage(src) { return loadImage(core.Platform.image.getRealURL(src)); }
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
core.Platform.ellipseToCurve = true;
|
|
94
|
+
core.Platform.event = {
|
|
95
|
+
stopDefault(_origin) { },
|
|
96
|
+
stopNow(_origin) { },
|
|
97
|
+
stop(_origin) { }
|
|
98
|
+
};
|
|
99
|
+
core.Platform.canvas = core.Creator.canvas();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
core.Platform.name = 'node';
|
|
103
|
+
core.Platform.requestRender = function (render) { setTimeout(render); };
|
|
104
|
+
core.Platform.devicePixelRatio = 1;
|
|
105
|
+
core.Platform.conicGradientSupport = true;
|
|
106
|
+
|
|
39
107
|
class Watcher {
|
|
40
108
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
41
109
|
get updatedList() {
|
|
@@ -217,7 +285,7 @@ class LayoutBlockData {
|
|
|
217
285
|
}
|
|
218
286
|
|
|
219
287
|
const { updateAllMatrix, updateAllChange } = core.LeafHelper;
|
|
220
|
-
const debug$
|
|
288
|
+
const debug$2 = core.Debug.get('Layouter');
|
|
221
289
|
class Layouter {
|
|
222
290
|
constructor(target, userConfig) {
|
|
223
291
|
this.totalTimes = 0;
|
|
@@ -252,7 +320,7 @@ class Layouter {
|
|
|
252
320
|
target.emitEvent(new core.LayoutEvent(core.LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
253
321
|
}
|
|
254
322
|
catch (e) {
|
|
255
|
-
debug$
|
|
323
|
+
debug$2.error(e);
|
|
256
324
|
}
|
|
257
325
|
this.layoutedBlocks = null;
|
|
258
326
|
}
|
|
@@ -266,9 +334,9 @@ class Layouter {
|
|
|
266
334
|
}
|
|
267
335
|
layoutOnce() {
|
|
268
336
|
if (this.layouting)
|
|
269
|
-
return debug$
|
|
337
|
+
return debug$2.warn('layouting');
|
|
270
338
|
if (this.times > 3)
|
|
271
|
-
return debug$
|
|
339
|
+
return debug$2.warn('layout max times');
|
|
272
340
|
this.times++;
|
|
273
341
|
this.totalTimes++;
|
|
274
342
|
this.layouting = true;
|
|
@@ -334,9 +402,11 @@ class Layouter {
|
|
|
334
402
|
updateAllChange(target);
|
|
335
403
|
}
|
|
336
404
|
addExtra(leaf) {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
405
|
+
if (!this.__updatedList.has(leaf)) {
|
|
406
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
407
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
408
|
+
updatedList.add(leaf);
|
|
409
|
+
}
|
|
340
410
|
}
|
|
341
411
|
createBlock(data) {
|
|
342
412
|
return new LayoutBlockData(data);
|
|
@@ -370,7 +440,7 @@ class Layouter {
|
|
|
370
440
|
}
|
|
371
441
|
}
|
|
372
442
|
|
|
373
|
-
const debug = core.Debug.get('Renderer');
|
|
443
|
+
const debug$1 = core.Debug.get('Renderer');
|
|
374
444
|
class Renderer {
|
|
375
445
|
get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
|
|
376
446
|
constructor(target, canvas, userConfig) {
|
|
@@ -408,7 +478,7 @@ class Renderer {
|
|
|
408
478
|
const { target } = this;
|
|
409
479
|
this.times = 0;
|
|
410
480
|
this.totalBounds = new core.Bounds();
|
|
411
|
-
debug.log(target.innerName, '--->');
|
|
481
|
+
debug$1.log(target.innerName, '--->');
|
|
412
482
|
try {
|
|
413
483
|
this.emitRender(core.RenderEvent.START);
|
|
414
484
|
this.renderOnce(callback);
|
|
@@ -417,9 +487,9 @@ class Renderer {
|
|
|
417
487
|
}
|
|
418
488
|
catch (e) {
|
|
419
489
|
this.rendering = false;
|
|
420
|
-
debug.error(e);
|
|
490
|
+
debug$1.error(e);
|
|
421
491
|
}
|
|
422
|
-
debug.log('-------------|');
|
|
492
|
+
debug$1.log('-------------|');
|
|
423
493
|
}
|
|
424
494
|
renderAgain() {
|
|
425
495
|
if (this.rendering) {
|
|
@@ -431,9 +501,9 @@ class Renderer {
|
|
|
431
501
|
}
|
|
432
502
|
renderOnce(callback) {
|
|
433
503
|
if (this.rendering)
|
|
434
|
-
return debug.warn('rendering');
|
|
504
|
+
return debug$1.warn('rendering');
|
|
435
505
|
if (this.times > 3)
|
|
436
|
-
return debug.warn('render max times');
|
|
506
|
+
return debug$1.warn('render max times');
|
|
437
507
|
this.times++;
|
|
438
508
|
this.totalTimes++;
|
|
439
509
|
this.rendering = true;
|
|
@@ -446,6 +516,10 @@ class Renderer {
|
|
|
446
516
|
}
|
|
447
517
|
else {
|
|
448
518
|
this.requestLayout();
|
|
519
|
+
if (this.ignore) {
|
|
520
|
+
this.ignore = this.rendering = false;
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
449
523
|
this.emitRender(core.RenderEvent.BEFORE);
|
|
450
524
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
451
525
|
this.partRender();
|
|
@@ -466,7 +540,7 @@ class Renderer {
|
|
|
466
540
|
partRender() {
|
|
467
541
|
const { canvas, updateBlocks: list } = this;
|
|
468
542
|
if (!list)
|
|
469
|
-
return debug.warn('PartRender: need update attr');
|
|
543
|
+
return debug$1.warn('PartRender: need update attr');
|
|
470
544
|
this.mergeBlocks();
|
|
471
545
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
472
546
|
this.clipRender(block); });
|
|
@@ -482,7 +556,7 @@ class Renderer {
|
|
|
482
556
|
canvas.clear();
|
|
483
557
|
}
|
|
484
558
|
else {
|
|
485
|
-
bounds.spread(
|
|
559
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
486
560
|
canvas.clearWorld(bounds, true);
|
|
487
561
|
canvas.clipWorld(bounds, true);
|
|
488
562
|
}
|
|
@@ -535,12 +609,12 @@ class Renderer {
|
|
|
535
609
|
const startTime = Date.now();
|
|
536
610
|
core.Platform.requestRender(() => {
|
|
537
611
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
538
|
-
if (this.
|
|
539
|
-
|
|
612
|
+
if (this.running) {
|
|
613
|
+
this.target.emit(core.AnimateEvent.FRAME);
|
|
614
|
+
if (this.changed && this.canvas.view)
|
|
540
615
|
this.render();
|
|
616
|
+
this.target.emit(core.RenderEvent.NEXT);
|
|
541
617
|
}
|
|
542
|
-
if (this.running)
|
|
543
|
-
this.target.emit(core.AnimateEvent.FRAME);
|
|
544
618
|
if (this.target)
|
|
545
619
|
this.__requestRender();
|
|
546
620
|
});
|
|
@@ -553,9 +627,12 @@ class Renderer {
|
|
|
553
627
|
const bounds = new core.Bounds(0, 0, width, height);
|
|
554
628
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
555
629
|
this.addBlock(this.canvas.bounds);
|
|
556
|
-
this.target.forceUpdate('
|
|
630
|
+
this.target.forceUpdate('surface');
|
|
631
|
+
return;
|
|
557
632
|
}
|
|
558
633
|
}
|
|
634
|
+
this.addBlock(new core.Bounds(0, 0, 1, 1));
|
|
635
|
+
this.changed = true;
|
|
559
636
|
}
|
|
560
637
|
__onLayoutEnd(event) {
|
|
561
638
|
if (event.data)
|
|
@@ -566,7 +643,7 @@ class Renderer {
|
|
|
566
643
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
567
644
|
if (empty) {
|
|
568
645
|
if (!leaf.isLeafer)
|
|
569
|
-
debug.tip(leaf.innerName, ': empty');
|
|
646
|
+
debug$1.tip(leaf.innerName, ': empty');
|
|
570
647
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
571
648
|
}
|
|
572
649
|
return empty;
|
|
@@ -593,23 +670,13 @@ class Renderer {
|
|
|
593
670
|
if (this.target) {
|
|
594
671
|
this.stop();
|
|
595
672
|
this.__removeListenEvents();
|
|
596
|
-
this.target = null;
|
|
597
|
-
this.canvas = null;
|
|
598
|
-
this.config = null;
|
|
673
|
+
this.target = this.canvas = this.config = null;
|
|
599
674
|
}
|
|
600
675
|
}
|
|
601
676
|
}
|
|
602
677
|
|
|
603
|
-
var AnswerType;
|
|
604
|
-
(function (AnswerType) {
|
|
605
|
-
AnswerType[AnswerType["No"] = 0] = "No";
|
|
606
|
-
AnswerType[AnswerType["Yes"] = 1] = "Yes";
|
|
607
|
-
AnswerType[AnswerType["NoAndSkip"] = 2] = "NoAndSkip";
|
|
608
|
-
AnswerType[AnswerType["YesAndSkip"] = 3] = "YesAndSkip";
|
|
609
|
-
})(AnswerType || (AnswerType = {}));
|
|
610
|
-
|
|
611
678
|
const { hitRadiusPoint } = core.BoundsHelper;
|
|
612
|
-
class
|
|
679
|
+
class Picker {
|
|
613
680
|
constructor(target, selector) {
|
|
614
681
|
this.target = target;
|
|
615
682
|
this.selector = selector;
|
|
@@ -621,33 +688,41 @@ class Pather {
|
|
|
621
688
|
options = {};
|
|
622
689
|
const through = options.through || false;
|
|
623
690
|
const ignoreHittable = options.ignoreHittable || false;
|
|
691
|
+
const target = options.target || this.target;
|
|
624
692
|
this.exclude = options.exclude || null;
|
|
625
693
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
626
|
-
this.findList =
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
const
|
|
694
|
+
this.findList = new core.LeafList(options.findList);
|
|
695
|
+
if (!options.findList)
|
|
696
|
+
this.hitBranch(target);
|
|
697
|
+
const { list } = this.findList;
|
|
698
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
630
699
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
631
700
|
this.clear();
|
|
632
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
701
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
633
702
|
}
|
|
634
|
-
getBestMatchLeaf() {
|
|
635
|
-
|
|
636
|
-
if (targets.length > 1) {
|
|
703
|
+
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
704
|
+
if (list.length) {
|
|
637
705
|
let find;
|
|
638
|
-
this.findList =
|
|
706
|
+
this.findList = new core.LeafList();
|
|
639
707
|
const { x, y } = this.point;
|
|
640
708
|
const point = { x, y, radiusX: 0, radiusY: 0 };
|
|
641
|
-
for (let i = 0, len =
|
|
642
|
-
find =
|
|
643
|
-
if (core.LeafHelper.worldHittable(find)) {
|
|
709
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
710
|
+
find = list[i];
|
|
711
|
+
if (ignoreHittable || core.LeafHelper.worldHittable(find)) {
|
|
644
712
|
this.hitChild(find, point);
|
|
645
713
|
if (this.findList.length)
|
|
646
|
-
return this.findList[0];
|
|
714
|
+
return this.findList.list[0];
|
|
647
715
|
}
|
|
648
716
|
}
|
|
649
717
|
}
|
|
650
|
-
|
|
718
|
+
if (bottomList) {
|
|
719
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
720
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
721
|
+
if (this.findList.length)
|
|
722
|
+
return this.findList.list[0];
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return list[0];
|
|
651
726
|
}
|
|
652
727
|
getPath(leaf) {
|
|
653
728
|
const path = new core.LeafList();
|
|
@@ -659,7 +734,7 @@ class Pather {
|
|
|
659
734
|
return path;
|
|
660
735
|
}
|
|
661
736
|
getHitablePath(leaf) {
|
|
662
|
-
const path = this.getPath(leaf);
|
|
737
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
663
738
|
let item, hittablePath = new core.LeafList();
|
|
664
739
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
665
740
|
item = path.list[i];
|
|
@@ -689,12 +764,15 @@ class Pather {
|
|
|
689
764
|
}
|
|
690
765
|
return throughPath;
|
|
691
766
|
}
|
|
767
|
+
hitBranch(branch) {
|
|
768
|
+
this.eachFind(branch.children, branch.__onlyHitMask);
|
|
769
|
+
}
|
|
692
770
|
eachFind(children, hitMask) {
|
|
693
771
|
let child, hit;
|
|
694
772
|
const { point } = this, len = children.length;
|
|
695
773
|
for (let i = len - 1; i > -1; i--) {
|
|
696
774
|
child = children[i];
|
|
697
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
775
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
698
776
|
continue;
|
|
699
777
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
700
778
|
if (child.isBranch) {
|
|
@@ -710,11 +788,15 @@ class Pather {
|
|
|
710
788
|
}
|
|
711
789
|
}
|
|
712
790
|
}
|
|
713
|
-
hitChild(child, point) {
|
|
791
|
+
hitChild(child, point, proxy) {
|
|
714
792
|
if (this.exclude && this.exclude.has(child))
|
|
715
793
|
return;
|
|
716
|
-
if (child.__hitWorld(point))
|
|
717
|
-
|
|
794
|
+
if (child.__hitWorld(point)) {
|
|
795
|
+
const { parent } = child;
|
|
796
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
|
|
797
|
+
return;
|
|
798
|
+
this.findList.add(proxy || child);
|
|
799
|
+
}
|
|
718
800
|
}
|
|
719
801
|
clear() {
|
|
720
802
|
this.point = null;
|
|
@@ -726,7 +808,8 @@ class Pather {
|
|
|
726
808
|
}
|
|
727
809
|
}
|
|
728
810
|
|
|
729
|
-
const { Yes, NoAndSkip, YesAndSkip } =
|
|
811
|
+
const { Yes, NoAndSkip, YesAndSkip } = core.Answer;
|
|
812
|
+
const idCondition = {}, classNameCondition = {}, tagCondition = {};
|
|
730
813
|
class Selector {
|
|
731
814
|
constructor(target, userConfig) {
|
|
732
815
|
this.config = {};
|
|
@@ -736,12 +819,13 @@ class Selector {
|
|
|
736
819
|
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
737
820
|
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
738
821
|
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
739
|
-
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
822
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
|
|
823
|
+
tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
740
824
|
};
|
|
741
825
|
this.target = target;
|
|
742
826
|
if (userConfig)
|
|
743
827
|
this.config = core.DataHelper.default(userConfig, this.config);
|
|
744
|
-
this.
|
|
828
|
+
this.picker = new Picker(target, this);
|
|
745
829
|
this.__listenEvents();
|
|
746
830
|
}
|
|
747
831
|
getBy(condition, branch, one, options) {
|
|
@@ -752,12 +836,25 @@ class Selector {
|
|
|
752
836
|
case 'string':
|
|
753
837
|
switch (condition[0]) {
|
|
754
838
|
case '#':
|
|
755
|
-
|
|
756
|
-
|
|
839
|
+
idCondition.id = condition.substring(1), condition = idCondition;
|
|
840
|
+
break;
|
|
757
841
|
case '.':
|
|
758
|
-
|
|
842
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition;
|
|
843
|
+
break;
|
|
759
844
|
default:
|
|
760
|
-
|
|
845
|
+
tagCondition.tag = condition, condition = tagCondition;
|
|
846
|
+
}
|
|
847
|
+
case 'object':
|
|
848
|
+
if (condition.id !== undefined) {
|
|
849
|
+
const leaf = this.getById(condition.id, branch);
|
|
850
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
851
|
+
}
|
|
852
|
+
else if (condition.tag) {
|
|
853
|
+
const { tag } = condition, isArray = tag instanceof Array;
|
|
854
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? core.DataHelper.toMap(tag) : tag);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className);
|
|
761
858
|
}
|
|
762
859
|
case 'function':
|
|
763
860
|
return this.getByMethod(condition, branch, one, options);
|
|
@@ -766,7 +863,7 @@ class Selector {
|
|
|
766
863
|
getByPoint(hitPoint, hitRadius, options) {
|
|
767
864
|
if (core.Platform.name === 'node')
|
|
768
865
|
this.target.emit(core.LayoutEvent.CHECK_UPDATE);
|
|
769
|
-
return this.
|
|
866
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
770
867
|
}
|
|
771
868
|
getByInnerId(innerId, branch) {
|
|
772
869
|
const cache = this.innerIdMap[innerId];
|
|
@@ -842,7 +939,7 @@ class Selector {
|
|
|
842
939
|
destroy() {
|
|
843
940
|
if (this.__eventIds.length) {
|
|
844
941
|
this.__removeListenEvents();
|
|
845
|
-
this.
|
|
942
|
+
this.picker.destroy();
|
|
846
943
|
this.findLeaf = null;
|
|
847
944
|
this.innerIdMap = {};
|
|
848
945
|
this.idMap = {};
|
|
@@ -858,466 +955,91 @@ Object.assign(core.Creator, {
|
|
|
858
955
|
});
|
|
859
956
|
core.Platform.layout = Layouter.fullLayout;
|
|
860
957
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
this.context.__proto__.roundRect = null;
|
|
869
|
-
core.canvasPatch(this.context.__proto__);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
__createView() {
|
|
873
|
-
this.view = core.Platform.origin.createCanvas(1, 1);
|
|
874
|
-
}
|
|
875
|
-
updateViewSize() {
|
|
876
|
-
const { width, height, pixelRatio } = this;
|
|
877
|
-
this.view.width = width * pixelRatio;
|
|
878
|
-
this.view.height = height * pixelRatio;
|
|
879
|
-
this.clientBounds = this.bounds;
|
|
880
|
-
}
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
const { mineType, fileType } = core.FileHelper;
|
|
884
|
-
Object.assign(core.Creator, {
|
|
885
|
-
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
886
|
-
image: (options) => new core.LeaferImage(options),
|
|
887
|
-
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
888
|
-
interaction: (target, canvas, selector, options) => { return new core.InteractionBase(target, canvas, selector, options); }
|
|
889
|
-
});
|
|
890
|
-
function useCanvas(canvasType, power) {
|
|
891
|
-
core.Platform.canvasType = canvasType;
|
|
892
|
-
if (!core.Platform.origin) {
|
|
893
|
-
if (canvasType === 'skia') {
|
|
894
|
-
const { Canvas, loadImage } = power;
|
|
895
|
-
core.Platform.origin = {
|
|
896
|
-
createCanvas: (width, height, format) => new Canvas(width, height, format),
|
|
897
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURLSync(type, { quality }),
|
|
898
|
-
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
899
|
-
canvasSaveAs: (canvas, filename, quality) => canvas.saveAs(filename, { quality }),
|
|
900
|
-
loadImage
|
|
901
|
-
};
|
|
902
|
-
core.Platform.roundRectPatch = true;
|
|
958
|
+
function fillText(ui, canvas) {
|
|
959
|
+
let row;
|
|
960
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
961
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
962
|
+
row = rows[i];
|
|
963
|
+
if (row.text) {
|
|
964
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
903
965
|
}
|
|
904
|
-
else if (
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
909
|
-
canvasToBolb: (canvas, type, quality) => __awaiter(this, void 0, void 0, function* () { return canvas.toBuffer(mineType(type), quality); }),
|
|
910
|
-
canvasSaveAs: (canvas, filename, quality) => __awaiter(this, void 0, void 0, function* () { return fs.writeFileSync(filename, canvas.toBuffer(mineType(fileType(filename)), quality)); }),
|
|
911
|
-
loadImage
|
|
912
|
-
};
|
|
966
|
+
else if (row.data) {
|
|
967
|
+
row.data.forEach(charData => {
|
|
968
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
969
|
+
});
|
|
913
970
|
}
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
stopDefault(_origin) { },
|
|
917
|
-
stopNow(_origin) { },
|
|
918
|
-
stop(_origin) { }
|
|
919
|
-
};
|
|
920
|
-
core.Platform.canvas = core.Creator.canvas();
|
|
971
|
+
if (decorationY)
|
|
972
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
921
973
|
}
|
|
922
974
|
}
|
|
923
|
-
core.Platform.name = 'node';
|
|
924
|
-
core.Platform.requestRender = function (render) { setTimeout(render); };
|
|
925
|
-
core.Platform.devicePixelRatio = 1;
|
|
926
|
-
core.Platform.conicGradientSupport = true;
|
|
927
975
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
const swap = rotation && rotation !== 180;
|
|
932
|
-
const sw = box.width / (swap ? height : width);
|
|
933
|
-
const sh = box.height / (swap ? width : height);
|
|
934
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
935
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
936
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
937
|
-
translate$1(transform, x, y);
|
|
938
|
-
scaleHelper(transform, scale);
|
|
939
|
-
if (rotation)
|
|
940
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
941
|
-
data.scaleX = data.scaleY = scale;
|
|
942
|
-
data.transform = transform;
|
|
943
|
-
}
|
|
944
|
-
function clipMode(data, box, offset, scale, rotation) {
|
|
945
|
-
const transform = get$4();
|
|
946
|
-
translate$1(transform, box.x, box.y);
|
|
947
|
-
if (offset)
|
|
948
|
-
translate$1(transform, offset.x, offset.y);
|
|
949
|
-
if (scale) {
|
|
950
|
-
typeof scale === 'number' ? scaleHelper(transform, scale) : scaleHelper(transform, scale.x, scale.y);
|
|
951
|
-
data.scaleX = transform.a;
|
|
952
|
-
data.scaleY = transform.d;
|
|
953
|
-
}
|
|
954
|
-
if (rotation)
|
|
955
|
-
rotate(transform, rotation);
|
|
956
|
-
data.transform = transform;
|
|
976
|
+
function fill(fill, ui, canvas) {
|
|
977
|
+
canvas.fillStyle = fill;
|
|
978
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
957
979
|
}
|
|
958
|
-
function
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
980
|
+
function fills(fills, ui, canvas) {
|
|
981
|
+
let item;
|
|
982
|
+
const { windingRule, __font } = ui.__;
|
|
983
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
984
|
+
item = fills[i];
|
|
985
|
+
if (item.image && draw.PaintImage.checkImage(ui, canvas, item, !__font))
|
|
986
|
+
continue;
|
|
987
|
+
if (item.style) {
|
|
988
|
+
canvas.fillStyle = item.style;
|
|
989
|
+
if (item.transform) {
|
|
990
|
+
canvas.save();
|
|
991
|
+
canvas.transform(item.transform);
|
|
992
|
+
if (item.blendMode)
|
|
993
|
+
canvas.blendMode = item.blendMode;
|
|
994
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
995
|
+
canvas.restore();
|
|
996
|
+
}
|
|
997
|
+
else {
|
|
998
|
+
if (item.blendMode) {
|
|
999
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1000
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1001
|
+
canvas.restoreBlendMode();
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
972
1007
|
}
|
|
973
1008
|
}
|
|
974
|
-
translate$1(transform, box.x, box.y);
|
|
975
|
-
if (scale) {
|
|
976
|
-
scaleOfOuter$2(transform, box, scale);
|
|
977
|
-
data.scaleX = data.scaleY = scale;
|
|
978
|
-
}
|
|
979
|
-
data.transform = transform;
|
|
980
1009
|
}
|
|
981
1010
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
const data = leafPaint.data = { mode };
|
|
990
|
-
switch (mode) {
|
|
991
|
-
case 'strench':
|
|
992
|
-
if (!sameBox)
|
|
993
|
-
width = box.width, height = box.height;
|
|
994
|
-
if (box.x || box.y) {
|
|
995
|
-
data.transform = get$3();
|
|
996
|
-
translate(data.transform, box.x, box.y);
|
|
997
|
-
}
|
|
1011
|
+
function strokeText(stroke, ui, canvas) {
|
|
1012
|
+
const { strokeAlign } = ui.__;
|
|
1013
|
+
const isStrokes = typeof stroke !== 'string';
|
|
1014
|
+
switch (strokeAlign) {
|
|
1015
|
+
case 'center':
|
|
1016
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1017
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
998
1018
|
break;
|
|
999
|
-
case '
|
|
1000
|
-
|
|
1001
|
-
clipMode(data, box, offset, scale, rotation);
|
|
1019
|
+
case 'inside':
|
|
1020
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1002
1021
|
break;
|
|
1003
|
-
case '
|
|
1004
|
-
|
|
1005
|
-
repeatMode(data, box, width, height, scale, rotation);
|
|
1006
|
-
if (!repeat)
|
|
1007
|
-
data.repeat = 'repeat';
|
|
1022
|
+
case 'outside':
|
|
1023
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1008
1024
|
break;
|
|
1009
|
-
case 'fit':
|
|
1010
|
-
case 'cover':
|
|
1011
|
-
default:
|
|
1012
|
-
if (!sameBox || rotation)
|
|
1013
|
-
fillOrFitMode(data, mode, box, width, height, rotation);
|
|
1014
1025
|
}
|
|
1015
|
-
data.width = width;
|
|
1016
|
-
data.height = height;
|
|
1017
|
-
if (opacity)
|
|
1018
|
-
data.opacity = opacity;
|
|
1019
|
-
if (repeat)
|
|
1020
|
-
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1021
1026
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
}
|
|
1034
|
-
}
|
|
1035
|
-
else if (image.error) {
|
|
1036
|
-
if (firstUse) {
|
|
1037
|
-
ui.forceUpdate('surface');
|
|
1038
|
-
event.error = image.error;
|
|
1039
|
-
emit(core.ImageEvent.ERROR, event);
|
|
1040
|
-
}
|
|
1027
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1028
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1029
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1030
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1031
|
+
out.font = __font;
|
|
1032
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1033
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1034
|
+
fillText(ui, out);
|
|
1035
|
+
out.blendMode = 'normal';
|
|
1036
|
+
if (ui.__worldFlipped) {
|
|
1037
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1041
1038
|
}
|
|
1042
1039
|
else {
|
|
1043
|
-
|
|
1044
|
-
emit(core.ImageEvent.LOAD, event);
|
|
1045
|
-
leafPaint.loadId = image.load(() => {
|
|
1046
|
-
if (!ui.destroyed) {
|
|
1047
|
-
if (hasNaturalSize(ui, attrName, image)) {
|
|
1048
|
-
createData(leafPaint, image, attrValue, box);
|
|
1049
|
-
ui.forceUpdate('surface');
|
|
1050
|
-
}
|
|
1051
|
-
emit(core.ImageEvent.LOADED, event);
|
|
1052
|
-
}
|
|
1053
|
-
}, (error) => {
|
|
1054
|
-
ui.forceUpdate('surface');
|
|
1055
|
-
event.error = error;
|
|
1056
|
-
emit(core.ImageEvent.ERROR, event);
|
|
1057
|
-
});
|
|
1058
|
-
}
|
|
1059
|
-
return leafPaint;
|
|
1060
|
-
}
|
|
1061
|
-
function hasNaturalSize(ui, attrName, image) {
|
|
1062
|
-
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1063
|
-
const { __: d } = ui;
|
|
1064
|
-
d.__naturalWidth = image.width;
|
|
1065
|
-
d.__naturalHeight = image.height;
|
|
1066
|
-
if (!d.__getInput('width') || !d.__getInput('height')) {
|
|
1067
|
-
ui.forceUpdate('width');
|
|
1068
|
-
if (ui.__proxyData) {
|
|
1069
|
-
ui.setProxyAttr('width', ui.__.width);
|
|
1070
|
-
ui.setProxyAttr('height', ui.__.height);
|
|
1071
|
-
}
|
|
1072
|
-
return false;
|
|
1073
|
-
}
|
|
1040
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1074
1041
|
}
|
|
1075
|
-
|
|
1076
|
-
}
|
|
1077
|
-
function emit(type, data) {
|
|
1078
|
-
if (data.target.hasEvent(type))
|
|
1079
|
-
data.target.emitEvent(new core.ImageEvent(type, data));
|
|
1080
|
-
}
|
|
1081
|
-
|
|
1082
|
-
const Export$1 = {};
|
|
1083
|
-
|
|
1084
|
-
const { get: get$2, scale, copy: copy$1 } = core.MatrixHelper;
|
|
1085
|
-
function createPattern(ui, paint, pixelRatio) {
|
|
1086
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1087
|
-
const id = scaleX + '-' + scaleY;
|
|
1088
|
-
if (paint.patternId !== id && !ui.destroyed) {
|
|
1089
|
-
scaleX = Math.abs(scaleX);
|
|
1090
|
-
scaleY = Math.abs(scaleY);
|
|
1091
|
-
const { image, data } = paint;
|
|
1092
|
-
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1093
|
-
if (sx) {
|
|
1094
|
-
imageMatrix = get$2();
|
|
1095
|
-
copy$1(imageMatrix, transform);
|
|
1096
|
-
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1097
|
-
scaleX *= sx;
|
|
1098
|
-
scaleY *= sy;
|
|
1099
|
-
}
|
|
1100
|
-
scaleX *= pixelRatio;
|
|
1101
|
-
scaleY *= pixelRatio;
|
|
1102
|
-
width *= scaleX;
|
|
1103
|
-
height *= scaleY;
|
|
1104
|
-
const size = width * height;
|
|
1105
|
-
if (!repeat) {
|
|
1106
|
-
if (size > core.Platform.image.maxCacheSize)
|
|
1107
|
-
return false;
|
|
1108
|
-
}
|
|
1109
|
-
let maxSize = core.Platform.image.maxPatternSize;
|
|
1110
|
-
if (!image.isSVG) {
|
|
1111
|
-
const imageSize = image.width * image.height;
|
|
1112
|
-
if (maxSize > imageSize)
|
|
1113
|
-
maxSize = imageSize;
|
|
1114
|
-
}
|
|
1115
|
-
if (size > maxSize)
|
|
1116
|
-
imageScale = Math.sqrt(size / maxSize);
|
|
1117
|
-
if (imageScale) {
|
|
1118
|
-
scaleX /= imageScale;
|
|
1119
|
-
scaleY /= imageScale;
|
|
1120
|
-
width /= imageScale;
|
|
1121
|
-
height /= imageScale;
|
|
1122
|
-
}
|
|
1123
|
-
if (sx) {
|
|
1124
|
-
scaleX /= sx;
|
|
1125
|
-
scaleY /= sy;
|
|
1126
|
-
}
|
|
1127
|
-
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1128
|
-
if (!imageMatrix) {
|
|
1129
|
-
imageMatrix = get$2();
|
|
1130
|
-
if (transform)
|
|
1131
|
-
copy$1(imageMatrix, transform);
|
|
1132
|
-
}
|
|
1133
|
-
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1134
|
-
}
|
|
1135
|
-
const pattern = core.Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), repeat || (core.Platform.origin.noRepeat || 'no-repeat'));
|
|
1136
|
-
try {
|
|
1137
|
-
if (paint.transform)
|
|
1138
|
-
paint.transform = null;
|
|
1139
|
-
if (imageMatrix)
|
|
1140
|
-
pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
|
|
1141
|
-
}
|
|
1142
|
-
catch (_a) {
|
|
1143
|
-
paint.transform = imageMatrix;
|
|
1144
|
-
}
|
|
1145
|
-
paint.style = pattern;
|
|
1146
|
-
paint.patternId = id;
|
|
1147
|
-
return true;
|
|
1148
|
-
}
|
|
1149
|
-
else {
|
|
1150
|
-
return false;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
|
|
1154
|
-
const { abs } = Math;
|
|
1155
|
-
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1156
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1157
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1158
|
-
return false;
|
|
1159
|
-
}
|
|
1160
|
-
else {
|
|
1161
|
-
const { data } = paint;
|
|
1162
|
-
if (allowPaint) {
|
|
1163
|
-
if (!data.repeat) {
|
|
1164
|
-
let { width, height } = data;
|
|
1165
|
-
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1166
|
-
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1167
|
-
if (data.scaleX) {
|
|
1168
|
-
width *= data.scaleX;
|
|
1169
|
-
height *= data.scaleY;
|
|
1170
|
-
}
|
|
1171
|
-
allowPaint = width * height > core.Platform.image.maxCacheSize;
|
|
1172
|
-
}
|
|
1173
|
-
else {
|
|
1174
|
-
allowPaint = false;
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
if (allowPaint) {
|
|
1178
|
-
canvas.save();
|
|
1179
|
-
canvas.clip();
|
|
1180
|
-
if (paint.blendMode)
|
|
1181
|
-
canvas.blendMode = paint.blendMode;
|
|
1182
|
-
if (data.opacity)
|
|
1183
|
-
canvas.opacity *= data.opacity;
|
|
1184
|
-
if (data.transform)
|
|
1185
|
-
canvas.transform(data.transform);
|
|
1186
|
-
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1187
|
-
canvas.restore();
|
|
1188
|
-
return true;
|
|
1189
|
-
}
|
|
1190
|
-
else {
|
|
1191
|
-
if (!paint.style || Export$1.running) {
|
|
1192
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1193
|
-
}
|
|
1194
|
-
else {
|
|
1195
|
-
if (!paint.patternTask) {
|
|
1196
|
-
paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1197
|
-
paint.patternTask = null;
|
|
1198
|
-
if (canvas.bounds.hit(ui.__world))
|
|
1199
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1200
|
-
ui.forceUpdate('surface');
|
|
1201
|
-
}), 300);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
return false;
|
|
1205
|
-
}
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
function recycleImage(attrName, data) {
|
|
1210
|
-
const paints = data['_' + attrName];
|
|
1211
|
-
if (paints instanceof Array) {
|
|
1212
|
-
let image, recycleMap, input, url;
|
|
1213
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1214
|
-
image = paints[i].image;
|
|
1215
|
-
url = image && image.url;
|
|
1216
|
-
if (url) {
|
|
1217
|
-
if (!recycleMap)
|
|
1218
|
-
recycleMap = {};
|
|
1219
|
-
recycleMap[url] = true;
|
|
1220
|
-
core.ImageManager.recycle(image);
|
|
1221
|
-
if (image.loading) {
|
|
1222
|
-
if (!input) {
|
|
1223
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1224
|
-
if (!(input instanceof Array))
|
|
1225
|
-
input = [input];
|
|
1226
|
-
}
|
|
1227
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1228
|
-
}
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
return recycleMap;
|
|
1232
|
-
}
|
|
1233
|
-
return null;
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
function fillText(ui, canvas) {
|
|
1237
|
-
let row;
|
|
1238
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1239
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1240
|
-
row = rows[i];
|
|
1241
|
-
if (row.text) {
|
|
1242
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1243
|
-
}
|
|
1244
|
-
else if (row.data) {
|
|
1245
|
-
row.data.forEach(charData => {
|
|
1246
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1247
|
-
});
|
|
1248
|
-
}
|
|
1249
|
-
if (decorationY)
|
|
1250
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
|
|
1254
|
-
function fill(fill, ui, canvas) {
|
|
1255
|
-
canvas.fillStyle = fill;
|
|
1256
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1257
|
-
}
|
|
1258
|
-
function fills(fills, ui, canvas) {
|
|
1259
|
-
let item;
|
|
1260
|
-
const { windingRule, __font } = ui.__;
|
|
1261
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1262
|
-
item = fills[i];
|
|
1263
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1264
|
-
continue;
|
|
1265
|
-
if (item.style) {
|
|
1266
|
-
canvas.fillStyle = item.style;
|
|
1267
|
-
if (item.transform) {
|
|
1268
|
-
canvas.save();
|
|
1269
|
-
canvas.transform(item.transform);
|
|
1270
|
-
if (item.blendMode)
|
|
1271
|
-
canvas.blendMode = item.blendMode;
|
|
1272
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1273
|
-
canvas.restore();
|
|
1274
|
-
}
|
|
1275
|
-
else {
|
|
1276
|
-
if (item.blendMode) {
|
|
1277
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1278
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1279
|
-
canvas.restoreBlendMode();
|
|
1280
|
-
}
|
|
1281
|
-
else {
|
|
1282
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
}
|
|
1287
|
-
}
|
|
1288
|
-
|
|
1289
|
-
function strokeText(stroke, ui, canvas, renderOptions) {
|
|
1290
|
-
const { strokeAlign } = ui.__;
|
|
1291
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1292
|
-
switch (strokeAlign) {
|
|
1293
|
-
case 'center':
|
|
1294
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1295
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1296
|
-
break;
|
|
1297
|
-
case 'inside':
|
|
1298
|
-
drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1299
|
-
break;
|
|
1300
|
-
case 'outside':
|
|
1301
|
-
drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1302
|
-
break;
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
|
|
1306
|
-
const { strokeWidth, __font } = ui.__;
|
|
1307
|
-
const out = canvas.getSameCanvas(true);
|
|
1308
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1309
|
-
out.font = __font;
|
|
1310
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1311
|
-
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1312
|
-
fillText(ui, out);
|
|
1313
|
-
out.blendMode = 'normal';
|
|
1314
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1315
|
-
canvas.copyWorldByReset(out);
|
|
1316
|
-
}
|
|
1317
|
-
else {
|
|
1318
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1319
|
-
}
|
|
1320
|
-
out.recycle();
|
|
1042
|
+
out.recycle(ui.__nowWorld);
|
|
1321
1043
|
}
|
|
1322
1044
|
function drawTextStroke(ui, canvas) {
|
|
1323
1045
|
let row;
|
|
@@ -1340,7 +1062,7 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
|
1340
1062
|
let item;
|
|
1341
1063
|
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1342
1064
|
item = strokes[i];
|
|
1343
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1065
|
+
if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false))
|
|
1344
1066
|
continue;
|
|
1345
1067
|
if (item.style) {
|
|
1346
1068
|
canvas.strokeStyle = item.style;
|
|
@@ -1356,138 +1078,567 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
|
1356
1078
|
}
|
|
1357
1079
|
}
|
|
1358
1080
|
|
|
1359
|
-
function stroke(stroke, ui, canvas
|
|
1081
|
+
function stroke(stroke, ui, canvas) {
|
|
1360
1082
|
const options = ui.__;
|
|
1361
|
-
const {
|
|
1362
|
-
if (!
|
|
1083
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1084
|
+
if (!__strokeWidth)
|
|
1363
1085
|
return;
|
|
1364
1086
|
if (__font) {
|
|
1365
|
-
strokeText(stroke, ui, canvas
|
|
1087
|
+
strokeText(stroke, ui, canvas);
|
|
1366
1088
|
}
|
|
1367
1089
|
else {
|
|
1368
1090
|
switch (strokeAlign) {
|
|
1369
1091
|
case 'center':
|
|
1370
|
-
canvas.setStroke(stroke,
|
|
1092
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1371
1093
|
canvas.stroke();
|
|
1372
1094
|
break;
|
|
1373
1095
|
case 'inside':
|
|
1374
1096
|
canvas.save();
|
|
1375
|
-
canvas.setStroke(stroke,
|
|
1097
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1376
1098
|
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1377
1099
|
canvas.stroke();
|
|
1378
1100
|
canvas.restore();
|
|
1379
1101
|
break;
|
|
1380
1102
|
case 'outside':
|
|
1381
|
-
const out = canvas.getSameCanvas(true);
|
|
1382
|
-
out.setStroke(stroke,
|
|
1103
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1104
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1383
1105
|
ui.__drawRenderPath(out);
|
|
1384
1106
|
out.stroke();
|
|
1385
1107
|
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1386
1108
|
out.clearWorld(ui.__layout.renderBounds);
|
|
1387
|
-
if (ui.__worldFlipped
|
|
1388
|
-
canvas.copyWorldByReset(out);
|
|
1109
|
+
if (ui.__worldFlipped) {
|
|
1110
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1114
|
+
}
|
|
1115
|
+
out.recycle(ui.__nowWorld);
|
|
1116
|
+
break;
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
function strokes(strokes, ui, canvas) {
|
|
1121
|
+
const options = ui.__;
|
|
1122
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1123
|
+
if (!__strokeWidth)
|
|
1124
|
+
return;
|
|
1125
|
+
if (__font) {
|
|
1126
|
+
strokeText(strokes, ui, canvas);
|
|
1127
|
+
}
|
|
1128
|
+
else {
|
|
1129
|
+
switch (strokeAlign) {
|
|
1130
|
+
case 'center':
|
|
1131
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1132
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1133
|
+
break;
|
|
1134
|
+
case 'inside':
|
|
1135
|
+
canvas.save();
|
|
1136
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1137
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1138
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1139
|
+
canvas.restore();
|
|
1140
|
+
break;
|
|
1141
|
+
case 'outside':
|
|
1142
|
+
const { renderBounds } = ui.__layout;
|
|
1143
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1144
|
+
ui.__drawRenderPath(out);
|
|
1145
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1146
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1147
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1148
|
+
out.clearWorld(renderBounds);
|
|
1149
|
+
if (ui.__worldFlipped) {
|
|
1150
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1389
1151
|
}
|
|
1390
1152
|
else {
|
|
1391
|
-
canvas.copyWorldToInner(out, ui.
|
|
1153
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1392
1154
|
}
|
|
1393
|
-
out.recycle();
|
|
1155
|
+
out.recycle(ui.__nowWorld);
|
|
1394
1156
|
break;
|
|
1395
1157
|
}
|
|
1396
1158
|
}
|
|
1397
1159
|
}
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1160
|
+
|
|
1161
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = core.BoundsHelper;
|
|
1162
|
+
function shape(ui, current, options) {
|
|
1163
|
+
const canvas = current.getSameCanvas();
|
|
1164
|
+
const nowWorld = ui.__nowWorld;
|
|
1165
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1166
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1167
|
+
if (scaleX < 0)
|
|
1168
|
+
scaleX = -scaleX;
|
|
1169
|
+
if (scaleY < 0)
|
|
1170
|
+
scaleY = -scaleY;
|
|
1171
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1172
|
+
worldCanvas = canvas;
|
|
1173
|
+
bounds = shapeBounds = nowWorld;
|
|
1174
|
+
}
|
|
1175
|
+
else {
|
|
1176
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1177
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1178
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1179
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1180
|
+
if (fitMatrix.a < 1) {
|
|
1181
|
+
worldCanvas = current.getSameCanvas();
|
|
1182
|
+
ui.__renderShape(worldCanvas, options);
|
|
1183
|
+
scaleX *= fitScaleX;
|
|
1184
|
+
scaleY *= fitScaleY;
|
|
1185
|
+
}
|
|
1186
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1187
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1188
|
+
if (options.matrix) {
|
|
1189
|
+
const { matrix } = options;
|
|
1190
|
+
fitMatrix.multiply(matrix);
|
|
1191
|
+
fitScaleX *= matrix.scaleX;
|
|
1192
|
+
fitScaleY *= matrix.scaleY;
|
|
1193
|
+
}
|
|
1194
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1195
|
+
}
|
|
1196
|
+
ui.__renderShape(canvas, options);
|
|
1197
|
+
return {
|
|
1198
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1199
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
let recycleMap;
|
|
1204
|
+
function compute(attrName, ui) {
|
|
1205
|
+
const data = ui.__, leafPaints = [];
|
|
1206
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1207
|
+
if (!(paints instanceof Array))
|
|
1208
|
+
paints = [paints];
|
|
1209
|
+
recycleMap = draw.PaintImage.recycleImage(attrName, data);
|
|
1210
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1211
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1212
|
+
if (item)
|
|
1213
|
+
leafPaints.push(item);
|
|
1214
|
+
}
|
|
1215
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1216
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1217
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1218
|
+
if (attrName === 'fill') {
|
|
1219
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1220
|
+
}
|
|
1221
|
+
else {
|
|
1222
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1226
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1227
|
+
return undefined;
|
|
1228
|
+
const { boxBounds } = ui.__layout;
|
|
1229
|
+
switch (paint.type) {
|
|
1230
|
+
case 'solid':
|
|
1231
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1232
|
+
return { type, blendMode, style: draw.ColorConvert.string(color, opacity) };
|
|
1233
|
+
case 'image':
|
|
1234
|
+
return draw.PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1235
|
+
case 'linear':
|
|
1236
|
+
return draw.PaintGradient.linearGradient(paint, boxBounds);
|
|
1237
|
+
case 'radial':
|
|
1238
|
+
return draw.PaintGradient.radialGradient(paint, boxBounds);
|
|
1239
|
+
case 'angular':
|
|
1240
|
+
return draw.PaintGradient.conicGradient(paint, boxBounds);
|
|
1241
|
+
default:
|
|
1242
|
+
return paint.r !== undefined ? { type: 'solid', style: draw.ColorConvert.string(paint) } : undefined;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
const PaintModule = {
|
|
1247
|
+
compute,
|
|
1248
|
+
fill,
|
|
1249
|
+
fills,
|
|
1250
|
+
fillText,
|
|
1251
|
+
stroke,
|
|
1252
|
+
strokes,
|
|
1253
|
+
strokeText,
|
|
1254
|
+
drawTextStroke,
|
|
1255
|
+
shape
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
let origin = {};
|
|
1259
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = core.MatrixHelper;
|
|
1260
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1261
|
+
const transform = get$3();
|
|
1262
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1263
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1264
|
+
if (rotation)
|
|
1265
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1266
|
+
data.transform = transform;
|
|
1267
|
+
}
|
|
1268
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1269
|
+
const transform = get$3();
|
|
1270
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1271
|
+
if (scaleX)
|
|
1272
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1273
|
+
if (rotation)
|
|
1274
|
+
rotate(transform, rotation);
|
|
1275
|
+
data.transform = transform;
|
|
1276
|
+
}
|
|
1277
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1278
|
+
const transform = get$3();
|
|
1279
|
+
if (rotation) {
|
|
1280
|
+
if (align === 'center') {
|
|
1281
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1282
|
+
}
|
|
1283
|
+
else {
|
|
1284
|
+
rotate(transform, rotation);
|
|
1285
|
+
switch (rotation) {
|
|
1286
|
+
case 90:
|
|
1287
|
+
translate$1(transform, height, 0);
|
|
1288
|
+
break;
|
|
1289
|
+
case 180:
|
|
1290
|
+
translate$1(transform, width, height);
|
|
1291
|
+
break;
|
|
1292
|
+
case 270:
|
|
1293
|
+
translate$1(transform, 0, width);
|
|
1294
|
+
break;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
origin.x = box.x + x;
|
|
1299
|
+
origin.y = box.y + y;
|
|
1300
|
+
translate$1(transform, origin.x, origin.y);
|
|
1301
|
+
if (scaleX)
|
|
1302
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1303
|
+
data.transform = transform;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const { get: get$2, translate } = core.MatrixHelper;
|
|
1307
|
+
const tempBox = new core.Bounds();
|
|
1308
|
+
const tempPoint = {};
|
|
1309
|
+
function createData(leafPaint, image, paint, box) {
|
|
1310
|
+
const { blendMode } = paint;
|
|
1311
|
+
if (blendMode)
|
|
1312
|
+
leafPaint.blendMode = blendMode;
|
|
1313
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1314
|
+
}
|
|
1315
|
+
function getPatternData(paint, box, image) {
|
|
1316
|
+
let { width, height } = image;
|
|
1317
|
+
if (paint.padding)
|
|
1318
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1319
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1320
|
+
const sameBox = box.width === width && box.height === height;
|
|
1321
|
+
const data = { mode };
|
|
1322
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1323
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1324
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1325
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1326
|
+
if (!sameBox || rotation) {
|
|
1327
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1328
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1329
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
else if (size) {
|
|
1333
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1334
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1335
|
+
}
|
|
1336
|
+
else if (scale) {
|
|
1337
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1338
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1339
|
+
}
|
|
1340
|
+
if (align) {
|
|
1341
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1342
|
+
if (scaleX)
|
|
1343
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1344
|
+
core.AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1345
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1346
|
+
}
|
|
1347
|
+
if (offset)
|
|
1348
|
+
x += offset.x, y += offset.y;
|
|
1349
|
+
switch (mode) {
|
|
1350
|
+
case 'strench':
|
|
1351
|
+
if (!sameBox)
|
|
1352
|
+
width = box.width, height = box.height;
|
|
1353
|
+
break;
|
|
1354
|
+
case 'normal':
|
|
1355
|
+
case 'clip':
|
|
1356
|
+
if (x || y || scaleX || rotation)
|
|
1357
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1358
|
+
break;
|
|
1359
|
+
case 'repeat':
|
|
1360
|
+
if (!sameBox || scaleX || rotation)
|
|
1361
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1362
|
+
if (!repeat)
|
|
1363
|
+
data.repeat = 'repeat';
|
|
1364
|
+
break;
|
|
1365
|
+
case 'fit':
|
|
1366
|
+
case 'cover':
|
|
1367
|
+
default:
|
|
1368
|
+
if (scaleX)
|
|
1369
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1370
|
+
}
|
|
1371
|
+
if (!data.transform) {
|
|
1372
|
+
if (box.x || box.y) {
|
|
1373
|
+
data.transform = get$2();
|
|
1374
|
+
translate(data.transform, box.x, box.y);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
if (scaleX && mode !== 'strench') {
|
|
1378
|
+
data.scaleX = scaleX;
|
|
1379
|
+
data.scaleY = scaleY;
|
|
1380
|
+
}
|
|
1381
|
+
data.width = width;
|
|
1382
|
+
data.height = height;
|
|
1383
|
+
if (opacity)
|
|
1384
|
+
data.opacity = opacity;
|
|
1385
|
+
if (repeat)
|
|
1386
|
+
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1387
|
+
return data;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
let cache, box = new core.Bounds();
|
|
1391
|
+
const { isSame } = core.BoundsHelper;
|
|
1392
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1393
|
+
let leafPaint, event;
|
|
1394
|
+
const image = core.ImageManager.get(paint);
|
|
1395
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1396
|
+
leafPaint = cache.leafPaint;
|
|
1397
|
+
}
|
|
1398
|
+
else {
|
|
1399
|
+
leafPaint = { type: paint.type, image };
|
|
1400
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1401
|
+
}
|
|
1402
|
+
if (firstUse || image.loading)
|
|
1403
|
+
event = { image, attrName, attrValue: paint };
|
|
1404
|
+
if (image.ready) {
|
|
1405
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1406
|
+
if (firstUse) {
|
|
1407
|
+
onLoad(ui, event);
|
|
1408
|
+
onLoadSuccess(ui, event);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
else if (image.error) {
|
|
1412
|
+
if (firstUse)
|
|
1413
|
+
onLoadError(ui, event, image.error);
|
|
1414
|
+
}
|
|
1415
|
+
else {
|
|
1416
|
+
ignoreRender(ui, true);
|
|
1417
|
+
if (firstUse)
|
|
1418
|
+
onLoad(ui, event);
|
|
1419
|
+
leafPaint.loadId = image.load(() => {
|
|
1420
|
+
ignoreRender(ui, false);
|
|
1421
|
+
if (!ui.destroyed) {
|
|
1422
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1423
|
+
if (image.hasOpacityPixel)
|
|
1424
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1425
|
+
ui.forceUpdate('surface');
|
|
1426
|
+
}
|
|
1427
|
+
onLoadSuccess(ui, event);
|
|
1428
|
+
}
|
|
1429
|
+
leafPaint.loadId = null;
|
|
1430
|
+
}, (error) => {
|
|
1431
|
+
ignoreRender(ui, false);
|
|
1432
|
+
onLoadError(ui, event, error);
|
|
1433
|
+
leafPaint.loadId = null;
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
return leafPaint;
|
|
1437
|
+
}
|
|
1438
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1439
|
+
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1440
|
+
const data = ui.__;
|
|
1441
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1442
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1443
|
+
if (data.__autoSide) {
|
|
1444
|
+
ui.forceUpdate('width');
|
|
1445
|
+
if (ui.__proxyData) {
|
|
1446
|
+
ui.setProxyAttr('width', data.width);
|
|
1447
|
+
ui.setProxyAttr('height', data.height);
|
|
1448
|
+
}
|
|
1449
|
+
return false;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (!leafPaint.data)
|
|
1453
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1454
|
+
return true;
|
|
1455
|
+
}
|
|
1456
|
+
function onLoad(ui, event) {
|
|
1457
|
+
emit(ui, core.ImageEvent.LOAD, event);
|
|
1458
|
+
}
|
|
1459
|
+
function onLoadSuccess(ui, event) {
|
|
1460
|
+
emit(ui, core.ImageEvent.LOADED, event);
|
|
1461
|
+
}
|
|
1462
|
+
function onLoadError(ui, event, error) {
|
|
1463
|
+
event.error = error;
|
|
1464
|
+
ui.forceUpdate('surface');
|
|
1465
|
+
emit(ui, core.ImageEvent.ERROR, event);
|
|
1466
|
+
}
|
|
1467
|
+
function emit(ui, type, data) {
|
|
1468
|
+
if (ui.hasEvent(type))
|
|
1469
|
+
ui.emitEvent(new core.ImageEvent(type, data));
|
|
1470
|
+
}
|
|
1471
|
+
function ignoreRender(ui, value) {
|
|
1472
|
+
const { leafer } = ui;
|
|
1473
|
+
if (leafer && leafer.viewReady)
|
|
1474
|
+
leafer.renderer.ignore = value;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
const { get: get$1, scale, copy: copy$1 } = core.MatrixHelper;
|
|
1478
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1479
|
+
function createPattern(ui, paint, pixelRatio) {
|
|
1480
|
+
let { scaleX, scaleY } = core.ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1481
|
+
const id = scaleX + '-' + scaleY;
|
|
1482
|
+
if (paint.patternId !== id && !ui.destroyed) {
|
|
1483
|
+
scaleX = abs$1(scaleX);
|
|
1484
|
+
scaleY = abs$1(scaleY);
|
|
1485
|
+
const { image, data } = paint;
|
|
1486
|
+
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1487
|
+
if (sx) {
|
|
1488
|
+
imageMatrix = get$1();
|
|
1489
|
+
copy$1(imageMatrix, transform);
|
|
1490
|
+
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1491
|
+
scaleX *= sx;
|
|
1492
|
+
scaleY *= sy;
|
|
1493
|
+
}
|
|
1494
|
+
scaleX *= pixelRatio;
|
|
1495
|
+
scaleY *= pixelRatio;
|
|
1496
|
+
width *= scaleX;
|
|
1497
|
+
height *= scaleY;
|
|
1498
|
+
const size = width * height;
|
|
1499
|
+
if (!repeat) {
|
|
1500
|
+
if (size > core.Platform.image.maxCacheSize)
|
|
1501
|
+
return false;
|
|
1502
|
+
}
|
|
1503
|
+
let maxSize = core.Platform.image.maxPatternSize;
|
|
1504
|
+
if (!image.isSVG) {
|
|
1505
|
+
const imageSize = image.width * image.height;
|
|
1506
|
+
if (maxSize > imageSize)
|
|
1507
|
+
maxSize = imageSize;
|
|
1508
|
+
}
|
|
1509
|
+
if (size > maxSize)
|
|
1510
|
+
imageScale = Math.sqrt(size / maxSize);
|
|
1511
|
+
if (imageScale) {
|
|
1512
|
+
scaleX /= imageScale;
|
|
1513
|
+
scaleY /= imageScale;
|
|
1514
|
+
width /= imageScale;
|
|
1515
|
+
height /= imageScale;
|
|
1516
|
+
}
|
|
1517
|
+
if (sx) {
|
|
1518
|
+
scaleX /= sx;
|
|
1519
|
+
scaleY /= sy;
|
|
1520
|
+
}
|
|
1521
|
+
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1522
|
+
if (!imageMatrix) {
|
|
1523
|
+
imageMatrix = get$1();
|
|
1524
|
+
if (transform)
|
|
1525
|
+
copy$1(imageMatrix, transform);
|
|
1526
|
+
}
|
|
1527
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1528
|
+
}
|
|
1529
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
1530
|
+
const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1531
|
+
paint.style = pattern;
|
|
1532
|
+
paint.patternId = id;
|
|
1533
|
+
return true;
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
const { abs } = Math;
|
|
1541
|
+
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1542
|
+
const { scaleX, scaleY } = core.ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1543
|
+
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1544
|
+
return false;
|
|
1405
1545
|
}
|
|
1406
1546
|
else {
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1417
|
-
canvas.restore();
|
|
1418
|
-
break;
|
|
1419
|
-
case 'outside':
|
|
1420
|
-
const { renderBounds } = ui.__layout;
|
|
1421
|
-
const out = canvas.getSameCanvas(true);
|
|
1422
|
-
ui.__drawRenderPath(out);
|
|
1423
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1424
|
-
drawStrokesStyle(strokes, false, ui, out);
|
|
1425
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1426
|
-
out.clearWorld(renderBounds);
|
|
1427
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1428
|
-
canvas.copyWorldByReset(out);
|
|
1547
|
+
const { data } = paint;
|
|
1548
|
+
if (allowPaint) {
|
|
1549
|
+
if (!data.repeat) {
|
|
1550
|
+
let { width, height } = data;
|
|
1551
|
+
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1552
|
+
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1553
|
+
if (data.scaleX) {
|
|
1554
|
+
width *= data.scaleX;
|
|
1555
|
+
height *= data.scaleY;
|
|
1429
1556
|
}
|
|
1430
|
-
|
|
1431
|
-
|
|
1557
|
+
allowPaint = (width * height > core.Platform.image.maxCacheSize) || draw.Export.running;
|
|
1558
|
+
}
|
|
1559
|
+
else {
|
|
1560
|
+
allowPaint = false;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
if (allowPaint) {
|
|
1564
|
+
canvas.save();
|
|
1565
|
+
canvas.clip();
|
|
1566
|
+
if (paint.blendMode)
|
|
1567
|
+
canvas.blendMode = paint.blendMode;
|
|
1568
|
+
if (data.opacity)
|
|
1569
|
+
canvas.opacity *= data.opacity;
|
|
1570
|
+
if (data.transform)
|
|
1571
|
+
canvas.transform(data.transform);
|
|
1572
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1573
|
+
canvas.restore();
|
|
1574
|
+
return true;
|
|
1575
|
+
}
|
|
1576
|
+
else {
|
|
1577
|
+
if (!paint.style || draw.Export.running) {
|
|
1578
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1579
|
+
}
|
|
1580
|
+
else {
|
|
1581
|
+
if (!paint.patternTask) {
|
|
1582
|
+
paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1583
|
+
paint.patternTask = null;
|
|
1584
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1585
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1586
|
+
ui.forceUpdate('surface');
|
|
1587
|
+
}), 300);
|
|
1432
1588
|
}
|
|
1433
|
-
|
|
1434
|
-
|
|
1589
|
+
}
|
|
1590
|
+
return false;
|
|
1435
1591
|
}
|
|
1436
1592
|
}
|
|
1437
1593
|
}
|
|
1438
1594
|
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1461
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1462
|
-
if (options.matrix)
|
|
1463
|
-
matrix.multiply(options.matrix);
|
|
1464
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1465
|
-
}
|
|
1466
|
-
else {
|
|
1467
|
-
if (options.matrix) {
|
|
1468
|
-
scaleX *= options.matrix.a;
|
|
1469
|
-
scaleY *= options.matrix.d;
|
|
1470
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1471
|
-
}
|
|
1472
|
-
else {
|
|
1473
|
-
bounds = shapeBounds = __world;
|
|
1595
|
+
function recycleImage(attrName, data) {
|
|
1596
|
+
const paints = data['_' + attrName];
|
|
1597
|
+
if (paints instanceof Array) {
|
|
1598
|
+
let image, recycleMap, input, url;
|
|
1599
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1600
|
+
image = paints[i].image;
|
|
1601
|
+
url = image && image.url;
|
|
1602
|
+
if (url) {
|
|
1603
|
+
if (!recycleMap)
|
|
1604
|
+
recycleMap = {};
|
|
1605
|
+
recycleMap[url] = true;
|
|
1606
|
+
core.ImageManager.recycle(image);
|
|
1607
|
+
if (image.loading) {
|
|
1608
|
+
if (!input) {
|
|
1609
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1610
|
+
if (!(input instanceof Array))
|
|
1611
|
+
input = [input];
|
|
1612
|
+
}
|
|
1613
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1474
1616
|
}
|
|
1475
|
-
|
|
1617
|
+
return recycleMap;
|
|
1476
1618
|
}
|
|
1477
|
-
|
|
1478
|
-
return {
|
|
1479
|
-
canvas, matrix, bounds,
|
|
1480
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1481
|
-
};
|
|
1619
|
+
return null;
|
|
1482
1620
|
}
|
|
1483
1621
|
|
|
1484
|
-
const
|
|
1485
|
-
|
|
1622
|
+
const PaintImageModule = {
|
|
1623
|
+
image,
|
|
1624
|
+
checkImage,
|
|
1625
|
+
createPattern,
|
|
1626
|
+
recycleImage,
|
|
1627
|
+
createData,
|
|
1628
|
+
getPatternData,
|
|
1629
|
+
fillOrFitMode,
|
|
1630
|
+
clipMode,
|
|
1631
|
+
repeatMode
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1634
|
+
const { toPoint: toPoint$2 } = core.AroundHelper;
|
|
1635
|
+
const realFrom$2 = {};
|
|
1636
|
+
const realTo$2 = {};
|
|
1486
1637
|
function linearGradient(paint, box) {
|
|
1487
1638
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1488
|
-
from ||
|
|
1489
|
-
to ||
|
|
1490
|
-
const style = core.Platform.canvas.createLinearGradient(
|
|
1639
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
1640
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
1641
|
+
const style = core.Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1491
1642
|
applyStops(style, paint.stops, opacity);
|
|
1492
1643
|
const data = { type, style };
|
|
1493
1644
|
if (blendMode)
|
|
@@ -1498,137 +1649,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1498
1649
|
let stop;
|
|
1499
1650
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1500
1651
|
stop = stops[i];
|
|
1501
|
-
|
|
1652
|
+
if (typeof stop === 'string') {
|
|
1653
|
+
gradient.addColorStop(i / (len - 1), draw.ColorConvert.string(stop, opacity));
|
|
1654
|
+
}
|
|
1655
|
+
else {
|
|
1656
|
+
gradient.addColorStop(stop.offset, draw.ColorConvert.string(stop.color, opacity));
|
|
1657
|
+
}
|
|
1502
1658
|
}
|
|
1503
1659
|
}
|
|
1504
1660
|
|
|
1505
|
-
const {
|
|
1506
|
-
const { get
|
|
1507
|
-
const
|
|
1508
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
1661
|
+
const { getAngle, getDistance: getDistance$1 } = core.PointHelper;
|
|
1662
|
+
const { get, rotateOfOuter, scaleOfOuter } = core.MatrixHelper;
|
|
1663
|
+
const { toPoint: toPoint$1 } = core.AroundHelper;
|
|
1509
1664
|
const realFrom$1 = {};
|
|
1510
1665
|
const realTo$1 = {};
|
|
1511
1666
|
function radialGradient(paint, box) {
|
|
1512
1667
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1513
|
-
from ||
|
|
1514
|
-
to ||
|
|
1515
|
-
const { x, y, width, height } = box;
|
|
1516
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
1517
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
1518
|
-
let transform;
|
|
1519
|
-
if (width !== height || stretch) {
|
|
1520
|
-
transform = get$1();
|
|
1521
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
1522
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
1523
|
-
}
|
|
1668
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
1669
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
1524
1670
|
const style = core.Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
1525
1671
|
applyStops(style, paint.stops, opacity);
|
|
1526
|
-
const data = { type, style
|
|
1672
|
+
const data = { type, style };
|
|
1673
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
1674
|
+
if (transform)
|
|
1675
|
+
data.transform = transform;
|
|
1527
1676
|
if (blendMode)
|
|
1528
1677
|
data.blendMode = blendMode;
|
|
1529
1678
|
return data;
|
|
1530
1679
|
}
|
|
1680
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
1681
|
+
let transform;
|
|
1682
|
+
const { width, height } = box;
|
|
1683
|
+
if (width !== height || stretch) {
|
|
1684
|
+
const angle = getAngle(from, to);
|
|
1685
|
+
transform = get();
|
|
1686
|
+
if (rotate90) {
|
|
1687
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
1688
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
1692
|
+
rotateOfOuter(transform, from, angle);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
return transform;
|
|
1696
|
+
}
|
|
1531
1697
|
|
|
1532
|
-
const {
|
|
1533
|
-
const {
|
|
1534
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
1535
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
1698
|
+
const { getDistance } = core.PointHelper;
|
|
1699
|
+
const { toPoint } = core.AroundHelper;
|
|
1536
1700
|
const realFrom = {};
|
|
1537
1701
|
const realTo = {};
|
|
1538
1702
|
function conicGradient(paint, box) {
|
|
1539
1703
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1540
|
-
from ||
|
|
1541
|
-
to ||
|
|
1542
|
-
const { x, y, width, height } = box;
|
|
1543
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
1544
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
1545
|
-
const transform = get();
|
|
1546
|
-
const angle = getAngle(realFrom, realTo);
|
|
1547
|
-
if (core.Platform.conicGradientRotate90) {
|
|
1548
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
1549
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
1550
|
-
}
|
|
1551
|
-
else {
|
|
1552
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
1553
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
1554
|
-
}
|
|
1704
|
+
toPoint(from || 'center', box, realFrom);
|
|
1705
|
+
toPoint(to || 'bottom', box, realTo);
|
|
1555
1706
|
const style = core.Platform.conicGradientSupport ? core.Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : core.Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
|
|
1556
1707
|
applyStops(style, paint.stops, opacity);
|
|
1557
|
-
const data = { type, style
|
|
1708
|
+
const data = { type, style };
|
|
1709
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, core.Platform.conicGradientRotate90);
|
|
1710
|
+
if (transform)
|
|
1711
|
+
data.transform = transform;
|
|
1558
1712
|
if (blendMode)
|
|
1559
1713
|
data.blendMode = blendMode;
|
|
1560
1714
|
return data;
|
|
1561
1715
|
}
|
|
1562
1716
|
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
if (!(paints instanceof Array))
|
|
1570
|
-
paints = [paints];
|
|
1571
|
-
recycleMap = recycleImage(attrName, data);
|
|
1572
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1573
|
-
item = getLeafPaint(attrName, paints[i], ui);
|
|
1574
|
-
if (item)
|
|
1575
|
-
value.push(item);
|
|
1576
|
-
}
|
|
1577
|
-
data['_' + attrName] = value.length ? value : undefined;
|
|
1578
|
-
let isPixel;
|
|
1579
|
-
if (paints.length === 1) {
|
|
1580
|
-
const paint = paints[0];
|
|
1581
|
-
if (paint.type === 'image')
|
|
1582
|
-
isPixel = core$1.ImageManager.isPixel(paint);
|
|
1583
|
-
}
|
|
1584
|
-
if (attrName === 'fill') {
|
|
1585
|
-
data.__pixelFill = isPixel;
|
|
1586
|
-
}
|
|
1587
|
-
else {
|
|
1588
|
-
data.__pixelStroke = isPixel;
|
|
1589
|
-
}
|
|
1590
|
-
}
|
|
1591
|
-
function getLeafPaint(attrName, paint, ui) {
|
|
1592
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1593
|
-
return undefined;
|
|
1594
|
-
const { boxBounds } = ui.__layout;
|
|
1595
|
-
switch (paint.type) {
|
|
1596
|
-
case 'solid':
|
|
1597
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1598
|
-
return { type, blendMode, style: core$1.ColorConvert.string(color, opacity) };
|
|
1599
|
-
case 'image':
|
|
1600
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1601
|
-
case 'linear':
|
|
1602
|
-
return linearGradient(paint, boxBounds);
|
|
1603
|
-
case 'radial':
|
|
1604
|
-
return radialGradient(paint, boxBounds);
|
|
1605
|
-
case 'angular':
|
|
1606
|
-
return conicGradient(paint, boxBounds);
|
|
1607
|
-
default:
|
|
1608
|
-
return paint.r ? { type: 'solid', style: core$1.ColorConvert.string(paint) } : undefined;
|
|
1609
|
-
}
|
|
1610
|
-
}
|
|
1611
|
-
|
|
1612
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1613
|
-
__proto__: null,
|
|
1614
|
-
compute: compute,
|
|
1615
|
-
drawTextStroke: drawTextStroke,
|
|
1616
|
-
fill: fill,
|
|
1617
|
-
fillText: fillText,
|
|
1618
|
-
fills: fills,
|
|
1619
|
-
recycleImage: recycleImage,
|
|
1620
|
-
shape: shape,
|
|
1621
|
-
stroke: stroke,
|
|
1622
|
-
strokeText: strokeText,
|
|
1623
|
-
strokes: strokes
|
|
1624
|
-
});
|
|
1717
|
+
const PaintGradientModule = {
|
|
1718
|
+
linearGradient,
|
|
1719
|
+
radialGradient,
|
|
1720
|
+
conicGradient,
|
|
1721
|
+
getTransform
|
|
1722
|
+
};
|
|
1625
1723
|
|
|
1626
1724
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = core.BoundsHelper;
|
|
1627
1725
|
const tempBounds = {};
|
|
1628
1726
|
const offsetOutBounds$1 = {};
|
|
1629
|
-
function shadow(ui, current, shape
|
|
1727
|
+
function shadow(ui, current, shape) {
|
|
1630
1728
|
let copyBounds, spreadScale;
|
|
1631
|
-
const {
|
|
1729
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1632
1730
|
const { shadow } = ui.__;
|
|
1633
1731
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1634
1732
|
const other = current.getSameCanvas();
|
|
@@ -1643,21 +1741,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
1643
1741
|
other.restore();
|
|
1644
1742
|
other.save();
|
|
1645
1743
|
if (worldCanvas) {
|
|
1646
|
-
other.copyWorld(other, bounds,
|
|
1647
|
-
copyBounds =
|
|
1744
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1745
|
+
copyBounds = nowWorld;
|
|
1648
1746
|
}
|
|
1649
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1747
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1650
1748
|
}
|
|
1651
|
-
if (ui.__worldFlipped
|
|
1652
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1749
|
+
if (ui.__worldFlipped) {
|
|
1750
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1653
1751
|
}
|
|
1654
1752
|
else {
|
|
1655
1753
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1656
1754
|
}
|
|
1657
1755
|
if (end && index < end)
|
|
1658
|
-
other.
|
|
1756
|
+
other.clearWorld(copyBounds, true);
|
|
1659
1757
|
});
|
|
1660
|
-
other.recycle();
|
|
1758
|
+
other.recycle(copyBounds);
|
|
1661
1759
|
}
|
|
1662
1760
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1663
1761
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1688,9 +1786,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1688
1786
|
|
|
1689
1787
|
const { toOffsetOutBounds } = core.BoundsHelper;
|
|
1690
1788
|
const offsetOutBounds = {};
|
|
1691
|
-
function innerShadow(ui, current, shape
|
|
1789
|
+
function innerShadow(ui, current, shape) {
|
|
1692
1790
|
let copyBounds, spreadScale;
|
|
1693
|
-
const {
|
|
1791
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1694
1792
|
const { innerShadow } = ui.__;
|
|
1695
1793
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1696
1794
|
const other = current.getSameCanvas();
|
|
@@ -1703,40 +1801,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
1703
1801
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1704
1802
|
other.restore();
|
|
1705
1803
|
if (worldCanvas) {
|
|
1706
|
-
other.copyWorld(other, bounds,
|
|
1707
|
-
other.copyWorld(worldCanvas,
|
|
1708
|
-
copyBounds =
|
|
1804
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1805
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1806
|
+
copyBounds = nowWorld;
|
|
1709
1807
|
}
|
|
1710
1808
|
else {
|
|
1711
1809
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1712
1810
|
copyBounds = bounds;
|
|
1713
1811
|
}
|
|
1714
1812
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1715
|
-
if (ui.__worldFlipped
|
|
1716
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1813
|
+
if (ui.__worldFlipped) {
|
|
1814
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1717
1815
|
}
|
|
1718
1816
|
else {
|
|
1719
1817
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1720
1818
|
}
|
|
1721
1819
|
if (end && index < end)
|
|
1722
|
-
other.
|
|
1820
|
+
other.clearWorld(copyBounds, true);
|
|
1723
1821
|
});
|
|
1724
|
-
other.recycle();
|
|
1822
|
+
other.recycle(copyBounds);
|
|
1725
1823
|
}
|
|
1726
1824
|
|
|
1727
1825
|
function blur(ui, current, origin) {
|
|
1728
1826
|
const { blur } = ui.__;
|
|
1729
|
-
origin.setWorldBlur(blur * ui.
|
|
1730
|
-
origin.copyWorldToInner(current, ui.
|
|
1827
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1828
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1731
1829
|
origin.filter = 'none';
|
|
1732
1830
|
}
|
|
1733
1831
|
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
shadow
|
|
1739
|
-
|
|
1832
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1835
|
+
const EffectModule = {
|
|
1836
|
+
shadow,
|
|
1837
|
+
innerShadow,
|
|
1838
|
+
blur,
|
|
1839
|
+
backgroundBlur
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1842
|
+
const { excludeRenderBounds } = core.LeafBoundsHelper;
|
|
1843
|
+
draw.Group.prototype.__renderMask = function (canvas, options) {
|
|
1844
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
1845
|
+
const { children } = this;
|
|
1846
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
1847
|
+
child = children[i];
|
|
1848
|
+
if (child.__.mask) {
|
|
1849
|
+
if (currentMask) {
|
|
1850
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1851
|
+
maskCanvas = contentCanvas = null;
|
|
1852
|
+
}
|
|
1853
|
+
if (child.__.mask === 'path') {
|
|
1854
|
+
if (child.opacity < 1) {
|
|
1855
|
+
currentMask = 'opacity-path';
|
|
1856
|
+
maskOpacity = child.opacity;
|
|
1857
|
+
if (!contentCanvas)
|
|
1858
|
+
contentCanvas = getCanvas(canvas);
|
|
1859
|
+
}
|
|
1860
|
+
else {
|
|
1861
|
+
currentMask = 'path';
|
|
1862
|
+
canvas.save();
|
|
1863
|
+
}
|
|
1864
|
+
child.__clip(contentCanvas || canvas, options);
|
|
1865
|
+
}
|
|
1866
|
+
else {
|
|
1867
|
+
currentMask = 'alpha';
|
|
1868
|
+
if (!maskCanvas)
|
|
1869
|
+
maskCanvas = getCanvas(canvas);
|
|
1870
|
+
if (!contentCanvas)
|
|
1871
|
+
contentCanvas = getCanvas(canvas);
|
|
1872
|
+
child.__render(maskCanvas, options);
|
|
1873
|
+
}
|
|
1874
|
+
if (child.__.mask !== 'clipping')
|
|
1875
|
+
continue;
|
|
1876
|
+
}
|
|
1877
|
+
if (excludeRenderBounds(child, options))
|
|
1878
|
+
continue;
|
|
1879
|
+
child.__render(contentCanvas || canvas, options);
|
|
1880
|
+
}
|
|
1881
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1882
|
+
};
|
|
1883
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
1884
|
+
switch (maskMode) {
|
|
1885
|
+
case 'alpha':
|
|
1886
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
1887
|
+
break;
|
|
1888
|
+
case 'opacity-path':
|
|
1889
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
1890
|
+
break;
|
|
1891
|
+
case 'path':
|
|
1892
|
+
canvas.restore();
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
function getCanvas(canvas) {
|
|
1896
|
+
return canvas.getSameCanvas(false, true);
|
|
1897
|
+
}
|
|
1898
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
1899
|
+
const realBounds = leaf.__nowWorld;
|
|
1900
|
+
content.resetTransform();
|
|
1901
|
+
content.opacity = 1;
|
|
1902
|
+
content.useMask(mask, realBounds);
|
|
1903
|
+
mask.recycle(realBounds);
|
|
1904
|
+
copyContent(leaf, canvas, content, 1);
|
|
1905
|
+
}
|
|
1906
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
1907
|
+
const realBounds = leaf.__nowWorld;
|
|
1908
|
+
canvas.resetTransform();
|
|
1909
|
+
canvas.opacity = maskOpacity;
|
|
1910
|
+
canvas.copyWorld(content, realBounds);
|
|
1911
|
+
content.recycle(realBounds);
|
|
1912
|
+
}
|
|
1740
1913
|
|
|
1741
1914
|
const money = '¥¥$€££¢¢';
|
|
1742
1915
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1893,7 +2066,8 @@ function createRows(drawData, content, style) {
|
|
|
1893
2066
|
if (breakAll) {
|
|
1894
2067
|
if (wordWidth)
|
|
1895
2068
|
addWord();
|
|
1896
|
-
|
|
2069
|
+
if (rowWidth)
|
|
2070
|
+
addRow();
|
|
1897
2071
|
}
|
|
1898
2072
|
else {
|
|
1899
2073
|
if (!afterBreak)
|
|
@@ -1901,10 +2075,12 @@ function createRows(drawData, content, style) {
|
|
|
1901
2075
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
1902
2076
|
if (wordWidth)
|
|
1903
2077
|
addWord();
|
|
1904
|
-
|
|
2078
|
+
if (rowWidth)
|
|
2079
|
+
addRow();
|
|
1905
2080
|
}
|
|
1906
2081
|
else {
|
|
1907
|
-
|
|
2082
|
+
if (rowWidth)
|
|
2083
|
+
addRow();
|
|
1908
2084
|
}
|
|
1909
2085
|
}
|
|
1910
2086
|
}
|
|
@@ -1999,11 +2175,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
1999
2175
|
if (mode === WordMode) {
|
|
2000
2176
|
wordChar = { char: '', x: charX };
|
|
2001
2177
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2002
|
-
if (wordChar.char !== ' ')
|
|
2178
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2003
2179
|
row.data.push(wordChar);
|
|
2004
2180
|
}
|
|
2005
2181
|
else {
|
|
2006
|
-
charX = toChar(word.data, charX, row.data);
|
|
2182
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2007
2183
|
}
|
|
2008
2184
|
if (!row.paraEnd && addWordWidth) {
|
|
2009
2185
|
charX += addWordWidth;
|
|
@@ -2030,9 +2206,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2030
2206
|
});
|
|
2031
2207
|
return charX;
|
|
2032
2208
|
}
|
|
2033
|
-
function toChar(data, charX, rowData) {
|
|
2209
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2034
2210
|
data.forEach(char => {
|
|
2035
|
-
if (char.char !== ' ') {
|
|
2211
|
+
if (isOverflow || char.char !== ' ') {
|
|
2036
2212
|
char.x = charX;
|
|
2037
2213
|
rowData.push(char);
|
|
2038
2214
|
}
|
|
@@ -2064,12 +2240,14 @@ function layoutText(drawData, style) {
|
|
|
2064
2240
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2065
2241
|
row = rows[i];
|
|
2066
2242
|
row.x = x;
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2243
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2244
|
+
switch (textAlign) {
|
|
2245
|
+
case 'center':
|
|
2246
|
+
row.x += (width - row.width) / 2;
|
|
2247
|
+
break;
|
|
2248
|
+
case 'right':
|
|
2249
|
+
row.x += width - row.width;
|
|
2250
|
+
}
|
|
2073
2251
|
}
|
|
2074
2252
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2075
2253
|
starY += paraSpacing;
|
|
@@ -2105,16 +2283,20 @@ function layoutText(drawData, style) {
|
|
|
2105
2283
|
bounds.height = realHeight;
|
|
2106
2284
|
}
|
|
2107
2285
|
|
|
2108
|
-
function clipText(drawData, style) {
|
|
2286
|
+
function clipText(drawData, style, x, width) {
|
|
2287
|
+
if (!width)
|
|
2288
|
+
return;
|
|
2109
2289
|
const { rows, overflow } = drawData;
|
|
2110
2290
|
let { textOverflow } = style;
|
|
2111
2291
|
rows.splice(overflow);
|
|
2112
|
-
if (textOverflow !== '
|
|
2113
|
-
if (textOverflow === '
|
|
2292
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2293
|
+
if (textOverflow === 'hide')
|
|
2294
|
+
textOverflow = '';
|
|
2295
|
+
else if (textOverflow === 'ellipsis')
|
|
2114
2296
|
textOverflow = '...';
|
|
2115
2297
|
let char, charRight;
|
|
2116
|
-
const ellipsisWidth = core.Platform.canvas.measureText(textOverflow).width;
|
|
2117
|
-
const right =
|
|
2298
|
+
const ellipsisWidth = textOverflow ? core.Platform.canvas.measureText(textOverflow).width : 0;
|
|
2299
|
+
const right = x + width - ellipsisWidth;
|
|
2118
2300
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2119
2301
|
list.forEach(row => {
|
|
2120
2302
|
if (row.isOverflow && row.data) {
|
|
@@ -2161,42 +2343,40 @@ function decorationText(drawData, style) {
|
|
|
2161
2343
|
}
|
|
2162
2344
|
|
|
2163
2345
|
const { top, right, bottom, left } = core.Direction4;
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
if (
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
}
|
|
2199
|
-
};
|
|
2346
|
+
function getDrawData(content, style) {
|
|
2347
|
+
if (typeof content !== 'string')
|
|
2348
|
+
content = String(content);
|
|
2349
|
+
let x = 0, y = 0;
|
|
2350
|
+
let width = style.__getInput('width') || 0;
|
|
2351
|
+
let height = style.__getInput('height') || 0;
|
|
2352
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2353
|
+
if (padding) {
|
|
2354
|
+
if (width) {
|
|
2355
|
+
x = padding[left];
|
|
2356
|
+
width -= (padding[right] + padding[left]);
|
|
2357
|
+
}
|
|
2358
|
+
if (height) {
|
|
2359
|
+
y = padding[top];
|
|
2360
|
+
height -= (padding[top] + padding[bottom]);
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
const drawData = {
|
|
2364
|
+
bounds: { x, y, width, height },
|
|
2365
|
+
rows: [],
|
|
2366
|
+
paraNumber: 0,
|
|
2367
|
+
font: core.Platform.canvas.font = __font
|
|
2368
|
+
};
|
|
2369
|
+
createRows(drawData, content, style);
|
|
2370
|
+
if (padding)
|
|
2371
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2372
|
+
layoutText(drawData, style);
|
|
2373
|
+
layoutChar(drawData, style, width);
|
|
2374
|
+
if (drawData.overflow)
|
|
2375
|
+
clipText(drawData, style, x, width);
|
|
2376
|
+
if (textDecoration !== 'none')
|
|
2377
|
+
decorationText(drawData, style);
|
|
2378
|
+
return drawData;
|
|
2379
|
+
}
|
|
2200
2380
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2201
2381
|
if (!width) {
|
|
2202
2382
|
switch (style.textAlign) {
|
|
@@ -2224,67 +2404,152 @@ function offsetText(drawData, attrName, value) {
|
|
|
2224
2404
|
rows[i][attrName] += value;
|
|
2225
2405
|
}
|
|
2226
2406
|
|
|
2227
|
-
const
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2407
|
+
const TextConvertModule = {
|
|
2408
|
+
getDrawData
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2411
|
+
function string(color, opacity) {
|
|
2412
|
+
if (typeof color === 'string')
|
|
2413
|
+
return color;
|
|
2414
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2415
|
+
if (opacity)
|
|
2416
|
+
a *= opacity;
|
|
2417
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2418
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
const ColorConvertModule = {
|
|
2422
|
+
string
|
|
2237
2423
|
};
|
|
2238
2424
|
|
|
2239
|
-
const
|
|
2425
|
+
const { setPoint, addPoint, toBounds } = core.TwoPointBoundsHelper;
|
|
2426
|
+
function getTrimBounds(canvas) {
|
|
2427
|
+
const { width, height } = canvas.view;
|
|
2428
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2429
|
+
let x, y, pointBounds, index = 0;
|
|
2430
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2431
|
+
if (data[i + 3] !== 0) {
|
|
2432
|
+
x = index % width;
|
|
2433
|
+
y = (index - x) / width;
|
|
2434
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2435
|
+
}
|
|
2436
|
+
index++;
|
|
2437
|
+
}
|
|
2438
|
+
const bounds = new core.Bounds();
|
|
2439
|
+
toBounds(pointBounds, bounds);
|
|
2440
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
const ExportModule = {
|
|
2240
2444
|
export(leaf, filename, options) {
|
|
2241
|
-
|
|
2445
|
+
this.running = true;
|
|
2446
|
+
const fileType = core.FileHelper.fileType(filename);
|
|
2447
|
+
options = core.FileHelper.getExportOptions(options);
|
|
2242
2448
|
return addTask((success) => new Promise((resolve) => {
|
|
2449
|
+
const over = (result) => {
|
|
2450
|
+
success(result);
|
|
2451
|
+
resolve();
|
|
2452
|
+
this.running = false;
|
|
2453
|
+
};
|
|
2454
|
+
const { toURL } = core.Platform;
|
|
2455
|
+
const { download } = core.Platform.origin;
|
|
2456
|
+
if (filename === 'json') {
|
|
2457
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
2458
|
+
}
|
|
2459
|
+
else if (fileType === 'json') {
|
|
2460
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
2461
|
+
return over({ data: true });
|
|
2462
|
+
}
|
|
2463
|
+
if (filename === 'svg') {
|
|
2464
|
+
return over({ data: leaf.toSVG() });
|
|
2465
|
+
}
|
|
2466
|
+
else if (fileType === 'svg') {
|
|
2467
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
2468
|
+
return over({ data: true });
|
|
2469
|
+
}
|
|
2243
2470
|
const { leafer } = leaf;
|
|
2244
2471
|
if (leafer) {
|
|
2472
|
+
checkLazy(leaf);
|
|
2245
2473
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2246
|
-
let
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2474
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2475
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
2476
|
+
const { slice, trim, onCanvas } = options;
|
|
2477
|
+
let scale = options.scale || 1;
|
|
2478
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
2479
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
2480
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
2481
|
+
if (leaf.isApp) {
|
|
2482
|
+
scale *= pixelRatio;
|
|
2483
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
2484
|
+
}
|
|
2485
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2486
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
2487
|
+
const needFill = core.FileHelper.isOpaqueImage(filename) || fill, matrix = new core.Matrix();
|
|
2488
|
+
if (screenshot) {
|
|
2489
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2253
2490
|
}
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2491
|
+
else {
|
|
2492
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
2493
|
+
scaleX = worldTransform.scaleX;
|
|
2494
|
+
scaleY = worldTransform.scaleY;
|
|
2495
|
+
switch (relative) {
|
|
2496
|
+
case 'inner':
|
|
2497
|
+
matrix.set(worldTransform);
|
|
2498
|
+
break;
|
|
2499
|
+
case 'local':
|
|
2500
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
2501
|
+
scaleX /= leaf.scaleX;
|
|
2502
|
+
scaleY /= leaf.scaleY;
|
|
2503
|
+
break;
|
|
2504
|
+
case 'world':
|
|
2505
|
+
scaleX = 1;
|
|
2506
|
+
scaleY = 1;
|
|
2507
|
+
break;
|
|
2508
|
+
case 'page':
|
|
2509
|
+
relative = leaf.leafer;
|
|
2510
|
+
default:
|
|
2511
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
2512
|
+
const l = relative.worldTransform;
|
|
2513
|
+
scaleX /= scaleX / l.scaleX;
|
|
2514
|
+
scaleY /= scaleY / l.scaleY;
|
|
2515
|
+
}
|
|
2516
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2266
2517
|
}
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2518
|
+
const { x, y, width, height } = new core.Bounds(renderBounds).scale(scale);
|
|
2519
|
+
let canvas = core.Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
2520
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
2521
|
+
if (slice) {
|
|
2522
|
+
leaf = leafer;
|
|
2523
|
+
renderOptions.bounds = canvas.bounds;
|
|
2270
2524
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2525
|
+
canvas.save();
|
|
2526
|
+
if (isFrame && fill !== undefined) {
|
|
2527
|
+
const oldFill = leaf.get('fill');
|
|
2528
|
+
leaf.fill = '';
|
|
2529
|
+
leaf.__render(canvas, renderOptions);
|
|
2530
|
+
leaf.fill = oldFill;
|
|
2273
2531
|
}
|
|
2274
2532
|
else {
|
|
2275
|
-
|
|
2533
|
+
leaf.__render(canvas, renderOptions);
|
|
2276
2534
|
}
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2535
|
+
canvas.restore();
|
|
2536
|
+
if (trim) {
|
|
2537
|
+
trimBounds = getTrimBounds(canvas);
|
|
2538
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2539
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2540
|
+
canvas = core.Creator.canvas(config);
|
|
2541
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2542
|
+
}
|
|
2543
|
+
if (needFill)
|
|
2544
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2545
|
+
if (onCanvas)
|
|
2546
|
+
onCanvas(canvas);
|
|
2547
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2548
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2282
2549
|
}));
|
|
2283
2550
|
}
|
|
2284
2551
|
else {
|
|
2285
|
-
|
|
2286
|
-
resolve();
|
|
2287
|
-
Export.running = false;
|
|
2552
|
+
over({ data: false });
|
|
2288
2553
|
}
|
|
2289
2554
|
}));
|
|
2290
2555
|
}
|
|
@@ -2297,14 +2562,66 @@ function addTask(task) {
|
|
|
2297
2562
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2298
2563
|
});
|
|
2299
2564
|
}
|
|
2565
|
+
function checkLazy(leaf) {
|
|
2566
|
+
if (leaf.__.__needComputePaint)
|
|
2567
|
+
leaf.__.__computePaint();
|
|
2568
|
+
if (leaf.isBranch)
|
|
2569
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
const canvas = core.LeaferCanvasBase.prototype;
|
|
2573
|
+
const debug = core.Debug.get('@leafer-ui/export');
|
|
2574
|
+
canvas.export = function (filename, options) {
|
|
2575
|
+
const { quality, blob } = core.FileHelper.getExportOptions(options);
|
|
2576
|
+
if (filename.includes('.')) {
|
|
2577
|
+
return this.saveAs(filename, quality);
|
|
2578
|
+
}
|
|
2579
|
+
else if (blob) {
|
|
2580
|
+
return this.toBlob(filename, quality);
|
|
2581
|
+
}
|
|
2582
|
+
else {
|
|
2583
|
+
return this.toDataURL(filename, quality);
|
|
2584
|
+
}
|
|
2585
|
+
};
|
|
2586
|
+
canvas.toBlob = function (type, quality) {
|
|
2587
|
+
return new Promise((resolve) => {
|
|
2588
|
+
core.Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2589
|
+
resolve(blob);
|
|
2590
|
+
}).catch((e) => {
|
|
2591
|
+
debug.error(e);
|
|
2592
|
+
resolve(null);
|
|
2593
|
+
});
|
|
2594
|
+
});
|
|
2595
|
+
};
|
|
2596
|
+
canvas.toDataURL = function (type, quality) {
|
|
2597
|
+
return core.Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2598
|
+
};
|
|
2599
|
+
canvas.saveAs = function (filename, quality) {
|
|
2600
|
+
return new Promise((resolve) => {
|
|
2601
|
+
core.Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2602
|
+
resolve(true);
|
|
2603
|
+
}).catch((e) => {
|
|
2604
|
+
debug.error(e);
|
|
2605
|
+
resolve(false);
|
|
2606
|
+
});
|
|
2607
|
+
});
|
|
2608
|
+
};
|
|
2300
2609
|
|
|
2301
|
-
Object.assign(
|
|
2302
|
-
Object.assign(
|
|
2303
|
-
Object.assign(
|
|
2304
|
-
Object.assign(
|
|
2305
|
-
Object.assign(
|
|
2610
|
+
Object.assign(draw.TextConvert, TextConvertModule);
|
|
2611
|
+
Object.assign(draw.ColorConvert, ColorConvertModule);
|
|
2612
|
+
Object.assign(draw.Paint, PaintModule);
|
|
2613
|
+
Object.assign(draw.PaintImage, PaintImageModule);
|
|
2614
|
+
Object.assign(draw.PaintGradient, PaintGradientModule);
|
|
2615
|
+
Object.assign(draw.Effect, EffectModule);
|
|
2616
|
+
Object.assign(draw.Export, ExportModule);
|
|
2617
|
+
|
|
2618
|
+
Object.assign(core.Creator, {
|
|
2619
|
+
interaction: (target, canvas, selector, options) => { return new core$1.InteractionBase(target, canvas, selector, options); },
|
|
2620
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2621
|
+
hitCanvasManager: () => new core$1.HitCanvasManager()
|
|
2622
|
+
});
|
|
2306
2623
|
|
|
2307
|
-
Object.defineProperty(exports,
|
|
2624
|
+
Object.defineProperty(exports, "LeaferImage", {
|
|
2308
2625
|
enumerable: true,
|
|
2309
2626
|
get: function () { return core.LeaferImage; }
|
|
2310
2627
|
});
|