leafer-ui 1.0.0-rc.9 → 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 +1296 -962
- package/dist/web.esm.min.js +1 -1
- package/dist/web.js +7095 -5952
- package/dist/web.min.js +1 -1
- package/dist/web.module.js +7067 -5942
- 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,180 +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
|
-
this.parentView.style.userSelect = 'none';
|
|
839
|
-
if (Platform.syncDomFont && !this.parentView) {
|
|
840
|
-
this.view.style.display = 'none';
|
|
841
|
-
document.body.appendChild(this.view);
|
|
842
|
-
}
|
|
843
|
-
this.__createContext();
|
|
844
|
-
if (!this.autoLayout)
|
|
845
|
-
this.resize(this.config);
|
|
846
|
-
}
|
|
847
|
-
set backgroundColor(color) { this.view.style.backgroundColor = color; }
|
|
848
|
-
get backgroundColor() { return this.view.style.backgroundColor; }
|
|
849
|
-
set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
|
|
850
|
-
get hittable() { return this.view.style.pointerEvents !== 'none'; }
|
|
851
|
-
__createView() {
|
|
852
|
-
this.view = document.createElement('canvas');
|
|
853
|
-
}
|
|
854
|
-
setCursor(cursor) {
|
|
855
|
-
const list = [];
|
|
856
|
-
this.eachCursor(cursor, list);
|
|
857
|
-
if (typeof list[list.length - 1] === 'object')
|
|
858
|
-
list.push('default');
|
|
859
|
-
this.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
|
|
860
|
-
}
|
|
861
|
-
eachCursor(cursor, list, level = 0) {
|
|
862
|
-
level++;
|
|
863
|
-
if (cursor instanceof Array) {
|
|
864
|
-
cursor.forEach(item => this.eachCursor(item, list, level));
|
|
865
|
-
}
|
|
866
|
-
else {
|
|
867
|
-
const custom = typeof cursor === 'string' && Cursor.get(cursor);
|
|
868
|
-
if (custom && level < 2) {
|
|
869
|
-
this.eachCursor(custom, list, level);
|
|
870
|
-
}
|
|
871
|
-
else {
|
|
872
|
-
list.push(cursor);
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
__createViewFrom(inputView) {
|
|
877
|
-
let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
|
|
878
|
-
if (find) {
|
|
879
|
-
if (find instanceof HTMLCanvasElement) {
|
|
880
|
-
this.view = find;
|
|
881
|
-
}
|
|
882
|
-
else {
|
|
883
|
-
let parent = find;
|
|
884
|
-
if (find === window || find === document) {
|
|
885
|
-
const div = document.createElement('div');
|
|
886
|
-
const { style } = div;
|
|
887
|
-
style.position = 'absolute';
|
|
888
|
-
style.top = style.bottom = style.left = style.right = '0px';
|
|
889
|
-
document.body.appendChild(div);
|
|
890
|
-
parent = div;
|
|
891
|
-
}
|
|
892
|
-
this.__createView();
|
|
893
|
-
const view = this.view;
|
|
894
|
-
if (parent.hasChildNodes()) {
|
|
895
|
-
const { style } = view;
|
|
896
|
-
style.position = 'absolute';
|
|
897
|
-
style.top = style.left = '0px';
|
|
898
|
-
parent.style.position || (parent.style.position = 'relative');
|
|
899
|
-
}
|
|
900
|
-
parent.appendChild(view);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
else {
|
|
904
|
-
debug.error(`no id: ${inputView}`);
|
|
905
|
-
this.__createView();
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
updateViewSize() {
|
|
909
|
-
const { width, height, pixelRatio } = this;
|
|
910
|
-
const { style } = this.view;
|
|
911
|
-
style.width = width + 'px';
|
|
912
|
-
style.height = height + 'px';
|
|
913
|
-
this.view.width = width * pixelRatio;
|
|
914
|
-
this.view.height = height * pixelRatio;
|
|
915
|
-
}
|
|
916
|
-
updateClientBounds() {
|
|
917
|
-
this.clientBounds = this.view.getBoundingClientRect();
|
|
918
|
-
}
|
|
919
|
-
startAutoLayout(autoBounds, listener) {
|
|
920
|
-
this.autoBounds = autoBounds;
|
|
921
|
-
this.resizeListener = listener;
|
|
922
|
-
try {
|
|
923
|
-
this.resizeObserver = new ResizeObserver((entries) => {
|
|
924
|
-
this.updateClientBounds();
|
|
925
|
-
for (const entry of entries)
|
|
926
|
-
this.checkAutoBounds(entry.contentRect);
|
|
927
|
-
});
|
|
928
|
-
const parent = this.parentView;
|
|
929
|
-
if (parent) {
|
|
930
|
-
this.resizeObserver.observe(parent);
|
|
931
|
-
this.checkAutoBounds(parent.getBoundingClientRect());
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
catch (_a) {
|
|
935
|
-
this.imitateResizeObserver();
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
imitateResizeObserver() {
|
|
939
|
-
if (this.autoLayout) {
|
|
940
|
-
if (this.parentView)
|
|
941
|
-
this.checkAutoBounds(this.parentView.getBoundingClientRect());
|
|
942
|
-
Platform.requestRender(this.imitateResizeObserver.bind(this));
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
checkAutoBounds(parentSize) {
|
|
946
|
-
const view = this.view;
|
|
947
|
-
const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
|
|
948
|
-
if (width !== this.width || height !== this.height) {
|
|
949
|
-
const { style } = view;
|
|
950
|
-
const { pixelRatio } = this;
|
|
951
|
-
style.marginLeft = x + 'px';
|
|
952
|
-
style.marginTop = y + 'px';
|
|
953
|
-
const size = { width, height, pixelRatio };
|
|
954
|
-
const oldSize = {};
|
|
955
|
-
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
956
|
-
this.resize(size);
|
|
957
|
-
if (this.width !== undefined)
|
|
958
|
-
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
stopAutoLayout() {
|
|
962
|
-
this.autoLayout = false;
|
|
963
|
-
this.resizeListener = null;
|
|
964
|
-
if (this.resizeObserver) {
|
|
965
|
-
this.resizeObserver.disconnect();
|
|
966
|
-
this.resizeObserver = null;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
unrealCanvas() {
|
|
970
|
-
if (!this.unreal && this.parentView) {
|
|
971
|
-
const view = this.view;
|
|
972
|
-
if (view)
|
|
973
|
-
view.remove();
|
|
974
|
-
this.view = this.parentView;
|
|
975
|
-
this.unreal = true;
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
destroy() {
|
|
979
|
-
if (this.view) {
|
|
980
|
-
this.stopAutoLayout();
|
|
981
|
-
if (!this.unreal) {
|
|
982
|
-
const view = this.view;
|
|
983
|
-
if (view.parentElement)
|
|
984
|
-
view.remove();
|
|
985
|
-
}
|
|
986
|
-
super.destroy();
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
canvasPatch(CanvasRenderingContext2D.prototype);
|
|
992
|
-
canvasPatch(Path2D.prototype);
|
|
993
|
-
|
|
994
|
-
const PointerEventHelper = {
|
|
995
|
-
convert(e, local) {
|
|
996
|
-
const base = InteractionHelper.getBase(e);
|
|
997
|
-
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 });
|
|
998
|
-
if (data.pointerType === 'pen') {
|
|
999
|
-
data.tangentialPressure = e.tangentialPressure;
|
|
1000
|
-
data.tiltX = e.tiltX;
|
|
1001
|
-
data.tiltY = e.tiltY;
|
|
1002
|
-
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;
|
|
1003
1114
|
}
|
|
1004
1115
|
return data;
|
|
1005
1116
|
},
|
|
@@ -1047,7 +1158,7 @@ const WheelEventHelper = {
|
|
|
1047
1158
|
if (zoom) {
|
|
1048
1159
|
zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
|
|
1049
1160
|
const min = e.deltaY ? config.delta.y : config.delta.x;
|
|
1050
|
-
scale = 1 - delta / (min *
|
|
1161
|
+
scale = 1 - delta / (min * 4) * zoomSpeed;
|
|
1051
1162
|
if (scale < 0.5)
|
|
1052
1163
|
scale = 0.5;
|
|
1053
1164
|
if (scale >= 1.5)
|
|
@@ -1115,12 +1226,6 @@ class Interaction extends InteractionBase {
|
|
|
1115
1226
|
this.windowEvents = {};
|
|
1116
1227
|
}
|
|
1117
1228
|
}
|
|
1118
|
-
getLocal(p, updateClient) {
|
|
1119
|
-
if (updateClient)
|
|
1120
|
-
this.canvas.updateClientBounds();
|
|
1121
|
-
const { clientBounds } = this.canvas;
|
|
1122
|
-
return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
|
|
1123
|
-
}
|
|
1124
1229
|
getTouches(touches) {
|
|
1125
1230
|
const list = [];
|
|
1126
1231
|
for (let i = 0, len = touches.length; i < len; i++) {
|
|
@@ -1148,6 +1253,8 @@ class Interaction extends InteractionBase {
|
|
|
1148
1253
|
this.keyUp(KeyEventHelper.convert(e));
|
|
1149
1254
|
}
|
|
1150
1255
|
onContextMenu(e) {
|
|
1256
|
+
if (this.config.pointer.preventDefaultMenu)
|
|
1257
|
+
e.preventDefault();
|
|
1151
1258
|
this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
|
|
1152
1259
|
}
|
|
1153
1260
|
onScroll() {
|
|
@@ -1277,17 +1384,23 @@ class Interaction extends InteractionBase {
|
|
|
1277
1384
|
onWheel(e) {
|
|
1278
1385
|
this.preventDefaultWheel(e);
|
|
1279
1386
|
const { wheel } = this.config;
|
|
1387
|
+
if (wheel.disabled)
|
|
1388
|
+
return;
|
|
1280
1389
|
const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
|
|
1281
1390
|
const local = this.getLocal(e);
|
|
1282
1391
|
const eventBase = InteractionHelper.getBase(e);
|
|
1283
1392
|
scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
|
|
1284
1393
|
}
|
|
1285
1394
|
onGesturestart(e) {
|
|
1395
|
+
if (this.useMultiTouch)
|
|
1396
|
+
return;
|
|
1286
1397
|
this.preventDefaultWheel(e);
|
|
1287
1398
|
this.lastGestureScale = 1;
|
|
1288
1399
|
this.lastGestureRotation = 0;
|
|
1289
1400
|
}
|
|
1290
1401
|
onGesturechange(e) {
|
|
1402
|
+
if (this.useMultiTouch)
|
|
1403
|
+
return;
|
|
1291
1404
|
this.preventDefaultWheel(e);
|
|
1292
1405
|
const local = this.getLocal(e);
|
|
1293
1406
|
const eventBase = InteractionHelper.getBase(e);
|
|
@@ -1301,9 +1414,34 @@ class Interaction extends InteractionBase {
|
|
|
1301
1414
|
this.lastGestureRotation = e.rotation;
|
|
1302
1415
|
}
|
|
1303
1416
|
onGestureend(e) {
|
|
1417
|
+
if (this.useMultiTouch)
|
|
1418
|
+
return;
|
|
1304
1419
|
this.preventDefaultWheel(e);
|
|
1305
1420
|
this.transformEnd();
|
|
1306
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
|
+
}
|
|
1307
1445
|
destroy() {
|
|
1308
1446
|
if (this.view) {
|
|
1309
1447
|
super.destroy();
|
|
@@ -1313,151 +1451,381 @@ class Interaction extends InteractionBase {
|
|
|
1313
1451
|
}
|
|
1314
1452
|
}
|
|
1315
1453
|
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
canvas.width = width;
|
|
1328
|
-
canvas.height = height;
|
|
1329
|
-
return canvas;
|
|
1330
|
-
},
|
|
1331
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
1332
|
-
canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
|
|
1333
|
-
canvasSaveAs: (canvas, filename, quality) => {
|
|
1334
|
-
return new Promise((resolve) => {
|
|
1335
|
-
let el = document.createElement('a');
|
|
1336
|
-
el.href = canvas.toDataURL(mineType(fileType(filename)), quality);
|
|
1337
|
-
el.download = filename;
|
|
1338
|
-
document.body.appendChild(el);
|
|
1339
|
-
el.click();
|
|
1340
|
-
document.body.removeChild(el);
|
|
1341
|
-
resolve();
|
|
1342
|
-
});
|
|
1343
|
-
},
|
|
1344
|
-
loadImage(src) {
|
|
1345
|
-
return new Promise((resolve, reject) => {
|
|
1346
|
-
const img = new Image();
|
|
1347
|
-
img.setAttribute('crossOrigin', 'anonymous');
|
|
1348
|
-
img.crossOrigin = 'anonymous';
|
|
1349
|
-
img.onload = () => { resolve(img); };
|
|
1350
|
-
img.onerror = (e) => { reject(e); };
|
|
1351
|
-
if (!src.startsWith('data:') && Platform.image.suffix)
|
|
1352
|
-
src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
|
|
1353
|
-
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);
|
|
1354
1465
|
});
|
|
1355
1466
|
}
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
stopNow(origin) { origin.stopImmediatePropagation(); },
|
|
1360
|
-
stop(origin) { origin.stopPropagation(); }
|
|
1361
|
-
};
|
|
1362
|
-
Platform.canvas = Creator.canvas();
|
|
1363
|
-
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
1364
|
-
}
|
|
1365
|
-
Platform.name = 'web';
|
|
1366
|
-
Platform.isMobile = 'ontouchstart' in window;
|
|
1367
|
-
Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
|
|
1368
|
-
Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
|
|
1369
|
-
const { userAgent } = navigator;
|
|
1370
|
-
if (userAgent.indexOf("Firefox") > -1) {
|
|
1371
|
-
Platform.conicGradientRotate90 = true;
|
|
1372
|
-
Platform.intWheelDeltaY = true;
|
|
1373
|
-
Platform.syncDomFont = true;
|
|
1374
|
-
}
|
|
1375
|
-
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
1376
|
-
Platform.fullImageShadow = true;
|
|
1377
|
-
}
|
|
1378
|
-
if (userAgent.indexOf('Windows') > -1) {
|
|
1379
|
-
Platform.os = 'Windows';
|
|
1380
|
-
Platform.intWheelDeltaY = true;
|
|
1381
|
-
}
|
|
1382
|
-
else if (userAgent.indexOf('Mac') > -1) {
|
|
1383
|
-
Platform.os = 'Mac';
|
|
1384
|
-
}
|
|
1385
|
-
else if (userAgent.indexOf('Linux') > -1) {
|
|
1386
|
-
Platform.os = 'Linux';
|
|
1467
|
+
if (decorationY)
|
|
1468
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1469
|
+
}
|
|
1387
1470
|
}
|
|
1388
1471
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
const transform = get$4();
|
|
1393
|
-
const swap = rotation && rotation !== 180;
|
|
1394
|
-
const sw = box.width / (swap ? height : width);
|
|
1395
|
-
const sh = box.height / (swap ? width : height);
|
|
1396
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1397
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
1398
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
1399
|
-
translate$1(transform, x, y);
|
|
1400
|
-
scaleHelper(transform, scale);
|
|
1401
|
-
if (rotation)
|
|
1402
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1403
|
-
data.scaleX = data.scaleY = scale;
|
|
1404
|
-
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());
|
|
1405
1475
|
}
|
|
1406
|
-
function
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
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
|
+
}
|
|
1505
|
+
}
|
|
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);
|
|
1612
|
+
break;
|
|
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);
|
|
1629
|
+
break;
|
|
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);
|
|
1652
|
+
break;
|
|
1653
|
+
}
|
|
1654
|
+
}
|
|
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;
|
|
1415
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);
|
|
1416
1769
|
if (rotation)
|
|
1417
1770
|
rotate(transform, rotation);
|
|
1418
1771
|
data.transform = transform;
|
|
1419
1772
|
}
|
|
1420
|
-
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
|
|
1421
|
-
const transform = get$
|
|
1773
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1774
|
+
const transform = get$3();
|
|
1422
1775
|
if (rotation) {
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
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
|
+
}
|
|
1434
1792
|
}
|
|
1435
1793
|
}
|
|
1436
|
-
origin.x = box.x;
|
|
1437
|
-
origin.y = box.y;
|
|
1438
|
-
if (x || y)
|
|
1439
|
-
origin.x += x, origin.y += y;
|
|
1794
|
+
origin.x = box.x + x;
|
|
1795
|
+
origin.y = box.y + y;
|
|
1440
1796
|
translate$1(transform, origin.x, origin.y);
|
|
1441
|
-
if (scaleX)
|
|
1442
|
-
scaleOfOuter$
|
|
1443
|
-
data.scaleX = scaleX;
|
|
1444
|
-
data.scaleY = scaleY;
|
|
1445
|
-
}
|
|
1797
|
+
if (scaleX)
|
|
1798
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1446
1799
|
data.transform = transform;
|
|
1447
1800
|
}
|
|
1448
1801
|
|
|
1449
|
-
const { get: get$
|
|
1802
|
+
const { get: get$2, translate } = MatrixHelper;
|
|
1803
|
+
const tempBox = new Bounds();
|
|
1804
|
+
const tempPoint = {};
|
|
1450
1805
|
function createData(leafPaint, image, paint, box) {
|
|
1451
|
-
|
|
1452
|
-
const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
|
|
1453
|
-
const sameBox = box.width === width && box.height === height;
|
|
1806
|
+
const { blendMode } = paint;
|
|
1454
1807
|
if (blendMode)
|
|
1455
1808
|
leafPaint.blendMode = blendMode;
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
if (
|
|
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) {
|
|
1461
1829
|
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1462
1830
|
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1463
1831
|
}
|
|
@@ -1465,30 +1833,46 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1465
1833
|
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1466
1834
|
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1467
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;
|
|
1468
1845
|
switch (mode) {
|
|
1469
1846
|
case 'strench':
|
|
1470
1847
|
if (!sameBox)
|
|
1471
1848
|
width = box.width, height = box.height;
|
|
1472
|
-
if (box.x || box.y) {
|
|
1473
|
-
data.transform = get$3();
|
|
1474
|
-
translate(data.transform, box.x, box.y);
|
|
1475
|
-
}
|
|
1476
1849
|
break;
|
|
1850
|
+
case 'normal':
|
|
1477
1851
|
case 'clip':
|
|
1478
|
-
if (
|
|
1852
|
+
if (x || y || scaleX || rotation)
|
|
1479
1853
|
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1480
1854
|
break;
|
|
1481
1855
|
case 'repeat':
|
|
1482
1856
|
if (!sameBox || scaleX || rotation)
|
|
1483
|
-
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1857
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1484
1858
|
if (!repeat)
|
|
1485
1859
|
data.repeat = 'repeat';
|
|
1486
1860
|
break;
|
|
1487
1861
|
case 'fit':
|
|
1488
1862
|
case 'cover':
|
|
1489
1863
|
default:
|
|
1490
|
-
if (
|
|
1491
|
-
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;
|
|
1492
1876
|
}
|
|
1493
1877
|
data.width = width;
|
|
1494
1878
|
data.height = height;
|
|
@@ -1496,112 +1880,108 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1496
1880
|
data.opacity = opacity;
|
|
1497
1881
|
if (repeat)
|
|
1498
1882
|
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1883
|
+
return data;
|
|
1499
1884
|
}
|
|
1500
1885
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
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 };
|
|
1505
1900
|
if (image.ready) {
|
|
1506
|
-
|
|
1507
|
-
createData(leafPaint, image, attrValue, box);
|
|
1901
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1508
1902
|
if (firstUse) {
|
|
1509
|
-
|
|
1510
|
-
|
|
1903
|
+
onLoad(ui, event);
|
|
1904
|
+
onLoadSuccess(ui, event);
|
|
1511
1905
|
}
|
|
1512
1906
|
}
|
|
1513
1907
|
else if (image.error) {
|
|
1514
|
-
if (firstUse)
|
|
1515
|
-
ui.
|
|
1516
|
-
event.error = image.error;
|
|
1517
|
-
emit(ImageEvent.ERROR, event);
|
|
1518
|
-
}
|
|
1908
|
+
if (firstUse)
|
|
1909
|
+
onLoadError(ui, event, image.error);
|
|
1519
1910
|
}
|
|
1520
1911
|
else {
|
|
1912
|
+
ignoreRender(ui, true);
|
|
1521
1913
|
if (firstUse)
|
|
1522
|
-
|
|
1914
|
+
onLoad(ui, event);
|
|
1523
1915
|
leafPaint.loadId = image.load(() => {
|
|
1916
|
+
ignoreRender(ui, false);
|
|
1524
1917
|
if (!ui.destroyed) {
|
|
1525
|
-
if (
|
|
1526
|
-
|
|
1918
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1919
|
+
if (image.hasOpacityPixel)
|
|
1920
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1527
1921
|
ui.forceUpdate('surface');
|
|
1528
1922
|
}
|
|
1529
|
-
|
|
1923
|
+
onLoadSuccess(ui, event);
|
|
1530
1924
|
}
|
|
1925
|
+
leafPaint.loadId = null;
|
|
1531
1926
|
}, (error) => {
|
|
1532
|
-
ui
|
|
1533
|
-
event
|
|
1534
|
-
|
|
1927
|
+
ignoreRender(ui, false);
|
|
1928
|
+
onLoadError(ui, event, error);
|
|
1929
|
+
leafPaint.loadId = null;
|
|
1535
1930
|
});
|
|
1536
1931
|
}
|
|
1537
1932
|
return leafPaint;
|
|
1538
1933
|
}
|
|
1539
|
-
function
|
|
1934
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1540
1935
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
if (
|
|
1936
|
+
const data = ui.__;
|
|
1937
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1938
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1939
|
+
if (data.__autoSide) {
|
|
1545
1940
|
ui.forceUpdate('width');
|
|
1546
1941
|
if (ui.__proxyData) {
|
|
1547
|
-
ui.setProxyAttr('width',
|
|
1548
|
-
ui.setProxyAttr('height',
|
|
1942
|
+
ui.setProxyAttr('width', data.width);
|
|
1943
|
+
ui.setProxyAttr('height', data.height);
|
|
1549
1944
|
}
|
|
1550
1945
|
return false;
|
|
1551
1946
|
}
|
|
1552
1947
|
}
|
|
1948
|
+
if (!leafPaint.data)
|
|
1949
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1553
1950
|
return true;
|
|
1554
1951
|
}
|
|
1555
|
-
function
|
|
1556
|
-
|
|
1557
|
-
|
|
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;
|
|
1558
1971
|
}
|
|
1559
1972
|
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1564
|
-
purpose with or without fee is hereby granted.
|
|
1565
|
-
|
|
1566
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1567
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1568
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1569
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1570
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1571
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1572
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1573
|
-
***************************************************************************** */
|
|
1574
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1578
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1579
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1580
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1581
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1582
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1583
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1584
|
-
});
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1588
|
-
var e = new Error(message);
|
|
1589
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1590
|
-
};
|
|
1591
|
-
|
|
1592
|
-
const Export$1 = {};
|
|
1593
|
-
|
|
1594
|
-
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;
|
|
1595
1975
|
function createPattern(ui, paint, pixelRatio) {
|
|
1596
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1976
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1597
1977
|
const id = scaleX + '-' + scaleY;
|
|
1598
1978
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1599
|
-
scaleX =
|
|
1600
|
-
scaleY =
|
|
1979
|
+
scaleX = abs$1(scaleX);
|
|
1980
|
+
scaleY = abs$1(scaleY);
|
|
1601
1981
|
const { image, data } = paint;
|
|
1602
1982
|
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1603
1983
|
if (sx) {
|
|
1604
|
-
imageMatrix = get$
|
|
1984
|
+
imageMatrix = get$1();
|
|
1605
1985
|
copy$1(imageMatrix, transform);
|
|
1606
1986
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1607
1987
|
scaleX *= sx;
|
|
@@ -1636,22 +2016,14 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1636
2016
|
}
|
|
1637
2017
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1638
2018
|
if (!imageMatrix) {
|
|
1639
|
-
imageMatrix = get$
|
|
2019
|
+
imageMatrix = get$1();
|
|
1640
2020
|
if (transform)
|
|
1641
2021
|
copy$1(imageMatrix, transform);
|
|
1642
2022
|
}
|
|
1643
2023
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1644
2024
|
}
|
|
1645
|
-
const
|
|
1646
|
-
|
|
1647
|
-
if (paint.transform)
|
|
1648
|
-
paint.transform = null;
|
|
1649
|
-
if (imageMatrix)
|
|
1650
|
-
pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
|
|
1651
|
-
}
|
|
1652
|
-
catch (_a) {
|
|
1653
|
-
paint.transform = imageMatrix;
|
|
1654
|
-
}
|
|
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);
|
|
1655
2027
|
paint.style = pattern;
|
|
1656
2028
|
paint.patternId = id;
|
|
1657
2029
|
return true;
|
|
@@ -1661,9 +2033,41 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1661
2033
|
}
|
|
1662
2034
|
}
|
|
1663
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
|
+
|
|
1664
2068
|
const { abs } = Math;
|
|
1665
2069
|
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1666
|
-
const { scaleX, scaleY } = ui.__world;
|
|
2070
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1667
2071
|
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1668
2072
|
return false;
|
|
1669
2073
|
}
|
|
@@ -1678,7 +2082,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1678
2082
|
width *= data.scaleX;
|
|
1679
2083
|
height *= data.scaleY;
|
|
1680
2084
|
}
|
|
1681
|
-
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
2085
|
+
allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
|
|
1682
2086
|
}
|
|
1683
2087
|
else {
|
|
1684
2088
|
allowPaint = false;
|
|
@@ -1697,307 +2101,72 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1697
2101
|
canvas.restore();
|
|
1698
2102
|
return true;
|
|
1699
2103
|
}
|
|
1700
|
-
else {
|
|
1701
|
-
if (!paint.style || Export
|
|
1702
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1703
|
-
}
|
|
1704
|
-
else {
|
|
1705
|
-
if (!paint.patternTask) {
|
|
1706
|
-
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1707
|
-
paint.patternTask = null;
|
|
1708
|
-
if (canvas.bounds.hit(ui.__world))
|
|
1709
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1710
|
-
ui.forceUpdate('surface');
|
|
1711
|
-
}), 300);
|
|
1712
|
-
}
|
|
1713
|
-
}
|
|
1714
|
-
return false;
|
|
1715
|
-
}
|
|
1716
|
-
}
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
function recycleImage(attrName, data) {
|
|
1720
|
-
const paints = data['_' + attrName];
|
|
1721
|
-
if (paints instanceof Array) {
|
|
1722
|
-
let image, recycleMap, input, url;
|
|
1723
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1724
|
-
image = paints[i].image;
|
|
1725
|
-
url = image && image.url;
|
|
1726
|
-
if (url) {
|
|
1727
|
-
if (!recycleMap)
|
|
1728
|
-
recycleMap = {};
|
|
1729
|
-
recycleMap[url] = true;
|
|
1730
|
-
ImageManager.recycle(image);
|
|
1731
|
-
if (image.loading) {
|
|
1732
|
-
if (!input) {
|
|
1733
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1734
|
-
if (!(input instanceof Array))
|
|
1735
|
-
input = [input];
|
|
1736
|
-
}
|
|
1737
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1738
|
-
}
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
return recycleMap;
|
|
1742
|
-
}
|
|
1743
|
-
return null;
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
function fillText(ui, canvas) {
|
|
1747
|
-
let row;
|
|
1748
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1749
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1750
|
-
row = rows[i];
|
|
1751
|
-
if (row.text) {
|
|
1752
|
-
canvas.fillText(row.text, row.x, row.y);
|
|
1753
|
-
}
|
|
1754
|
-
else if (row.data) {
|
|
1755
|
-
row.data.forEach(charData => {
|
|
1756
|
-
canvas.fillText(charData.char, charData.x, row.y);
|
|
1757
|
-
});
|
|
1758
|
-
}
|
|
1759
|
-
if (decorationY)
|
|
1760
|
-
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
|
|
1764
|
-
function fill(fill, ui, canvas) {
|
|
1765
|
-
canvas.fillStyle = fill;
|
|
1766
|
-
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1767
|
-
}
|
|
1768
|
-
function fills(fills, ui, canvas) {
|
|
1769
|
-
let item;
|
|
1770
|
-
const { windingRule, __font } = ui.__;
|
|
1771
|
-
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1772
|
-
item = fills[i];
|
|
1773
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1774
|
-
continue;
|
|
1775
|
-
if (item.style) {
|
|
1776
|
-
canvas.fillStyle = item.style;
|
|
1777
|
-
if (item.transform) {
|
|
1778
|
-
canvas.save();
|
|
1779
|
-
canvas.transform(item.transform);
|
|
1780
|
-
if (item.blendMode)
|
|
1781
|
-
canvas.blendMode = item.blendMode;
|
|
1782
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1783
|
-
canvas.restore();
|
|
1784
|
-
}
|
|
1785
|
-
else {
|
|
1786
|
-
if (item.blendMode) {
|
|
1787
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1788
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1789
|
-
canvas.restoreBlendMode();
|
|
1790
|
-
}
|
|
1791
|
-
else {
|
|
1792
|
-
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1793
|
-
}
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
function strokeText(stroke, ui, canvas, renderOptions) {
|
|
1800
|
-
const { strokeAlign } = ui.__;
|
|
1801
|
-
const isStrokes = typeof stroke !== 'string';
|
|
1802
|
-
switch (strokeAlign) {
|
|
1803
|
-
case 'center':
|
|
1804
|
-
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1805
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1806
|
-
break;
|
|
1807
|
-
case 'inside':
|
|
1808
|
-
drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1809
|
-
break;
|
|
1810
|
-
case 'outside':
|
|
1811
|
-
drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
|
|
1812
|
-
break;
|
|
1813
|
-
}
|
|
1814
|
-
}
|
|
1815
|
-
function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
|
|
1816
|
-
const { strokeWidth, __font } = ui.__;
|
|
1817
|
-
const out = canvas.getSameCanvas(true);
|
|
1818
|
-
out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
|
|
1819
|
-
out.font = __font;
|
|
1820
|
-
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1821
|
-
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1822
|
-
fillText(ui, out);
|
|
1823
|
-
out.blendMode = 'normal';
|
|
1824
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1825
|
-
canvas.copyWorldByReset(out);
|
|
1826
|
-
}
|
|
1827
|
-
else {
|
|
1828
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1829
|
-
}
|
|
1830
|
-
out.recycle();
|
|
1831
|
-
}
|
|
1832
|
-
function drawTextStroke(ui, canvas) {
|
|
1833
|
-
let row;
|
|
1834
|
-
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1835
|
-
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1836
|
-
row = rows[i];
|
|
1837
|
-
if (row.text) {
|
|
1838
|
-
canvas.strokeText(row.text, row.x, row.y);
|
|
1839
|
-
}
|
|
1840
|
-
else if (row.data) {
|
|
1841
|
-
row.data.forEach(charData => {
|
|
1842
|
-
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1843
|
-
});
|
|
1844
|
-
}
|
|
1845
|
-
if (decorationY)
|
|
1846
|
-
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1850
|
-
let item;
|
|
1851
|
-
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1852
|
-
item = strokes[i];
|
|
1853
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1854
|
-
continue;
|
|
1855
|
-
if (item.style) {
|
|
1856
|
-
canvas.strokeStyle = item.style;
|
|
1857
|
-
if (item.blendMode) {
|
|
1858
|
-
canvas.saveBlendMode(item.blendMode);
|
|
1859
|
-
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1860
|
-
canvas.restoreBlendMode();
|
|
2104
|
+
else {
|
|
2105
|
+
if (!paint.style || Export.running) {
|
|
2106
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1861
2107
|
}
|
|
1862
2108
|
else {
|
|
1863
|
-
|
|
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
|
+
}
|
|
1864
2117
|
}
|
|
2118
|
+
return false;
|
|
1865
2119
|
}
|
|
1866
2120
|
}
|
|
1867
2121
|
}
|
|
1868
2122
|
|
|
1869
|
-
function
|
|
1870
|
-
const
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
canvas.restore();
|
|
1889
|
-
break;
|
|
1890
|
-
case 'outside':
|
|
1891
|
-
const out = canvas.getSameCanvas(true);
|
|
1892
|
-
out.setStroke(stroke, strokeWidth * 2, ui.__);
|
|
1893
|
-
ui.__drawRenderPath(out);
|
|
1894
|
-
out.stroke();
|
|
1895
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1896
|
-
out.clearWorld(ui.__layout.renderBounds);
|
|
1897
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1898
|
-
canvas.copyWorldByReset(out);
|
|
1899
|
-
}
|
|
1900
|
-
else {
|
|
1901
|
-
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
|
|
1902
|
-
}
|
|
1903
|
-
out.recycle();
|
|
1904
|
-
break;
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
function strokes(strokes, ui, canvas, renderOptions) {
|
|
1909
|
-
const options = ui.__;
|
|
1910
|
-
const { strokeWidth, strokeAlign, __font } = options;
|
|
1911
|
-
if (!strokeWidth)
|
|
1912
|
-
return;
|
|
1913
|
-
if (__font) {
|
|
1914
|
-
strokeText(strokes, ui, canvas, renderOptions);
|
|
1915
|
-
}
|
|
1916
|
-
else {
|
|
1917
|
-
switch (strokeAlign) {
|
|
1918
|
-
case 'center':
|
|
1919
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1920
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1921
|
-
break;
|
|
1922
|
-
case 'inside':
|
|
1923
|
-
canvas.save();
|
|
1924
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1925
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1926
|
-
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1927
|
-
canvas.restore();
|
|
1928
|
-
break;
|
|
1929
|
-
case 'outside':
|
|
1930
|
-
const { renderBounds } = ui.__layout;
|
|
1931
|
-
const out = canvas.getSameCanvas(true);
|
|
1932
|
-
ui.__drawRenderPath(out);
|
|
1933
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1934
|
-
drawStrokesStyle(strokes, false, ui, out);
|
|
1935
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1936
|
-
out.clearWorld(renderBounds);
|
|
1937
|
-
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
1938
|
-
canvas.copyWorldByReset(out);
|
|
1939
|
-
}
|
|
1940
|
-
else {
|
|
1941
|
-
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));
|
|
1942
2142
|
}
|
|
1943
|
-
|
|
1944
|
-
break;
|
|
2143
|
+
}
|
|
1945
2144
|
}
|
|
2145
|
+
return recycleMap;
|
|
1946
2146
|
}
|
|
2147
|
+
return null;
|
|
1947
2148
|
}
|
|
1948
2149
|
|
|
1949
|
-
const
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
if (!current.bounds.includes(__world, options.matrix)) {
|
|
1961
|
-
const { renderShapeSpread: spread } = ui.__layout;
|
|
1962
|
-
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
|
|
1963
|
-
matrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1964
|
-
if (matrix.a < 1) {
|
|
1965
|
-
worldCanvas = current.getSameCanvas();
|
|
1966
|
-
ui.__renderShape(worldCanvas, options);
|
|
1967
|
-
scaleX *= matrix.a;
|
|
1968
|
-
scaleY *= matrix.d;
|
|
1969
|
-
}
|
|
1970
|
-
shapeBounds = getOuterOf(__world, matrix);
|
|
1971
|
-
bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
|
|
1972
|
-
if (options.matrix)
|
|
1973
|
-
matrix.multiply(options.matrix);
|
|
1974
|
-
options = Object.assign(Object.assign({}, options), { matrix });
|
|
1975
|
-
}
|
|
1976
|
-
else {
|
|
1977
|
-
if (options.matrix) {
|
|
1978
|
-
scaleX *= options.matrix.a;
|
|
1979
|
-
scaleY *= options.matrix.d;
|
|
1980
|
-
bounds = shapeBounds = getOuterOf(__world, options.matrix);
|
|
1981
|
-
}
|
|
1982
|
-
else {
|
|
1983
|
-
bounds = shapeBounds = __world;
|
|
1984
|
-
}
|
|
1985
|
-
worldCanvas = canvas;
|
|
1986
|
-
}
|
|
1987
|
-
ui.__renderShape(canvas, options);
|
|
1988
|
-
return {
|
|
1989
|
-
canvas, matrix, bounds,
|
|
1990
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1991
|
-
};
|
|
1992
|
-
}
|
|
2150
|
+
const PaintImageModule = {
|
|
2151
|
+
image,
|
|
2152
|
+
checkImage,
|
|
2153
|
+
createPattern,
|
|
2154
|
+
recycleImage,
|
|
2155
|
+
createData,
|
|
2156
|
+
getPatternData,
|
|
2157
|
+
fillOrFitMode,
|
|
2158
|
+
clipMode,
|
|
2159
|
+
repeatMode
|
|
2160
|
+
};
|
|
1993
2161
|
|
|
1994
|
-
const
|
|
1995
|
-
const
|
|
2162
|
+
const { toPoint: toPoint$2 } = AroundHelper;
|
|
2163
|
+
const realFrom$2 = {};
|
|
2164
|
+
const realTo$2 = {};
|
|
1996
2165
|
function linearGradient(paint, box) {
|
|
1997
2166
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1998
|
-
from ||
|
|
1999
|
-
to ||
|
|
2000
|
-
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);
|
|
2001
2170
|
applyStops(style, paint.stops, opacity);
|
|
2002
2171
|
const data = { type, style };
|
|
2003
2172
|
if (blendMode)
|
|
@@ -2008,137 +2177,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
2008
2177
|
let stop;
|
|
2009
2178
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
2010
2179
|
stop = stops[i];
|
|
2011
|
-
|
|
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
|
+
}
|
|
2012
2186
|
}
|
|
2013
2187
|
}
|
|
2014
2188
|
|
|
2015
|
-
const {
|
|
2016
|
-
const { get
|
|
2017
|
-
const
|
|
2018
|
-
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;
|
|
2019
2192
|
const realFrom$1 = {};
|
|
2020
2193
|
const realTo$1 = {};
|
|
2021
2194
|
function radialGradient(paint, box) {
|
|
2022
2195
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
2023
|
-
from ||
|
|
2024
|
-
to ||
|
|
2025
|
-
const { x, y, width, height } = box;
|
|
2026
|
-
set$1(realFrom$1, x + from.x * width, y + from.y * height);
|
|
2027
|
-
set$1(realTo$1, x + to.x * width, y + to.y * height);
|
|
2028
|
-
let transform;
|
|
2029
|
-
if (width !== height || stretch) {
|
|
2030
|
-
transform = get$1();
|
|
2031
|
-
scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
|
|
2032
|
-
rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
|
|
2033
|
-
}
|
|
2196
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
2197
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
2034
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));
|
|
2035
2199
|
applyStops(style, paint.stops, opacity);
|
|
2036
|
-
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;
|
|
2037
2204
|
if (blendMode)
|
|
2038
2205
|
data.blendMode = blendMode;
|
|
2039
2206
|
return data;
|
|
2040
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
|
+
}
|
|
2041
2225
|
|
|
2042
|
-
const {
|
|
2043
|
-
const {
|
|
2044
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
2045
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
2226
|
+
const { getDistance } = PointHelper;
|
|
2227
|
+
const { toPoint } = AroundHelper;
|
|
2046
2228
|
const realFrom = {};
|
|
2047
2229
|
const realTo = {};
|
|
2048
2230
|
function conicGradient(paint, box) {
|
|
2049
2231
|
let { from, to, type, opacity, blendMode, stretch } = paint;
|
|
2050
|
-
from ||
|
|
2051
|
-
to ||
|
|
2052
|
-
const { x, y, width, height } = box;
|
|
2053
|
-
set(realFrom, x + from.x * width, y + from.y * height);
|
|
2054
|
-
set(realTo, x + to.x * width, y + to.y * height);
|
|
2055
|
-
const transform = get();
|
|
2056
|
-
const angle = getAngle(realFrom, realTo);
|
|
2057
|
-
if (Platform.conicGradientRotate90) {
|
|
2058
|
-
scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
|
|
2059
|
-
rotateOfOuter(transform, realFrom, angle + 90);
|
|
2060
|
-
}
|
|
2061
|
-
else {
|
|
2062
|
-
scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
|
|
2063
|
-
rotateOfOuter(transform, realFrom, angle);
|
|
2064
|
-
}
|
|
2232
|
+
toPoint(from || 'center', box, realFrom);
|
|
2233
|
+
toPoint(to || 'bottom', box, realTo);
|
|
2065
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));
|
|
2066
2235
|
applyStops(style, paint.stops, opacity);
|
|
2067
|
-
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;
|
|
2068
2240
|
if (blendMode)
|
|
2069
2241
|
data.blendMode = blendMode;
|
|
2070
2242
|
return data;
|
|
2071
2243
|
}
|
|
2072
2244
|
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
if (!(paints instanceof Array))
|
|
2080
|
-
paints = [paints];
|
|
2081
|
-
recycleMap = recycleImage(attrName, data);
|
|
2082
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
2083
|
-
item = getLeafPaint(attrName, paints[i], ui);
|
|
2084
|
-
if (item)
|
|
2085
|
-
value.push(item);
|
|
2086
|
-
}
|
|
2087
|
-
data['_' + attrName] = value.length ? value : undefined;
|
|
2088
|
-
let isPixel;
|
|
2089
|
-
if (paints.length === 1) {
|
|
2090
|
-
const paint = paints[0];
|
|
2091
|
-
if (paint.type === 'image')
|
|
2092
|
-
isPixel = ImageManager$1.isPixel(paint);
|
|
2093
|
-
}
|
|
2094
|
-
if (attrName === 'fill') {
|
|
2095
|
-
data.__pixelFill = isPixel;
|
|
2096
|
-
}
|
|
2097
|
-
else {
|
|
2098
|
-
data.__pixelStroke = isPixel;
|
|
2099
|
-
}
|
|
2100
|
-
}
|
|
2101
|
-
function getLeafPaint(attrName, paint, ui) {
|
|
2102
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
2103
|
-
return undefined;
|
|
2104
|
-
const { boxBounds } = ui.__layout;
|
|
2105
|
-
switch (paint.type) {
|
|
2106
|
-
case 'solid':
|
|
2107
|
-
let { type, blendMode, color, opacity } = paint;
|
|
2108
|
-
return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
|
|
2109
|
-
case 'image':
|
|
2110
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
2111
|
-
case 'linear':
|
|
2112
|
-
return linearGradient(paint, boxBounds);
|
|
2113
|
-
case 'radial':
|
|
2114
|
-
return radialGradient(paint, boxBounds);
|
|
2115
|
-
case 'angular':
|
|
2116
|
-
return conicGradient(paint, boxBounds);
|
|
2117
|
-
default:
|
|
2118
|
-
return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
|
|
2119
|
-
}
|
|
2120
|
-
}
|
|
2121
|
-
|
|
2122
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
2123
|
-
__proto__: null,
|
|
2124
|
-
compute: compute,
|
|
2125
|
-
drawTextStroke: drawTextStroke,
|
|
2126
|
-
fill: fill,
|
|
2127
|
-
fillText: fillText,
|
|
2128
|
-
fills: fills,
|
|
2129
|
-
recycleImage: recycleImage,
|
|
2130
|
-
shape: shape,
|
|
2131
|
-
stroke: stroke,
|
|
2132
|
-
strokeText: strokeText,
|
|
2133
|
-
strokes: strokes
|
|
2134
|
-
});
|
|
2245
|
+
const PaintGradientModule = {
|
|
2246
|
+
linearGradient,
|
|
2247
|
+
radialGradient,
|
|
2248
|
+
conicGradient,
|
|
2249
|
+
getTransform
|
|
2250
|
+
};
|
|
2135
2251
|
|
|
2136
2252
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
2137
2253
|
const tempBounds = {};
|
|
2138
2254
|
const offsetOutBounds$1 = {};
|
|
2139
|
-
function shadow(ui, current, shape
|
|
2255
|
+
function shadow(ui, current, shape) {
|
|
2140
2256
|
let copyBounds, spreadScale;
|
|
2141
|
-
const {
|
|
2257
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
2142
2258
|
const { shadow } = ui.__;
|
|
2143
2259
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2144
2260
|
const other = current.getSameCanvas();
|
|
@@ -2153,21 +2269,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
2153
2269
|
other.restore();
|
|
2154
2270
|
other.save();
|
|
2155
2271
|
if (worldCanvas) {
|
|
2156
|
-
other.copyWorld(other, bounds,
|
|
2157
|
-
copyBounds =
|
|
2272
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2273
|
+
copyBounds = nowWorld;
|
|
2158
2274
|
}
|
|
2159
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
2275
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
2160
2276
|
}
|
|
2161
|
-
if (ui.__worldFlipped
|
|
2162
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2277
|
+
if (ui.__worldFlipped) {
|
|
2278
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2163
2279
|
}
|
|
2164
2280
|
else {
|
|
2165
2281
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2166
2282
|
}
|
|
2167
2283
|
if (end && index < end)
|
|
2168
|
-
other.
|
|
2284
|
+
other.clearWorld(copyBounds, true);
|
|
2169
2285
|
});
|
|
2170
|
-
other.recycle();
|
|
2286
|
+
other.recycle(copyBounds);
|
|
2171
2287
|
}
|
|
2172
2288
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
2173
2289
|
const { bounds, shapeBounds } = shape;
|
|
@@ -2198,9 +2314,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
2198
2314
|
|
|
2199
2315
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
2200
2316
|
const offsetOutBounds = {};
|
|
2201
|
-
function innerShadow(ui, current, shape
|
|
2317
|
+
function innerShadow(ui, current, shape) {
|
|
2202
2318
|
let copyBounds, spreadScale;
|
|
2203
|
-
const {
|
|
2319
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
2204
2320
|
const { innerShadow } = ui.__;
|
|
2205
2321
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2206
2322
|
const other = current.getSameCanvas();
|
|
@@ -2213,40 +2329,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
2213
2329
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
2214
2330
|
other.restore();
|
|
2215
2331
|
if (worldCanvas) {
|
|
2216
|
-
other.copyWorld(other, bounds,
|
|
2217
|
-
other.copyWorld(worldCanvas,
|
|
2218
|
-
copyBounds =
|
|
2332
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2333
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
2334
|
+
copyBounds = nowWorld;
|
|
2219
2335
|
}
|
|
2220
2336
|
else {
|
|
2221
2337
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
2222
2338
|
copyBounds = bounds;
|
|
2223
2339
|
}
|
|
2224
2340
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
2225
|
-
if (ui.__worldFlipped
|
|
2226
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2341
|
+
if (ui.__worldFlipped) {
|
|
2342
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2227
2343
|
}
|
|
2228
2344
|
else {
|
|
2229
2345
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2230
2346
|
}
|
|
2231
2347
|
if (end && index < end)
|
|
2232
|
-
other.
|
|
2348
|
+
other.clearWorld(copyBounds, true);
|
|
2233
2349
|
});
|
|
2234
|
-
other.recycle();
|
|
2350
|
+
other.recycle(copyBounds);
|
|
2235
2351
|
}
|
|
2236
2352
|
|
|
2237
2353
|
function blur(ui, current, origin) {
|
|
2238
2354
|
const { blur } = ui.__;
|
|
2239
|
-
origin.setWorldBlur(blur * ui.
|
|
2240
|
-
origin.copyWorldToInner(current, ui.
|
|
2355
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
2356
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
2241
2357
|
origin.filter = 'none';
|
|
2242
2358
|
}
|
|
2243
2359
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
shadow
|
|
2249
|
-
|
|
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
|
+
}
|
|
2250
2441
|
|
|
2251
2442
|
const money = '¥¥$€££¢¢';
|
|
2252
2443
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -2403,7 +2594,8 @@ function createRows(drawData, content, style) {
|
|
|
2403
2594
|
if (breakAll) {
|
|
2404
2595
|
if (wordWidth)
|
|
2405
2596
|
addWord();
|
|
2406
|
-
|
|
2597
|
+
if (rowWidth)
|
|
2598
|
+
addRow();
|
|
2407
2599
|
}
|
|
2408
2600
|
else {
|
|
2409
2601
|
if (!afterBreak)
|
|
@@ -2411,10 +2603,12 @@ function createRows(drawData, content, style) {
|
|
|
2411
2603
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2412
2604
|
if (wordWidth)
|
|
2413
2605
|
addWord();
|
|
2414
|
-
|
|
2606
|
+
if (rowWidth)
|
|
2607
|
+
addRow();
|
|
2415
2608
|
}
|
|
2416
2609
|
else {
|
|
2417
|
-
|
|
2610
|
+
if (rowWidth)
|
|
2611
|
+
addRow();
|
|
2418
2612
|
}
|
|
2419
2613
|
}
|
|
2420
2614
|
}
|
|
@@ -2509,11 +2703,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2509
2703
|
if (mode === WordMode) {
|
|
2510
2704
|
wordChar = { char: '', x: charX };
|
|
2511
2705
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2512
|
-
if (wordChar.char !== ' ')
|
|
2706
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2513
2707
|
row.data.push(wordChar);
|
|
2514
2708
|
}
|
|
2515
2709
|
else {
|
|
2516
|
-
charX = toChar(word.data, charX, row.data);
|
|
2710
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2517
2711
|
}
|
|
2518
2712
|
if (!row.paraEnd && addWordWidth) {
|
|
2519
2713
|
charX += addWordWidth;
|
|
@@ -2540,9 +2734,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2540
2734
|
});
|
|
2541
2735
|
return charX;
|
|
2542
2736
|
}
|
|
2543
|
-
function toChar(data, charX, rowData) {
|
|
2737
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2544
2738
|
data.forEach(char => {
|
|
2545
|
-
if (char.char !== ' ') {
|
|
2739
|
+
if (isOverflow || char.char !== ' ') {
|
|
2546
2740
|
char.x = charX;
|
|
2547
2741
|
rowData.push(char);
|
|
2548
2742
|
}
|
|
@@ -2574,12 +2768,14 @@ function layoutText(drawData, style) {
|
|
|
2574
2768
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2575
2769
|
row = rows[i];
|
|
2576
2770
|
row.x = x;
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
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
|
+
}
|
|
2583
2779
|
}
|
|
2584
2780
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2585
2781
|
starY += paraSpacing;
|
|
@@ -2615,16 +2811,20 @@ function layoutText(drawData, style) {
|
|
|
2615
2811
|
bounds.height = realHeight;
|
|
2616
2812
|
}
|
|
2617
2813
|
|
|
2618
|
-
function clipText(drawData, style) {
|
|
2814
|
+
function clipText(drawData, style, x, width) {
|
|
2815
|
+
if (!width)
|
|
2816
|
+
return;
|
|
2619
2817
|
const { rows, overflow } = drawData;
|
|
2620
2818
|
let { textOverflow } = style;
|
|
2621
2819
|
rows.splice(overflow);
|
|
2622
|
-
if (textOverflow !== '
|
|
2623
|
-
if (textOverflow === '
|
|
2820
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2821
|
+
if (textOverflow === 'hide')
|
|
2822
|
+
textOverflow = '';
|
|
2823
|
+
else if (textOverflow === 'ellipsis')
|
|
2624
2824
|
textOverflow = '...';
|
|
2625
2825
|
let char, charRight;
|
|
2626
|
-
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2627
|
-
const right =
|
|
2826
|
+
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2827
|
+
const right = x + width - ellipsisWidth;
|
|
2628
2828
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2629
2829
|
list.forEach(row => {
|
|
2630
2830
|
if (row.isOverflow && row.data) {
|
|
@@ -2671,42 +2871,40 @@ function decorationText(drawData, style) {
|
|
|
2671
2871
|
}
|
|
2672
2872
|
|
|
2673
2873
|
const { top, right, bottom, left } = Direction4;
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
if (
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
}
|
|
2709
|
-
};
|
|
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
|
+
}
|
|
2710
2908
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2711
2909
|
if (!width) {
|
|
2712
2910
|
switch (style.textAlign) {
|
|
@@ -2734,67 +2932,152 @@ function offsetText(drawData, attrName, value) {
|
|
|
2734
2932
|
rows[i][attrName] += value;
|
|
2735
2933
|
}
|
|
2736
2934
|
|
|
2737
|
-
const
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
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
|
|
2747
2951
|
};
|
|
2748
2952
|
|
|
2749
|
-
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 = {
|
|
2750
2972
|
export(leaf, filename, options) {
|
|
2751
|
-
|
|
2973
|
+
this.running = true;
|
|
2974
|
+
const fileType = FileHelper.fileType(filename);
|
|
2975
|
+
options = FileHelper.getExportOptions(options);
|
|
2752
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
|
+
}
|
|
2753
2998
|
const { leafer } = leaf;
|
|
2754
2999
|
if (leafer) {
|
|
3000
|
+
checkLazy(leaf);
|
|
2755
3001
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2756
|
-
let
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
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;
|
|
2763
3018
|
}
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
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);
|
|
2776
3045
|
}
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
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;
|
|
2780
3052
|
}
|
|
2781
|
-
|
|
2782
|
-
|
|
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;
|
|
2783
3059
|
}
|
|
2784
3060
|
else {
|
|
2785
|
-
|
|
3061
|
+
leaf.__render(canvas, renderOptions);
|
|
2786
3062
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
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 });
|
|
2792
3077
|
}));
|
|
2793
3078
|
}
|
|
2794
3079
|
else {
|
|
2795
|
-
|
|
2796
|
-
resolve();
|
|
2797
|
-
Export.running = false;
|
|
3080
|
+
over({ data: false });
|
|
2798
3081
|
}
|
|
2799
3082
|
}));
|
|
2800
3083
|
}
|
|
@@ -2807,13 +3090,64 @@ function addTask(task) {
|
|
|
2807
3090
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2808
3091
|
});
|
|
2809
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
|
+
};
|
|
2810
3137
|
|
|
2811
|
-
Object.assign(
|
|
2812
|
-
Object.assign(
|
|
2813
|
-
Object.assign(
|
|
2814
|
-
Object.assign(
|
|
2815
|
-
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);
|
|
2816
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
|
+
});
|
|
2817
3151
|
useCanvas();
|
|
2818
3152
|
|
|
2819
3153
|
export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|