leafer-ui 1.0.0-rc.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -5
- package/dist/web.esm.js +1307 -955
- package/dist/web.esm.min.js +1 -1
- package/dist/web.js +7020 -5845
- package/dist/web.min.js +1 -1
- package/dist/web.module.js +6992 -5836
- package/dist/web.module.min.js +1 -1
- package/package.json +11 -4
- package/src/index.ts +1 -1
package/dist/web.esm.js
CHANGED
|
@@ -1,8 +1,255 @@
|
|
|
1
|
-
import {
|
|
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, Answer, MathHelper, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
|
|
2
2
|
export * from '@leafer/core';
|
|
3
3
|
export { LeaferImage } from '@leafer/core';
|
|
4
|
-
import {
|
|
4
|
+
import { InteractionHelper, InteractionBase, Cursor, HitCanvasManager } from '@leafer-ui/core';
|
|
5
5
|
export * from '@leafer-ui/core';
|
|
6
|
+
import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
|
|
7
|
+
|
|
8
|
+
const debug$3 = Debug.get('LeaferCanvas');
|
|
9
|
+
class LeaferCanvas extends LeaferCanvasBase {
|
|
10
|
+
set zIndex(zIndex) {
|
|
11
|
+
const { style } = this.view;
|
|
12
|
+
style.zIndex = zIndex;
|
|
13
|
+
this.setAbsolute(this.view);
|
|
14
|
+
}
|
|
15
|
+
set childIndex(index) {
|
|
16
|
+
const { view, parentView } = this;
|
|
17
|
+
if (view && parentView) {
|
|
18
|
+
const beforeNode = parentView.children[index];
|
|
19
|
+
if (beforeNode) {
|
|
20
|
+
this.setAbsolute(beforeNode);
|
|
21
|
+
parentView.insertBefore(view, beforeNode);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
parentView.appendChild(beforeNode);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
init() {
|
|
29
|
+
const { view } = this.config;
|
|
30
|
+
view ? this.__createViewFrom(view) : this.__createView();
|
|
31
|
+
const { style } = this.view;
|
|
32
|
+
style.display || (style.display = 'block');
|
|
33
|
+
this.parentView = this.view.parentElement;
|
|
34
|
+
if (this.parentView) {
|
|
35
|
+
const pStyle = this.parentView.style;
|
|
36
|
+
pStyle.webkitUserSelect = pStyle.userSelect = 'none';
|
|
37
|
+
}
|
|
38
|
+
if (Platform.syncDomFont && !this.parentView) {
|
|
39
|
+
style.display = 'none';
|
|
40
|
+
document.body.appendChild(this.view);
|
|
41
|
+
}
|
|
42
|
+
this.__createContext();
|
|
43
|
+
if (!this.autoLayout)
|
|
44
|
+
this.resize(this.config);
|
|
45
|
+
}
|
|
46
|
+
set backgroundColor(color) { this.view.style.backgroundColor = color; }
|
|
47
|
+
get backgroundColor() { return this.view.style.backgroundColor; }
|
|
48
|
+
set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
|
|
49
|
+
get hittable() { return this.view.style.pointerEvents !== 'none'; }
|
|
50
|
+
__createView() {
|
|
51
|
+
this.view = document.createElement('canvas');
|
|
52
|
+
}
|
|
53
|
+
__createViewFrom(inputView) {
|
|
54
|
+
let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
|
|
55
|
+
if (find) {
|
|
56
|
+
if (find instanceof HTMLCanvasElement) {
|
|
57
|
+
this.view = find;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
let parent = find;
|
|
61
|
+
if (find === window || find === document) {
|
|
62
|
+
const div = document.createElement('div');
|
|
63
|
+
const { style } = div;
|
|
64
|
+
style.position = 'absolute';
|
|
65
|
+
style.top = style.bottom = style.left = style.right = '0px';
|
|
66
|
+
document.body.appendChild(div);
|
|
67
|
+
parent = div;
|
|
68
|
+
}
|
|
69
|
+
this.__createView();
|
|
70
|
+
const view = this.view;
|
|
71
|
+
if (parent.hasChildNodes()) {
|
|
72
|
+
this.setAbsolute(view);
|
|
73
|
+
parent.style.position || (parent.style.position = 'relative');
|
|
74
|
+
}
|
|
75
|
+
parent.appendChild(view);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
debug$3.error(`no id: ${inputView}`);
|
|
80
|
+
this.__createView();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
setAbsolute(view) {
|
|
84
|
+
const { style } = view;
|
|
85
|
+
style.position = 'absolute';
|
|
86
|
+
style.top = style.left = '0px';
|
|
87
|
+
}
|
|
88
|
+
updateViewSize() {
|
|
89
|
+
const { width, height, pixelRatio } = this;
|
|
90
|
+
const { style } = this.view;
|
|
91
|
+
style.width = width + 'px';
|
|
92
|
+
style.height = height + 'px';
|
|
93
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
94
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
95
|
+
}
|
|
96
|
+
updateClientBounds() {
|
|
97
|
+
this.clientBounds = this.view.getBoundingClientRect();
|
|
98
|
+
}
|
|
99
|
+
startAutoLayout(autoBounds, listener) {
|
|
100
|
+
this.autoBounds = autoBounds;
|
|
101
|
+
this.resizeListener = listener;
|
|
102
|
+
try {
|
|
103
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
104
|
+
this.updateClientBounds();
|
|
105
|
+
for (const entry of entries)
|
|
106
|
+
this.checkAutoBounds(entry.contentRect);
|
|
107
|
+
});
|
|
108
|
+
const parent = this.parentView;
|
|
109
|
+
if (parent) {
|
|
110
|
+
this.resizeObserver.observe(parent);
|
|
111
|
+
this.checkAutoBounds(parent.getBoundingClientRect());
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
this.checkAutoBounds(this.view);
|
|
115
|
+
debug$3.warn('no parent');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (_a) {
|
|
119
|
+
this.imitateResizeObserver();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
imitateResizeObserver() {
|
|
123
|
+
if (this.autoLayout) {
|
|
124
|
+
if (this.parentView)
|
|
125
|
+
this.checkAutoBounds(this.parentView.getBoundingClientRect());
|
|
126
|
+
Platform.requestRender(this.imitateResizeObserver.bind(this));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
checkAutoBounds(parentSize) {
|
|
130
|
+
const view = this.view;
|
|
131
|
+
const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
|
|
132
|
+
if (width !== this.width || height !== this.height) {
|
|
133
|
+
const { style } = view;
|
|
134
|
+
const { pixelRatio } = this;
|
|
135
|
+
style.marginLeft = x + 'px';
|
|
136
|
+
style.marginTop = y + 'px';
|
|
137
|
+
const size = { width, height, pixelRatio };
|
|
138
|
+
const oldSize = {};
|
|
139
|
+
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
140
|
+
this.resize(size);
|
|
141
|
+
if (this.width !== undefined)
|
|
142
|
+
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
stopAutoLayout() {
|
|
146
|
+
this.autoLayout = false;
|
|
147
|
+
this.resizeListener = null;
|
|
148
|
+
if (this.resizeObserver) {
|
|
149
|
+
this.resizeObserver.disconnect();
|
|
150
|
+
this.resizeObserver = null;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
unrealCanvas() {
|
|
154
|
+
if (!this.unreal && this.parentView) {
|
|
155
|
+
const view = this.view;
|
|
156
|
+
if (view)
|
|
157
|
+
view.remove();
|
|
158
|
+
this.view = this.parentView;
|
|
159
|
+
this.unreal = true;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
destroy() {
|
|
163
|
+
if (this.view) {
|
|
164
|
+
this.stopAutoLayout();
|
|
165
|
+
if (!this.unreal) {
|
|
166
|
+
const view = this.view;
|
|
167
|
+
if (view.parentElement)
|
|
168
|
+
view.remove();
|
|
169
|
+
}
|
|
170
|
+
super.destroy();
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
canvasPatch(CanvasRenderingContext2D.prototype);
|
|
176
|
+
canvasPatch(Path2D.prototype);
|
|
177
|
+
|
|
178
|
+
const { mineType, fileType } = FileHelper;
|
|
179
|
+
Object.assign(Creator, {
|
|
180
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
181
|
+
image: (options) => new LeaferImage(options)
|
|
182
|
+
});
|
|
183
|
+
function useCanvas(_canvasType, _power) {
|
|
184
|
+
Platform.origin = {
|
|
185
|
+
createCanvas(width, height) {
|
|
186
|
+
const canvas = document.createElement('canvas');
|
|
187
|
+
canvas.width = width;
|
|
188
|
+
canvas.height = height;
|
|
189
|
+
return canvas;
|
|
190
|
+
},
|
|
191
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
192
|
+
canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
|
|
193
|
+
canvasSaveAs: (canvas, filename, quality) => {
|
|
194
|
+
const url = canvas.toDataURL(mineType(fileType(filename)), quality);
|
|
195
|
+
return Platform.origin.download(url, filename);
|
|
196
|
+
},
|
|
197
|
+
download(url, filename) {
|
|
198
|
+
return new Promise((resolve) => {
|
|
199
|
+
let el = document.createElement('a');
|
|
200
|
+
el.href = url;
|
|
201
|
+
el.download = filename;
|
|
202
|
+
document.body.appendChild(el);
|
|
203
|
+
el.click();
|
|
204
|
+
document.body.removeChild(el);
|
|
205
|
+
resolve();
|
|
206
|
+
});
|
|
207
|
+
},
|
|
208
|
+
loadImage(src) {
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
const img = new Image();
|
|
211
|
+
const { crossOrigin } = Platform.image;
|
|
212
|
+
if (crossOrigin) {
|
|
213
|
+
img.setAttribute('crossOrigin', crossOrigin);
|
|
214
|
+
img.crossOrigin = crossOrigin;
|
|
215
|
+
}
|
|
216
|
+
img.onload = () => { resolve(img); };
|
|
217
|
+
img.onerror = (e) => { reject(e); };
|
|
218
|
+
img.src = Platform.image.getRealURL(src);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
Platform.event = {
|
|
223
|
+
stopDefault(origin) { origin.preventDefault(); },
|
|
224
|
+
stopNow(origin) { origin.stopImmediatePropagation(); },
|
|
225
|
+
stop(origin) { origin.stopPropagation(); }
|
|
226
|
+
};
|
|
227
|
+
Platform.canvas = Creator.canvas();
|
|
228
|
+
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
229
|
+
}
|
|
230
|
+
Platform.name = 'web';
|
|
231
|
+
Platform.isMobile = 'ontouchstart' in window;
|
|
232
|
+
Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
|
|
233
|
+
Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
|
|
234
|
+
const { userAgent } = navigator;
|
|
235
|
+
if (userAgent.indexOf("Firefox") > -1) {
|
|
236
|
+
Platform.conicGradientRotate90 = true;
|
|
237
|
+
Platform.intWheelDeltaY = true;
|
|
238
|
+
Platform.syncDomFont = true;
|
|
239
|
+
}
|
|
240
|
+
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
241
|
+
Platform.fullImageShadow = true;
|
|
242
|
+
}
|
|
243
|
+
if (userAgent.indexOf('Windows') > -1) {
|
|
244
|
+
Platform.os = 'Windows';
|
|
245
|
+
Platform.intWheelDeltaY = true;
|
|
246
|
+
}
|
|
247
|
+
else if (userAgent.indexOf('Mac') > -1) {
|
|
248
|
+
Platform.os = 'Mac';
|
|
249
|
+
}
|
|
250
|
+
else if (userAgent.indexOf('Linux') > -1) {
|
|
251
|
+
Platform.os = 'Linux';
|
|
252
|
+
}
|
|
6
253
|
|
|
7
254
|
class Watcher {
|
|
8
255
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -302,9 +549,11 @@ class Layouter {
|
|
|
302
549
|
updateAllChange(target);
|
|
303
550
|
}
|
|
304
551
|
addExtra(leaf) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
552
|
+
if (!this.__updatedList.has(leaf)) {
|
|
553
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
554
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
555
|
+
updatedList.add(leaf);
|
|
556
|
+
}
|
|
308
557
|
}
|
|
309
558
|
createBlock(data) {
|
|
310
559
|
return new LayoutBlockData(data);
|
|
@@ -414,6 +663,10 @@ class Renderer {
|
|
|
414
663
|
}
|
|
415
664
|
else {
|
|
416
665
|
this.requestLayout();
|
|
666
|
+
if (this.ignore) {
|
|
667
|
+
this.ignore = this.rendering = false;
|
|
668
|
+
return;
|
|
669
|
+
}
|
|
417
670
|
this.emitRender(RenderEvent.BEFORE);
|
|
418
671
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
419
672
|
this.partRender();
|
|
@@ -450,7 +703,7 @@ class Renderer {
|
|
|
450
703
|
canvas.clear();
|
|
451
704
|
}
|
|
452
705
|
else {
|
|
453
|
-
bounds.spread(
|
|
706
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
454
707
|
canvas.clearWorld(bounds, true);
|
|
455
708
|
canvas.clipWorld(bounds, true);
|
|
456
709
|
}
|
|
@@ -503,12 +756,12 @@ class Renderer {
|
|
|
503
756
|
const startTime = Date.now();
|
|
504
757
|
Platform.requestRender(() => {
|
|
505
758
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
506
|
-
if (this.
|
|
507
|
-
|
|
759
|
+
if (this.running) {
|
|
760
|
+
this.target.emit(AnimateEvent.FRAME);
|
|
761
|
+
if (this.changed && this.canvas.view)
|
|
508
762
|
this.render();
|
|
763
|
+
this.target.emit(RenderEvent.NEXT);
|
|
509
764
|
}
|
|
510
|
-
if (this.running)
|
|
511
|
-
this.target.emit(AnimateEvent.FRAME);
|
|
512
765
|
if (this.target)
|
|
513
766
|
this.__requestRender();
|
|
514
767
|
});
|
|
@@ -521,9 +774,12 @@ class Renderer {
|
|
|
521
774
|
const bounds = new Bounds(0, 0, width, height);
|
|
522
775
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
523
776
|
this.addBlock(this.canvas.bounds);
|
|
524
|
-
this.target.forceUpdate('
|
|
777
|
+
this.target.forceUpdate('surface');
|
|
778
|
+
return;
|
|
525
779
|
}
|
|
526
780
|
}
|
|
781
|
+
this.addBlock(new Bounds(0, 0, 1, 1));
|
|
782
|
+
this.changed = true;
|
|
527
783
|
}
|
|
528
784
|
__onLayoutEnd(event) {
|
|
529
785
|
if (event.data)
|
|
@@ -561,23 +817,13 @@ class Renderer {
|
|
|
561
817
|
if (this.target) {
|
|
562
818
|
this.stop();
|
|
563
819
|
this.__removeListenEvents();
|
|
564
|
-
this.target = null;
|
|
565
|
-
this.canvas = null;
|
|
566
|
-
this.config = null;
|
|
820
|
+
this.target = this.canvas = this.config = null;
|
|
567
821
|
}
|
|
568
822
|
}
|
|
569
823
|
}
|
|
570
824
|
|
|
571
|
-
var AnswerType;
|
|
572
|
-
(function (AnswerType) {
|
|
573
|
-
AnswerType[AnswerType["No"] = 0] = "No";
|
|
574
|
-
AnswerType[AnswerType["Yes"] = 1] = "Yes";
|
|
575
|
-
AnswerType[AnswerType["NoAndSkip"] = 2] = "NoAndSkip";
|
|
576
|
-
AnswerType[AnswerType["YesAndSkip"] = 3] = "YesAndSkip";
|
|
577
|
-
})(AnswerType || (AnswerType = {}));
|
|
578
|
-
|
|
579
825
|
const { hitRadiusPoint } = BoundsHelper;
|
|
580
|
-
class
|
|
826
|
+
class Picker {
|
|
581
827
|
constructor(target, selector) {
|
|
582
828
|
this.target = target;
|
|
583
829
|
this.selector = selector;
|
|
@@ -589,33 +835,41 @@ class Pather {
|
|
|
589
835
|
options = {};
|
|
590
836
|
const through = options.through || false;
|
|
591
837
|
const ignoreHittable = options.ignoreHittable || false;
|
|
838
|
+
const target = options.target || this.target;
|
|
592
839
|
this.exclude = options.exclude || null;
|
|
593
840
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
594
|
-
this.findList =
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const
|
|
841
|
+
this.findList = new LeafList(options.findList);
|
|
842
|
+
if (!options.findList)
|
|
843
|
+
this.hitBranch(target);
|
|
844
|
+
const { list } = this.findList;
|
|
845
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
598
846
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
599
847
|
this.clear();
|
|
600
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
848
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
601
849
|
}
|
|
602
|
-
getBestMatchLeaf() {
|
|
603
|
-
|
|
604
|
-
if (targets.length > 1) {
|
|
850
|
+
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
851
|
+
if (list.length) {
|
|
605
852
|
let find;
|
|
606
|
-
this.findList =
|
|
853
|
+
this.findList = new LeafList();
|
|
607
854
|
const { x, y } = this.point;
|
|
608
855
|
const point = { x, y, radiusX: 0, radiusY: 0 };
|
|
609
|
-
for (let i = 0, len =
|
|
610
|
-
find =
|
|
611
|
-
if (LeafHelper.worldHittable(find)) {
|
|
856
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
857
|
+
find = list[i];
|
|
858
|
+
if (ignoreHittable || LeafHelper.worldHittable(find)) {
|
|
612
859
|
this.hitChild(find, point);
|
|
613
860
|
if (this.findList.length)
|
|
614
|
-
return this.findList[0];
|
|
861
|
+
return this.findList.list[0];
|
|
615
862
|
}
|
|
616
863
|
}
|
|
617
864
|
}
|
|
618
|
-
|
|
865
|
+
if (bottomList) {
|
|
866
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
867
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
868
|
+
if (this.findList.length)
|
|
869
|
+
return this.findList.list[0];
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return list[0];
|
|
619
873
|
}
|
|
620
874
|
getPath(leaf) {
|
|
621
875
|
const path = new LeafList();
|
|
@@ -627,7 +881,7 @@ class Pather {
|
|
|
627
881
|
return path;
|
|
628
882
|
}
|
|
629
883
|
getHitablePath(leaf) {
|
|
630
|
-
const path = this.getPath(leaf);
|
|
884
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
631
885
|
let item, hittablePath = new LeafList();
|
|
632
886
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
633
887
|
item = path.list[i];
|
|
@@ -657,12 +911,15 @@ class Pather {
|
|
|
657
911
|
}
|
|
658
912
|
return throughPath;
|
|
659
913
|
}
|
|
914
|
+
hitBranch(branch) {
|
|
915
|
+
this.eachFind(branch.children, branch.__onlyHitMask);
|
|
916
|
+
}
|
|
660
917
|
eachFind(children, hitMask) {
|
|
661
918
|
let child, hit;
|
|
662
919
|
const { point } = this, len = children.length;
|
|
663
920
|
for (let i = len - 1; i > -1; i--) {
|
|
664
921
|
child = children[i];
|
|
665
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
922
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
666
923
|
continue;
|
|
667
924
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
668
925
|
if (child.isBranch) {
|
|
@@ -678,11 +935,15 @@ class Pather {
|
|
|
678
935
|
}
|
|
679
936
|
}
|
|
680
937
|
}
|
|
681
|
-
hitChild(child, point) {
|
|
938
|
+
hitChild(child, point, proxy) {
|
|
682
939
|
if (this.exclude && this.exclude.has(child))
|
|
683
940
|
return;
|
|
684
|
-
if (child.__hitWorld(point))
|
|
685
|
-
|
|
941
|
+
if (child.__hitWorld(point)) {
|
|
942
|
+
const { parent } = child;
|
|
943
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
|
|
944
|
+
return;
|
|
945
|
+
this.findList.add(proxy || child);
|
|
946
|
+
}
|
|
686
947
|
}
|
|
687
948
|
clear() {
|
|
688
949
|
this.point = null;
|
|
@@ -694,7 +955,8 @@ class Pather {
|
|
|
694
955
|
}
|
|
695
956
|
}
|
|
696
957
|
|
|
697
|
-
const { Yes, NoAndSkip, YesAndSkip } =
|
|
958
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer;
|
|
959
|
+
const idCondition = {}, classNameCondition = {}, tagCondition = {};
|
|
698
960
|
class Selector {
|
|
699
961
|
constructor(target, userConfig) {
|
|
700
962
|
this.config = {};
|
|
@@ -704,12 +966,13 @@ class Selector {
|
|
|
704
966
|
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
705
967
|
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
706
968
|
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
707
|
-
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
969
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
|
|
970
|
+
tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
708
971
|
};
|
|
709
972
|
this.target = target;
|
|
710
973
|
if (userConfig)
|
|
711
974
|
this.config = DataHelper.default(userConfig, this.config);
|
|
712
|
-
this.
|
|
975
|
+
this.picker = new Picker(target, this);
|
|
713
976
|
this.__listenEvents();
|
|
714
977
|
}
|
|
715
978
|
getBy(condition, branch, one, options) {
|
|
@@ -720,12 +983,25 @@ class Selector {
|
|
|
720
983
|
case 'string':
|
|
721
984
|
switch (condition[0]) {
|
|
722
985
|
case '#':
|
|
723
|
-
|
|
724
|
-
|
|
986
|
+
idCondition.id = condition.substring(1), condition = idCondition;
|
|
987
|
+
break;
|
|
725
988
|
case '.':
|
|
726
|
-
|
|
989
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition;
|
|
990
|
+
break;
|
|
727
991
|
default:
|
|
728
|
-
|
|
992
|
+
tagCondition.tag = condition, condition = tagCondition;
|
|
993
|
+
}
|
|
994
|
+
case 'object':
|
|
995
|
+
if (condition.id !== undefined) {
|
|
996
|
+
const leaf = this.getById(condition.id, branch);
|
|
997
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
998
|
+
}
|
|
999
|
+
else if (condition.tag) {
|
|
1000
|
+
const { tag } = condition, isArray = tag instanceof Array;
|
|
1001
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
|
|
1002
|
+
}
|
|
1003
|
+
else {
|
|
1004
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className);
|
|
729
1005
|
}
|
|
730
1006
|
case 'function':
|
|
731
1007
|
return this.getByMethod(condition, branch, one, options);
|
|
@@ -734,7 +1010,7 @@ class Selector {
|
|
|
734
1010
|
getByPoint(hitPoint, hitRadius, options) {
|
|
735
1011
|
if (Platform.name === 'node')
|
|
736
1012
|
this.target.emit(LayoutEvent.CHECK_UPDATE);
|
|
737
|
-
return this.
|
|
1013
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
738
1014
|
}
|
|
739
1015
|
getByInnerId(innerId, branch) {
|
|
740
1016
|
const cache = this.innerIdMap[innerId];
|
|
@@ -810,7 +1086,7 @@ class Selector {
|
|
|
810
1086
|
destroy() {
|
|
811
1087
|
if (this.__eventIds.length) {
|
|
812
1088
|
this.__removeListenEvents();
|
|
813
|
-
this.
|
|
1089
|
+
this.picker.destroy();
|
|
814
1090
|
this.findLeaf = null;
|
|
815
1091
|
this.innerIdMap = {};
|
|
816
1092
|
this.idMap = {};
|
|
@@ -826,179 +1102,15 @@ Object.assign(Creator, {
|
|
|
826
1102
|
});
|
|
827
1103
|
Platform.layout = Layouter.fullLayout;
|
|
828
1104
|
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (Platform.syncDomFont && !this.parentView) {
|
|
839
|
-
this.view.style.display = 'none';
|
|
840
|
-
document.body.appendChild(this.view);
|
|
841
|
-
}
|
|
842
|
-
this.__createContext();
|
|
843
|
-
if (!this.autoLayout)
|
|
844
|
-
this.resize(this.config);
|
|
845
|
-
}
|
|
846
|
-
set backgroundColor(color) { this.view.style.backgroundColor = color; }
|
|
847
|
-
get backgroundColor() { return this.view.style.backgroundColor; }
|
|
848
|
-
set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
|
|
849
|
-
get hittable() { return this.view.style.pointerEvents !== 'none'; }
|
|
850
|
-
__createView() {
|
|
851
|
-
this.view = document.createElement('canvas');
|
|
852
|
-
}
|
|
853
|
-
setCursor(cursor) {
|
|
854
|
-
const list = [];
|
|
855
|
-
this.eachCursor(cursor, list);
|
|
856
|
-
if (typeof list[list.length - 1] === 'object')
|
|
857
|
-
list.push('default');
|
|
858
|
-
this.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
|
|
859
|
-
}
|
|
860
|
-
eachCursor(cursor, list, level = 0) {
|
|
861
|
-
level++;
|
|
862
|
-
if (cursor instanceof Array) {
|
|
863
|
-
cursor.forEach(item => this.eachCursor(item, list, level));
|
|
864
|
-
}
|
|
865
|
-
else {
|
|
866
|
-
const custom = typeof cursor === 'string' && Cursor.get(cursor);
|
|
867
|
-
if (custom && level < 2) {
|
|
868
|
-
this.eachCursor(custom, list, level);
|
|
869
|
-
}
|
|
870
|
-
else {
|
|
871
|
-
list.push(cursor);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
__createViewFrom(inputView) {
|
|
876
|
-
let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
|
|
877
|
-
if (find) {
|
|
878
|
-
if (find instanceof HTMLCanvasElement) {
|
|
879
|
-
this.view = find;
|
|
880
|
-
}
|
|
881
|
-
else {
|
|
882
|
-
let parent = find;
|
|
883
|
-
if (find === window || find === document) {
|
|
884
|
-
const div = document.createElement('div');
|
|
885
|
-
const { style } = div;
|
|
886
|
-
style.position = 'absolute';
|
|
887
|
-
style.top = style.bottom = style.left = style.right = '0px';
|
|
888
|
-
document.body.appendChild(div);
|
|
889
|
-
parent = div;
|
|
890
|
-
}
|
|
891
|
-
this.__createView();
|
|
892
|
-
const view = this.view;
|
|
893
|
-
if (parent.hasChildNodes()) {
|
|
894
|
-
const { style } = view;
|
|
895
|
-
style.position = 'absolute';
|
|
896
|
-
style.top = style.left = '0px';
|
|
897
|
-
parent.style.position || (parent.style.position = 'relative');
|
|
898
|
-
}
|
|
899
|
-
parent.appendChild(view);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
else {
|
|
903
|
-
debug.error(`no id: ${inputView}`);
|
|
904
|
-
this.__createView();
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
updateViewSize() {
|
|
908
|
-
const { width, height, pixelRatio } = this;
|
|
909
|
-
const { style } = this.view;
|
|
910
|
-
style.width = width + 'px';
|
|
911
|
-
style.height = height + 'px';
|
|
912
|
-
this.view.width = width * pixelRatio;
|
|
913
|
-
this.view.height = height * pixelRatio;
|
|
914
|
-
}
|
|
915
|
-
updateClientBounds() {
|
|
916
|
-
this.clientBounds = this.view.getBoundingClientRect();
|
|
917
|
-
}
|
|
918
|
-
startAutoLayout(autoBounds, listener) {
|
|
919
|
-
this.autoBounds = autoBounds;
|
|
920
|
-
this.resizeListener = listener;
|
|
921
|
-
try {
|
|
922
|
-
this.resizeObserver = new ResizeObserver((entries) => {
|
|
923
|
-
this.updateClientBounds();
|
|
924
|
-
for (const entry of entries)
|
|
925
|
-
this.checkAutoBounds(entry.contentRect);
|
|
926
|
-
});
|
|
927
|
-
const parent = this.parentView;
|
|
928
|
-
if (parent) {
|
|
929
|
-
this.resizeObserver.observe(parent);
|
|
930
|
-
this.checkAutoBounds(parent.getBoundingClientRect());
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
catch (_a) {
|
|
934
|
-
this.imitateResizeObserver();
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
imitateResizeObserver() {
|
|
938
|
-
if (this.autoLayout) {
|
|
939
|
-
if (this.parentView)
|
|
940
|
-
this.checkAutoBounds(this.parentView.getBoundingClientRect());
|
|
941
|
-
Platform.requestRender(this.imitateResizeObserver.bind(this));
|
|
942
|
-
}
|
|
943
|
-
}
|
|
944
|
-
checkAutoBounds(parentSize) {
|
|
945
|
-
const view = this.view;
|
|
946
|
-
const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
|
|
947
|
-
if (width !== this.width || height !== this.height) {
|
|
948
|
-
const { style } = view;
|
|
949
|
-
const { pixelRatio } = this;
|
|
950
|
-
style.marginLeft = x + 'px';
|
|
951
|
-
style.marginTop = y + 'px';
|
|
952
|
-
const size = { width, height, pixelRatio };
|
|
953
|
-
const oldSize = {};
|
|
954
|
-
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
955
|
-
this.resize(size);
|
|
956
|
-
if (this.width !== undefined)
|
|
957
|
-
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
stopAutoLayout() {
|
|
961
|
-
this.autoLayout = false;
|
|
962
|
-
this.resizeListener = null;
|
|
963
|
-
if (this.resizeObserver) {
|
|
964
|
-
this.resizeObserver.disconnect();
|
|
965
|
-
this.resizeObserver = null;
|
|
966
|
-
}
|
|
967
|
-
}
|
|
968
|
-
unrealCanvas() {
|
|
969
|
-
if (!this.unreal && this.parentView) {
|
|
970
|
-
const view = this.view;
|
|
971
|
-
if (view)
|
|
972
|
-
view.remove();
|
|
973
|
-
this.view = this.parentView;
|
|
974
|
-
this.unreal = true;
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
destroy() {
|
|
978
|
-
if (this.view) {
|
|
979
|
-
this.stopAutoLayout();
|
|
980
|
-
if (!this.unreal) {
|
|
981
|
-
const view = this.view;
|
|
982
|
-
if (view.parentElement)
|
|
983
|
-
view.remove();
|
|
984
|
-
}
|
|
985
|
-
super.destroy();
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
canvasPatch(CanvasRenderingContext2D.prototype);
|
|
991
|
-
canvasPatch(Path2D.prototype);
|
|
992
|
-
|
|
993
|
-
const PointerEventHelper = {
|
|
994
|
-
convert(e, local) {
|
|
995
|
-
const base = InteractionHelper.getBase(e);
|
|
996
|
-
const data = Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: e.width, height: e.height, pointerType: e.pointerType, pressure: e.pressure });
|
|
997
|
-
if (data.pointerType === 'pen') {
|
|
998
|
-
data.tangentialPressure = e.tangentialPressure;
|
|
999
|
-
data.tiltX = e.tiltX;
|
|
1000
|
-
data.tiltY = e.tiltY;
|
|
1001
|
-
data.twist = e.twist;
|
|
1105
|
+
const PointerEventHelper = {
|
|
1106
|
+
convert(e, local) {
|
|
1107
|
+
const base = InteractionHelper.getBase(e);
|
|
1108
|
+
const data = Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: e.width, height: e.height, pointerType: e.pointerType, pressure: e.pressure });
|
|
1109
|
+
if (data.pointerType === 'pen') {
|
|
1110
|
+
data.tangentialPressure = e.tangentialPressure;
|
|
1111
|
+
data.tiltX = e.tiltX;
|
|
1112
|
+
data.tiltY = e.tiltY;
|
|
1113
|
+
data.twist = e.twist;
|
|
1002
1114
|
}
|
|
1003
1115
|
return data;
|
|
1004
1116
|
},
|
|
@@ -1046,7 +1158,7 @@ const WheelEventHelper = {
|
|
|
1046
1158
|
if (zoom) {
|
|
1047
1159
|
zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
|
|
1048
1160
|
const min = e.deltaY ? config.delta.y : config.delta.x;
|
|
1049
|
-
scale = 1 - delta / (min *
|
|
1161
|
+
scale = 1 - delta / (min * 4) * zoomSpeed;
|
|
1050
1162
|
if (scale < 0.5)
|
|
1051
1163
|
scale = 0.5;
|
|
1052
1164
|
if (scale >= 1.5)
|
|
@@ -1114,12 +1226,6 @@ class Interaction extends InteractionBase {
|
|
|
1114
1226
|
this.windowEvents = {};
|
|
1115
1227
|
}
|
|
1116
1228
|
}
|
|
1117
|
-
getLocal(p, updateClient) {
|
|
1118
|
-
if (updateClient)
|
|
1119
|
-
this.canvas.updateClientBounds();
|
|
1120
|
-
const { clientBounds } = this.canvas;
|
|
1121
|
-
return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
|
|
1122
|
-
}
|
|
1123
1229
|
getTouches(touches) {
|
|
1124
1230
|
const list = [];
|
|
1125
1231
|
for (let i = 0, len = touches.length; i < len; i++) {
|
|
@@ -1147,6 +1253,8 @@ class Interaction extends InteractionBase {
|
|
|
1147
1253
|
this.keyUp(KeyEventHelper.convert(e));
|
|
1148
1254
|
}
|
|
1149
1255
|
onContextMenu(e) {
|
|
1256
|
+
if (this.config.pointer.preventDefaultMenu)
|
|
1257
|
+
e.preventDefault();
|
|
1150
1258
|
this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
|
|
1151
1259
|
}
|
|
1152
1260
|
onScroll() {
|
|
@@ -1276,17 +1384,23 @@ class Interaction extends InteractionBase {
|
|
|
1276
1384
|
onWheel(e) {
|
|
1277
1385
|
this.preventDefaultWheel(e);
|
|
1278
1386
|
const { wheel } = this.config;
|
|
1387
|
+
if (wheel.disabled)
|
|
1388
|
+
return;
|
|
1279
1389
|
const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
|
|
1280
1390
|
const local = this.getLocal(e);
|
|
1281
1391
|
const eventBase = InteractionHelper.getBase(e);
|
|
1282
1392
|
scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
|
|
1283
1393
|
}
|
|
1284
1394
|
onGesturestart(e) {
|
|
1395
|
+
if (this.useMultiTouch)
|
|
1396
|
+
return;
|
|
1285
1397
|
this.preventDefaultWheel(e);
|
|
1286
1398
|
this.lastGestureScale = 1;
|
|
1287
1399
|
this.lastGestureRotation = 0;
|
|
1288
1400
|
}
|
|
1289
1401
|
onGesturechange(e) {
|
|
1402
|
+
if (this.useMultiTouch)
|
|
1403
|
+
return;
|
|
1290
1404
|
this.preventDefaultWheel(e);
|
|
1291
1405
|
const local = this.getLocal(e);
|
|
1292
1406
|
const eventBase = InteractionHelper.getBase(e);
|
|
@@ -1300,9 +1414,34 @@ class Interaction extends InteractionBase {
|
|
|
1300
1414
|
this.lastGestureRotation = e.rotation;
|
|
1301
1415
|
}
|
|
1302
1416
|
onGestureend(e) {
|
|
1417
|
+
if (this.useMultiTouch)
|
|
1418
|
+
return;
|
|
1303
1419
|
this.preventDefaultWheel(e);
|
|
1304
1420
|
this.transformEnd();
|
|
1305
1421
|
}
|
|
1422
|
+
setCursor(cursor) {
|
|
1423
|
+
super.setCursor(cursor);
|
|
1424
|
+
const list = [];
|
|
1425
|
+
this.eachCursor(cursor, list);
|
|
1426
|
+
if (typeof list[list.length - 1] === 'object')
|
|
1427
|
+
list.push('default');
|
|
1428
|
+
this.canvas.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
|
|
1429
|
+
}
|
|
1430
|
+
eachCursor(cursor, list, level = 0) {
|
|
1431
|
+
level++;
|
|
1432
|
+
if (cursor instanceof Array) {
|
|
1433
|
+
cursor.forEach(item => this.eachCursor(item, list, level));
|
|
1434
|
+
}
|
|
1435
|
+
else {
|
|
1436
|
+
const custom = typeof cursor === 'string' && Cursor.get(cursor);
|
|
1437
|
+
if (custom && level < 2) {
|
|
1438
|
+
this.eachCursor(custom, list, level);
|
|
1439
|
+
}
|
|
1440
|
+
else {
|
|
1441
|
+
list.push(cursor);
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1306
1445
|
destroy() {
|
|
1307
1446
|
if (this.view) {
|
|
1308
1447
|
super.destroy();
|
|
@@ -1312,165 +1451,428 @@ class Interaction extends InteractionBase {
|
|
|
1312
1451
|
}
|
|
1313
1452
|
}
|
|
1314
1453
|
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
canvas.width = width;
|
|
1327
|
-
canvas.height = height;
|
|
1328
|
-
return canvas;
|
|
1329
|
-
},
|
|
1330
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
1331
|
-
canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
|
|
1332
|
-
canvasSaveAs: (canvas, filename, quality) => {
|
|
1333
|
-
return new Promise((resolve) => {
|
|
1334
|
-
let el = document.createElement('a');
|
|
1335
|
-
el.href = canvas.toDataURL(mineType(fileType(filename)), quality);
|
|
1336
|
-
el.download = filename;
|
|
1337
|
-
document.body.appendChild(el);
|
|
1338
|
-
el.click();
|
|
1339
|
-
document.body.removeChild(el);
|
|
1340
|
-
resolve();
|
|
1341
|
-
});
|
|
1342
|
-
},
|
|
1343
|
-
loadImage(src) {
|
|
1344
|
-
return new Promise((resolve, reject) => {
|
|
1345
|
-
const img = new Image();
|
|
1346
|
-
img.setAttribute('crossOrigin', 'anonymous');
|
|
1347
|
-
img.crossOrigin = 'anonymous';
|
|
1348
|
-
img.onload = () => { resolve(img); };
|
|
1349
|
-
img.onerror = (e) => { reject(e); };
|
|
1350
|
-
if (!src.startsWith('data:') && Platform.image.suffix)
|
|
1351
|
-
src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
|
|
1352
|
-
img.src = src;
|
|
1454
|
+
function fillText(ui, canvas) {
|
|
1455
|
+
let row;
|
|
1456
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1457
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1458
|
+
row = rows[i];
|
|
1459
|
+
if (row.text) {
|
|
1460
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
1461
|
+
}
|
|
1462
|
+
else if (row.data) {
|
|
1463
|
+
row.data.forEach(charData => {
|
|
1464
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
1353
1465
|
});
|
|
1354
1466
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
stopNow(origin) { origin.stopImmediatePropagation(); },
|
|
1359
|
-
stop(origin) { origin.stopPropagation(); }
|
|
1360
|
-
};
|
|
1361
|
-
Platform.canvas = Creator.canvas();
|
|
1362
|
-
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
1363
|
-
}
|
|
1364
|
-
Platform.name = 'web';
|
|
1365
|
-
Platform.isMobile = 'ontouchstart' in window;
|
|
1366
|
-
Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
|
|
1367
|
-
Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
|
|
1368
|
-
const { userAgent } = navigator;
|
|
1369
|
-
if (userAgent.indexOf("Firefox") > -1) {
|
|
1370
|
-
Platform.conicGradientRotate90 = true;
|
|
1371
|
-
Platform.intWheelDeltaY = true;
|
|
1372
|
-
Platform.syncDomFont = true;
|
|
1373
|
-
}
|
|
1374
|
-
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
1375
|
-
Platform.fullImageShadow = true;
|
|
1376
|
-
}
|
|
1377
|
-
if (userAgent.indexOf('Windows') > -1) {
|
|
1378
|
-
Platform.os = 'Windows';
|
|
1379
|
-
Platform.intWheelDeltaY = true;
|
|
1380
|
-
}
|
|
1381
|
-
else if (userAgent.indexOf('Mac') > -1) {
|
|
1382
|
-
Platform.os = 'Mac';
|
|
1383
|
-
}
|
|
1384
|
-
else if (userAgent.indexOf('Linux') > -1) {
|
|
1385
|
-
Platform.os = 'Linux';
|
|
1467
|
+
if (decorationY)
|
|
1468
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1469
|
+
}
|
|
1386
1470
|
}
|
|
1387
1471
|
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
const swap = rotation && rotation !== 180;
|
|
1392
|
-
const sw = box.width / (swap ? height : width);
|
|
1393
|
-
const sh = box.height / (swap ? width : height);
|
|
1394
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1395
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
1396
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
1397
|
-
translate$1(transform, x, y);
|
|
1398
|
-
scaleHelper(transform, scale);
|
|
1399
|
-
if (rotation)
|
|
1400
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1401
|
-
data.scaleX = data.scaleY = scale;
|
|
1402
|
-
data.transform = transform;
|
|
1472
|
+
function fill(fill, ui, canvas) {
|
|
1473
|
+
canvas.fillStyle = fill;
|
|
1474
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1403
1475
|
}
|
|
1404
|
-
function
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1476
|
+
function fills(fills, ui, canvas) {
|
|
1477
|
+
let item;
|
|
1478
|
+
const { windingRule, __font } = ui.__;
|
|
1479
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1480
|
+
item = fills[i];
|
|
1481
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
1482
|
+
continue;
|
|
1483
|
+
if (item.style) {
|
|
1484
|
+
canvas.fillStyle = item.style;
|
|
1485
|
+
if (item.transform) {
|
|
1486
|
+
canvas.save();
|
|
1487
|
+
canvas.transform(item.transform);
|
|
1488
|
+
if (item.blendMode)
|
|
1489
|
+
canvas.blendMode = item.blendMode;
|
|
1490
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1491
|
+
canvas.restore();
|
|
1492
|
+
}
|
|
1493
|
+
else {
|
|
1494
|
+
if (item.blendMode) {
|
|
1495
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1496
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1497
|
+
canvas.restoreBlendMode();
|
|
1498
|
+
}
|
|
1499
|
+
else {
|
|
1500
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1417
1505
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1506
|
+
|
|
1507
|
+
function strokeText(stroke, ui, canvas) {
|
|
1508
|
+
const { strokeAlign } = ui.__;
|
|
1509
|
+
const isStrokes = typeof stroke !== 'string';
|
|
1510
|
+
switch (strokeAlign) {
|
|
1511
|
+
case 'center':
|
|
1512
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1513
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1514
|
+
break;
|
|
1515
|
+
case 'inside':
|
|
1516
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1517
|
+
break;
|
|
1518
|
+
case 'outside':
|
|
1519
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1520
|
+
break;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1524
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1525
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1526
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1527
|
+
out.font = __font;
|
|
1528
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1529
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1530
|
+
fillText(ui, out);
|
|
1531
|
+
out.blendMode = 'normal';
|
|
1532
|
+
if (ui.__worldFlipped) {
|
|
1533
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1534
|
+
}
|
|
1535
|
+
else {
|
|
1536
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1537
|
+
}
|
|
1538
|
+
out.recycle(ui.__nowWorld);
|
|
1539
|
+
}
|
|
1540
|
+
function drawTextStroke(ui, canvas) {
|
|
1541
|
+
let row;
|
|
1542
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1543
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1544
|
+
row = rows[i];
|
|
1545
|
+
if (row.text) {
|
|
1546
|
+
canvas.strokeText(row.text, row.x, row.y);
|
|
1547
|
+
}
|
|
1548
|
+
else if (row.data) {
|
|
1549
|
+
row.data.forEach(charData => {
|
|
1550
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1551
|
+
});
|
|
1552
|
+
}
|
|
1553
|
+
if (decorationY)
|
|
1554
|
+
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1555
|
+
}
|
|
1556
|
+
}
|
|
1557
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1558
|
+
let item;
|
|
1559
|
+
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1560
|
+
item = strokes[i];
|
|
1561
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1562
|
+
continue;
|
|
1563
|
+
if (item.style) {
|
|
1564
|
+
canvas.strokeStyle = item.style;
|
|
1565
|
+
if (item.blendMode) {
|
|
1566
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1567
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1568
|
+
canvas.restoreBlendMode();
|
|
1569
|
+
}
|
|
1570
|
+
else {
|
|
1571
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
function stroke(stroke, ui, canvas) {
|
|
1578
|
+
const options = ui.__;
|
|
1579
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1580
|
+
if (!__strokeWidth)
|
|
1581
|
+
return;
|
|
1582
|
+
if (__font) {
|
|
1583
|
+
strokeText(stroke, ui, canvas);
|
|
1584
|
+
}
|
|
1585
|
+
else {
|
|
1586
|
+
switch (strokeAlign) {
|
|
1587
|
+
case 'center':
|
|
1588
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1589
|
+
canvas.stroke();
|
|
1590
|
+
break;
|
|
1591
|
+
case 'inside':
|
|
1592
|
+
canvas.save();
|
|
1593
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1594
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1595
|
+
canvas.stroke();
|
|
1596
|
+
canvas.restore();
|
|
1597
|
+
break;
|
|
1598
|
+
case 'outside':
|
|
1599
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1600
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1601
|
+
ui.__drawRenderPath(out);
|
|
1602
|
+
out.stroke();
|
|
1603
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1604
|
+
out.clearWorld(ui.__layout.renderBounds);
|
|
1605
|
+
if (ui.__worldFlipped) {
|
|
1606
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1607
|
+
}
|
|
1608
|
+
else {
|
|
1609
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1610
|
+
}
|
|
1611
|
+
out.recycle(ui.__nowWorld);
|
|
1425
1612
|
break;
|
|
1426
|
-
|
|
1427
|
-
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
function strokes(strokes, ui, canvas) {
|
|
1617
|
+
const options = ui.__;
|
|
1618
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1619
|
+
if (!__strokeWidth)
|
|
1620
|
+
return;
|
|
1621
|
+
if (__font) {
|
|
1622
|
+
strokeText(strokes, ui, canvas);
|
|
1623
|
+
}
|
|
1624
|
+
else {
|
|
1625
|
+
switch (strokeAlign) {
|
|
1626
|
+
case 'center':
|
|
1627
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1628
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1428
1629
|
break;
|
|
1429
|
-
case
|
|
1430
|
-
|
|
1630
|
+
case 'inside':
|
|
1631
|
+
canvas.save();
|
|
1632
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1633
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1634
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1635
|
+
canvas.restore();
|
|
1636
|
+
break;
|
|
1637
|
+
case 'outside':
|
|
1638
|
+
const { renderBounds } = ui.__layout;
|
|
1639
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1640
|
+
ui.__drawRenderPath(out);
|
|
1641
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1642
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1643
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1644
|
+
out.clearWorld(renderBounds);
|
|
1645
|
+
if (ui.__worldFlipped) {
|
|
1646
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1647
|
+
}
|
|
1648
|
+
else {
|
|
1649
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1650
|
+
}
|
|
1651
|
+
out.recycle(ui.__nowWorld);
|
|
1431
1652
|
break;
|
|
1432
1653
|
}
|
|
1433
1654
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1658
|
+
function shape(ui, current, options) {
|
|
1659
|
+
const canvas = current.getSameCanvas();
|
|
1660
|
+
const nowWorld = ui.__nowWorld;
|
|
1661
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1662
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1663
|
+
if (scaleX < 0)
|
|
1664
|
+
scaleX = -scaleX;
|
|
1665
|
+
if (scaleY < 0)
|
|
1666
|
+
scaleY = -scaleY;
|
|
1667
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1668
|
+
worldCanvas = canvas;
|
|
1669
|
+
bounds = shapeBounds = nowWorld;
|
|
1670
|
+
}
|
|
1671
|
+
else {
|
|
1672
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1673
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1674
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1675
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1676
|
+
if (fitMatrix.a < 1) {
|
|
1677
|
+
worldCanvas = current.getSameCanvas();
|
|
1678
|
+
ui.__renderShape(worldCanvas, options);
|
|
1679
|
+
scaleX *= fitScaleX;
|
|
1680
|
+
scaleY *= fitScaleY;
|
|
1681
|
+
}
|
|
1682
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1683
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1684
|
+
if (options.matrix) {
|
|
1685
|
+
const { matrix } = options;
|
|
1686
|
+
fitMatrix.multiply(matrix);
|
|
1687
|
+
fitScaleX *= matrix.scaleX;
|
|
1688
|
+
fitScaleY *= matrix.scaleY;
|
|
1689
|
+
}
|
|
1690
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1691
|
+
}
|
|
1692
|
+
ui.__renderShape(canvas, options);
|
|
1693
|
+
return {
|
|
1694
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1695
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1696
|
+
};
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
let recycleMap;
|
|
1700
|
+
function compute(attrName, ui) {
|
|
1701
|
+
const data = ui.__, leafPaints = [];
|
|
1702
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1703
|
+
if (!(paints instanceof Array))
|
|
1704
|
+
paints = [paints];
|
|
1705
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1706
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1707
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1708
|
+
if (item)
|
|
1709
|
+
leafPaints.push(item);
|
|
1710
|
+
}
|
|
1711
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1712
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1713
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1714
|
+
if (attrName === 'fill') {
|
|
1715
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1716
|
+
}
|
|
1717
|
+
else {
|
|
1718
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1722
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1723
|
+
return undefined;
|
|
1724
|
+
const { boxBounds } = ui.__layout;
|
|
1725
|
+
switch (paint.type) {
|
|
1726
|
+
case 'solid':
|
|
1727
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1728
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1729
|
+
case 'image':
|
|
1730
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1731
|
+
case 'linear':
|
|
1732
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1733
|
+
case 'radial':
|
|
1734
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1735
|
+
case 'angular':
|
|
1736
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1737
|
+
default:
|
|
1738
|
+
return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
const PaintModule = {
|
|
1743
|
+
compute,
|
|
1744
|
+
fill,
|
|
1745
|
+
fills,
|
|
1746
|
+
fillText,
|
|
1747
|
+
stroke,
|
|
1748
|
+
strokes,
|
|
1749
|
+
strokeText,
|
|
1750
|
+
drawTextStroke,
|
|
1751
|
+
shape
|
|
1752
|
+
};
|
|
1753
|
+
|
|
1754
|
+
let origin = {};
|
|
1755
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1756
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1757
|
+
const transform = get$3();
|
|
1758
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1759
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1760
|
+
if (rotation)
|
|
1761
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1762
|
+
data.transform = transform;
|
|
1763
|
+
}
|
|
1764
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1765
|
+
const transform = get$3();
|
|
1766
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1767
|
+
if (scaleX)
|
|
1768
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1769
|
+
if (rotation)
|
|
1770
|
+
rotate(transform, rotation);
|
|
1771
|
+
data.transform = transform;
|
|
1772
|
+
}
|
|
1773
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1774
|
+
const transform = get$3();
|
|
1775
|
+
if (rotation) {
|
|
1776
|
+
if (align === 'center') {
|
|
1777
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1778
|
+
}
|
|
1779
|
+
else {
|
|
1780
|
+
rotate(transform, rotation);
|
|
1781
|
+
switch (rotation) {
|
|
1782
|
+
case 90:
|
|
1783
|
+
translate$1(transform, height, 0);
|
|
1784
|
+
break;
|
|
1785
|
+
case 180:
|
|
1786
|
+
translate$1(transform, width, height);
|
|
1787
|
+
break;
|
|
1788
|
+
case 270:
|
|
1789
|
+
translate$1(transform, 0, width);
|
|
1790
|
+
break;
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1438
1793
|
}
|
|
1794
|
+
origin.x = box.x + x;
|
|
1795
|
+
origin.y = box.y + y;
|
|
1796
|
+
translate$1(transform, origin.x, origin.y);
|
|
1797
|
+
if (scaleX)
|
|
1798
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1439
1799
|
data.transform = transform;
|
|
1440
1800
|
}
|
|
1441
1801
|
|
|
1442
|
-
const { get: get$
|
|
1802
|
+
const { get: get$2, translate } = MatrixHelper;
|
|
1803
|
+
const tempBox = new Bounds();
|
|
1804
|
+
const tempPoint = {};
|
|
1443
1805
|
function createData(leafPaint, image, paint, box) {
|
|
1444
|
-
|
|
1445
|
-
const { opacity, mode, offset, scale, rotation, blendMode, repeat } = paint;
|
|
1446
|
-
const sameBox = box.width === width && box.height === height;
|
|
1806
|
+
const { blendMode } = paint;
|
|
1447
1807
|
if (blendMode)
|
|
1448
1808
|
leafPaint.blendMode = blendMode;
|
|
1449
|
-
|
|
1809
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1810
|
+
}
|
|
1811
|
+
function getPatternData(paint, box, image) {
|
|
1812
|
+
let { width, height } = image;
|
|
1813
|
+
if (paint.padding)
|
|
1814
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1815
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1816
|
+
const sameBox = box.width === width && box.height === height;
|
|
1817
|
+
const data = { mode };
|
|
1818
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1819
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1820
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1821
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1822
|
+
if (!sameBox || rotation) {
|
|
1823
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1824
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1825
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
else if (size) {
|
|
1829
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1830
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1831
|
+
}
|
|
1832
|
+
else if (scale) {
|
|
1833
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1834
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1835
|
+
}
|
|
1836
|
+
if (align) {
|
|
1837
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1838
|
+
if (scaleX)
|
|
1839
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1840
|
+
AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1841
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1842
|
+
}
|
|
1843
|
+
if (offset)
|
|
1844
|
+
x += offset.x, y += offset.y;
|
|
1450
1845
|
switch (mode) {
|
|
1451
1846
|
case 'strench':
|
|
1452
1847
|
if (!sameBox)
|
|
1453
1848
|
width = box.width, height = box.height;
|
|
1454
|
-
if (box.x || box.y) {
|
|
1455
|
-
data.transform = get$3();
|
|
1456
|
-
translate(data.transform, box.x, box.y);
|
|
1457
|
-
}
|
|
1458
1849
|
break;
|
|
1850
|
+
case 'normal':
|
|
1459
1851
|
case 'clip':
|
|
1460
|
-
if (
|
|
1461
|
-
clipMode(data, box,
|
|
1852
|
+
if (x || y || scaleX || rotation)
|
|
1853
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1462
1854
|
break;
|
|
1463
1855
|
case 'repeat':
|
|
1464
|
-
if (!sameBox ||
|
|
1465
|
-
repeatMode(data, box, width, height,
|
|
1856
|
+
if (!sameBox || scaleX || rotation)
|
|
1857
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1466
1858
|
if (!repeat)
|
|
1467
1859
|
data.repeat = 'repeat';
|
|
1468
1860
|
break;
|
|
1469
1861
|
case 'fit':
|
|
1470
1862
|
case 'cover':
|
|
1471
1863
|
default:
|
|
1472
|
-
if (
|
|
1473
|
-
fillOrFitMode(data,
|
|
1864
|
+
if (scaleX)
|
|
1865
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1866
|
+
}
|
|
1867
|
+
if (!data.transform) {
|
|
1868
|
+
if (box.x || box.y) {
|
|
1869
|
+
data.transform = get$2();
|
|
1870
|
+
translate(data.transform, box.x, box.y);
|
|
1871
|
+
}
|
|
1872
|
+
}
|
|
1873
|
+
if (scaleX && mode !== 'strench') {
|
|
1874
|
+
data.scaleX = scaleX;
|
|
1875
|
+
data.scaleY = scaleY;
|
|
1474
1876
|
}
|
|
1475
1877
|
data.width = width;
|
|
1476
1878
|
data.height = height;
|
|
@@ -1478,112 +1880,108 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1478
1880
|
data.opacity = opacity;
|
|
1479
1881
|
if (repeat)
|
|
1480
1882
|
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1883
|
+
return data;
|
|
1481
1884
|
}
|
|
1482
1885
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1886
|
+
let cache, box = new Bounds();
|
|
1887
|
+
const { isSame } = BoundsHelper;
|
|
1888
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1889
|
+
let leafPaint, event;
|
|
1890
|
+
const image = ImageManager.get(paint);
|
|
1891
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1892
|
+
leafPaint = cache.leafPaint;
|
|
1893
|
+
}
|
|
1894
|
+
else {
|
|
1895
|
+
leafPaint = { type: paint.type, image };
|
|
1896
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1897
|
+
}
|
|
1898
|
+
if (firstUse || image.loading)
|
|
1899
|
+
event = { image, attrName, attrValue: paint };
|
|
1487
1900
|
if (image.ready) {
|
|
1488
|
-
|
|
1489
|
-
createData(leafPaint, image, attrValue, box);
|
|
1901
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1490
1902
|
if (firstUse) {
|
|
1491
|
-
|
|
1492
|
-
|
|
1903
|
+
onLoad(ui, event);
|
|
1904
|
+
onLoadSuccess(ui, event);
|
|
1493
1905
|
}
|
|
1494
1906
|
}
|
|
1495
1907
|
else if (image.error) {
|
|
1496
|
-
if (firstUse)
|
|
1497
|
-
ui.
|
|
1498
|
-
event.error = image.error;
|
|
1499
|
-
emit(ImageEvent.ERROR, event);
|
|
1500
|
-
}
|
|
1908
|
+
if (firstUse)
|
|
1909
|
+
onLoadError(ui, event, image.error);
|
|
1501
1910
|
}
|
|
1502
1911
|
else {
|
|
1912
|
+
ignoreRender(ui, true);
|
|
1503
1913
|
if (firstUse)
|
|
1504
|
-
|
|
1914
|
+
onLoad(ui, event);
|
|
1505
1915
|
leafPaint.loadId = image.load(() => {
|
|
1916
|
+
ignoreRender(ui, false);
|
|
1506
1917
|
if (!ui.destroyed) {
|
|
1507
|
-
if (
|
|
1508
|
-
|
|
1918
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1919
|
+
if (image.hasOpacityPixel)
|
|
1920
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1509
1921
|
ui.forceUpdate('surface');
|
|
1510
1922
|
}
|
|
1511
|
-
|
|
1923
|
+
onLoadSuccess(ui, event);
|
|
1512
1924
|
}
|
|
1925
|
+
leafPaint.loadId = null;
|
|
1513
1926
|
}, (error) => {
|
|
1514
|
-
ui
|
|
1515
|
-
event
|
|
1516
|
-
|
|
1927
|
+
ignoreRender(ui, false);
|
|
1928
|
+
onLoadError(ui, event, error);
|
|
1929
|
+
leafPaint.loadId = null;
|
|
1517
1930
|
});
|
|
1518
1931
|
}
|
|
1519
1932
|
return leafPaint;
|
|
1520
1933
|
}
|
|
1521
|
-
function
|
|
1934
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1522
1935
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1523
|
-
const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
if (
|
|
1936
|
+
const data = ui.__;
|
|
1937
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1938
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1939
|
+
if (data.__autoSide) {
|
|
1527
1940
|
ui.forceUpdate('width');
|
|
1528
1941
|
if (ui.__proxyData) {
|
|
1529
|
-
ui.setProxyAttr('width',
|
|
1530
|
-
ui.setProxyAttr('height',
|
|
1942
|
+
ui.setProxyAttr('width', data.width);
|
|
1943
|
+
ui.setProxyAttr('height', data.height);
|
|
1531
1944
|
}
|
|
1532
1945
|
return false;
|
|
1533
1946
|
}
|
|
1534
1947
|
}
|
|
1948
|
+
if (!leafPaint.data)
|
|
1949
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1535
1950
|
return true;
|
|
1536
1951
|
}
|
|
1537
|
-
function
|
|
1538
|
-
|
|
1539
|
-
|
|
1952
|
+
function onLoad(ui, event) {
|
|
1953
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1954
|
+
}
|
|
1955
|
+
function onLoadSuccess(ui, event) {
|
|
1956
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1957
|
+
}
|
|
1958
|
+
function onLoadError(ui, event, error) {
|
|
1959
|
+
event.error = error;
|
|
1960
|
+
ui.forceUpdate('surface');
|
|
1961
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1962
|
+
}
|
|
1963
|
+
function emit(ui, type, data) {
|
|
1964
|
+
if (ui.hasEvent(type))
|
|
1965
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1966
|
+
}
|
|
1967
|
+
function ignoreRender(ui, value) {
|
|
1968
|
+
const { leafer } = ui;
|
|
1969
|
+
if (leafer && leafer.viewReady)
|
|
1970
|
+
leafer.renderer.ignore = value;
|
|
1540
1971
|
}
|
|
1541
1972
|
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1546
|
-
purpose with or without fee is hereby granted.
|
|
1547
|
-
|
|
1548
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1549
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1550
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1551
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1552
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1553
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1554
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1555
|
-
***************************************************************************** */
|
|
1556
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1560
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1561
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1562
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1563
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1564
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1565
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1566
|
-
});
|
|
1567
|
-
}
|
|
1568
|
-
|
|
1569
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1570
|
-
var e = new Error(message);
|
|
1571
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1572
|
-
};
|
|
1573
|
-
|
|
1574
|
-
const Export$1 = {};
|
|
1575
|
-
|
|
1576
|
-
const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
|
|
1973
|
+
const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
|
|
1974
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1577
1975
|
function createPattern(ui, paint, pixelRatio) {
|
|
1578
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1976
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1579
1977
|
const id = scaleX + '-' + scaleY;
|
|
1580
1978
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1581
|
-
scaleX =
|
|
1582
|
-
scaleY =
|
|
1979
|
+
scaleX = abs$1(scaleX);
|
|
1980
|
+
scaleY = abs$1(scaleY);
|
|
1583
1981
|
const { image, data } = paint;
|
|
1584
1982
|
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1585
1983
|
if (sx) {
|
|
1586
|
-
imageMatrix = get$
|
|
1984
|
+
imageMatrix = get$1();
|
|
1587
1985
|
copy$1(imageMatrix, transform);
|
|
1588
1986
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1589
1987
|
scaleX *= sx;
|
|
@@ -1618,22 +2016,14 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1618
2016
|
}
|
|
1619
2017
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1620
2018
|
if (!imageMatrix) {
|
|
1621
|
-
imageMatrix = get$
|
|
2019
|
+
imageMatrix = get$1();
|
|
1622
2020
|
if (transform)
|
|
1623
2021
|
copy$1(imageMatrix, transform);
|
|
1624
2022
|
}
|
|
1625
2023
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1626
2024
|
}
|
|
1627
|
-
const
|
|
1628
|
-
|
|
1629
|
-
if (paint.transform)
|
|
1630
|
-
paint.transform = null;
|
|
1631
|
-
if (imageMatrix)
|
|
1632
|
-
pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
|
|
1633
|
-
}
|
|
1634
|
-
catch (_a) {
|
|
1635
|
-
paint.transform = imageMatrix;
|
|
1636
|
-
}
|
|
2025
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
2026
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1637
2027
|
paint.style = pattern;
|
|
1638
2028
|
paint.patternId = id;
|
|
1639
2029
|
return true;
|
|
@@ -1643,9 +2033,41 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1643
2033
|
}
|
|
1644
2034
|
}
|
|
1645
2035
|
|
|
2036
|
+
/******************************************************************************
|
|
2037
|
+
Copyright (c) Microsoft Corporation.
|
|
2038
|
+
|
|
2039
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
2040
|
+
purpose with or without fee is hereby granted.
|
|
2041
|
+
|
|
2042
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
2043
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
2044
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
2045
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
2046
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
2047
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
2048
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
2049
|
+
***************************************************************************** */
|
|
2050
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
2051
|
+
|
|
2052
|
+
|
|
2053
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
2054
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
2055
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
2056
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
2057
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
2058
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
2059
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
2064
|
+
var e = new Error(message);
|
|
2065
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
2066
|
+
};
|
|
2067
|
+
|
|
1646
2068
|
const { abs } = Math;
|
|
1647
2069
|
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1648
|
-
const { scaleX, scaleY } = ui.__world;
|
|
2070
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1649
2071
|
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1650
2072
|
return false;
|
|
1651
2073
|
}
|
|
@@ -1660,7 +2082,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1660
2082
|
width *= data.scaleX;
|
|
1661
2083
|
height *= data.scaleY;
|
|
1662
2084
|
}
|
|
1663
|
-
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
2085
|
+
allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
|
|
1664
2086
|
}
|
|
1665
2087
|
else {
|
|
1666
2088
|
allowPaint = false;
|
|
@@ -1679,307 +2101,72 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1679
2101
|
canvas.restore();
|
|
1680
2102
|
return true;
|
|
1681
2103
|
}
|
|
1682
|
-
else {
|
|
1683
|
-
if (!paint.style || Export
|
|
1684
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1685
|
-
}
|
|
1686
|
-
else {
|
|
1687
|
-
if (!paint.patternTask) {
|
|
1688
|
-
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1689
|
-
paint.patternTask = null;
|
|
1690
|
-
if (canvas.bounds.hit(ui.__world))
|
|
1691
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1692
|
-
ui.forceUpdate('surface');
|
|
1693
|
-
}), 300);
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
return false;
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
|
|
1701
|
-
function recycleImage(attrName, data) {
|
|
1702
|
-
const paints = data['_' + attrName];
|
|
1703
|
-
if (paints instanceof Array) {
|
|
1704
|
-
let image, recycleMap, input, url;
|
|
1705
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1706
|
-
image = paints[i].image;
|
|
1707
|
-
url = image && image.url;
|
|
1708
|
-
if (url) {
|
|
1709
|
-
if (!recycleMap)
|
|
1710
|
-
recycleMap = {};
|
|
1711
|
-
recycleMap[url] = true;
|
|
1712
|
-
ImageManager.recycle(image);
|
|
1713
|
-
if (image.loading) {
|
|
1714
|
-
if (!input) {
|
|
1715
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1716
|
-
if (!(input instanceof Array))
|
|
1717
|
-
input = [input];
|
|
1718
|
-
}
|
|
1719
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1720
|
-
}
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
return recycleMap;
|
|
1724
|
-
}
|
|
1725
|
-
return null;
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
function fillText(ui, canvas) {
|
|
1729
|
-
let row;
|
|
1730
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1731
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1732
|
-
row = rows[i];
|
|
1733
|
-
if (row.text) {
|
|
1734
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1735
|
-
}
|
|
1736
|
-
else if (row.data) {
|
|
1737
|
-
row.data.forEach(charData => {
|
|
1738
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1739
|
-
});
|
|
1740
|
-
}
|
|
1741
|
-
if (decorationY)
|
|
1742
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
function fill(fill, ui, canvas) {
|
|
1747
|
-
canvas.fillStyle = fill;
|
|
1748
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1749
|
-
}
|
|
1750
|
-
function fills(fills, ui, canvas) {
|
|
1751
|
-
let item;
|
|
1752
|
-
const { windingRule, __font } = ui.__;
|
|
1753
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1754
|
-
item = fills[i];
|
|
1755
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1756
|
-
continue;
|
|
1757
|
-
if (item.style) {
|
|
1758
|
-
canvas.fillStyle = item.style;
|
|
1759
|
-
if (item.transform) {
|
|
1760
|
-
canvas.save();
|
|
1761
|
-
canvas.transform(item.transform);
|
|
1762
|
-
if (item.blendMode)
|
|
1763
|
-
canvas.blendMode = item.blendMode;
|
|
1764
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1765
|
-
canvas.restore();
|
|
1766
|
-
}
|
|
1767
|
-
else {
|
|
1768
|
-
if (item.blendMode) {
|
|
1769
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1770
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1771
|
-
canvas.restoreBlendMode();
|
|
1772
|
-
}
|
|
1773
|
-
else {
|
|
1774
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1781
|
-
function strokeText(stroke, ui, canvas, renderOptions) {
|
|
1782
|
-
const { strokeAlign } = ui.__;
|
|
1783
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1784
|
-
switch (strokeAlign) {
|
|
1785
|
-
case 'center':
|
|
1786
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1787
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1788
|
-
break;
|
|
1789
|
-
case 'inside':
|
|
1790
|
-
drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1791
|
-
break;
|
|
1792
|
-
case 'outside':
|
|
1793
|
-
drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1794
|
-
break;
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
|
-
function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
|
|
1798
|
-
const { strokeWidth, __font } = ui.__;
|
|
1799
|
-
const out = canvas.getSameCanvas(true);
|
|
1800
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1801
|
-
out.font = __font;
|
|
1802
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1803
|
-
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1804
|
-
fillText(ui, out);
|
|
1805
|
-
out.blendMode = 'normal';
|
|
1806
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1807
|
-
canvas.copyWorldByReset(out);
|
|
1808
|
-
}
|
|
1809
|
-
else {
|
|
1810
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1811
|
-
}
|
|
1812
|
-
out.recycle();
|
|
1813
|
-
}
|
|
1814
|
-
function drawTextStroke(ui, canvas) {
|
|
1815
|
-
let row;
|
|
1816
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1817
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1818
|
-
row = rows[i];
|
|
1819
|
-
if (row.text) {
|
|
1820
|
-
canvas.strokeText(row.text, row.x, row.y);
|
|
1821
|
-
}
|
|
1822
|
-
else if (row.data) {
|
|
1823
|
-
row.data.forEach(charData => {
|
|
1824
|
-
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1825
|
-
});
|
|
1826
|
-
}
|
|
1827
|
-
if (decorationY)
|
|
1828
|
-
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1832
|
-
let item;
|
|
1833
|
-
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1834
|
-
item = strokes[i];
|
|
1835
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1836
|
-
continue;
|
|
1837
|
-
if (item.style) {
|
|
1838
|
-
canvas.strokeStyle = item.style;
|
|
1839
|
-
if (item.blendMode) {
|
|
1840
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1841
|
-
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1842
|
-
canvas.restoreBlendMode();
|
|
2104
|
+
else {
|
|
2105
|
+
if (!paint.style || Export.running) {
|
|
2106
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1843
2107
|
}
|
|
1844
2108
|
else {
|
|
1845
|
-
|
|
2109
|
+
if (!paint.patternTask) {
|
|
2110
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
2111
|
+
paint.patternTask = null;
|
|
2112
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
2113
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
2114
|
+
ui.forceUpdate('surface');
|
|
2115
|
+
}), 300);
|
|
2116
|
+
}
|
|
1846
2117
|
}
|
|
2118
|
+
return false;
|
|
1847
2119
|
}
|
|
1848
2120
|
}
|
|
1849
2121
|
}
|
|
1850
2122
|
|
|
1851
|
-
function
|
|
1852
|
-
const
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
canvas.restore();
|
|
1871
|
-
break;
|
|
1872
|
-
case 'outside':
|
|
1873
|
-
const out = canvas.getSameCanvas(true);
|
|
1874
|
-
out.setStroke(stroke, strokeWidth * 2, ui.__);
|
|
1875
|
-
ui.__drawRenderPath(out);
|
|
1876
|
-
out.stroke();
|
|
1877
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1878
|
-
out.clearWorld(ui.__layout.renderBounds);
|
|
1879
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1880
|
-
canvas.copyWorldByReset(out);
|
|
1881
|
-
}
|
|
1882
|
-
else {
|
|
1883
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1884
|
-
}
|
|
1885
|
-
out.recycle();
|
|
1886
|
-
break;
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
}
|
|
1890
|
-
function strokes(strokes, ui, canvas, renderOptions) {
|
|
1891
|
-
const options = ui.__;
|
|
1892
|
-
const { strokeWidth, strokeAlign, __font } = options;
|
|
1893
|
-
if (!strokeWidth)
|
|
1894
|
-
return;
|
|
1895
|
-
if (__font) {
|
|
1896
|
-
strokeText(strokes, ui, canvas, renderOptions);
|
|
1897
|
-
}
|
|
1898
|
-
else {
|
|
1899
|
-
switch (strokeAlign) {
|
|
1900
|
-
case 'center':
|
|
1901
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1902
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1903
|
-
break;
|
|
1904
|
-
case 'inside':
|
|
1905
|
-
canvas.save();
|
|
1906
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1907
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1908
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1909
|
-
canvas.restore();
|
|
1910
|
-
break;
|
|
1911
|
-
case 'outside':
|
|
1912
|
-
const { renderBounds } = ui.__layout;
|
|
1913
|
-
const out = canvas.getSameCanvas(true);
|
|
1914
|
-
ui.__drawRenderPath(out);
|
|
1915
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1916
|
-
drawStrokesStyle(strokes, false, ui, out);
|
|
1917
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1918
|
-
out.clearWorld(renderBounds);
|
|
1919
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1920
|
-
canvas.copyWorldByReset(out);
|
|
1921
|
-
}
|
|
1922
|
-
else {
|
|
1923
|
-
canvas.copyWorldToInner(out, ui.__world, renderBounds);
|
|
2123
|
+
function recycleImage(attrName, data) {
|
|
2124
|
+
const paints = data['_' + attrName];
|
|
2125
|
+
if (paints instanceof Array) {
|
|
2126
|
+
let image, recycleMap, input, url;
|
|
2127
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
2128
|
+
image = paints[i].image;
|
|
2129
|
+
url = image && image.url;
|
|
2130
|
+
if (url) {
|
|
2131
|
+
if (!recycleMap)
|
|
2132
|
+
recycleMap = {};
|
|
2133
|
+
recycleMap[url] = true;
|
|
2134
|
+
ImageManager.recycle(image);
|
|
2135
|
+
if (image.loading) {
|
|
2136
|
+
if (!input) {
|
|
2137
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
2138
|
+
if (!(input instanceof Array))
|
|
2139
|
+
input = [input];
|
|
2140
|
+
}
|
|
2141
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1924
2142
|
}
|
|
1925
|
-
|
|
1926
|
-
break;
|
|
2143
|
+
}
|
|
1927
2144
|
}
|
|
2145
|
+
return recycleMap;
|
|
1928
2146
|
}
|
|
2147
|
+
return null;
|
|
1929
2148
|
}
|
|
1930
2149
|
|
|
1931
|
-
const
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
if (!current.bounds.includes(__world, options.matrix)) {
|
|
1943
|
-
const { renderShapeSpread: spread } = ui.__layout;
|
|
1944
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
|
|
1945
|
-
matrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1946
|
-
if (matrix.a < 1) {
|
|
1947
|
-
worldCanvas = current.getSameCanvas();
|
|
1948
|
-
ui.__renderShape(worldCanvas, options);
|
|
1949
|
-
scaleX *= matrix.a;
|
|
1950
|
-
scaleY *= matrix.d;
|
|
1951
|
-
}
|
|
1952
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1953
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1954
|
-
if (options.matrix)
|
|
1955
|
-
matrix.multiply(options.matrix);
|
|
1956
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1957
|
-
}
|
|
1958
|
-
else {
|
|
1959
|
-
if (options.matrix) {
|
|
1960
|
-
scaleX *= options.matrix.a;
|
|
1961
|
-
scaleY *= options.matrix.d;
|
|
1962
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1963
|
-
}
|
|
1964
|
-
else {
|
|
1965
|
-
bounds = shapeBounds = __world;
|
|
1966
|
-
}
|
|
1967
|
-
worldCanvas = canvas;
|
|
1968
|
-
}
|
|
1969
|
-
ui.__renderShape(canvas, options);
|
|
1970
|
-
return {
|
|
1971
|
-
canvas, matrix, bounds,
|
|
1972
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1973
|
-
};
|
|
1974
|
-
}
|
|
2150
|
+
const PaintImageModule = {
|
|
2151
|
+
image,
|
|
2152
|
+
checkImage,
|
|
2153
|
+
createPattern,
|
|
2154
|
+
recycleImage,
|
|
2155
|
+
createData,
|
|
2156
|
+
getPatternData,
|
|
2157
|
+
fillOrFitMode,
|
|
2158
|
+
clipMode,
|
|
2159
|
+
repeatMode
|
|
2160
|
+
};
|
|
1975
2161
|
|
|
1976
|
-
const
|
|
1977
|
-
const
|
|
2162
|
+
const { toPoint: toPoint$2 } = AroundHelper;
|
|
2163
|
+
const realFrom$2 = {};
|
|
2164
|
+
const realTo$2 = {};
|
|
1978
2165
|
function linearGradient(paint, box) {
|
|
1979
2166
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1980
|
-
from ||
|
|
1981
|
-
to ||
|
|
1982
|
-
const style = Platform.canvas.createLinearGradient(
|
|
2167
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
2168
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
2169
|
+
const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
1983
2170
|
applyStops(style, paint.stops, opacity);
|
|
1984
2171
|
const data = { type, style };
|
|
1985
2172
|
if (blendMode)
|
|
@@ -1990,137 +2177,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1990
2177
|
let stop;
|
|
1991
2178
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1992
2179
|
stop = stops[i];
|
|
1993
|
-
|
|
2180
|
+
if (typeof stop === 'string') {
|
|
2181
|
+
gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
|
|
2182
|
+
}
|
|
2183
|
+
else {
|
|
2184
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
2185
|
+
}
|
|
1994
2186
|
}
|
|
1995
2187
|
}
|
|
1996
2188
|
|
|
1997
|
-
const {
|
|
1998
|
-
const { get
|
|
1999
|
-
const
|
|
2000
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
2189
|
+
const { getAngle, getDistance: getDistance$1 } = PointHelper;
|
|
2190
|
+
const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
|
|
2191
|
+
const { toPoint: toPoint$1 } = AroundHelper;
|
|
2001
2192
|
const realFrom$1 = {};
|
|
2002
2193
|
const realTo$1 = {};
|
|
2003
2194
|
function radialGradient(paint, box) {
|
|
2004
2195
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
2005
|
-
from ||
|
|
2006
|
-
to ||
|
|
2007
|
-
const { x, y, width, height } = box;
|
|
2008
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
2009
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
2010
|
-
let transform;
|
|
2011
|
-
if (width !== height || stretch) {
|
|
2012
|
-
transform = get$1();
|
|
2013
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
2014
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
2015
|
-
}
|
|
2196
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
2197
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
2016
2198
|
const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
|
|
2017
2199
|
applyStops(style, paint.stops, opacity);
|
|
2018
|
-
const data = { type, style
|
|
2200
|
+
const data = { type, style };
|
|
2201
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
2202
|
+
if (transform)
|
|
2203
|
+
data.transform = transform;
|
|
2019
2204
|
if (blendMode)
|
|
2020
2205
|
data.blendMode = blendMode;
|
|
2021
2206
|
return data;
|
|
2022
2207
|
}
|
|
2208
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
2209
|
+
let transform;
|
|
2210
|
+
const { width, height } = box;
|
|
2211
|
+
if (width !== height || stretch) {
|
|
2212
|
+
const angle = getAngle(from, to);
|
|
2213
|
+
transform = get();
|
|
2214
|
+
if (rotate90) {
|
|
2215
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
2216
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
2217
|
+
}
|
|
2218
|
+
else {
|
|
2219
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
2220
|
+
rotateOfOuter(transform, from, angle);
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
return transform;
|
|
2224
|
+
}
|
|
2023
2225
|
|
|
2024
|
-
const {
|
|
2025
|
-
const {
|
|
2026
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
2027
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
2226
|
+
const { getDistance } = PointHelper;
|
|
2227
|
+
const { toPoint } = AroundHelper;
|
|
2028
2228
|
const realFrom = {};
|
|
2029
2229
|
const realTo = {};
|
|
2030
2230
|
function conicGradient(paint, box) {
|
|
2031
2231
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
2032
|
-
from ||
|
|
2033
|
-
to ||
|
|
2034
|
-
const { x, y, width, height } = box;
|
|
2035
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
2036
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
2037
|
-
const transform = get();
|
|
2038
|
-
const angle = getAngle(realFrom, realTo);
|
|
2039
|
-
if (Platform.conicGradientRotate90) {
|
|
2040
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
2041
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
2042
|
-
}
|
|
2043
|
-
else {
|
|
2044
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
2045
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
2046
|
-
}
|
|
2232
|
+
toPoint(from || 'center', box, realFrom);
|
|
2233
|
+
toPoint(to || 'bottom', box, realTo);
|
|
2047
2234
|
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));
|
|
2048
2235
|
applyStops(style, paint.stops, opacity);
|
|
2049
|
-
const data = { type, style
|
|
2236
|
+
const data = { type, style };
|
|
2237
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
|
|
2238
|
+
if (transform)
|
|
2239
|
+
data.transform = transform;
|
|
2050
2240
|
if (blendMode)
|
|
2051
2241
|
data.blendMode = blendMode;
|
|
2052
2242
|
return data;
|
|
2053
2243
|
}
|
|
2054
2244
|
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
if (!(paints instanceof Array))
|
|
2062
|
-
paints = [paints];
|
|
2063
|
-
recycleMap = recycleImage(attrName, data);
|
|
2064
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
2065
|
-
item = getLeafPaint(attrName, paints[i], ui);
|
|
2066
|
-
if (item)
|
|
2067
|
-
value.push(item);
|
|
2068
|
-
}
|
|
2069
|
-
data['_' + attrName] = value.length ? value : undefined;
|
|
2070
|
-
let isPixel;
|
|
2071
|
-
if (paints.length === 1) {
|
|
2072
|
-
const paint = paints[0];
|
|
2073
|
-
if (paint.type === 'image')
|
|
2074
|
-
isPixel = ImageManager$1.isPixel(paint);
|
|
2075
|
-
}
|
|
2076
|
-
if (attrName === 'fill') {
|
|
2077
|
-
data.__pixelFill = isPixel;
|
|
2078
|
-
}
|
|
2079
|
-
else {
|
|
2080
|
-
data.__pixelStroke = isPixel;
|
|
2081
|
-
}
|
|
2082
|
-
}
|
|
2083
|
-
function getLeafPaint(attrName, paint, ui) {
|
|
2084
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
2085
|
-
return undefined;
|
|
2086
|
-
const { boxBounds } = ui.__layout;
|
|
2087
|
-
switch (paint.type) {
|
|
2088
|
-
case 'solid':
|
|
2089
|
-
let { type, blendMode, color, opacity } = paint;
|
|
2090
|
-
return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
|
|
2091
|
-
case 'image':
|
|
2092
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
2093
|
-
case 'linear':
|
|
2094
|
-
return linearGradient(paint, boxBounds);
|
|
2095
|
-
case 'radial':
|
|
2096
|
-
return radialGradient(paint, boxBounds);
|
|
2097
|
-
case 'angular':
|
|
2098
|
-
return conicGradient(paint, boxBounds);
|
|
2099
|
-
default:
|
|
2100
|
-
return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
|
|
2101
|
-
}
|
|
2102
|
-
}
|
|
2103
|
-
|
|
2104
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
2105
|
-
__proto__: null,
|
|
2106
|
-
compute: compute,
|
|
2107
|
-
drawTextStroke: drawTextStroke,
|
|
2108
|
-
fill: fill,
|
|
2109
|
-
fillText: fillText,
|
|
2110
|
-
fills: fills,
|
|
2111
|
-
recycleImage: recycleImage,
|
|
2112
|
-
shape: shape,
|
|
2113
|
-
stroke: stroke,
|
|
2114
|
-
strokeText: strokeText,
|
|
2115
|
-
strokes: strokes
|
|
2116
|
-
});
|
|
2245
|
+
const PaintGradientModule = {
|
|
2246
|
+
linearGradient,
|
|
2247
|
+
radialGradient,
|
|
2248
|
+
conicGradient,
|
|
2249
|
+
getTransform
|
|
2250
|
+
};
|
|
2117
2251
|
|
|
2118
2252
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
2119
2253
|
const tempBounds = {};
|
|
2120
2254
|
const offsetOutBounds$1 = {};
|
|
2121
|
-
function shadow(ui, current, shape
|
|
2255
|
+
function shadow(ui, current, shape) {
|
|
2122
2256
|
let copyBounds, spreadScale;
|
|
2123
|
-
const {
|
|
2257
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
2124
2258
|
const { shadow } = ui.__;
|
|
2125
2259
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2126
2260
|
const other = current.getSameCanvas();
|
|
@@ -2135,21 +2269,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
2135
2269
|
other.restore();
|
|
2136
2270
|
other.save();
|
|
2137
2271
|
if (worldCanvas) {
|
|
2138
|
-
other.copyWorld(other, bounds,
|
|
2139
|
-
copyBounds =
|
|
2272
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2273
|
+
copyBounds = nowWorld;
|
|
2140
2274
|
}
|
|
2141
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
2275
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
2142
2276
|
}
|
|
2143
|
-
if (ui.__worldFlipped
|
|
2144
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2277
|
+
if (ui.__worldFlipped) {
|
|
2278
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2145
2279
|
}
|
|
2146
2280
|
else {
|
|
2147
2281
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2148
2282
|
}
|
|
2149
2283
|
if (end && index < end)
|
|
2150
|
-
other.
|
|
2284
|
+
other.clearWorld(copyBounds, true);
|
|
2151
2285
|
});
|
|
2152
|
-
other.recycle();
|
|
2286
|
+
other.recycle(copyBounds);
|
|
2153
2287
|
}
|
|
2154
2288
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
2155
2289
|
const { bounds, shapeBounds } = shape;
|
|
@@ -2180,9 +2314,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
2180
2314
|
|
|
2181
2315
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
2182
2316
|
const offsetOutBounds = {};
|
|
2183
|
-
function innerShadow(ui, current, shape
|
|
2317
|
+
function innerShadow(ui, current, shape) {
|
|
2184
2318
|
let copyBounds, spreadScale;
|
|
2185
|
-
const {
|
|
2319
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
2186
2320
|
const { innerShadow } = ui.__;
|
|
2187
2321
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2188
2322
|
const other = current.getSameCanvas();
|
|
@@ -2195,40 +2329,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
2195
2329
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
2196
2330
|
other.restore();
|
|
2197
2331
|
if (worldCanvas) {
|
|
2198
|
-
other.copyWorld(other, bounds,
|
|
2199
|
-
other.copyWorld(worldCanvas,
|
|
2200
|
-
copyBounds =
|
|
2332
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2333
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
2334
|
+
copyBounds = nowWorld;
|
|
2201
2335
|
}
|
|
2202
2336
|
else {
|
|
2203
2337
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
2204
2338
|
copyBounds = bounds;
|
|
2205
2339
|
}
|
|
2206
2340
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
2207
|
-
if (ui.__worldFlipped
|
|
2208
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2341
|
+
if (ui.__worldFlipped) {
|
|
2342
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2209
2343
|
}
|
|
2210
2344
|
else {
|
|
2211
2345
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2212
2346
|
}
|
|
2213
2347
|
if (end && index < end)
|
|
2214
|
-
other.
|
|
2348
|
+
other.clearWorld(copyBounds, true);
|
|
2215
2349
|
});
|
|
2216
|
-
other.recycle();
|
|
2350
|
+
other.recycle(copyBounds);
|
|
2217
2351
|
}
|
|
2218
2352
|
|
|
2219
2353
|
function blur(ui, current, origin) {
|
|
2220
2354
|
const { blur } = ui.__;
|
|
2221
|
-
origin.setWorldBlur(blur * ui.
|
|
2222
|
-
origin.copyWorldToInner(current, ui.
|
|
2355
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
2356
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
2223
2357
|
origin.filter = 'none';
|
|
2224
2358
|
}
|
|
2225
2359
|
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
shadow
|
|
2231
|
-
|
|
2360
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
const EffectModule = {
|
|
2364
|
+
shadow,
|
|
2365
|
+
innerShadow,
|
|
2366
|
+
blur,
|
|
2367
|
+
backgroundBlur
|
|
2368
|
+
};
|
|
2369
|
+
|
|
2370
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
2371
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
2372
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
2373
|
+
const { children } = this;
|
|
2374
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
2375
|
+
child = children[i];
|
|
2376
|
+
if (child.__.mask) {
|
|
2377
|
+
if (currentMask) {
|
|
2378
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2379
|
+
maskCanvas = contentCanvas = null;
|
|
2380
|
+
}
|
|
2381
|
+
if (child.__.mask === 'path') {
|
|
2382
|
+
if (child.opacity < 1) {
|
|
2383
|
+
currentMask = 'opacity-path';
|
|
2384
|
+
maskOpacity = child.opacity;
|
|
2385
|
+
if (!contentCanvas)
|
|
2386
|
+
contentCanvas = getCanvas(canvas);
|
|
2387
|
+
}
|
|
2388
|
+
else {
|
|
2389
|
+
currentMask = 'path';
|
|
2390
|
+
canvas.save();
|
|
2391
|
+
}
|
|
2392
|
+
child.__clip(contentCanvas || canvas, options);
|
|
2393
|
+
}
|
|
2394
|
+
else {
|
|
2395
|
+
currentMask = 'alpha';
|
|
2396
|
+
if (!maskCanvas)
|
|
2397
|
+
maskCanvas = getCanvas(canvas);
|
|
2398
|
+
if (!contentCanvas)
|
|
2399
|
+
contentCanvas = getCanvas(canvas);
|
|
2400
|
+
child.__render(maskCanvas, options);
|
|
2401
|
+
}
|
|
2402
|
+
if (child.__.mask !== 'clipping')
|
|
2403
|
+
continue;
|
|
2404
|
+
}
|
|
2405
|
+
if (excludeRenderBounds(child, options))
|
|
2406
|
+
continue;
|
|
2407
|
+
child.__render(contentCanvas || canvas, options);
|
|
2408
|
+
}
|
|
2409
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2410
|
+
};
|
|
2411
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
2412
|
+
switch (maskMode) {
|
|
2413
|
+
case 'alpha':
|
|
2414
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
2415
|
+
break;
|
|
2416
|
+
case 'opacity-path':
|
|
2417
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
2418
|
+
break;
|
|
2419
|
+
case 'path':
|
|
2420
|
+
canvas.restore();
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
function getCanvas(canvas) {
|
|
2424
|
+
return canvas.getSameCanvas(false, true);
|
|
2425
|
+
}
|
|
2426
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
2427
|
+
const realBounds = leaf.__nowWorld;
|
|
2428
|
+
content.resetTransform();
|
|
2429
|
+
content.opacity = 1;
|
|
2430
|
+
content.useMask(mask, realBounds);
|
|
2431
|
+
mask.recycle(realBounds);
|
|
2432
|
+
copyContent(leaf, canvas, content, 1);
|
|
2433
|
+
}
|
|
2434
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
2435
|
+
const realBounds = leaf.__nowWorld;
|
|
2436
|
+
canvas.resetTransform();
|
|
2437
|
+
canvas.opacity = maskOpacity;
|
|
2438
|
+
canvas.copyWorld(content, realBounds);
|
|
2439
|
+
content.recycle(realBounds);
|
|
2440
|
+
}
|
|
2232
2441
|
|
|
2233
2442
|
const money = '¥¥$€££¢¢';
|
|
2234
2443
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -2385,7 +2594,8 @@ function createRows(drawData, content, style) {
|
|
|
2385
2594
|
if (breakAll) {
|
|
2386
2595
|
if (wordWidth)
|
|
2387
2596
|
addWord();
|
|
2388
|
-
|
|
2597
|
+
if (rowWidth)
|
|
2598
|
+
addRow();
|
|
2389
2599
|
}
|
|
2390
2600
|
else {
|
|
2391
2601
|
if (!afterBreak)
|
|
@@ -2393,10 +2603,12 @@ function createRows(drawData, content, style) {
|
|
|
2393
2603
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2394
2604
|
if (wordWidth)
|
|
2395
2605
|
addWord();
|
|
2396
|
-
|
|
2606
|
+
if (rowWidth)
|
|
2607
|
+
addRow();
|
|
2397
2608
|
}
|
|
2398
2609
|
else {
|
|
2399
|
-
|
|
2610
|
+
if (rowWidth)
|
|
2611
|
+
addRow();
|
|
2400
2612
|
}
|
|
2401
2613
|
}
|
|
2402
2614
|
}
|
|
@@ -2491,11 +2703,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2491
2703
|
if (mode === WordMode) {
|
|
2492
2704
|
wordChar = { char: '', x: charX };
|
|
2493
2705
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2494
|
-
if (wordChar.char !== ' ')
|
|
2706
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2495
2707
|
row.data.push(wordChar);
|
|
2496
2708
|
}
|
|
2497
2709
|
else {
|
|
2498
|
-
charX = toChar(word.data, charX, row.data);
|
|
2710
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2499
2711
|
}
|
|
2500
2712
|
if (!row.paraEnd && addWordWidth) {
|
|
2501
2713
|
charX += addWordWidth;
|
|
@@ -2522,9 +2734,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2522
2734
|
});
|
|
2523
2735
|
return charX;
|
|
2524
2736
|
}
|
|
2525
|
-
function toChar(data, charX, rowData) {
|
|
2737
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2526
2738
|
data.forEach(char => {
|
|
2527
|
-
if (char.char !== ' ') {
|
|
2739
|
+
if (isOverflow || char.char !== ' ') {
|
|
2528
2740
|
char.x = charX;
|
|
2529
2741
|
rowData.push(char);
|
|
2530
2742
|
}
|
|
@@ -2556,12 +2768,14 @@ function layoutText(drawData, style) {
|
|
|
2556
2768
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2557
2769
|
row = rows[i];
|
|
2558
2770
|
row.x = x;
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2771
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2772
|
+
switch (textAlign) {
|
|
2773
|
+
case 'center':
|
|
2774
|
+
row.x += (width - row.width) / 2;
|
|
2775
|
+
break;
|
|
2776
|
+
case 'right':
|
|
2777
|
+
row.x += width - row.width;
|
|
2778
|
+
}
|
|
2565
2779
|
}
|
|
2566
2780
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2567
2781
|
starY += paraSpacing;
|
|
@@ -2597,16 +2811,20 @@ function layoutText(drawData, style) {
|
|
|
2597
2811
|
bounds.height = realHeight;
|
|
2598
2812
|
}
|
|
2599
2813
|
|
|
2600
|
-
function clipText(drawData, style) {
|
|
2814
|
+
function clipText(drawData, style, x, width) {
|
|
2815
|
+
if (!width)
|
|
2816
|
+
return;
|
|
2601
2817
|
const { rows, overflow } = drawData;
|
|
2602
2818
|
let { textOverflow } = style;
|
|
2603
2819
|
rows.splice(overflow);
|
|
2604
|
-
if (textOverflow !== '
|
|
2605
|
-
if (textOverflow === '
|
|
2820
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2821
|
+
if (textOverflow === 'hide')
|
|
2822
|
+
textOverflow = '';
|
|
2823
|
+
else if (textOverflow === 'ellipsis')
|
|
2606
2824
|
textOverflow = '...';
|
|
2607
2825
|
let char, charRight;
|
|
2608
|
-
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2609
|
-
const right =
|
|
2826
|
+
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2827
|
+
const right = x + width - ellipsisWidth;
|
|
2610
2828
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2611
2829
|
list.forEach(row => {
|
|
2612
2830
|
if (row.isOverflow && row.data) {
|
|
@@ -2653,42 +2871,40 @@ function decorationText(drawData, style) {
|
|
|
2653
2871
|
}
|
|
2654
2872
|
|
|
2655
2873
|
const { top, right, bottom, left } = Direction4;
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
if (
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
}
|
|
2691
|
-
};
|
|
2874
|
+
function getDrawData(content, style) {
|
|
2875
|
+
if (typeof content !== 'string')
|
|
2876
|
+
content = String(content);
|
|
2877
|
+
let x = 0, y = 0;
|
|
2878
|
+
let width = style.__getInput('width') || 0;
|
|
2879
|
+
let height = style.__getInput('height') || 0;
|
|
2880
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2881
|
+
if (padding) {
|
|
2882
|
+
if (width) {
|
|
2883
|
+
x = padding[left];
|
|
2884
|
+
width -= (padding[right] + padding[left]);
|
|
2885
|
+
}
|
|
2886
|
+
if (height) {
|
|
2887
|
+
y = padding[top];
|
|
2888
|
+
height -= (padding[top] + padding[bottom]);
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
const drawData = {
|
|
2892
|
+
bounds: { x, y, width, height },
|
|
2893
|
+
rows: [],
|
|
2894
|
+
paraNumber: 0,
|
|
2895
|
+
font: Platform.canvas.font = __font
|
|
2896
|
+
};
|
|
2897
|
+
createRows(drawData, content, style);
|
|
2898
|
+
if (padding)
|
|
2899
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2900
|
+
layoutText(drawData, style);
|
|
2901
|
+
layoutChar(drawData, style, width);
|
|
2902
|
+
if (drawData.overflow)
|
|
2903
|
+
clipText(drawData, style, x, width);
|
|
2904
|
+
if (textDecoration !== 'none')
|
|
2905
|
+
decorationText(drawData, style);
|
|
2906
|
+
return drawData;
|
|
2907
|
+
}
|
|
2692
2908
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2693
2909
|
if (!width) {
|
|
2694
2910
|
switch (style.textAlign) {
|
|
@@ -2716,67 +2932,152 @@ function offsetText(drawData, attrName, value) {
|
|
|
2716
2932
|
rows[i][attrName] += value;
|
|
2717
2933
|
}
|
|
2718
2934
|
|
|
2719
|
-
const
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2935
|
+
const TextConvertModule = {
|
|
2936
|
+
getDrawData
|
|
2937
|
+
};
|
|
2938
|
+
|
|
2939
|
+
function string(color, opacity) {
|
|
2940
|
+
if (typeof color === 'string')
|
|
2941
|
+
return color;
|
|
2942
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2943
|
+
if (opacity)
|
|
2944
|
+
a *= opacity;
|
|
2945
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2946
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
const ColorConvertModule = {
|
|
2950
|
+
string
|
|
2729
2951
|
};
|
|
2730
2952
|
|
|
2731
|
-
const
|
|
2953
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2954
|
+
function getTrimBounds(canvas) {
|
|
2955
|
+
const { width, height } = canvas.view;
|
|
2956
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2957
|
+
let x, y, pointBounds, index = 0;
|
|
2958
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2959
|
+
if (data[i + 3] !== 0) {
|
|
2960
|
+
x = index % width;
|
|
2961
|
+
y = (index - x) / width;
|
|
2962
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2963
|
+
}
|
|
2964
|
+
index++;
|
|
2965
|
+
}
|
|
2966
|
+
const bounds = new Bounds();
|
|
2967
|
+
toBounds(pointBounds, bounds);
|
|
2968
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2969
|
+
}
|
|
2970
|
+
|
|
2971
|
+
const ExportModule = {
|
|
2732
2972
|
export(leaf, filename, options) {
|
|
2733
|
-
|
|
2973
|
+
this.running = true;
|
|
2974
|
+
const fileType = FileHelper.fileType(filename);
|
|
2975
|
+
options = FileHelper.getExportOptions(options);
|
|
2734
2976
|
return addTask((success) => new Promise((resolve) => {
|
|
2977
|
+
const over = (result) => {
|
|
2978
|
+
success(result);
|
|
2979
|
+
resolve();
|
|
2980
|
+
this.running = false;
|
|
2981
|
+
};
|
|
2982
|
+
const { toURL } = Platform;
|
|
2983
|
+
const { download } = Platform.origin;
|
|
2984
|
+
if (filename === 'json') {
|
|
2985
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
2986
|
+
}
|
|
2987
|
+
else if (fileType === 'json') {
|
|
2988
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
2989
|
+
return over({ data: true });
|
|
2990
|
+
}
|
|
2991
|
+
if (filename === 'svg') {
|
|
2992
|
+
return over({ data: leaf.toSVG() });
|
|
2993
|
+
}
|
|
2994
|
+
else if (fileType === 'svg') {
|
|
2995
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
2996
|
+
return over({ data: true });
|
|
2997
|
+
}
|
|
2735
2998
|
const { leafer } = leaf;
|
|
2736
2999
|
if (leafer) {
|
|
3000
|
+
checkLazy(leaf);
|
|
2737
3001
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2738
|
-
let
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
3002
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
3003
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
3004
|
+
const { slice, trim, onCanvas } = options;
|
|
3005
|
+
let scale = options.scale || 1;
|
|
3006
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
3007
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
3008
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
3009
|
+
if (leaf.isApp) {
|
|
3010
|
+
scale *= pixelRatio;
|
|
3011
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
3012
|
+
}
|
|
3013
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
3014
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
3015
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
3016
|
+
if (screenshot) {
|
|
3017
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2745
3018
|
}
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
3019
|
+
else {
|
|
3020
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
3021
|
+
scaleX = worldTransform.scaleX;
|
|
3022
|
+
scaleY = worldTransform.scaleY;
|
|
3023
|
+
switch (relative) {
|
|
3024
|
+
case 'inner':
|
|
3025
|
+
matrix.set(worldTransform);
|
|
3026
|
+
break;
|
|
3027
|
+
case 'local':
|
|
3028
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
3029
|
+
scaleX /= leaf.scaleX;
|
|
3030
|
+
scaleY /= leaf.scaleY;
|
|
3031
|
+
break;
|
|
3032
|
+
case 'world':
|
|
3033
|
+
scaleX = 1;
|
|
3034
|
+
scaleY = 1;
|
|
3035
|
+
break;
|
|
3036
|
+
case 'page':
|
|
3037
|
+
relative = leaf.leafer;
|
|
3038
|
+
default:
|
|
3039
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
3040
|
+
const l = relative.worldTransform;
|
|
3041
|
+
scaleX /= scaleX / l.scaleX;
|
|
3042
|
+
scaleY /= scaleY / l.scaleY;
|
|
3043
|
+
}
|
|
3044
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2758
3045
|
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
3046
|
+
const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
|
|
3047
|
+
let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
3048
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
3049
|
+
if (slice) {
|
|
3050
|
+
leaf = leafer;
|
|
3051
|
+
renderOptions.bounds = canvas.bounds;
|
|
2762
3052
|
}
|
|
2763
|
-
|
|
2764
|
-
|
|
3053
|
+
canvas.save();
|
|
3054
|
+
if (isFrame && fill !== undefined) {
|
|
3055
|
+
const oldFill = leaf.get('fill');
|
|
3056
|
+
leaf.fill = '';
|
|
3057
|
+
leaf.__render(canvas, renderOptions);
|
|
3058
|
+
leaf.fill = oldFill;
|
|
2765
3059
|
}
|
|
2766
3060
|
else {
|
|
2767
|
-
|
|
3061
|
+
leaf.__render(canvas, renderOptions);
|
|
2768
3062
|
}
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
3063
|
+
canvas.restore();
|
|
3064
|
+
if (trim) {
|
|
3065
|
+
trimBounds = getTrimBounds(canvas);
|
|
3066
|
+
const old = canvas, { width, height } = trimBounds;
|
|
3067
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
3068
|
+
canvas = Creator.canvas(config);
|
|
3069
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
3070
|
+
}
|
|
3071
|
+
if (needFill)
|
|
3072
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
3073
|
+
if (onCanvas)
|
|
3074
|
+
onCanvas(canvas);
|
|
3075
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
3076
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2774
3077
|
}));
|
|
2775
3078
|
}
|
|
2776
3079
|
else {
|
|
2777
|
-
|
|
2778
|
-
resolve();
|
|
2779
|
-
Export.running = false;
|
|
3080
|
+
over({ data: false });
|
|
2780
3081
|
}
|
|
2781
3082
|
}));
|
|
2782
3083
|
}
|
|
@@ -2789,13 +3090,64 @@ function addTask(task) {
|
|
|
2789
3090
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2790
3091
|
});
|
|
2791
3092
|
}
|
|
3093
|
+
function checkLazy(leaf) {
|
|
3094
|
+
if (leaf.__.__needComputePaint)
|
|
3095
|
+
leaf.__.__computePaint();
|
|
3096
|
+
if (leaf.isBranch)
|
|
3097
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
const canvas = LeaferCanvasBase.prototype;
|
|
3101
|
+
const debug = Debug.get('@leafer-ui/export');
|
|
3102
|
+
canvas.export = function (filename, options) {
|
|
3103
|
+
const { quality, blob } = FileHelper.getExportOptions(options);
|
|
3104
|
+
if (filename.includes('.')) {
|
|
3105
|
+
return this.saveAs(filename, quality);
|
|
3106
|
+
}
|
|
3107
|
+
else if (blob) {
|
|
3108
|
+
return this.toBlob(filename, quality);
|
|
3109
|
+
}
|
|
3110
|
+
else {
|
|
3111
|
+
return this.toDataURL(filename, quality);
|
|
3112
|
+
}
|
|
3113
|
+
};
|
|
3114
|
+
canvas.toBlob = function (type, quality) {
|
|
3115
|
+
return new Promise((resolve) => {
|
|
3116
|
+
Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
3117
|
+
resolve(blob);
|
|
3118
|
+
}).catch((e) => {
|
|
3119
|
+
debug.error(e);
|
|
3120
|
+
resolve(null);
|
|
3121
|
+
});
|
|
3122
|
+
});
|
|
3123
|
+
};
|
|
3124
|
+
canvas.toDataURL = function (type, quality) {
|
|
3125
|
+
return Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
3126
|
+
};
|
|
3127
|
+
canvas.saveAs = function (filename, quality) {
|
|
3128
|
+
return new Promise((resolve) => {
|
|
3129
|
+
Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
3130
|
+
resolve(true);
|
|
3131
|
+
}).catch((e) => {
|
|
3132
|
+
debug.error(e);
|
|
3133
|
+
resolve(false);
|
|
3134
|
+
});
|
|
3135
|
+
});
|
|
3136
|
+
};
|
|
2792
3137
|
|
|
2793
|
-
Object.assign(
|
|
2794
|
-
Object.assign(
|
|
2795
|
-
Object.assign(
|
|
2796
|
-
Object.assign(
|
|
2797
|
-
Object.assign(
|
|
3138
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
3139
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
3140
|
+
Object.assign(Paint, PaintModule);
|
|
3141
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
3142
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
3143
|
+
Object.assign(Effect, EffectModule);
|
|
3144
|
+
Object.assign(Export, ExportModule);
|
|
2798
3145
|
|
|
3146
|
+
Object.assign(Creator, {
|
|
3147
|
+
interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
|
|
3148
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
3149
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
3150
|
+
});
|
|
2799
3151
|
useCanvas();
|
|
2800
3152
|
|
|
2801
3153
|
export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|