leafer-draw 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/web.esm.js +426 -233
- package/dist/web.esm.min.js +1 -1
- package/dist/web.js +2043 -1297
- package/dist/web.min.js +1 -1
- package/dist/web.module.js +2024 -1297
- package/dist/web.module.min.js +1 -1
- package/package.json +8 -4
package/dist/web.esm.js
CHANGED
|
@@ -1,26 +1,47 @@
|
|
|
1
|
-
import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, MatrixHelper, ImageEvent, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
|
|
1
|
+
import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
|
|
2
2
|
export * from '@leafer/core';
|
|
3
3
|
export { LeaferImage } from '@leafer/core';
|
|
4
|
-
import { ColorConvert, Export, Group, TextConvert, Paint,
|
|
4
|
+
import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
|
|
5
5
|
export * from '@leafer-ui/draw';
|
|
6
6
|
|
|
7
|
-
const debug$
|
|
7
|
+
const debug$3 = Debug.get('LeaferCanvas');
|
|
8
8
|
class LeaferCanvas extends LeaferCanvasBase {
|
|
9
|
+
set zIndex(zIndex) {
|
|
10
|
+
const { style } = this.view;
|
|
11
|
+
style.zIndex = zIndex;
|
|
12
|
+
this.setAbsolute(this.view);
|
|
13
|
+
}
|
|
14
|
+
set childIndex(index) {
|
|
15
|
+
const { view, parentView } = this;
|
|
16
|
+
if (view && parentView) {
|
|
17
|
+
const beforeNode = parentView.children[index];
|
|
18
|
+
if (beforeNode) {
|
|
19
|
+
this.setAbsolute(beforeNode);
|
|
20
|
+
parentView.insertBefore(view, beforeNode);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
parentView.appendChild(beforeNode);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
9
27
|
init() {
|
|
10
|
-
const {
|
|
28
|
+
const { config } = this;
|
|
29
|
+
const view = config.view || config.canvas;
|
|
11
30
|
view ? this.__createViewFrom(view) : this.__createView();
|
|
12
31
|
const { style } = this.view;
|
|
13
32
|
style.display || (style.display = 'block');
|
|
14
33
|
this.parentView = this.view.parentElement;
|
|
15
|
-
if (this.parentView)
|
|
16
|
-
this.parentView.style
|
|
34
|
+
if (this.parentView) {
|
|
35
|
+
const pStyle = this.parentView.style;
|
|
36
|
+
pStyle.webkitUserSelect = pStyle.userSelect = 'none';
|
|
37
|
+
}
|
|
17
38
|
if (Platform.syncDomFont && !this.parentView) {
|
|
18
|
-
|
|
39
|
+
style.display = 'none';
|
|
19
40
|
document.body.appendChild(this.view);
|
|
20
41
|
}
|
|
21
42
|
this.__createContext();
|
|
22
43
|
if (!this.autoLayout)
|
|
23
|
-
this.resize(
|
|
44
|
+
this.resize(config);
|
|
24
45
|
}
|
|
25
46
|
set backgroundColor(color) { this.view.style.backgroundColor = color; }
|
|
26
47
|
get backgroundColor() { return this.view.style.backgroundColor; }
|
|
@@ -48,19 +69,22 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
48
69
|
this.__createView();
|
|
49
70
|
const view = this.view;
|
|
50
71
|
if (parent.hasChildNodes()) {
|
|
51
|
-
|
|
52
|
-
style.position = 'absolute';
|
|
53
|
-
style.top = style.left = '0px';
|
|
72
|
+
this.setAbsolute(view);
|
|
54
73
|
parent.style.position || (parent.style.position = 'relative');
|
|
55
74
|
}
|
|
56
75
|
parent.appendChild(view);
|
|
57
76
|
}
|
|
58
77
|
}
|
|
59
78
|
else {
|
|
60
|
-
debug$
|
|
79
|
+
debug$3.error(`no id: ${inputView}`);
|
|
61
80
|
this.__createView();
|
|
62
81
|
}
|
|
63
82
|
}
|
|
83
|
+
setAbsolute(view) {
|
|
84
|
+
const { style } = view;
|
|
85
|
+
style.position = 'absolute';
|
|
86
|
+
style.top = style.left = '0px';
|
|
87
|
+
}
|
|
64
88
|
updateViewSize() {
|
|
65
89
|
const { width, height, pixelRatio } = this;
|
|
66
90
|
const { style } = this.view;
|
|
@@ -73,22 +97,37 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
73
97
|
this.clientBounds = this.view.getBoundingClientRect();
|
|
74
98
|
}
|
|
75
99
|
startAutoLayout(autoBounds, listener) {
|
|
76
|
-
this.autoBounds = autoBounds;
|
|
77
100
|
this.resizeListener = listener;
|
|
78
|
-
|
|
79
|
-
this.
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
this.
|
|
87
|
-
|
|
101
|
+
if (autoBounds) {
|
|
102
|
+
this.autoBounds = autoBounds;
|
|
103
|
+
try {
|
|
104
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
105
|
+
this.updateClientBounds();
|
|
106
|
+
for (const entry of entries)
|
|
107
|
+
this.checkAutoBounds(entry.contentRect);
|
|
108
|
+
});
|
|
109
|
+
const parent = this.parentView;
|
|
110
|
+
if (parent) {
|
|
111
|
+
this.resizeObserver.observe(parent);
|
|
112
|
+
this.checkAutoBounds(parent.getBoundingClientRect());
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.checkAutoBounds(this.view);
|
|
116
|
+
debug$3.warn('no parent');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
catch (_a) {
|
|
120
|
+
this.imitateResizeObserver();
|
|
88
121
|
}
|
|
89
122
|
}
|
|
90
|
-
|
|
91
|
-
|
|
123
|
+
else {
|
|
124
|
+
window.addEventListener('resize', () => {
|
|
125
|
+
const pixelRatio = Platform.devicePixelRatio;
|
|
126
|
+
if (this.pixelRatio !== pixelRatio) {
|
|
127
|
+
const { width, height } = this;
|
|
128
|
+
this.emitResize({ width, height, pixelRatio });
|
|
129
|
+
}
|
|
130
|
+
});
|
|
92
131
|
}
|
|
93
132
|
}
|
|
94
133
|
imitateResizeObserver() {
|
|
@@ -101,17 +140,12 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
101
140
|
checkAutoBounds(parentSize) {
|
|
102
141
|
const view = this.view;
|
|
103
142
|
const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
|
|
104
|
-
|
|
143
|
+
const size = { width, height, pixelRatio: Platform.devicePixelRatio };
|
|
144
|
+
if (!this.isSameSize(size)) {
|
|
105
145
|
const { style } = view;
|
|
106
|
-
const { pixelRatio } = this;
|
|
107
146
|
style.marginLeft = x + 'px';
|
|
108
147
|
style.marginTop = y + 'px';
|
|
109
|
-
|
|
110
|
-
const oldSize = {};
|
|
111
|
-
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
112
|
-
this.resize(size);
|
|
113
|
-
if (this.width !== undefined)
|
|
114
|
-
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
148
|
+
this.emitResize(size);
|
|
115
149
|
}
|
|
116
150
|
}
|
|
117
151
|
stopAutoLayout() {
|
|
@@ -122,6 +156,13 @@ class LeaferCanvas extends LeaferCanvasBase {
|
|
|
122
156
|
this.resizeObserver = null;
|
|
123
157
|
}
|
|
124
158
|
}
|
|
159
|
+
emitResize(size) {
|
|
160
|
+
const oldSize = {};
|
|
161
|
+
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
162
|
+
this.resize(size);
|
|
163
|
+
if (this.width !== undefined)
|
|
164
|
+
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
165
|
+
}
|
|
125
166
|
unrealCanvas() {
|
|
126
167
|
if (!this.unreal && this.parentView) {
|
|
127
168
|
const view = this.view;
|
|
@@ -163,9 +204,13 @@ function useCanvas(_canvasType, _power) {
|
|
|
163
204
|
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
164
205
|
canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
|
|
165
206
|
canvasSaveAs: (canvas, filename, quality) => {
|
|
207
|
+
const url = canvas.toDataURL(mineType(fileType(filename)), quality);
|
|
208
|
+
return Platform.origin.download(url, filename);
|
|
209
|
+
},
|
|
210
|
+
download(url, filename) {
|
|
166
211
|
return new Promise((resolve) => {
|
|
167
212
|
let el = document.createElement('a');
|
|
168
|
-
el.href =
|
|
213
|
+
el.href = url;
|
|
169
214
|
el.download = filename;
|
|
170
215
|
document.body.appendChild(el);
|
|
171
216
|
el.click();
|
|
@@ -176,16 +221,14 @@ function useCanvas(_canvasType, _power) {
|
|
|
176
221
|
loadImage(src) {
|
|
177
222
|
return new Promise((resolve, reject) => {
|
|
178
223
|
const img = new Image();
|
|
179
|
-
const {
|
|
224
|
+
const { crossOrigin } = Platform.image;
|
|
180
225
|
if (crossOrigin) {
|
|
181
226
|
img.setAttribute('crossOrigin', crossOrigin);
|
|
182
227
|
img.crossOrigin = crossOrigin;
|
|
183
228
|
}
|
|
184
229
|
img.onload = () => { resolve(img); };
|
|
185
230
|
img.onerror = (e) => { reject(e); };
|
|
186
|
-
|
|
187
|
-
src += (src.includes("?") ? "&" : "?") + suffix;
|
|
188
|
-
img.src = src;
|
|
231
|
+
img.src = Platform.image.getRealURL(src);
|
|
189
232
|
});
|
|
190
233
|
}
|
|
191
234
|
};
|
|
@@ -200,7 +243,7 @@ function useCanvas(_canvasType, _power) {
|
|
|
200
243
|
Platform.name = 'web';
|
|
201
244
|
Platform.isMobile = 'ontouchstart' in window;
|
|
202
245
|
Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
|
|
203
|
-
Platform
|
|
246
|
+
defineKey(Platform, 'devicePixelRatio', { get() { return Math.max(1, devicePixelRatio); } });
|
|
204
247
|
const { userAgent } = navigator;
|
|
205
248
|
if (userAgent.indexOf("Firefox") > -1) {
|
|
206
249
|
Platform.conicGradientRotate90 = true;
|
|
@@ -402,7 +445,7 @@ class LayoutBlockData {
|
|
|
402
445
|
}
|
|
403
446
|
|
|
404
447
|
const { updateAllMatrix, updateAllChange } = LeafHelper;
|
|
405
|
-
const debug$
|
|
448
|
+
const debug$2 = Debug.get('Layouter');
|
|
406
449
|
class Layouter {
|
|
407
450
|
constructor(target, userConfig) {
|
|
408
451
|
this.totalTimes = 0;
|
|
@@ -437,7 +480,7 @@ class Layouter {
|
|
|
437
480
|
target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
438
481
|
}
|
|
439
482
|
catch (e) {
|
|
440
|
-
debug$
|
|
483
|
+
debug$2.error(e);
|
|
441
484
|
}
|
|
442
485
|
this.layoutedBlocks = null;
|
|
443
486
|
}
|
|
@@ -451,9 +494,9 @@ class Layouter {
|
|
|
451
494
|
}
|
|
452
495
|
layoutOnce() {
|
|
453
496
|
if (this.layouting)
|
|
454
|
-
return debug$
|
|
497
|
+
return debug$2.warn('layouting');
|
|
455
498
|
if (this.times > 3)
|
|
456
|
-
return debug$
|
|
499
|
+
return debug$2.warn('layout max times');
|
|
457
500
|
this.times++;
|
|
458
501
|
this.totalTimes++;
|
|
459
502
|
this.layouting = true;
|
|
@@ -519,9 +562,11 @@ class Layouter {
|
|
|
519
562
|
updateAllChange(target);
|
|
520
563
|
}
|
|
521
564
|
addExtra(leaf) {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
565
|
+
if (!this.__updatedList.has(leaf)) {
|
|
566
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
567
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
568
|
+
updatedList.add(leaf);
|
|
569
|
+
}
|
|
525
570
|
}
|
|
526
571
|
createBlock(data) {
|
|
527
572
|
return new LayoutBlockData(data);
|
|
@@ -555,7 +600,7 @@ class Layouter {
|
|
|
555
600
|
}
|
|
556
601
|
}
|
|
557
602
|
|
|
558
|
-
const debug = Debug.get('Renderer');
|
|
603
|
+
const debug$1 = Debug.get('Renderer');
|
|
559
604
|
class Renderer {
|
|
560
605
|
get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
|
|
561
606
|
constructor(target, canvas, userConfig) {
|
|
@@ -593,7 +638,7 @@ class Renderer {
|
|
|
593
638
|
const { target } = this;
|
|
594
639
|
this.times = 0;
|
|
595
640
|
this.totalBounds = new Bounds();
|
|
596
|
-
debug.log(target.innerName, '--->');
|
|
641
|
+
debug$1.log(target.innerName, '--->');
|
|
597
642
|
try {
|
|
598
643
|
this.emitRender(RenderEvent.START);
|
|
599
644
|
this.renderOnce(callback);
|
|
@@ -602,9 +647,9 @@ class Renderer {
|
|
|
602
647
|
}
|
|
603
648
|
catch (e) {
|
|
604
649
|
this.rendering = false;
|
|
605
|
-
debug.error(e);
|
|
650
|
+
debug$1.error(e);
|
|
606
651
|
}
|
|
607
|
-
debug.log('-------------|');
|
|
652
|
+
debug$1.log('-------------|');
|
|
608
653
|
}
|
|
609
654
|
renderAgain() {
|
|
610
655
|
if (this.rendering) {
|
|
@@ -616,9 +661,9 @@ class Renderer {
|
|
|
616
661
|
}
|
|
617
662
|
renderOnce(callback) {
|
|
618
663
|
if (this.rendering)
|
|
619
|
-
return debug.warn('rendering');
|
|
664
|
+
return debug$1.warn('rendering');
|
|
620
665
|
if (this.times > 3)
|
|
621
|
-
return debug.warn('render max times');
|
|
666
|
+
return debug$1.warn('render max times');
|
|
622
667
|
this.times++;
|
|
623
668
|
this.totalTimes++;
|
|
624
669
|
this.rendering = true;
|
|
@@ -631,6 +676,10 @@ class Renderer {
|
|
|
631
676
|
}
|
|
632
677
|
else {
|
|
633
678
|
this.requestLayout();
|
|
679
|
+
if (this.ignore) {
|
|
680
|
+
this.ignore = this.rendering = false;
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
634
683
|
this.emitRender(RenderEvent.BEFORE);
|
|
635
684
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
636
685
|
this.partRender();
|
|
@@ -651,7 +700,7 @@ class Renderer {
|
|
|
651
700
|
partRender() {
|
|
652
701
|
const { canvas, updateBlocks: list } = this;
|
|
653
702
|
if (!list)
|
|
654
|
-
return debug.warn('PartRender: need update attr');
|
|
703
|
+
return debug$1.warn('PartRender: need update attr');
|
|
655
704
|
this.mergeBlocks();
|
|
656
705
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
657
706
|
this.clipRender(block); });
|
|
@@ -667,7 +716,7 @@ class Renderer {
|
|
|
667
716
|
canvas.clear();
|
|
668
717
|
}
|
|
669
718
|
else {
|
|
670
|
-
bounds.spread(
|
|
719
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
671
720
|
canvas.clearWorld(bounds, true);
|
|
672
721
|
canvas.clipWorld(bounds, true);
|
|
673
722
|
}
|
|
@@ -691,14 +740,14 @@ class Renderer {
|
|
|
691
740
|
if (Debug.showRepaint)
|
|
692
741
|
this.canvas.strokeWorld(bounds, 'red');
|
|
693
742
|
this.target.__render(this.canvas, options);
|
|
694
|
-
this.renderBounds = realBounds || bounds;
|
|
743
|
+
this.renderBounds = realBounds = realBounds || bounds;
|
|
695
744
|
this.renderOptions = options;
|
|
696
|
-
this.totalBounds.isEmpty() ? this.totalBounds =
|
|
745
|
+
this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
|
|
697
746
|
if (Debug.showHitView)
|
|
698
747
|
this.renderHitView(options);
|
|
699
748
|
if (Debug.showBoundsView)
|
|
700
749
|
this.renderBoundsView(options);
|
|
701
|
-
this.canvas.updateRender();
|
|
750
|
+
this.canvas.updateRender(realBounds);
|
|
702
751
|
}
|
|
703
752
|
renderHitView(_options) { }
|
|
704
753
|
renderBoundsView(_options) { }
|
|
@@ -739,8 +788,11 @@ class Renderer {
|
|
|
739
788
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
740
789
|
this.addBlock(this.canvas.bounds);
|
|
741
790
|
this.target.forceUpdate('surface');
|
|
791
|
+
return;
|
|
742
792
|
}
|
|
743
793
|
}
|
|
794
|
+
this.addBlock(new Bounds(0, 0, 1, 1));
|
|
795
|
+
this.changed = true;
|
|
744
796
|
}
|
|
745
797
|
__onLayoutEnd(event) {
|
|
746
798
|
if (event.data)
|
|
@@ -751,7 +803,7 @@ class Renderer {
|
|
|
751
803
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
752
804
|
if (empty) {
|
|
753
805
|
if (!leaf.isLeafer)
|
|
754
|
-
debug.tip(leaf.innerName, ': empty');
|
|
806
|
+
debug$1.tip(leaf.innerName, ': empty');
|
|
755
807
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
756
808
|
}
|
|
757
809
|
return empty;
|
|
@@ -778,9 +830,7 @@ class Renderer {
|
|
|
778
830
|
if (this.target) {
|
|
779
831
|
this.stop();
|
|
780
832
|
this.__removeListenEvents();
|
|
781
|
-
this.target = null;
|
|
782
|
-
this.canvas = null;
|
|
783
|
-
this.config = null;
|
|
833
|
+
this.target = this.canvas = this.config = null;
|
|
784
834
|
}
|
|
785
835
|
}
|
|
786
836
|
}
|
|
@@ -794,9 +844,6 @@ Object.assign(Creator, {
|
|
|
794
844
|
});
|
|
795
845
|
Platform.layout = Layouter.fullLayout;
|
|
796
846
|
|
|
797
|
-
const PaintImage = {};
|
|
798
|
-
const PaintGradient = {};
|
|
799
|
-
|
|
800
847
|
function fillText(ui, canvas) {
|
|
801
848
|
let row;
|
|
802
849
|
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
@@ -1016,7 +1063,7 @@ function shape(ui, current, options) {
|
|
|
1016
1063
|
}
|
|
1017
1064
|
else {
|
|
1018
1065
|
const { renderShapeSpread: spread } = ui.__layout;
|
|
1019
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread *
|
|
1066
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1020
1067
|
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1021
1068
|
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1022
1069
|
if (fitMatrix.a < 1) {
|
|
@@ -1081,7 +1128,7 @@ function getLeafPaint(attrName, paint, ui) {
|
|
|
1081
1128
|
case 'angular':
|
|
1082
1129
|
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1083
1130
|
default:
|
|
1084
|
-
return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1131
|
+
return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1085
1132
|
}
|
|
1086
1133
|
}
|
|
1087
1134
|
|
|
@@ -1098,77 +1145,80 @@ const PaintModule = {
|
|
|
1098
1145
|
};
|
|
1099
1146
|
|
|
1100
1147
|
let origin = {};
|
|
1101
|
-
const { get: get$
|
|
1102
|
-
function fillOrFitMode(data,
|
|
1103
|
-
const transform = get$
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
const sh = box.height / (swap ? width : height);
|
|
1107
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1108
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
1109
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
1110
|
-
translate$1(transform, x, y);
|
|
1111
|
-
scaleHelper(transform, scale);
|
|
1148
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1149
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1150
|
+
const transform = get$3();
|
|
1151
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1152
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1112
1153
|
if (rotation)
|
|
1113
|
-
rotateOfOuter$
|
|
1114
|
-
data.scaleX = data.scaleY = scale;
|
|
1154
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1115
1155
|
data.transform = transform;
|
|
1116
1156
|
}
|
|
1117
1157
|
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1118
|
-
const transform = get$
|
|
1119
|
-
translate$1(transform, box.x, box.y);
|
|
1120
|
-
if (
|
|
1121
|
-
translate$1(transform, x, y);
|
|
1122
|
-
if (scaleX) {
|
|
1158
|
+
const transform = get$3();
|
|
1159
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1160
|
+
if (scaleX)
|
|
1123
1161
|
scaleHelper(transform, scaleX, scaleY);
|
|
1124
|
-
data.scaleX = transform.a;
|
|
1125
|
-
data.scaleY = transform.d;
|
|
1126
|
-
}
|
|
1127
1162
|
if (rotation)
|
|
1128
1163
|
rotate(transform, rotation);
|
|
1129
1164
|
data.transform = transform;
|
|
1130
1165
|
}
|
|
1131
|
-
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
|
|
1132
|
-
const transform = get$
|
|
1166
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1167
|
+
const transform = get$3();
|
|
1133
1168
|
if (rotation) {
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1169
|
+
if (align === 'center') {
|
|
1170
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1171
|
+
}
|
|
1172
|
+
else {
|
|
1173
|
+
rotate(transform, rotation);
|
|
1174
|
+
switch (rotation) {
|
|
1175
|
+
case 90:
|
|
1176
|
+
translate$1(transform, height, 0);
|
|
1177
|
+
break;
|
|
1178
|
+
case 180:
|
|
1179
|
+
translate$1(transform, width, height);
|
|
1180
|
+
break;
|
|
1181
|
+
case 270:
|
|
1182
|
+
translate$1(transform, 0, width);
|
|
1183
|
+
break;
|
|
1184
|
+
}
|
|
1145
1185
|
}
|
|
1146
1186
|
}
|
|
1147
|
-
origin.x = box.x;
|
|
1148
|
-
origin.y = box.y;
|
|
1149
|
-
if (x || y)
|
|
1150
|
-
origin.x += x, origin.y += y;
|
|
1187
|
+
origin.x = box.x + x;
|
|
1188
|
+
origin.y = box.y + y;
|
|
1151
1189
|
translate$1(transform, origin.x, origin.y);
|
|
1152
|
-
if (scaleX)
|
|
1153
|
-
scaleOfOuter$
|
|
1154
|
-
data.scaleX = scaleX;
|
|
1155
|
-
data.scaleY = scaleY;
|
|
1156
|
-
}
|
|
1190
|
+
if (scaleX)
|
|
1191
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1157
1192
|
data.transform = transform;
|
|
1158
1193
|
}
|
|
1159
1194
|
|
|
1160
|
-
const { get: get$
|
|
1195
|
+
const { get: get$2, translate } = MatrixHelper;
|
|
1196
|
+
const tempBox = new Bounds();
|
|
1197
|
+
const tempPoint = {};
|
|
1161
1198
|
function createData(leafPaint, image, paint, box) {
|
|
1162
|
-
|
|
1163
|
-
const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
|
|
1164
|
-
const sameBox = box.width === width && box.height === height;
|
|
1199
|
+
const { blendMode } = paint;
|
|
1165
1200
|
if (blendMode)
|
|
1166
1201
|
leafPaint.blendMode = blendMode;
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
if (
|
|
1202
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1203
|
+
}
|
|
1204
|
+
function getPatternData(paint, box, image) {
|
|
1205
|
+
let { width, height } = image;
|
|
1206
|
+
if (paint.padding)
|
|
1207
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1208
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1209
|
+
const sameBox = box.width === width && box.height === height;
|
|
1210
|
+
const data = { mode };
|
|
1211
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1212
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1213
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1214
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1215
|
+
if (!sameBox || rotation) {
|
|
1216
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1217
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1218
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
else if (size) {
|
|
1172
1222
|
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1173
1223
|
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1174
1224
|
}
|
|
@@ -1176,30 +1226,46 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1176
1226
|
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1177
1227
|
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1178
1228
|
}
|
|
1229
|
+
if (align) {
|
|
1230
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1231
|
+
if (scaleX)
|
|
1232
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1233
|
+
AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1234
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1235
|
+
}
|
|
1236
|
+
if (offset)
|
|
1237
|
+
x += offset.x, y += offset.y;
|
|
1179
1238
|
switch (mode) {
|
|
1180
1239
|
case 'strench':
|
|
1181
1240
|
if (!sameBox)
|
|
1182
1241
|
width = box.width, height = box.height;
|
|
1183
|
-
if (box.x || box.y) {
|
|
1184
|
-
data.transform = get$3();
|
|
1185
|
-
translate(data.transform, box.x, box.y);
|
|
1186
|
-
}
|
|
1187
1242
|
break;
|
|
1243
|
+
case 'normal':
|
|
1188
1244
|
case 'clip':
|
|
1189
|
-
if (
|
|
1245
|
+
if (x || y || scaleX || rotation)
|
|
1190
1246
|
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1191
1247
|
break;
|
|
1192
1248
|
case 'repeat':
|
|
1193
1249
|
if (!sameBox || scaleX || rotation)
|
|
1194
|
-
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1250
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1195
1251
|
if (!repeat)
|
|
1196
1252
|
data.repeat = 'repeat';
|
|
1197
1253
|
break;
|
|
1198
1254
|
case 'fit':
|
|
1199
1255
|
case 'cover':
|
|
1200
1256
|
default:
|
|
1201
|
-
if (
|
|
1202
|
-
fillOrFitMode(data,
|
|
1257
|
+
if (scaleX)
|
|
1258
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1259
|
+
}
|
|
1260
|
+
if (!data.transform) {
|
|
1261
|
+
if (box.x || box.y) {
|
|
1262
|
+
data.transform = get$2();
|
|
1263
|
+
translate(data.transform, box.x, box.y);
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
if (scaleX && mode !== 'strench') {
|
|
1267
|
+
data.scaleX = scaleX;
|
|
1268
|
+
data.scaleY = scaleY;
|
|
1203
1269
|
}
|
|
1204
1270
|
data.width = width;
|
|
1205
1271
|
data.height = height;
|
|
@@ -1207,6 +1273,7 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1207
1273
|
data.opacity = opacity;
|
|
1208
1274
|
if (repeat)
|
|
1209
1275
|
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1276
|
+
return data;
|
|
1210
1277
|
}
|
|
1211
1278
|
|
|
1212
1279
|
let cache, box = new Bounds();
|
|
@@ -1218,8 +1285,7 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
|
1218
1285
|
leafPaint = cache.leafPaint;
|
|
1219
1286
|
}
|
|
1220
1287
|
else {
|
|
1221
|
-
leafPaint = { type: paint.type };
|
|
1222
|
-
leafPaint.image = image;
|
|
1288
|
+
leafPaint = { type: paint.type, image };
|
|
1223
1289
|
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1224
1290
|
}
|
|
1225
1291
|
if (firstUse || image.loading)
|
|
@@ -1236,16 +1302,22 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
|
1236
1302
|
onLoadError(ui, event, image.error);
|
|
1237
1303
|
}
|
|
1238
1304
|
else {
|
|
1305
|
+
ignoreRender(ui, true);
|
|
1239
1306
|
if (firstUse)
|
|
1240
1307
|
onLoad(ui, event);
|
|
1241
1308
|
leafPaint.loadId = image.load(() => {
|
|
1309
|
+
ignoreRender(ui, false);
|
|
1242
1310
|
if (!ui.destroyed) {
|
|
1243
|
-
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds))
|
|
1311
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1312
|
+
if (image.hasOpacityPixel)
|
|
1313
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1244
1314
|
ui.forceUpdate('surface');
|
|
1315
|
+
}
|
|
1245
1316
|
onLoadSuccess(ui, event);
|
|
1246
1317
|
}
|
|
1247
1318
|
leafPaint.loadId = null;
|
|
1248
1319
|
}, (error) => {
|
|
1320
|
+
ignoreRender(ui, false);
|
|
1249
1321
|
onLoadError(ui, event, error);
|
|
1250
1322
|
leafPaint.loadId = null;
|
|
1251
1323
|
});
|
|
@@ -1255,9 +1327,9 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
|
1255
1327
|
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1256
1328
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1257
1329
|
const data = ui.__;
|
|
1258
|
-
data.__naturalWidth = image.width;
|
|
1259
|
-
data.__naturalHeight = image.height;
|
|
1260
|
-
if (data.
|
|
1330
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1331
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1332
|
+
if (data.__autoSide) {
|
|
1261
1333
|
ui.forceUpdate('width');
|
|
1262
1334
|
if (ui.__proxyData) {
|
|
1263
1335
|
ui.setProxyAttr('width', data.width);
|
|
@@ -1285,11 +1357,16 @@ function emit(ui, type, data) {
|
|
|
1285
1357
|
if (ui.hasEvent(type))
|
|
1286
1358
|
ui.emitEvent(new ImageEvent(type, data));
|
|
1287
1359
|
}
|
|
1360
|
+
function ignoreRender(ui, value) {
|
|
1361
|
+
const { leafer } = ui;
|
|
1362
|
+
if (leafer && leafer.viewReady)
|
|
1363
|
+
leafer.renderer.ignore = value;
|
|
1364
|
+
}
|
|
1288
1365
|
|
|
1289
|
-
const { get: get$
|
|
1290
|
-
const {
|
|
1366
|
+
const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
|
|
1367
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1291
1368
|
function createPattern(ui, paint, pixelRatio) {
|
|
1292
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1369
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1293
1370
|
const id = scaleX + '-' + scaleY;
|
|
1294
1371
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1295
1372
|
scaleX = abs$1(scaleX);
|
|
@@ -1297,7 +1374,7 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1297
1374
|
const { image, data } = paint;
|
|
1298
1375
|
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1299
1376
|
if (sx) {
|
|
1300
|
-
imageMatrix = get$
|
|
1377
|
+
imageMatrix = get$1();
|
|
1301
1378
|
copy$1(imageMatrix, transform);
|
|
1302
1379
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1303
1380
|
scaleX *= sx;
|
|
@@ -1332,13 +1409,13 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1332
1409
|
}
|
|
1333
1410
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1334
1411
|
if (!imageMatrix) {
|
|
1335
|
-
imageMatrix = get$
|
|
1412
|
+
imageMatrix = get$1();
|
|
1336
1413
|
if (transform)
|
|
1337
1414
|
copy$1(imageMatrix, transform);
|
|
1338
1415
|
}
|
|
1339
1416
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1340
1417
|
}
|
|
1341
|
-
const canvas = image.getCanvas(width
|
|
1418
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
1342
1419
|
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1343
1420
|
paint.style = pattern;
|
|
1344
1421
|
paint.patternId = id;
|
|
@@ -1383,8 +1460,8 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
1383
1460
|
|
|
1384
1461
|
const { abs } = Math;
|
|
1385
1462
|
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1386
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1387
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1463
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1464
|
+
if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
|
|
1388
1465
|
return false;
|
|
1389
1466
|
}
|
|
1390
1467
|
else {
|
|
@@ -1398,7 +1475,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1398
1475
|
width *= data.scaleX;
|
|
1399
1476
|
height *= data.scaleY;
|
|
1400
1477
|
}
|
|
1401
|
-
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
1478
|
+
allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
|
|
1402
1479
|
}
|
|
1403
1480
|
else {
|
|
1404
1481
|
allowPaint = false;
|
|
@@ -1425,7 +1502,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1425
1502
|
if (!paint.patternTask) {
|
|
1426
1503
|
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1427
1504
|
paint.patternTask = null;
|
|
1428
|
-
if (canvas.bounds.hit(ui.
|
|
1505
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1429
1506
|
createPattern(ui, paint, canvas.pixelRatio);
|
|
1430
1507
|
ui.forceUpdate('surface');
|
|
1431
1508
|
}), 300);
|
|
@@ -1465,22 +1542,24 @@ function recycleImage(attrName, data) {
|
|
|
1465
1542
|
|
|
1466
1543
|
const PaintImageModule = {
|
|
1467
1544
|
image,
|
|
1545
|
+
checkImage,
|
|
1546
|
+
createPattern,
|
|
1547
|
+
recycleImage,
|
|
1468
1548
|
createData,
|
|
1549
|
+
getPatternData,
|
|
1469
1550
|
fillOrFitMode,
|
|
1470
1551
|
clipMode,
|
|
1471
|
-
repeatMode
|
|
1472
|
-
createPattern,
|
|
1473
|
-
checkImage,
|
|
1474
|
-
recycleImage
|
|
1552
|
+
repeatMode
|
|
1475
1553
|
};
|
|
1476
1554
|
|
|
1477
|
-
const
|
|
1478
|
-
const
|
|
1555
|
+
const { toPoint: toPoint$2 } = AroundHelper;
|
|
1556
|
+
const realFrom$2 = {};
|
|
1557
|
+
const realTo$2 = {};
|
|
1479
1558
|
function linearGradient(paint, box) {
|
|
1480
1559
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1481
|
-
from ||
|
|
1482
|
-
to ||
|
|
1483
|
-
const style = Platform.canvas.createLinearGradient(
|
|
1560
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
1561
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
1562
|
+
const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1484
1563
|
applyStops(style, paint.stops, opacity);
|
|
1485
1564
|
const data = { type, style };
|
|
1486
1565
|
if (blendMode)
|
|
@@ -1491,63 +1570,66 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1491
1570
|
let stop;
|
|
1492
1571
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1493
1572
|
stop = stops[i];
|
|
1494
|
-
|
|
1573
|
+
if (typeof stop === 'string') {
|
|
1574
|
+
gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
|
|
1575
|
+
}
|
|
1576
|
+
else {
|
|
1577
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
1578
|
+
}
|
|
1495
1579
|
}
|
|
1496
1580
|
}
|
|
1497
1581
|
|
|
1498
|
-
const {
|
|
1499
|
-
const { get
|
|
1500
|
-
const
|
|
1501
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
1582
|
+
const { getAngle, getDistance: getDistance$1 } = PointHelper;
|
|
1583
|
+
const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
|
|
1584
|
+
const { toPoint: toPoint$1 } = AroundHelper;
|
|
1502
1585
|
const realFrom$1 = {};
|
|
1503
1586
|
const realTo$1 = {};
|
|
1504
1587
|
function radialGradient(paint, box) {
|
|
1505
1588
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1506
|
-
from ||
|
|
1507
|
-
to ||
|
|
1508
|
-
const { x, y, width, height } = box;
|
|
1509
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
1510
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
1511
|
-
let transform;
|
|
1512
|
-
if (width !== height || stretch) {
|
|
1513
|
-
transform = get$1();
|
|
1514
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
1515
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
1516
|
-
}
|
|
1589
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
1590
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
1517
1591
|
const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
1518
1592
|
applyStops(style, paint.stops, opacity);
|
|
1519
|
-
const data = { type, style
|
|
1593
|
+
const data = { type, style };
|
|
1594
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
1595
|
+
if (transform)
|
|
1596
|
+
data.transform = transform;
|
|
1520
1597
|
if (blendMode)
|
|
1521
1598
|
data.blendMode = blendMode;
|
|
1522
1599
|
return data;
|
|
1523
1600
|
}
|
|
1601
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
1602
|
+
let transform;
|
|
1603
|
+
const { width, height } = box;
|
|
1604
|
+
if (width !== height || stretch) {
|
|
1605
|
+
const angle = getAngle(from, to);
|
|
1606
|
+
transform = get();
|
|
1607
|
+
if (rotate90) {
|
|
1608
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
1609
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
1610
|
+
}
|
|
1611
|
+
else {
|
|
1612
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
1613
|
+
rotateOfOuter(transform, from, angle);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
return transform;
|
|
1617
|
+
}
|
|
1524
1618
|
|
|
1525
|
-
const {
|
|
1526
|
-
const {
|
|
1527
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
1528
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
1619
|
+
const { getDistance } = PointHelper;
|
|
1620
|
+
const { toPoint } = AroundHelper;
|
|
1529
1621
|
const realFrom = {};
|
|
1530
1622
|
const realTo = {};
|
|
1531
1623
|
function conicGradient(paint, box) {
|
|
1532
1624
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
1533
|
-
from ||
|
|
1534
|
-
to ||
|
|
1535
|
-
const { x, y, width, height } = box;
|
|
1536
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
1537
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
1538
|
-
const transform = get();
|
|
1539
|
-
const angle = getAngle(realFrom, realTo);
|
|
1540
|
-
if (Platform.conicGradientRotate90) {
|
|
1541
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
1542
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
1543
|
-
}
|
|
1544
|
-
else {
|
|
1545
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
1546
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
1547
|
-
}
|
|
1625
|
+
toPoint(from || 'center', box, realFrom);
|
|
1626
|
+
toPoint(to || 'bottom', box, realTo);
|
|
1548
1627
|
const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
|
|
1549
1628
|
applyStops(style, paint.stops, opacity);
|
|
1550
|
-
const data = { type, style
|
|
1629
|
+
const data = { type, style };
|
|
1630
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
|
|
1631
|
+
if (transform)
|
|
1632
|
+
data.transform = transform;
|
|
1551
1633
|
if (blendMode)
|
|
1552
1634
|
data.blendMode = blendMode;
|
|
1553
1635
|
return data;
|
|
@@ -1556,7 +1638,8 @@ function conicGradient(paint, box) {
|
|
|
1556
1638
|
const PaintGradientModule = {
|
|
1557
1639
|
linearGradient,
|
|
1558
1640
|
radialGradient,
|
|
1559
|
-
conicGradient
|
|
1641
|
+
conicGradient,
|
|
1642
|
+
getTransform
|
|
1560
1643
|
};
|
|
1561
1644
|
|
|
1562
1645
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
@@ -1662,8 +1745,8 @@ function innerShadow(ui, current, shape) {
|
|
|
1662
1745
|
|
|
1663
1746
|
function blur(ui, current, origin) {
|
|
1664
1747
|
const { blur } = ui.__;
|
|
1665
|
-
origin.setWorldBlur(blur * ui.
|
|
1666
|
-
origin.copyWorldToInner(current, ui.
|
|
1748
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
1749
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1667
1750
|
origin.filter = 'none';
|
|
1668
1751
|
}
|
|
1669
1752
|
|
|
@@ -1688,7 +1771,7 @@ Group.prototype.__renderMask = function (canvas, options) {
|
|
|
1688
1771
|
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
1689
1772
|
maskCanvas = contentCanvas = null;
|
|
1690
1773
|
}
|
|
1691
|
-
if (child.__.
|
|
1774
|
+
if (child.__.mask === 'path') {
|
|
1692
1775
|
if (child.opacity < 1) {
|
|
1693
1776
|
currentMask = 'opacity-path';
|
|
1694
1777
|
maskOpacity = child.opacity;
|
|
@@ -1709,7 +1792,7 @@ Group.prototype.__renderMask = function (canvas, options) {
|
|
|
1709
1792
|
contentCanvas = getCanvas(canvas);
|
|
1710
1793
|
child.__render(maskCanvas, options);
|
|
1711
1794
|
}
|
|
1712
|
-
if (child.__.
|
|
1795
|
+
if (child.__.mask !== 'clipping')
|
|
1713
1796
|
continue;
|
|
1714
1797
|
}
|
|
1715
1798
|
if (excludeRenderBounds(child, options))
|
|
@@ -1904,7 +1987,8 @@ function createRows(drawData, content, style) {
|
|
|
1904
1987
|
if (breakAll) {
|
|
1905
1988
|
if (wordWidth)
|
|
1906
1989
|
addWord();
|
|
1907
|
-
|
|
1990
|
+
if (rowWidth)
|
|
1991
|
+
addRow();
|
|
1908
1992
|
}
|
|
1909
1993
|
else {
|
|
1910
1994
|
if (!afterBreak)
|
|
@@ -1912,10 +1996,12 @@ function createRows(drawData, content, style) {
|
|
|
1912
1996
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
1913
1997
|
if (wordWidth)
|
|
1914
1998
|
addWord();
|
|
1915
|
-
|
|
1999
|
+
if (rowWidth)
|
|
2000
|
+
addRow();
|
|
1916
2001
|
}
|
|
1917
2002
|
else {
|
|
1918
|
-
|
|
2003
|
+
if (rowWidth)
|
|
2004
|
+
addRow();
|
|
1919
2005
|
}
|
|
1920
2006
|
}
|
|
1921
2007
|
}
|
|
@@ -2010,11 +2096,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2010
2096
|
if (mode === WordMode) {
|
|
2011
2097
|
wordChar = { char: '', x: charX };
|
|
2012
2098
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2013
|
-
if (wordChar.char !== ' ')
|
|
2099
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2014
2100
|
row.data.push(wordChar);
|
|
2015
2101
|
}
|
|
2016
2102
|
else {
|
|
2017
|
-
charX = toChar(word.data, charX, row.data);
|
|
2103
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2018
2104
|
}
|
|
2019
2105
|
if (!row.paraEnd && addWordWidth) {
|
|
2020
2106
|
charX += addWordWidth;
|
|
@@ -2041,9 +2127,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2041
2127
|
});
|
|
2042
2128
|
return charX;
|
|
2043
2129
|
}
|
|
2044
|
-
function toChar(data, charX, rowData) {
|
|
2130
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2045
2131
|
data.forEach(char => {
|
|
2046
|
-
if (char.char !== ' ') {
|
|
2132
|
+
if (isOverflow || char.char !== ' ') {
|
|
2047
2133
|
char.x = charX;
|
|
2048
2134
|
rowData.push(char);
|
|
2049
2135
|
}
|
|
@@ -2075,12 +2161,14 @@ function layoutText(drawData, style) {
|
|
|
2075
2161
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2076
2162
|
row = rows[i];
|
|
2077
2163
|
row.x = x;
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2164
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2165
|
+
switch (textAlign) {
|
|
2166
|
+
case 'center':
|
|
2167
|
+
row.x += (width - row.width) / 2;
|
|
2168
|
+
break;
|
|
2169
|
+
case 'right':
|
|
2170
|
+
row.x += width - row.width;
|
|
2171
|
+
}
|
|
2084
2172
|
}
|
|
2085
2173
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2086
2174
|
starY += paraSpacing;
|
|
@@ -2116,16 +2204,20 @@ function layoutText(drawData, style) {
|
|
|
2116
2204
|
bounds.height = realHeight;
|
|
2117
2205
|
}
|
|
2118
2206
|
|
|
2119
|
-
function clipText(drawData, style) {
|
|
2207
|
+
function clipText(drawData, style, x, width) {
|
|
2208
|
+
if (!width)
|
|
2209
|
+
return;
|
|
2120
2210
|
const { rows, overflow } = drawData;
|
|
2121
2211
|
let { textOverflow } = style;
|
|
2122
2212
|
rows.splice(overflow);
|
|
2123
|
-
if (textOverflow !== '
|
|
2124
|
-
if (textOverflow === '
|
|
2213
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2214
|
+
if (textOverflow === 'hide')
|
|
2215
|
+
textOverflow = '';
|
|
2216
|
+
else if (textOverflow === 'ellipsis')
|
|
2125
2217
|
textOverflow = '...';
|
|
2126
2218
|
let char, charRight;
|
|
2127
|
-
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2128
|
-
const right =
|
|
2219
|
+
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2220
|
+
const right = x + width - ellipsisWidth;
|
|
2129
2221
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2130
2222
|
list.forEach(row => {
|
|
2131
2223
|
if (row.isOverflow && row.data) {
|
|
@@ -2201,7 +2293,7 @@ function getDrawData(content, style) {
|
|
|
2201
2293
|
layoutText(drawData, style);
|
|
2202
2294
|
layoutChar(drawData, style, width);
|
|
2203
2295
|
if (drawData.overflow)
|
|
2204
|
-
clipText(drawData, style);
|
|
2296
|
+
clipText(drawData, style, x, width);
|
|
2205
2297
|
if (textDecoration !== 'none')
|
|
2206
2298
|
decorationText(drawData, style);
|
|
2207
2299
|
return drawData;
|
|
@@ -2272,46 +2364,101 @@ function getTrimBounds(canvas) {
|
|
|
2272
2364
|
const ExportModule = {
|
|
2273
2365
|
export(leaf, filename, options) {
|
|
2274
2366
|
this.running = true;
|
|
2367
|
+
const fileType = FileHelper.fileType(filename);
|
|
2368
|
+
options = FileHelper.getExportOptions(options);
|
|
2275
2369
|
return addTask((success) => new Promise((resolve) => {
|
|
2276
2370
|
const over = (result) => {
|
|
2277
2371
|
success(result);
|
|
2278
2372
|
resolve();
|
|
2279
2373
|
this.running = false;
|
|
2280
2374
|
};
|
|
2375
|
+
const { toURL } = Platform;
|
|
2376
|
+
const { download } = Platform.origin;
|
|
2377
|
+
if (filename === 'json') {
|
|
2378
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
2379
|
+
}
|
|
2380
|
+
else if (fileType === 'json') {
|
|
2381
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
2382
|
+
return over({ data: true });
|
|
2383
|
+
}
|
|
2384
|
+
if (filename === 'svg') {
|
|
2385
|
+
return over({ data: leaf.toSVG() });
|
|
2386
|
+
}
|
|
2387
|
+
else if (fileType === 'svg') {
|
|
2388
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
2389
|
+
return over({ data: true });
|
|
2390
|
+
}
|
|
2281
2391
|
const { leafer } = leaf;
|
|
2282
2392
|
if (leafer) {
|
|
2393
|
+
checkLazy(leaf);
|
|
2283
2394
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2284
2395
|
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2285
|
-
|
|
2286
|
-
const {
|
|
2396
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
2397
|
+
const { slice, trim, onCanvas } = options;
|
|
2398
|
+
let scale = options.scale || 1;
|
|
2399
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
2400
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
2401
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
2402
|
+
if (leaf.isApp) {
|
|
2403
|
+
scale *= pixelRatio;
|
|
2404
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
2405
|
+
}
|
|
2287
2406
|
const screenshot = options.screenshot || leaf.isApp;
|
|
2288
|
-
const fill =
|
|
2407
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
2289
2408
|
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
2290
2409
|
if (screenshot) {
|
|
2291
|
-
renderBounds = screenshot === true ? (
|
|
2410
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2292
2411
|
}
|
|
2293
2412
|
else {
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2413
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
2414
|
+
scaleX = worldTransform.scaleX;
|
|
2415
|
+
scaleY = worldTransform.scaleY;
|
|
2416
|
+
switch (relative) {
|
|
2417
|
+
case 'inner':
|
|
2418
|
+
matrix.set(worldTransform);
|
|
2419
|
+
break;
|
|
2420
|
+
case 'local':
|
|
2421
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
2422
|
+
scaleX /= leaf.scaleX;
|
|
2423
|
+
scaleY /= leaf.scaleY;
|
|
2424
|
+
break;
|
|
2425
|
+
case 'world':
|
|
2426
|
+
scaleX = 1;
|
|
2427
|
+
scaleY = 1;
|
|
2428
|
+
break;
|
|
2429
|
+
case 'page':
|
|
2430
|
+
relative = leaf.leafer;
|
|
2431
|
+
default:
|
|
2432
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
2433
|
+
const l = relative.worldTransform;
|
|
2434
|
+
scaleX /= scaleX / l.scaleX;
|
|
2435
|
+
scaleY /= scaleY / l.scaleY;
|
|
2436
|
+
}
|
|
2437
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2305
2438
|
}
|
|
2306
|
-
|
|
2307
|
-
|
|
2439
|
+
const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
|
|
2440
|
+
let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
2441
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
2442
|
+
let sliceLeaf;
|
|
2308
2443
|
if (slice) {
|
|
2444
|
+
sliceLeaf = leaf;
|
|
2445
|
+
sliceLeaf.__worldOpacity = 0;
|
|
2309
2446
|
leaf = leafer;
|
|
2310
2447
|
renderOptions.bounds = canvas.bounds;
|
|
2311
2448
|
}
|
|
2312
2449
|
canvas.save();
|
|
2313
|
-
|
|
2450
|
+
if (isFrame && fill !== undefined) {
|
|
2451
|
+
const oldFill = leaf.get('fill');
|
|
2452
|
+
leaf.fill = '';
|
|
2453
|
+
leaf.__render(canvas, renderOptions);
|
|
2454
|
+
leaf.fill = oldFill;
|
|
2455
|
+
}
|
|
2456
|
+
else {
|
|
2457
|
+
leaf.__render(canvas, renderOptions);
|
|
2458
|
+
}
|
|
2314
2459
|
canvas.restore();
|
|
2460
|
+
if (sliceLeaf)
|
|
2461
|
+
sliceLeaf.__updateWorldOpacity();
|
|
2315
2462
|
if (trim) {
|
|
2316
2463
|
trimBounds = getTrimBounds(canvas);
|
|
2317
2464
|
const old = canvas, { width, height } = trimBounds;
|
|
@@ -2321,8 +2468,10 @@ const ExportModule = {
|
|
|
2321
2468
|
}
|
|
2322
2469
|
if (needFill)
|
|
2323
2470
|
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2471
|
+
if (onCanvas)
|
|
2472
|
+
onCanvas(canvas);
|
|
2324
2473
|
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2325
|
-
over({ data, renderBounds, trimBounds });
|
|
2474
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2326
2475
|
}));
|
|
2327
2476
|
}
|
|
2328
2477
|
else {
|
|
@@ -2339,12 +2488,56 @@ function addTask(task) {
|
|
|
2339
2488
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2340
2489
|
});
|
|
2341
2490
|
}
|
|
2491
|
+
function checkLazy(leaf) {
|
|
2492
|
+
if (leaf.__.__needComputePaint)
|
|
2493
|
+
leaf.__.__computePaint();
|
|
2494
|
+
if (leaf.isBranch)
|
|
2495
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
const canvas = LeaferCanvasBase.prototype;
|
|
2499
|
+
const debug = Debug.get('@leafer-ui/export');
|
|
2500
|
+
canvas.export = function (filename, options) {
|
|
2501
|
+
const { quality, blob } = FileHelper.getExportOptions(options);
|
|
2502
|
+
if (filename.includes('.')) {
|
|
2503
|
+
return this.saveAs(filename, quality);
|
|
2504
|
+
}
|
|
2505
|
+
else if (blob) {
|
|
2506
|
+
return this.toBlob(filename, quality);
|
|
2507
|
+
}
|
|
2508
|
+
else {
|
|
2509
|
+
return this.toDataURL(filename, quality);
|
|
2510
|
+
}
|
|
2511
|
+
};
|
|
2512
|
+
canvas.toBlob = function (type, quality) {
|
|
2513
|
+
return new Promise((resolve) => {
|
|
2514
|
+
Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2515
|
+
resolve(blob);
|
|
2516
|
+
}).catch((e) => {
|
|
2517
|
+
debug.error(e);
|
|
2518
|
+
resolve(null);
|
|
2519
|
+
});
|
|
2520
|
+
});
|
|
2521
|
+
};
|
|
2522
|
+
canvas.toDataURL = function (type, quality) {
|
|
2523
|
+
return Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2524
|
+
};
|
|
2525
|
+
canvas.saveAs = function (filename, quality) {
|
|
2526
|
+
return new Promise((resolve) => {
|
|
2527
|
+
Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2528
|
+
resolve(true);
|
|
2529
|
+
}).catch((e) => {
|
|
2530
|
+
debug.error(e);
|
|
2531
|
+
resolve(false);
|
|
2532
|
+
});
|
|
2533
|
+
});
|
|
2534
|
+
};
|
|
2342
2535
|
|
|
2343
2536
|
Object.assign(TextConvert, TextConvertModule);
|
|
2344
2537
|
Object.assign(ColorConvert, ColorConvertModule);
|
|
2345
2538
|
Object.assign(Paint, PaintModule);
|
|
2346
|
-
Object.assign(PaintImage
|
|
2347
|
-
Object.assign(PaintGradient
|
|
2539
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
2540
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
2348
2541
|
Object.assign(Effect, EffectModule);
|
|
2349
2542
|
Object.assign(Export, ExportModule);
|
|
2350
2543
|
|