@leafer-ui/node 1.0.0-rc.9 → 1.0.1
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 +1150 -845
- package/dist/node.esm.js +1151 -846
- 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.defineKey(core.Platform, 'devicePixelRatio', { get() { return 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
|
}
|
|
@@ -506,14 +580,14 @@ class Renderer {
|
|
|
506
580
|
if (core.Debug.showRepaint)
|
|
507
581
|
this.canvas.strokeWorld(bounds, 'red');
|
|
508
582
|
this.target.__render(this.canvas, options);
|
|
509
|
-
this.renderBounds = realBounds || bounds;
|
|
583
|
+
this.renderBounds = realBounds = realBounds || bounds;
|
|
510
584
|
this.renderOptions = options;
|
|
511
|
-
this.totalBounds.isEmpty() ? this.totalBounds =
|
|
585
|
+
this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
|
|
512
586
|
if (core.Debug.showHitView)
|
|
513
587
|
this.renderHitView(options);
|
|
514
588
|
if (core.Debug.showBoundsView)
|
|
515
589
|
this.renderBoundsView(options);
|
|
516
|
-
this.canvas.updateRender();
|
|
590
|
+
this.canvas.updateRender(realBounds);
|
|
517
591
|
}
|
|
518
592
|
renderHitView(_options) { }
|
|
519
593
|
renderBoundsView(_options) { }
|
|
@@ -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,483 +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 transform = get$4();
|
|
932
|
-
const swap = rotation && rotation !== 180;
|
|
933
|
-
const sw = box.width / (swap ? height : width);
|
|
934
|
-
const sh = box.height / (swap ? width : height);
|
|
935
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
936
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
937
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
938
|
-
translate$1(transform, x, y);
|
|
939
|
-
scaleHelper(transform, scale);
|
|
940
|
-
if (rotation)
|
|
941
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
942
|
-
data.scaleX = data.scaleY = scale;
|
|
943
|
-
data.transform = transform;
|
|
944
|
-
}
|
|
945
|
-
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
946
|
-
const transform = get$4();
|
|
947
|
-
translate$1(transform, box.x, box.y);
|
|
948
|
-
if (x || y)
|
|
949
|
-
translate$1(transform, x, y);
|
|
950
|
-
if (scaleX) {
|
|
951
|
-
scaleHelper(transform, scaleX, scaleY);
|
|
952
|
-
data.scaleX = transform.a;
|
|
953
|
-
data.scaleY = transform.d;
|
|
954
|
-
}
|
|
955
|
-
if (rotation)
|
|
956
|
-
rotate(transform, rotation);
|
|
957
|
-
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());
|
|
958
979
|
}
|
|
959
|
-
function
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
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
|
+
}
|
|
973
1007
|
}
|
|
974
1008
|
}
|
|
975
|
-
origin.x = box.x;
|
|
976
|
-
origin.y = box.y;
|
|
977
|
-
if (x || y)
|
|
978
|
-
origin.x += x, origin.y += y;
|
|
979
|
-
translate$1(transform, origin.x, origin.y);
|
|
980
|
-
if (scaleX) {
|
|
981
|
-
scaleOfOuter$2(transform, origin, scaleX, scaleY);
|
|
982
|
-
data.scaleX = scaleX;
|
|
983
|
-
data.scaleY = scaleY;
|
|
984
|
-
}
|
|
985
|
-
data.transform = transform;
|
|
986
1009
|
}
|
|
987
1010
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
const data = leafPaint.data = { mode };
|
|
996
|
-
let x, y, scaleX, scaleY;
|
|
997
|
-
if (offset)
|
|
998
|
-
x = offset.x, y = offset.y;
|
|
999
|
-
if (size) {
|
|
1000
|
-
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1001
|
-
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1002
|
-
}
|
|
1003
|
-
else if (scale) {
|
|
1004
|
-
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1005
|
-
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1006
|
-
}
|
|
1007
|
-
switch (mode) {
|
|
1008
|
-
case 'strench':
|
|
1009
|
-
if (!sameBox)
|
|
1010
|
-
width = box.width, height = box.height;
|
|
1011
|
-
if (box.x || box.y) {
|
|
1012
|
-
data.transform = get$3();
|
|
1013
|
-
translate(data.transform, box.x, box.y);
|
|
1014
|
-
}
|
|
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);
|
|
1015
1018
|
break;
|
|
1016
|
-
case '
|
|
1017
|
-
|
|
1018
|
-
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1019
|
+
case 'inside':
|
|
1020
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1019
1021
|
break;
|
|
1020
|
-
case '
|
|
1021
|
-
|
|
1022
|
-
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1023
|
-
if (!repeat)
|
|
1024
|
-
data.repeat = 'repeat';
|
|
1022
|
+
case 'outside':
|
|
1023
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1025
1024
|
break;
|
|
1026
|
-
case 'fit':
|
|
1027
|
-
case 'cover':
|
|
1028
|
-
default:
|
|
1029
|
-
if (!sameBox || rotation)
|
|
1030
|
-
fillOrFitMode(data, mode, box, width, height, rotation);
|
|
1031
1025
|
}
|
|
1032
|
-
data.width = width;
|
|
1033
|
-
data.height = height;
|
|
1034
|
-
if (opacity)
|
|
1035
|
-
data.opacity = opacity;
|
|
1036
|
-
if (repeat)
|
|
1037
|
-
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1038
1026
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
else if (image.error) {
|
|
1053
|
-
if (firstUse) {
|
|
1054
|
-
ui.forceUpdate('surface');
|
|
1055
|
-
event.error = image.error;
|
|
1056
|
-
emit(core.ImageEvent.ERROR, event);
|
|
1057
|
-
}
|
|
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);
|
|
1058
1038
|
}
|
|
1059
1039
|
else {
|
|
1060
|
-
|
|
1061
|
-
emit(core.ImageEvent.LOAD, event);
|
|
1062
|
-
leafPaint.loadId = image.load(() => {
|
|
1063
|
-
if (!ui.destroyed) {
|
|
1064
|
-
if (hasNaturalSize(ui, attrName, image)) {
|
|
1065
|
-
createData(leafPaint, image, attrValue, box);
|
|
1066
|
-
ui.forceUpdate('surface');
|
|
1067
|
-
}
|
|
1068
|
-
emit(core.ImageEvent.LOADED, event);
|
|
1069
|
-
}
|
|
1070
|
-
}, (error) => {
|
|
1071
|
-
ui.forceUpdate('surface');
|
|
1072
|
-
event.error = error;
|
|
1073
|
-
emit(core.ImageEvent.ERROR, event);
|
|
1074
|
-
});
|
|
1075
|
-
}
|
|
1076
|
-
return leafPaint;
|
|
1077
|
-
}
|
|
1078
|
-
function hasNaturalSize(ui, attrName, image) {
|
|
1079
|
-
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1080
|
-
const { __: d } = ui;
|
|
1081
|
-
d.__naturalWidth = image.width;
|
|
1082
|
-
d.__naturalHeight = image.height;
|
|
1083
|
-
if (!d.__getInput('width') || !d.__getInput('height')) {
|
|
1084
|
-
ui.forceUpdate('width');
|
|
1085
|
-
if (ui.__proxyData) {
|
|
1086
|
-
ui.setProxyAttr('width', ui.__.width);
|
|
1087
|
-
ui.setProxyAttr('height', ui.__.height);
|
|
1088
|
-
}
|
|
1089
|
-
return false;
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
return true;
|
|
1093
|
-
}
|
|
1094
|
-
function emit(type, data) {
|
|
1095
|
-
if (data.target.hasEvent(type))
|
|
1096
|
-
data.target.emitEvent(new core.ImageEvent(type, data));
|
|
1097
|
-
}
|
|
1098
|
-
|
|
1099
|
-
const Export$1 = {};
|
|
1100
|
-
|
|
1101
|
-
const { get: get$2, scale, copy: copy$1 } = core.MatrixHelper;
|
|
1102
|
-
function createPattern(ui, paint, pixelRatio) {
|
|
1103
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1104
|
-
const id = scaleX + '-' + scaleY;
|
|
1105
|
-
if (paint.patternId !== id && !ui.destroyed) {
|
|
1106
|
-
scaleX = Math.abs(scaleX);
|
|
1107
|
-
scaleY = Math.abs(scaleY);
|
|
1108
|
-
const { image, data } = paint;
|
|
1109
|
-
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1110
|
-
if (sx) {
|
|
1111
|
-
imageMatrix = get$2();
|
|
1112
|
-
copy$1(imageMatrix, transform);
|
|
1113
|
-
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1114
|
-
scaleX *= sx;
|
|
1115
|
-
scaleY *= sy;
|
|
1116
|
-
}
|
|
1117
|
-
scaleX *= pixelRatio;
|
|
1118
|
-
scaleY *= pixelRatio;
|
|
1119
|
-
width *= scaleX;
|
|
1120
|
-
height *= scaleY;
|
|
1121
|
-
const size = width * height;
|
|
1122
|
-
if (!repeat) {
|
|
1123
|
-
if (size > core.Platform.image.maxCacheSize)
|
|
1124
|
-
return false;
|
|
1125
|
-
}
|
|
1126
|
-
let maxSize = core.Platform.image.maxPatternSize;
|
|
1127
|
-
if (!image.isSVG) {
|
|
1128
|
-
const imageSize = image.width * image.height;
|
|
1129
|
-
if (maxSize > imageSize)
|
|
1130
|
-
maxSize = imageSize;
|
|
1131
|
-
}
|
|
1132
|
-
if (size > maxSize)
|
|
1133
|
-
imageScale = Math.sqrt(size / maxSize);
|
|
1134
|
-
if (imageScale) {
|
|
1135
|
-
scaleX /= imageScale;
|
|
1136
|
-
scaleY /= imageScale;
|
|
1137
|
-
width /= imageScale;
|
|
1138
|
-
height /= imageScale;
|
|
1139
|
-
}
|
|
1140
|
-
if (sx) {
|
|
1141
|
-
scaleX /= sx;
|
|
1142
|
-
scaleY /= sy;
|
|
1143
|
-
}
|
|
1144
|
-
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1145
|
-
if (!imageMatrix) {
|
|
1146
|
-
imageMatrix = get$2();
|
|
1147
|
-
if (transform)
|
|
1148
|
-
copy$1(imageMatrix, transform);
|
|
1149
|
-
}
|
|
1150
|
-
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1151
|
-
}
|
|
1152
|
-
const pattern = core.Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), repeat || (core.Platform.origin.noRepeat || 'no-repeat'));
|
|
1153
|
-
try {
|
|
1154
|
-
if (paint.transform)
|
|
1155
|
-
paint.transform = null;
|
|
1156
|
-
if (imageMatrix)
|
|
1157
|
-
pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
|
|
1158
|
-
}
|
|
1159
|
-
catch (_a) {
|
|
1160
|
-
paint.transform = imageMatrix;
|
|
1161
|
-
}
|
|
1162
|
-
paint.style = pattern;
|
|
1163
|
-
paint.patternId = id;
|
|
1164
|
-
return true;
|
|
1165
|
-
}
|
|
1166
|
-
else {
|
|
1167
|
-
return false;
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
const { abs } = Math;
|
|
1172
|
-
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1173
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1174
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1175
|
-
return false;
|
|
1176
|
-
}
|
|
1177
|
-
else {
|
|
1178
|
-
const { data } = paint;
|
|
1179
|
-
if (allowPaint) {
|
|
1180
|
-
if (!data.repeat) {
|
|
1181
|
-
let { width, height } = data;
|
|
1182
|
-
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1183
|
-
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1184
|
-
if (data.scaleX) {
|
|
1185
|
-
width *= data.scaleX;
|
|
1186
|
-
height *= data.scaleY;
|
|
1187
|
-
}
|
|
1188
|
-
allowPaint = width * height > core.Platform.image.maxCacheSize;
|
|
1189
|
-
}
|
|
1190
|
-
else {
|
|
1191
|
-
allowPaint = false;
|
|
1192
|
-
}
|
|
1193
|
-
}
|
|
1194
|
-
if (allowPaint) {
|
|
1195
|
-
canvas.save();
|
|
1196
|
-
canvas.clip();
|
|
1197
|
-
if (paint.blendMode)
|
|
1198
|
-
canvas.blendMode = paint.blendMode;
|
|
1199
|
-
if (data.opacity)
|
|
1200
|
-
canvas.opacity *= data.opacity;
|
|
1201
|
-
if (data.transform)
|
|
1202
|
-
canvas.transform(data.transform);
|
|
1203
|
-
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1204
|
-
canvas.restore();
|
|
1205
|
-
return true;
|
|
1206
|
-
}
|
|
1207
|
-
else {
|
|
1208
|
-
if (!paint.style || Export$1.running) {
|
|
1209
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1210
|
-
}
|
|
1211
|
-
else {
|
|
1212
|
-
if (!paint.patternTask) {
|
|
1213
|
-
paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1214
|
-
paint.patternTask = null;
|
|
1215
|
-
if (canvas.bounds.hit(ui.__world))
|
|
1216
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1217
|
-
ui.forceUpdate('surface');
|
|
1218
|
-
}), 300);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
return false;
|
|
1222
|
-
}
|
|
1040
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1223
1041
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
function recycleImage(attrName, data) {
|
|
1227
|
-
const paints = data['_' + attrName];
|
|
1228
|
-
if (paints instanceof Array) {
|
|
1229
|
-
let image, recycleMap, input, url;
|
|
1230
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1231
|
-
image = paints[i].image;
|
|
1232
|
-
url = image && image.url;
|
|
1233
|
-
if (url) {
|
|
1234
|
-
if (!recycleMap)
|
|
1235
|
-
recycleMap = {};
|
|
1236
|
-
recycleMap[url] = true;
|
|
1237
|
-
core.ImageManager.recycle(image);
|
|
1238
|
-
if (image.loading) {
|
|
1239
|
-
if (!input) {
|
|
1240
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1241
|
-
if (!(input instanceof Array))
|
|
1242
|
-
input = [input];
|
|
1243
|
-
}
|
|
1244
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
}
|
|
1248
|
-
return recycleMap;
|
|
1249
|
-
}
|
|
1250
|
-
return null;
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
function fillText(ui, canvas) {
|
|
1254
|
-
let row;
|
|
1255
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1256
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1257
|
-
row = rows[i];
|
|
1258
|
-
if (row.text) {
|
|
1259
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1260
|
-
}
|
|
1261
|
-
else if (row.data) {
|
|
1262
|
-
row.data.forEach(charData => {
|
|
1263
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
if (decorationY)
|
|
1267
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
function fill(fill, ui, canvas) {
|
|
1272
|
-
canvas.fillStyle = fill;
|
|
1273
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1274
|
-
}
|
|
1275
|
-
function fills(fills, ui, canvas) {
|
|
1276
|
-
let item;
|
|
1277
|
-
const { windingRule, __font } = ui.__;
|
|
1278
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1279
|
-
item = fills[i];
|
|
1280
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1281
|
-
continue;
|
|
1282
|
-
if (item.style) {
|
|
1283
|
-
canvas.fillStyle = item.style;
|
|
1284
|
-
if (item.transform) {
|
|
1285
|
-
canvas.save();
|
|
1286
|
-
canvas.transform(item.transform);
|
|
1287
|
-
if (item.blendMode)
|
|
1288
|
-
canvas.blendMode = item.blendMode;
|
|
1289
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1290
|
-
canvas.restore();
|
|
1291
|
-
}
|
|
1292
|
-
else {
|
|
1293
|
-
if (item.blendMode) {
|
|
1294
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1295
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1296
|
-
canvas.restoreBlendMode();
|
|
1297
|
-
}
|
|
1298
|
-
else {
|
|
1299
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
}
|
|
1303
|
-
}
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
function strokeText(stroke, ui, canvas, renderOptions) {
|
|
1307
|
-
const { strokeAlign } = ui.__;
|
|
1308
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1309
|
-
switch (strokeAlign) {
|
|
1310
|
-
case 'center':
|
|
1311
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1312
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1313
|
-
break;
|
|
1314
|
-
case 'inside':
|
|
1315
|
-
drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1316
|
-
break;
|
|
1317
|
-
case 'outside':
|
|
1318
|
-
drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1319
|
-
break;
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
|
|
1323
|
-
const { strokeWidth, __font } = ui.__;
|
|
1324
|
-
const out = canvas.getSameCanvas(true);
|
|
1325
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1326
|
-
out.font = __font;
|
|
1327
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1328
|
-
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1329
|
-
fillText(ui, out);
|
|
1330
|
-
out.blendMode = 'normal';
|
|
1331
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1332
|
-
canvas.copyWorldByReset(out);
|
|
1333
|
-
}
|
|
1334
|
-
else {
|
|
1335
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1336
|
-
}
|
|
1337
|
-
out.recycle();
|
|
1042
|
+
out.recycle(ui.__nowWorld);
|
|
1338
1043
|
}
|
|
1339
1044
|
function drawTextStroke(ui, canvas) {
|
|
1340
1045
|
let row;
|
|
@@ -1357,7 +1062,7 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
|
1357
1062
|
let item;
|
|
1358
1063
|
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1359
1064
|
item = strokes[i];
|
|
1360
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1065
|
+
if (item.image && draw.PaintImage.checkImage(ui, canvas, item, false))
|
|
1361
1066
|
continue;
|
|
1362
1067
|
if (item.style) {
|
|
1363
1068
|
canvas.strokeStyle = item.style;
|
|
@@ -1373,138 +1078,567 @@ function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
|
1373
1078
|
}
|
|
1374
1079
|
}
|
|
1375
1080
|
|
|
1376
|
-
function stroke(stroke, ui, canvas
|
|
1081
|
+
function stroke(stroke, ui, canvas) {
|
|
1377
1082
|
const options = ui.__;
|
|
1378
|
-
const {
|
|
1379
|
-
if (!
|
|
1083
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1084
|
+
if (!__strokeWidth)
|
|
1380
1085
|
return;
|
|
1381
1086
|
if (__font) {
|
|
1382
|
-
strokeText(stroke, ui, canvas
|
|
1087
|
+
strokeText(stroke, ui, canvas);
|
|
1383
1088
|
}
|
|
1384
1089
|
else {
|
|
1385
1090
|
switch (strokeAlign) {
|
|
1386
1091
|
case 'center':
|
|
1387
|
-
canvas.setStroke(stroke,
|
|
1092
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1388
1093
|
canvas.stroke();
|
|
1389
1094
|
break;
|
|
1390
1095
|
case 'inside':
|
|
1391
1096
|
canvas.save();
|
|
1392
|
-
canvas.setStroke(stroke,
|
|
1097
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1393
1098
|
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1394
1099
|
canvas.stroke();
|
|
1395
1100
|
canvas.restore();
|
|
1396
1101
|
break;
|
|
1397
1102
|
case 'outside':
|
|
1398
|
-
const out = canvas.getSameCanvas(true);
|
|
1399
|
-
out.setStroke(stroke,
|
|
1103
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1104
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1400
1105
|
ui.__drawRenderPath(out);
|
|
1401
1106
|
out.stroke();
|
|
1402
1107
|
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1403
1108
|
out.clearWorld(ui.__layout.renderBounds);
|
|
1404
|
-
if (ui.__worldFlipped
|
|
1405
|
-
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);
|
|
1406
1151
|
}
|
|
1407
1152
|
else {
|
|
1408
|
-
canvas.copyWorldToInner(out, ui.
|
|
1153
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1409
1154
|
}
|
|
1410
|
-
out.recycle();
|
|
1155
|
+
out.recycle(ui.__nowWorld);
|
|
1411
1156
|
break;
|
|
1412
1157
|
}
|
|
1413
1158
|
}
|
|
1414
1159
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
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 && !draw.Export.running)) {
|
|
1544
|
+
return false;
|
|
1422
1545
|
}
|
|
1423
1546
|
else {
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1434
|
-
canvas.restore();
|
|
1435
|
-
break;
|
|
1436
|
-
case 'outside':
|
|
1437
|
-
const { renderBounds } = ui.__layout;
|
|
1438
|
-
const out = canvas.getSameCanvas(true);
|
|
1439
|
-
ui.__drawRenderPath(out);
|
|
1440
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1441
|
-
drawStrokesStyle(strokes, false, ui, out);
|
|
1442
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1443
|
-
out.clearWorld(renderBounds);
|
|
1444
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1445
|
-
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;
|
|
1446
1556
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
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);
|
|
1449
1588
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1589
|
+
}
|
|
1590
|
+
return false;
|
|
1452
1591
|
}
|
|
1453
1592
|
}
|
|
1454
1593
|
}
|
|
1455
1594
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1478
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1479
|
-
if (options.matrix)
|
|
1480
|
-
matrix.multiply(options.matrix);
|
|
1481
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1482
|
-
}
|
|
1483
|
-
else {
|
|
1484
|
-
if (options.matrix) {
|
|
1485
|
-
scaleX *= options.matrix.a;
|
|
1486
|
-
scaleY *= options.matrix.d;
|
|
1487
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1488
|
-
}
|
|
1489
|
-
else {
|
|
1490
|
-
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
|
+
}
|
|
1491
1616
|
}
|
|
1492
|
-
|
|
1617
|
+
return recycleMap;
|
|
1493
1618
|
}
|
|
1494
|
-
|
|
1495
|
-
return {
|
|
1496
|
-
canvas, matrix, bounds,
|
|
1497
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1498
|
-
};
|
|
1619
|
+
return null;
|
|
1499
1620
|
}
|
|
1500
1621
|
|
|
1501
|
-
const
|
|
1502
|
-
|
|
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 = {};
|
|
1503
1637
|
function linearGradient(paint, box) {
|
|
1504
1638
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1505
|
-
from ||
|
|
1506
|
-
to ||
|
|
1507
|
-
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);
|
|
1508
1642
|
applyStops(style, paint.stops, opacity);
|
|
1509
1643
|
const data = { type, style };
|
|
1510
1644
|
if (blendMode)
|
|
@@ -1515,137 +1649,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1515
1649
|
let stop;
|
|
1516
1650
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1517
1651
|
stop = stops[i];
|
|
1518
|
-
|
|
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
|
+
}
|
|
1519
1658
|
}
|
|
1520
1659
|
}
|
|
1521
1660
|
|
|
1522
|
-
const {
|
|
1523
|
-
const { get
|
|
1524
|
-
const
|
|
1525
|
-
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;
|
|
1526
1664
|
const realFrom$1 = {};
|
|
1527
1665
|
const realTo$1 = {};
|
|
1528
1666
|
function radialGradient(paint, box) {
|
|
1529
1667
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1530
|
-
from ||
|
|
1531
|
-
to ||
|
|
1532
|
-
const { x, y, width, height } = box;
|
|
1533
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
1534
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
1535
|
-
let transform;
|
|
1536
|
-
if (width !== height || stretch) {
|
|
1537
|
-
transform = get$1();
|
|
1538
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
1539
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
1540
|
-
}
|
|
1668
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
1669
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
1541
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));
|
|
1542
1671
|
applyStops(style, paint.stops, opacity);
|
|
1543
|
-
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;
|
|
1544
1676
|
if (blendMode)
|
|
1545
1677
|
data.blendMode = blendMode;
|
|
1546
1678
|
return data;
|
|
1547
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
|
+
}
|
|
1548
1697
|
|
|
1549
|
-
const {
|
|
1550
|
-
const {
|
|
1551
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
1552
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
1698
|
+
const { getDistance } = core.PointHelper;
|
|
1699
|
+
const { toPoint } = core.AroundHelper;
|
|
1553
1700
|
const realFrom = {};
|
|
1554
1701
|
const realTo = {};
|
|
1555
1702
|
function conicGradient(paint, box) {
|
|
1556
1703
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1557
|
-
from ||
|
|
1558
|
-
to ||
|
|
1559
|
-
const { x, y, width, height } = box;
|
|
1560
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
1561
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
1562
|
-
const transform = get();
|
|
1563
|
-
const angle = getAngle(realFrom, realTo);
|
|
1564
|
-
if (core.Platform.conicGradientRotate90) {
|
|
1565
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
1566
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
1567
|
-
}
|
|
1568
|
-
else {
|
|
1569
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
1570
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
1571
|
-
}
|
|
1704
|
+
toPoint(from || 'center', box, realFrom);
|
|
1705
|
+
toPoint(to || 'bottom', box, realTo);
|
|
1572
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));
|
|
1573
1707
|
applyStops(style, paint.stops, opacity);
|
|
1574
|
-
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;
|
|
1575
1712
|
if (blendMode)
|
|
1576
1713
|
data.blendMode = blendMode;
|
|
1577
1714
|
return data;
|
|
1578
1715
|
}
|
|
1579
1716
|
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
if (!(paints instanceof Array))
|
|
1587
|
-
paints = [paints];
|
|
1588
|
-
recycleMap = recycleImage(attrName, data);
|
|
1589
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1590
|
-
item = getLeafPaint(attrName, paints[i], ui);
|
|
1591
|
-
if (item)
|
|
1592
|
-
value.push(item);
|
|
1593
|
-
}
|
|
1594
|
-
data['_' + attrName] = value.length ? value : undefined;
|
|
1595
|
-
let isPixel;
|
|
1596
|
-
if (paints.length === 1) {
|
|
1597
|
-
const paint = paints[0];
|
|
1598
|
-
if (paint.type === 'image')
|
|
1599
|
-
isPixel = core$1.ImageManager.isPixel(paint);
|
|
1600
|
-
}
|
|
1601
|
-
if (attrName === 'fill') {
|
|
1602
|
-
data.__pixelFill = isPixel;
|
|
1603
|
-
}
|
|
1604
|
-
else {
|
|
1605
|
-
data.__pixelStroke = isPixel;
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
function getLeafPaint(attrName, paint, ui) {
|
|
1609
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1610
|
-
return undefined;
|
|
1611
|
-
const { boxBounds } = ui.__layout;
|
|
1612
|
-
switch (paint.type) {
|
|
1613
|
-
case 'solid':
|
|
1614
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1615
|
-
return { type, blendMode, style: core$1.ColorConvert.string(color, opacity) };
|
|
1616
|
-
case 'image':
|
|
1617
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1618
|
-
case 'linear':
|
|
1619
|
-
return linearGradient(paint, boxBounds);
|
|
1620
|
-
case 'radial':
|
|
1621
|
-
return radialGradient(paint, boxBounds);
|
|
1622
|
-
case 'angular':
|
|
1623
|
-
return conicGradient(paint, boxBounds);
|
|
1624
|
-
default:
|
|
1625
|
-
return paint.r ? { type: 'solid', style: core$1.ColorConvert.string(paint) } : undefined;
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1630
|
-
__proto__: null,
|
|
1631
|
-
compute: compute,
|
|
1632
|
-
drawTextStroke: drawTextStroke,
|
|
1633
|
-
fill: fill,
|
|
1634
|
-
fillText: fillText,
|
|
1635
|
-
fills: fills,
|
|
1636
|
-
recycleImage: recycleImage,
|
|
1637
|
-
shape: shape,
|
|
1638
|
-
stroke: stroke,
|
|
1639
|
-
strokeText: strokeText,
|
|
1640
|
-
strokes: strokes
|
|
1641
|
-
});
|
|
1717
|
+
const PaintGradientModule = {
|
|
1718
|
+
linearGradient,
|
|
1719
|
+
radialGradient,
|
|
1720
|
+
conicGradient,
|
|
1721
|
+
getTransform
|
|
1722
|
+
};
|
|
1642
1723
|
|
|
1643
1724
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = core.BoundsHelper;
|
|
1644
1725
|
const tempBounds = {};
|
|
1645
1726
|
const offsetOutBounds$1 = {};
|
|
1646
|
-
function shadow(ui, current, shape
|
|
1727
|
+
function shadow(ui, current, shape) {
|
|
1647
1728
|
let copyBounds, spreadScale;
|
|
1648
|
-
const {
|
|
1729
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1649
1730
|
const { shadow } = ui.__;
|
|
1650
1731
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1651
1732
|
const other = current.getSameCanvas();
|
|
@@ -1660,21 +1741,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
1660
1741
|
other.restore();
|
|
1661
1742
|
other.save();
|
|
1662
1743
|
if (worldCanvas) {
|
|
1663
|
-
other.copyWorld(other, bounds,
|
|
1664
|
-
copyBounds =
|
|
1744
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1745
|
+
copyBounds = nowWorld;
|
|
1665
1746
|
}
|
|
1666
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1747
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1667
1748
|
}
|
|
1668
|
-
if (ui.__worldFlipped
|
|
1669
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1749
|
+
if (ui.__worldFlipped) {
|
|
1750
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1670
1751
|
}
|
|
1671
1752
|
else {
|
|
1672
1753
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1673
1754
|
}
|
|
1674
1755
|
if (end && index < end)
|
|
1675
|
-
other.
|
|
1756
|
+
other.clearWorld(copyBounds, true);
|
|
1676
1757
|
});
|
|
1677
|
-
other.recycle();
|
|
1758
|
+
other.recycle(copyBounds);
|
|
1678
1759
|
}
|
|
1679
1760
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1680
1761
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1705,9 +1786,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1705
1786
|
|
|
1706
1787
|
const { toOffsetOutBounds } = core.BoundsHelper;
|
|
1707
1788
|
const offsetOutBounds = {};
|
|
1708
|
-
function innerShadow(ui, current, shape
|
|
1789
|
+
function innerShadow(ui, current, shape) {
|
|
1709
1790
|
let copyBounds, spreadScale;
|
|
1710
|
-
const {
|
|
1791
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1711
1792
|
const { innerShadow } = ui.__;
|
|
1712
1793
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1713
1794
|
const other = current.getSameCanvas();
|
|
@@ -1720,40 +1801,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
1720
1801
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1721
1802
|
other.restore();
|
|
1722
1803
|
if (worldCanvas) {
|
|
1723
|
-
other.copyWorld(other, bounds,
|
|
1724
|
-
other.copyWorld(worldCanvas,
|
|
1725
|
-
copyBounds =
|
|
1804
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1805
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
1806
|
+
copyBounds = nowWorld;
|
|
1726
1807
|
}
|
|
1727
1808
|
else {
|
|
1728
1809
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1729
1810
|
copyBounds = bounds;
|
|
1730
1811
|
}
|
|
1731
1812
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1732
|
-
if (ui.__worldFlipped
|
|
1733
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1813
|
+
if (ui.__worldFlipped) {
|
|
1814
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1734
1815
|
}
|
|
1735
1816
|
else {
|
|
1736
1817
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1737
1818
|
}
|
|
1738
1819
|
if (end && index < end)
|
|
1739
|
-
other.
|
|
1820
|
+
other.clearWorld(copyBounds, true);
|
|
1740
1821
|
});
|
|
1741
|
-
other.recycle();
|
|
1822
|
+
other.recycle(copyBounds);
|
|
1742
1823
|
}
|
|
1743
1824
|
|
|
1744
1825
|
function blur(ui, current, origin) {
|
|
1745
1826
|
const { blur } = ui.__;
|
|
1746
|
-
origin.setWorldBlur(blur * ui.
|
|
1747
|
-
origin.copyWorldToInner(current, ui.
|
|
1827
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1828
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1748
1829
|
origin.filter = 'none';
|
|
1749
1830
|
}
|
|
1750
1831
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
shadow
|
|
1756
|
-
|
|
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
|
+
}
|
|
1757
1913
|
|
|
1758
1914
|
const money = '¥¥$€££¢¢';
|
|
1759
1915
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -1910,7 +2066,8 @@ function createRows(drawData, content, style) {
|
|
|
1910
2066
|
if (breakAll) {
|
|
1911
2067
|
if (wordWidth)
|
|
1912
2068
|
addWord();
|
|
1913
|
-
|
|
2069
|
+
if (rowWidth)
|
|
2070
|
+
addRow();
|
|
1914
2071
|
}
|
|
1915
2072
|
else {
|
|
1916
2073
|
if (!afterBreak)
|
|
@@ -1918,10 +2075,12 @@ function createRows(drawData, content, style) {
|
|
|
1918
2075
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
1919
2076
|
if (wordWidth)
|
|
1920
2077
|
addWord();
|
|
1921
|
-
|
|
2078
|
+
if (rowWidth)
|
|
2079
|
+
addRow();
|
|
1922
2080
|
}
|
|
1923
2081
|
else {
|
|
1924
|
-
|
|
2082
|
+
if (rowWidth)
|
|
2083
|
+
addRow();
|
|
1925
2084
|
}
|
|
1926
2085
|
}
|
|
1927
2086
|
}
|
|
@@ -2016,11 +2175,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2016
2175
|
if (mode === WordMode) {
|
|
2017
2176
|
wordChar = { char: '', x: charX };
|
|
2018
2177
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2019
|
-
if (wordChar.char !== ' ')
|
|
2178
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2020
2179
|
row.data.push(wordChar);
|
|
2021
2180
|
}
|
|
2022
2181
|
else {
|
|
2023
|
-
charX = toChar(word.data, charX, row.data);
|
|
2182
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2024
2183
|
}
|
|
2025
2184
|
if (!row.paraEnd && addWordWidth) {
|
|
2026
2185
|
charX += addWordWidth;
|
|
@@ -2047,9 +2206,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2047
2206
|
});
|
|
2048
2207
|
return charX;
|
|
2049
2208
|
}
|
|
2050
|
-
function toChar(data, charX, rowData) {
|
|
2209
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2051
2210
|
data.forEach(char => {
|
|
2052
|
-
if (char.char !== ' ') {
|
|
2211
|
+
if (isOverflow || char.char !== ' ') {
|
|
2053
2212
|
char.x = charX;
|
|
2054
2213
|
rowData.push(char);
|
|
2055
2214
|
}
|
|
@@ -2081,12 +2240,14 @@ function layoutText(drawData, style) {
|
|
|
2081
2240
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2082
2241
|
row = rows[i];
|
|
2083
2242
|
row.x = x;
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
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
|
+
}
|
|
2090
2251
|
}
|
|
2091
2252
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2092
2253
|
starY += paraSpacing;
|
|
@@ -2122,16 +2283,20 @@ function layoutText(drawData, style) {
|
|
|
2122
2283
|
bounds.height = realHeight;
|
|
2123
2284
|
}
|
|
2124
2285
|
|
|
2125
|
-
function clipText(drawData, style) {
|
|
2286
|
+
function clipText(drawData, style, x, width) {
|
|
2287
|
+
if (!width)
|
|
2288
|
+
return;
|
|
2126
2289
|
const { rows, overflow } = drawData;
|
|
2127
2290
|
let { textOverflow } = style;
|
|
2128
2291
|
rows.splice(overflow);
|
|
2129
|
-
if (textOverflow !== '
|
|
2130
|
-
if (textOverflow === '
|
|
2292
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2293
|
+
if (textOverflow === 'hide')
|
|
2294
|
+
textOverflow = '';
|
|
2295
|
+
else if (textOverflow === 'ellipsis')
|
|
2131
2296
|
textOverflow = '...';
|
|
2132
2297
|
let char, charRight;
|
|
2133
|
-
const ellipsisWidth = core.Platform.canvas.measureText(textOverflow).width;
|
|
2134
|
-
const right =
|
|
2298
|
+
const ellipsisWidth = textOverflow ? core.Platform.canvas.measureText(textOverflow).width : 0;
|
|
2299
|
+
const right = x + width - ellipsisWidth;
|
|
2135
2300
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2136
2301
|
list.forEach(row => {
|
|
2137
2302
|
if (row.isOverflow && row.data) {
|
|
@@ -2178,42 +2343,40 @@ function decorationText(drawData, style) {
|
|
|
2178
2343
|
}
|
|
2179
2344
|
|
|
2180
2345
|
const { top, right, bottom, left } = core.Direction4;
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
if (
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
}
|
|
2216
|
-
};
|
|
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
|
+
}
|
|
2217
2380
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2218
2381
|
if (!width) {
|
|
2219
2382
|
switch (style.textAlign) {
|
|
@@ -2241,67 +2404,157 @@ function offsetText(drawData, attrName, value) {
|
|
|
2241
2404
|
rows[i][attrName] += value;
|
|
2242
2405
|
}
|
|
2243
2406
|
|
|
2244
|
-
const
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
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
|
|
2254
2423
|
};
|
|
2255
2424
|
|
|
2256
|
-
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 = {
|
|
2257
2444
|
export(leaf, filename, options) {
|
|
2258
|
-
|
|
2445
|
+
this.running = true;
|
|
2446
|
+
const fileType = core.FileHelper.fileType(filename);
|
|
2447
|
+
options = core.FileHelper.getExportOptions(options);
|
|
2259
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
|
+
}
|
|
2260
2470
|
const { leafer } = leaf;
|
|
2261
2471
|
if (leafer) {
|
|
2472
|
+
checkLazy(leaf);
|
|
2262
2473
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2263
|
-
let
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
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;
|
|
2270
2490
|
}
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
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);
|
|
2283
2517
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
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
|
+
let sliceLeaf;
|
|
2522
|
+
if (slice) {
|
|
2523
|
+
sliceLeaf = leaf;
|
|
2524
|
+
sliceLeaf.__worldOpacity = 0;
|
|
2525
|
+
leaf = leafer;
|
|
2526
|
+
renderOptions.bounds = canvas.bounds;
|
|
2287
2527
|
}
|
|
2288
|
-
|
|
2289
|
-
|
|
2528
|
+
canvas.save();
|
|
2529
|
+
if (isFrame && fill !== undefined) {
|
|
2530
|
+
const oldFill = leaf.get('fill');
|
|
2531
|
+
leaf.fill = '';
|
|
2532
|
+
leaf.__render(canvas, renderOptions);
|
|
2533
|
+
leaf.fill = oldFill;
|
|
2290
2534
|
}
|
|
2291
2535
|
else {
|
|
2292
|
-
|
|
2536
|
+
leaf.__render(canvas, renderOptions);
|
|
2293
2537
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
if (
|
|
2298
|
-
canvas
|
|
2538
|
+
canvas.restore();
|
|
2539
|
+
if (sliceLeaf)
|
|
2540
|
+
sliceLeaf.__updateWorldOpacity();
|
|
2541
|
+
if (trim) {
|
|
2542
|
+
trimBounds = getTrimBounds(canvas);
|
|
2543
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2544
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2545
|
+
canvas = core.Creator.canvas(config);
|
|
2546
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2547
|
+
}
|
|
2548
|
+
if (needFill)
|
|
2549
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2550
|
+
if (onCanvas)
|
|
2551
|
+
onCanvas(canvas);
|
|
2552
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2553
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2299
2554
|
}));
|
|
2300
2555
|
}
|
|
2301
2556
|
else {
|
|
2302
|
-
|
|
2303
|
-
resolve();
|
|
2304
|
-
Export.running = false;
|
|
2557
|
+
over({ data: false });
|
|
2305
2558
|
}
|
|
2306
2559
|
}));
|
|
2307
2560
|
}
|
|
@@ -2314,14 +2567,66 @@ function addTask(task) {
|
|
|
2314
2567
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2315
2568
|
});
|
|
2316
2569
|
}
|
|
2570
|
+
function checkLazy(leaf) {
|
|
2571
|
+
if (leaf.__.__needComputePaint)
|
|
2572
|
+
leaf.__.__computePaint();
|
|
2573
|
+
if (leaf.isBranch)
|
|
2574
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
const canvas = core.LeaferCanvasBase.prototype;
|
|
2578
|
+
const debug = core.Debug.get('@leafer-ui/export');
|
|
2579
|
+
canvas.export = function (filename, options) {
|
|
2580
|
+
const { quality, blob } = core.FileHelper.getExportOptions(options);
|
|
2581
|
+
if (filename.includes('.')) {
|
|
2582
|
+
return this.saveAs(filename, quality);
|
|
2583
|
+
}
|
|
2584
|
+
else if (blob) {
|
|
2585
|
+
return this.toBlob(filename, quality);
|
|
2586
|
+
}
|
|
2587
|
+
else {
|
|
2588
|
+
return this.toDataURL(filename, quality);
|
|
2589
|
+
}
|
|
2590
|
+
};
|
|
2591
|
+
canvas.toBlob = function (type, quality) {
|
|
2592
|
+
return new Promise((resolve) => {
|
|
2593
|
+
core.Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2594
|
+
resolve(blob);
|
|
2595
|
+
}).catch((e) => {
|
|
2596
|
+
debug.error(e);
|
|
2597
|
+
resolve(null);
|
|
2598
|
+
});
|
|
2599
|
+
});
|
|
2600
|
+
};
|
|
2601
|
+
canvas.toDataURL = function (type, quality) {
|
|
2602
|
+
return core.Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2603
|
+
};
|
|
2604
|
+
canvas.saveAs = function (filename, quality) {
|
|
2605
|
+
return new Promise((resolve) => {
|
|
2606
|
+
core.Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2607
|
+
resolve(true);
|
|
2608
|
+
}).catch((e) => {
|
|
2609
|
+
debug.error(e);
|
|
2610
|
+
resolve(false);
|
|
2611
|
+
});
|
|
2612
|
+
});
|
|
2613
|
+
};
|
|
2317
2614
|
|
|
2318
|
-
Object.assign(
|
|
2319
|
-
Object.assign(
|
|
2320
|
-
Object.assign(
|
|
2321
|
-
Object.assign(
|
|
2322
|
-
Object.assign(
|
|
2615
|
+
Object.assign(draw.TextConvert, TextConvertModule);
|
|
2616
|
+
Object.assign(draw.ColorConvert, ColorConvertModule);
|
|
2617
|
+
Object.assign(draw.Paint, PaintModule);
|
|
2618
|
+
Object.assign(draw.PaintImage, PaintImageModule);
|
|
2619
|
+
Object.assign(draw.PaintGradient, PaintGradientModule);
|
|
2620
|
+
Object.assign(draw.Effect, EffectModule);
|
|
2621
|
+
Object.assign(draw.Export, ExportModule);
|
|
2622
|
+
|
|
2623
|
+
Object.assign(core.Creator, {
|
|
2624
|
+
interaction: (target, canvas, selector, options) => { return new core$1.InteractionBase(target, canvas, selector, options); },
|
|
2625
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2626
|
+
hitCanvasManager: () => new core$1.HitCanvasManager()
|
|
2627
|
+
});
|
|
2323
2628
|
|
|
2324
|
-
Object.defineProperty(exports,
|
|
2629
|
+
Object.defineProperty(exports, "LeaferImage", {
|
|
2325
2630
|
enumerable: true,
|
|
2326
2631
|
get: function () { return core.LeaferImage; }
|
|
2327
2632
|
});
|