leafer-ui 1.0.0-rc.9 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -6
- package/dist/web.esm.js +1343 -990
- package/dist/web.esm.min.js +1 -1
- package/dist/web.js +7702 -6498
- package/dist/web.min.js +1 -1
- package/dist/web.module.js +7674 -6488
- 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,269 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, 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 { config } = this;
|
|
30
|
+
const view = config.view || config.canvas;
|
|
31
|
+
view ? this.__createViewFrom(view) : this.__createView();
|
|
32
|
+
const { style } = this.view;
|
|
33
|
+
style.display || (style.display = 'block');
|
|
34
|
+
this.parentView = this.view.parentElement;
|
|
35
|
+
if (this.parentView) {
|
|
36
|
+
const pStyle = this.parentView.style;
|
|
37
|
+
pStyle.webkitUserSelect = pStyle.userSelect = 'none';
|
|
38
|
+
}
|
|
39
|
+
if (Platform.syncDomFont && !this.parentView) {
|
|
40
|
+
style.display = 'none';
|
|
41
|
+
document.body.appendChild(this.view);
|
|
42
|
+
}
|
|
43
|
+
this.__createContext();
|
|
44
|
+
if (!this.autoLayout)
|
|
45
|
+
this.resize(config);
|
|
46
|
+
}
|
|
47
|
+
set backgroundColor(color) { this.view.style.backgroundColor = color; }
|
|
48
|
+
get backgroundColor() { return this.view.style.backgroundColor; }
|
|
49
|
+
set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
|
|
50
|
+
get hittable() { return this.view.style.pointerEvents !== 'none'; }
|
|
51
|
+
__createView() {
|
|
52
|
+
this.view = document.createElement('canvas');
|
|
53
|
+
}
|
|
54
|
+
__createViewFrom(inputView) {
|
|
55
|
+
let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
|
|
56
|
+
if (find) {
|
|
57
|
+
if (find instanceof HTMLCanvasElement) {
|
|
58
|
+
this.view = find;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
let parent = find;
|
|
62
|
+
if (find === window || find === document) {
|
|
63
|
+
const div = document.createElement('div');
|
|
64
|
+
const { style } = div;
|
|
65
|
+
style.position = 'absolute';
|
|
66
|
+
style.top = style.bottom = style.left = style.right = '0px';
|
|
67
|
+
document.body.appendChild(div);
|
|
68
|
+
parent = div;
|
|
69
|
+
}
|
|
70
|
+
this.__createView();
|
|
71
|
+
const view = this.view;
|
|
72
|
+
if (parent.hasChildNodes()) {
|
|
73
|
+
this.setAbsolute(view);
|
|
74
|
+
parent.style.position || (parent.style.position = 'relative');
|
|
75
|
+
}
|
|
76
|
+
parent.appendChild(view);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
debug$3.error(`no id: ${inputView}`);
|
|
81
|
+
this.__createView();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
setAbsolute(view) {
|
|
85
|
+
const { style } = view;
|
|
86
|
+
style.position = 'absolute';
|
|
87
|
+
style.top = style.left = '0px';
|
|
88
|
+
}
|
|
89
|
+
updateViewSize() {
|
|
90
|
+
const { width, height, pixelRatio } = this;
|
|
91
|
+
const { style } = this.view;
|
|
92
|
+
style.width = width + 'px';
|
|
93
|
+
style.height = height + 'px';
|
|
94
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
95
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
96
|
+
}
|
|
97
|
+
updateClientBounds() {
|
|
98
|
+
this.clientBounds = this.view.getBoundingClientRect();
|
|
99
|
+
}
|
|
100
|
+
startAutoLayout(autoBounds, listener) {
|
|
101
|
+
this.resizeListener = listener;
|
|
102
|
+
if (autoBounds) {
|
|
103
|
+
this.autoBounds = autoBounds;
|
|
104
|
+
try {
|
|
105
|
+
this.resizeObserver = new ResizeObserver((entries) => {
|
|
106
|
+
this.updateClientBounds();
|
|
107
|
+
for (const entry of entries)
|
|
108
|
+
this.checkAutoBounds(entry.contentRect);
|
|
109
|
+
});
|
|
110
|
+
const parent = this.parentView;
|
|
111
|
+
if (parent) {
|
|
112
|
+
this.resizeObserver.observe(parent);
|
|
113
|
+
this.checkAutoBounds(parent.getBoundingClientRect());
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this.checkAutoBounds(this.view);
|
|
117
|
+
debug$3.warn('no parent');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (_a) {
|
|
121
|
+
this.imitateResizeObserver();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
window.addEventListener('resize', () => {
|
|
126
|
+
const pixelRatio = Platform.devicePixelRatio;
|
|
127
|
+
if (this.pixelRatio !== pixelRatio) {
|
|
128
|
+
const { width, height } = this;
|
|
129
|
+
this.emitResize({ width, height, pixelRatio });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
imitateResizeObserver() {
|
|
135
|
+
if (this.autoLayout) {
|
|
136
|
+
if (this.parentView)
|
|
137
|
+
this.checkAutoBounds(this.parentView.getBoundingClientRect());
|
|
138
|
+
Platform.requestRender(this.imitateResizeObserver.bind(this));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
checkAutoBounds(parentSize) {
|
|
142
|
+
const view = this.view;
|
|
143
|
+
const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
|
|
144
|
+
const size = { width, height, pixelRatio: Platform.devicePixelRatio };
|
|
145
|
+
if (!this.isSameSize(size)) {
|
|
146
|
+
const { style } = view;
|
|
147
|
+
style.marginLeft = x + 'px';
|
|
148
|
+
style.marginTop = y + 'px';
|
|
149
|
+
this.emitResize(size);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
stopAutoLayout() {
|
|
153
|
+
this.autoLayout = false;
|
|
154
|
+
this.resizeListener = null;
|
|
155
|
+
if (this.resizeObserver) {
|
|
156
|
+
this.resizeObserver.disconnect();
|
|
157
|
+
this.resizeObserver = null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
emitResize(size) {
|
|
161
|
+
const oldSize = {};
|
|
162
|
+
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
163
|
+
this.resize(size);
|
|
164
|
+
if (this.width !== undefined)
|
|
165
|
+
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
166
|
+
}
|
|
167
|
+
unrealCanvas() {
|
|
168
|
+
if (!this.unreal && this.parentView) {
|
|
169
|
+
const view = this.view;
|
|
170
|
+
if (view)
|
|
171
|
+
view.remove();
|
|
172
|
+
this.view = this.parentView;
|
|
173
|
+
this.unreal = true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
destroy() {
|
|
177
|
+
if (this.view) {
|
|
178
|
+
this.stopAutoLayout();
|
|
179
|
+
if (!this.unreal) {
|
|
180
|
+
const view = this.view;
|
|
181
|
+
if (view.parentElement)
|
|
182
|
+
view.remove();
|
|
183
|
+
}
|
|
184
|
+
super.destroy();
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
canvasPatch(CanvasRenderingContext2D.prototype);
|
|
190
|
+
canvasPatch(Path2D.prototype);
|
|
191
|
+
|
|
192
|
+
const { mineType, fileType } = FileHelper;
|
|
193
|
+
Object.assign(Creator, {
|
|
194
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
195
|
+
image: (options) => new LeaferImage(options)
|
|
196
|
+
});
|
|
197
|
+
function useCanvas(_canvasType, _power) {
|
|
198
|
+
Platform.origin = {
|
|
199
|
+
createCanvas(width, height) {
|
|
200
|
+
const canvas = document.createElement('canvas');
|
|
201
|
+
canvas.width = width;
|
|
202
|
+
canvas.height = height;
|
|
203
|
+
return canvas;
|
|
204
|
+
},
|
|
205
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
206
|
+
canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
|
|
207
|
+
canvasSaveAs: (canvas, filename, quality) => {
|
|
208
|
+
const url = canvas.toDataURL(mineType(fileType(filename)), quality);
|
|
209
|
+
return Platform.origin.download(url, filename);
|
|
210
|
+
},
|
|
211
|
+
download(url, filename) {
|
|
212
|
+
return new Promise((resolve) => {
|
|
213
|
+
let el = document.createElement('a');
|
|
214
|
+
el.href = url;
|
|
215
|
+
el.download = filename;
|
|
216
|
+
document.body.appendChild(el);
|
|
217
|
+
el.click();
|
|
218
|
+
document.body.removeChild(el);
|
|
219
|
+
resolve();
|
|
220
|
+
});
|
|
221
|
+
},
|
|
222
|
+
loadImage(src) {
|
|
223
|
+
return new Promise((resolve, reject) => {
|
|
224
|
+
const img = new Image();
|
|
225
|
+
const { crossOrigin } = Platform.image;
|
|
226
|
+
if (crossOrigin) {
|
|
227
|
+
img.setAttribute('crossOrigin', crossOrigin);
|
|
228
|
+
img.crossOrigin = crossOrigin;
|
|
229
|
+
}
|
|
230
|
+
img.onload = () => { resolve(img); };
|
|
231
|
+
img.onerror = (e) => { reject(e); };
|
|
232
|
+
img.src = Platform.image.getRealURL(src);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
Platform.event = {
|
|
237
|
+
stopDefault(origin) { origin.preventDefault(); },
|
|
238
|
+
stopNow(origin) { origin.stopImmediatePropagation(); },
|
|
239
|
+
stop(origin) { origin.stopPropagation(); }
|
|
240
|
+
};
|
|
241
|
+
Platform.canvas = Creator.canvas();
|
|
242
|
+
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
243
|
+
}
|
|
244
|
+
Platform.name = 'web';
|
|
245
|
+
Platform.isMobile = 'ontouchstart' in window;
|
|
246
|
+
Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
|
|
247
|
+
defineKey(Platform, 'devicePixelRatio', { get() { return Math.max(1, devicePixelRatio); } });
|
|
248
|
+
const { userAgent } = navigator;
|
|
249
|
+
if (userAgent.indexOf("Firefox") > -1) {
|
|
250
|
+
Platform.conicGradientRotate90 = true;
|
|
251
|
+
Platform.intWheelDeltaY = true;
|
|
252
|
+
Platform.syncDomFont = true;
|
|
253
|
+
}
|
|
254
|
+
else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
|
|
255
|
+
Platform.fullImageShadow = true;
|
|
256
|
+
}
|
|
257
|
+
if (userAgent.indexOf('Windows') > -1) {
|
|
258
|
+
Platform.os = 'Windows';
|
|
259
|
+
Platform.intWheelDeltaY = true;
|
|
260
|
+
}
|
|
261
|
+
else if (userAgent.indexOf('Mac') > -1) {
|
|
262
|
+
Platform.os = 'Mac';
|
|
263
|
+
}
|
|
264
|
+
else if (userAgent.indexOf('Linux') > -1) {
|
|
265
|
+
Platform.os = 'Linux';
|
|
266
|
+
}
|
|
6
267
|
|
|
7
268
|
class Watcher {
|
|
8
269
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -302,9 +563,11 @@ class Layouter {
|
|
|
302
563
|
updateAllChange(target);
|
|
303
564
|
}
|
|
304
565
|
addExtra(leaf) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
566
|
+
if (!this.__updatedList.has(leaf)) {
|
|
567
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
568
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
569
|
+
updatedList.add(leaf);
|
|
570
|
+
}
|
|
308
571
|
}
|
|
309
572
|
createBlock(data) {
|
|
310
573
|
return new LayoutBlockData(data);
|
|
@@ -414,6 +677,10 @@ class Renderer {
|
|
|
414
677
|
}
|
|
415
678
|
else {
|
|
416
679
|
this.requestLayout();
|
|
680
|
+
if (this.ignore) {
|
|
681
|
+
this.ignore = this.rendering = false;
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
417
684
|
this.emitRender(RenderEvent.BEFORE);
|
|
418
685
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
419
686
|
this.partRender();
|
|
@@ -450,7 +717,7 @@ class Renderer {
|
|
|
450
717
|
canvas.clear();
|
|
451
718
|
}
|
|
452
719
|
else {
|
|
453
|
-
bounds.spread(
|
|
720
|
+
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
454
721
|
canvas.clearWorld(bounds, true);
|
|
455
722
|
canvas.clipWorld(bounds, true);
|
|
456
723
|
}
|
|
@@ -474,14 +741,14 @@ class Renderer {
|
|
|
474
741
|
if (Debug.showRepaint)
|
|
475
742
|
this.canvas.strokeWorld(bounds, 'red');
|
|
476
743
|
this.target.__render(this.canvas, options);
|
|
477
|
-
this.renderBounds = realBounds || bounds;
|
|
744
|
+
this.renderBounds = realBounds = realBounds || bounds;
|
|
478
745
|
this.renderOptions = options;
|
|
479
|
-
this.totalBounds.isEmpty() ? this.totalBounds =
|
|
746
|
+
this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
|
|
480
747
|
if (Debug.showHitView)
|
|
481
748
|
this.renderHitView(options);
|
|
482
749
|
if (Debug.showBoundsView)
|
|
483
750
|
this.renderBoundsView(options);
|
|
484
|
-
this.canvas.updateRender();
|
|
751
|
+
this.canvas.updateRender(realBounds);
|
|
485
752
|
}
|
|
486
753
|
renderHitView(_options) { }
|
|
487
754
|
renderBoundsView(_options) { }
|
|
@@ -503,12 +770,12 @@ class Renderer {
|
|
|
503
770
|
const startTime = Date.now();
|
|
504
771
|
Platform.requestRender(() => {
|
|
505
772
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
506
|
-
if (this.
|
|
507
|
-
|
|
773
|
+
if (this.running) {
|
|
774
|
+
this.target.emit(AnimateEvent.FRAME);
|
|
775
|
+
if (this.changed && this.canvas.view)
|
|
508
776
|
this.render();
|
|
777
|
+
this.target.emit(RenderEvent.NEXT);
|
|
509
778
|
}
|
|
510
|
-
if (this.running)
|
|
511
|
-
this.target.emit(AnimateEvent.FRAME);
|
|
512
779
|
if (this.target)
|
|
513
780
|
this.__requestRender();
|
|
514
781
|
});
|
|
@@ -521,9 +788,12 @@ class Renderer {
|
|
|
521
788
|
const bounds = new Bounds(0, 0, width, height);
|
|
522
789
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
523
790
|
this.addBlock(this.canvas.bounds);
|
|
524
|
-
this.target.forceUpdate('
|
|
791
|
+
this.target.forceUpdate('surface');
|
|
792
|
+
return;
|
|
525
793
|
}
|
|
526
794
|
}
|
|
795
|
+
this.addBlock(new Bounds(0, 0, 1, 1));
|
|
796
|
+
this.changed = true;
|
|
527
797
|
}
|
|
528
798
|
__onLayoutEnd(event) {
|
|
529
799
|
if (event.data)
|
|
@@ -561,23 +831,13 @@ class Renderer {
|
|
|
561
831
|
if (this.target) {
|
|
562
832
|
this.stop();
|
|
563
833
|
this.__removeListenEvents();
|
|
564
|
-
this.target = null;
|
|
565
|
-
this.canvas = null;
|
|
566
|
-
this.config = null;
|
|
834
|
+
this.target = this.canvas = this.config = null;
|
|
567
835
|
}
|
|
568
836
|
}
|
|
569
837
|
}
|
|
570
838
|
|
|
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
839
|
const { hitRadiusPoint } = BoundsHelper;
|
|
580
|
-
class
|
|
840
|
+
class Picker {
|
|
581
841
|
constructor(target, selector) {
|
|
582
842
|
this.target = target;
|
|
583
843
|
this.selector = selector;
|
|
@@ -589,33 +849,41 @@ class Pather {
|
|
|
589
849
|
options = {};
|
|
590
850
|
const through = options.through || false;
|
|
591
851
|
const ignoreHittable = options.ignoreHittable || false;
|
|
852
|
+
const target = options.target || this.target;
|
|
592
853
|
this.exclude = options.exclude || null;
|
|
593
854
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
594
|
-
this.findList =
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const
|
|
855
|
+
this.findList = new LeafList(options.findList);
|
|
856
|
+
if (!options.findList)
|
|
857
|
+
this.hitBranch(target);
|
|
858
|
+
const { list } = this.findList;
|
|
859
|
+
const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
|
|
598
860
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
599
861
|
this.clear();
|
|
600
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
862
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
601
863
|
}
|
|
602
|
-
getBestMatchLeaf() {
|
|
603
|
-
|
|
604
|
-
if (targets.length > 1) {
|
|
864
|
+
getBestMatchLeaf(list, bottomList, ignoreHittable) {
|
|
865
|
+
if (list.length) {
|
|
605
866
|
let find;
|
|
606
|
-
this.findList =
|
|
867
|
+
this.findList = new LeafList();
|
|
607
868
|
const { x, y } = this.point;
|
|
608
869
|
const point = { x, y, radiusX: 0, radiusY: 0 };
|
|
609
|
-
for (let i = 0, len =
|
|
610
|
-
find =
|
|
611
|
-
if (LeafHelper.worldHittable(find)) {
|
|
870
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
871
|
+
find = list[i];
|
|
872
|
+
if (ignoreHittable || LeafHelper.worldHittable(find)) {
|
|
612
873
|
this.hitChild(find, point);
|
|
613
874
|
if (this.findList.length)
|
|
614
|
-
return this.findList[0];
|
|
875
|
+
return this.findList.list[0];
|
|
615
876
|
}
|
|
616
877
|
}
|
|
617
878
|
}
|
|
618
|
-
|
|
879
|
+
if (bottomList) {
|
|
880
|
+
for (let i = 0, len = bottomList.length; i < len; i++) {
|
|
881
|
+
this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
|
|
882
|
+
if (this.findList.length)
|
|
883
|
+
return this.findList.list[0];
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return list[0];
|
|
619
887
|
}
|
|
620
888
|
getPath(leaf) {
|
|
621
889
|
const path = new LeafList();
|
|
@@ -627,7 +895,7 @@ class Pather {
|
|
|
627
895
|
return path;
|
|
628
896
|
}
|
|
629
897
|
getHitablePath(leaf) {
|
|
630
|
-
const path = this.getPath(leaf);
|
|
898
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
631
899
|
let item, hittablePath = new LeafList();
|
|
632
900
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
633
901
|
item = path.list[i];
|
|
@@ -657,12 +925,15 @@ class Pather {
|
|
|
657
925
|
}
|
|
658
926
|
return throughPath;
|
|
659
927
|
}
|
|
928
|
+
hitBranch(branch) {
|
|
929
|
+
this.eachFind(branch.children, branch.__onlyHitMask);
|
|
930
|
+
}
|
|
660
931
|
eachFind(children, hitMask) {
|
|
661
932
|
let child, hit;
|
|
662
933
|
const { point } = this, len = children.length;
|
|
663
934
|
for (let i = len - 1; i > -1; i--) {
|
|
664
935
|
child = children[i];
|
|
665
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
936
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
666
937
|
continue;
|
|
667
938
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
668
939
|
if (child.isBranch) {
|
|
@@ -678,11 +949,15 @@ class Pather {
|
|
|
678
949
|
}
|
|
679
950
|
}
|
|
680
951
|
}
|
|
681
|
-
hitChild(child, point) {
|
|
952
|
+
hitChild(child, point, proxy) {
|
|
682
953
|
if (this.exclude && this.exclude.has(child))
|
|
683
954
|
return;
|
|
684
|
-
if (child.__hitWorld(point))
|
|
685
|
-
|
|
955
|
+
if (child.__hitWorld(point)) {
|
|
956
|
+
const { parent } = child;
|
|
957
|
+
if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
|
|
958
|
+
return;
|
|
959
|
+
this.findList.add(proxy || child);
|
|
960
|
+
}
|
|
686
961
|
}
|
|
687
962
|
clear() {
|
|
688
963
|
this.point = null;
|
|
@@ -694,7 +969,8 @@ class Pather {
|
|
|
694
969
|
}
|
|
695
970
|
}
|
|
696
971
|
|
|
697
|
-
const { Yes, NoAndSkip, YesAndSkip } =
|
|
972
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer;
|
|
973
|
+
const idCondition = {}, classNameCondition = {}, tagCondition = {};
|
|
698
974
|
class Selector {
|
|
699
975
|
constructor(target, userConfig) {
|
|
700
976
|
this.config = {};
|
|
@@ -704,12 +980,13 @@ class Selector {
|
|
|
704
980
|
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
705
981
|
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
706
982
|
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
707
|
-
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
983
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
|
|
984
|
+
tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
|
|
708
985
|
};
|
|
709
986
|
this.target = target;
|
|
710
987
|
if (userConfig)
|
|
711
988
|
this.config = DataHelper.default(userConfig, this.config);
|
|
712
|
-
this.
|
|
989
|
+
this.picker = new Picker(target, this);
|
|
713
990
|
this.__listenEvents();
|
|
714
991
|
}
|
|
715
992
|
getBy(condition, branch, one, options) {
|
|
@@ -720,12 +997,25 @@ class Selector {
|
|
|
720
997
|
case 'string':
|
|
721
998
|
switch (condition[0]) {
|
|
722
999
|
case '#':
|
|
723
|
-
|
|
724
|
-
|
|
1000
|
+
idCondition.id = condition.substring(1), condition = idCondition;
|
|
1001
|
+
break;
|
|
725
1002
|
case '.':
|
|
726
|
-
|
|
1003
|
+
classNameCondition.className = condition.substring(1), condition = classNameCondition;
|
|
1004
|
+
break;
|
|
727
1005
|
default:
|
|
728
|
-
|
|
1006
|
+
tagCondition.tag = condition, condition = tagCondition;
|
|
1007
|
+
}
|
|
1008
|
+
case 'object':
|
|
1009
|
+
if (condition.id !== undefined) {
|
|
1010
|
+
const leaf = this.getById(condition.id, branch);
|
|
1011
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
1012
|
+
}
|
|
1013
|
+
else if (condition.tag) {
|
|
1014
|
+
const { tag } = condition, isArray = tag instanceof Array;
|
|
1015
|
+
return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
|
|
1016
|
+
}
|
|
1017
|
+
else {
|
|
1018
|
+
return this.getByMethod(this.methods.className, branch, one, condition.className);
|
|
729
1019
|
}
|
|
730
1020
|
case 'function':
|
|
731
1021
|
return this.getByMethod(condition, branch, one, options);
|
|
@@ -734,7 +1024,7 @@ class Selector {
|
|
|
734
1024
|
getByPoint(hitPoint, hitRadius, options) {
|
|
735
1025
|
if (Platform.name === 'node')
|
|
736
1026
|
this.target.emit(LayoutEvent.CHECK_UPDATE);
|
|
737
|
-
return this.
|
|
1027
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
738
1028
|
}
|
|
739
1029
|
getByInnerId(innerId, branch) {
|
|
740
1030
|
const cache = this.innerIdMap[innerId];
|
|
@@ -810,7 +1100,7 @@ class Selector {
|
|
|
810
1100
|
destroy() {
|
|
811
1101
|
if (this.__eventIds.length) {
|
|
812
1102
|
this.__removeListenEvents();
|
|
813
|
-
this.
|
|
1103
|
+
this.picker.destroy();
|
|
814
1104
|
this.findLeaf = null;
|
|
815
1105
|
this.innerIdMap = {};
|
|
816
1106
|
this.idMap = {};
|
|
@@ -826,194 +1116,29 @@ Object.assign(Creator, {
|
|
|
826
1116
|
});
|
|
827
1117
|
Platform.layout = Layouter.fullLayout;
|
|
828
1118
|
|
|
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);
|
|
1119
|
+
const PointerEventHelper = {
|
|
1120
|
+
convert(e, local) {
|
|
1121
|
+
const base = InteractionHelper.getBase(e);
|
|
1122
|
+
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 });
|
|
1123
|
+
if (data.pointerType === 'pen') {
|
|
1124
|
+
data.tangentialPressure = e.tangentialPressure;
|
|
1125
|
+
data.tiltX = e.tiltX;
|
|
1126
|
+
data.tiltY = e.tiltY;
|
|
1127
|
+
data.twist = e.twist;
|
|
842
1128
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
|
|
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;
|
|
1003
|
-
}
|
|
1004
|
-
return data;
|
|
1005
|
-
},
|
|
1006
|
-
convertMouse(e, local) {
|
|
1007
|
-
const base = InteractionHelper.getBase(e);
|
|
1008
|
-
return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'mouse', pressure: 0.5 });
|
|
1009
|
-
},
|
|
1010
|
-
convertTouch(e, local) {
|
|
1011
|
-
const touch = PointerEventHelper.getTouch(e);
|
|
1012
|
-
const base = InteractionHelper.getBase(e);
|
|
1013
|
-
return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'touch', pressure: touch.force });
|
|
1014
|
-
},
|
|
1015
|
-
getTouch(e) {
|
|
1016
|
-
return e.targetTouches[0] || e.changedTouches[0];
|
|
1129
|
+
return data;
|
|
1130
|
+
},
|
|
1131
|
+
convertMouse(e, local) {
|
|
1132
|
+
const base = InteractionHelper.getBase(e);
|
|
1133
|
+
return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'mouse', pressure: 0.5 });
|
|
1134
|
+
},
|
|
1135
|
+
convertTouch(e, local) {
|
|
1136
|
+
const touch = PointerEventHelper.getTouch(e);
|
|
1137
|
+
const base = InteractionHelper.getBase(e);
|
|
1138
|
+
return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'touch', multiTouch: e.touches.length > 1, pressure: touch.force });
|
|
1139
|
+
},
|
|
1140
|
+
getTouch(e) {
|
|
1141
|
+
return e.targetTouches[0] || e.changedTouches[0];
|
|
1017
1142
|
}
|
|
1018
1143
|
};
|
|
1019
1144
|
|
|
@@ -1047,7 +1172,7 @@ const WheelEventHelper = {
|
|
|
1047
1172
|
if (zoom) {
|
|
1048
1173
|
zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
|
|
1049
1174
|
const min = e.deltaY ? config.delta.y : config.delta.x;
|
|
1050
|
-
scale = 1 - delta / (min *
|
|
1175
|
+
scale = 1 - delta / (min * 4) * zoomSpeed;
|
|
1051
1176
|
if (scale < 0.5)
|
|
1052
1177
|
scale = 0.5;
|
|
1053
1178
|
if (scale >= 1.5)
|
|
@@ -1115,12 +1240,6 @@ class Interaction extends InteractionBase {
|
|
|
1115
1240
|
this.windowEvents = {};
|
|
1116
1241
|
}
|
|
1117
1242
|
}
|
|
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
1243
|
getTouches(touches) {
|
|
1125
1244
|
const list = [];
|
|
1126
1245
|
for (let i = 0, len = touches.length; i < len; i++) {
|
|
@@ -1148,6 +1267,8 @@ class Interaction extends InteractionBase {
|
|
|
1148
1267
|
this.keyUp(KeyEventHelper.convert(e));
|
|
1149
1268
|
}
|
|
1150
1269
|
onContextMenu(e) {
|
|
1270
|
+
if (this.config.pointer.preventDefaultMenu)
|
|
1271
|
+
e.preventDefault();
|
|
1151
1272
|
this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
|
|
1152
1273
|
}
|
|
1153
1274
|
onScroll() {
|
|
@@ -1155,21 +1276,21 @@ class Interaction extends InteractionBase {
|
|
|
1155
1276
|
}
|
|
1156
1277
|
onPointerDown(e) {
|
|
1157
1278
|
this.preventDefaultPointer(e);
|
|
1158
|
-
this.
|
|
1159
|
-
if (this.useMultiTouch)
|
|
1279
|
+
if (this.config.pointer.touch || this.useMultiTouch)
|
|
1160
1280
|
return;
|
|
1281
|
+
this.usePointer || (this.usePointer = true);
|
|
1161
1282
|
this.pointerDown(PointerEventHelper.convert(e, this.getLocal(e)));
|
|
1162
1283
|
}
|
|
1163
1284
|
onPointerMove(e) {
|
|
1164
|
-
this.
|
|
1165
|
-
if (this.useMultiTouch || this.preventWindowPointer(e))
|
|
1285
|
+
if (this.config.pointer.touch || this.useMultiTouch || this.preventWindowPointer(e))
|
|
1166
1286
|
return;
|
|
1287
|
+
this.usePointer || (this.usePointer = true);
|
|
1167
1288
|
this.pointerMove(PointerEventHelper.convert(e, this.getLocal(e, true)));
|
|
1168
1289
|
}
|
|
1169
1290
|
onPointerUp(e) {
|
|
1170
1291
|
if (this.downData)
|
|
1171
1292
|
this.preventDefaultPointer(e);
|
|
1172
|
-
if (this.useMultiTouch || this.preventWindowPointer(e))
|
|
1293
|
+
if (this.config.pointer.touch || this.useMultiTouch || this.preventWindowPointer(e))
|
|
1173
1294
|
return;
|
|
1174
1295
|
this.pointerUp(PointerEventHelper.convert(e, this.getLocal(e)));
|
|
1175
1296
|
}
|
|
@@ -1239,7 +1360,7 @@ class Interaction extends InteractionBase {
|
|
|
1239
1360
|
this.pointerCancel();
|
|
1240
1361
|
}
|
|
1241
1362
|
multiTouchStart(e) {
|
|
1242
|
-
this.useMultiTouch = (e.touches.length
|
|
1363
|
+
this.useMultiTouch = (e.touches.length > 1);
|
|
1243
1364
|
this.touches = this.useMultiTouch ? this.getTouches(e.touches) : undefined;
|
|
1244
1365
|
if (this.useMultiTouch)
|
|
1245
1366
|
this.pointerCancel();
|
|
@@ -1277,17 +1398,23 @@ class Interaction extends InteractionBase {
|
|
|
1277
1398
|
onWheel(e) {
|
|
1278
1399
|
this.preventDefaultWheel(e);
|
|
1279
1400
|
const { wheel } = this.config;
|
|
1401
|
+
if (wheel.disabled)
|
|
1402
|
+
return;
|
|
1280
1403
|
const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
|
|
1281
1404
|
const local = this.getLocal(e);
|
|
1282
1405
|
const eventBase = InteractionHelper.getBase(e);
|
|
1283
1406
|
scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
|
|
1284
1407
|
}
|
|
1285
1408
|
onGesturestart(e) {
|
|
1409
|
+
if (this.useMultiTouch)
|
|
1410
|
+
return;
|
|
1286
1411
|
this.preventDefaultWheel(e);
|
|
1287
1412
|
this.lastGestureScale = 1;
|
|
1288
1413
|
this.lastGestureRotation = 0;
|
|
1289
1414
|
}
|
|
1290
1415
|
onGesturechange(e) {
|
|
1416
|
+
if (this.useMultiTouch)
|
|
1417
|
+
return;
|
|
1291
1418
|
this.preventDefaultWheel(e);
|
|
1292
1419
|
const local = this.getLocal(e);
|
|
1293
1420
|
const eventBase = InteractionHelper.getBase(e);
|
|
@@ -1301,9 +1428,34 @@ class Interaction extends InteractionBase {
|
|
|
1301
1428
|
this.lastGestureRotation = e.rotation;
|
|
1302
1429
|
}
|
|
1303
1430
|
onGestureend(e) {
|
|
1431
|
+
if (this.useMultiTouch)
|
|
1432
|
+
return;
|
|
1304
1433
|
this.preventDefaultWheel(e);
|
|
1305
1434
|
this.transformEnd();
|
|
1306
1435
|
}
|
|
1436
|
+
setCursor(cursor) {
|
|
1437
|
+
super.setCursor(cursor);
|
|
1438
|
+
const list = [];
|
|
1439
|
+
this.eachCursor(cursor, list);
|
|
1440
|
+
if (typeof list[list.length - 1] === 'object')
|
|
1441
|
+
list.push('default');
|
|
1442
|
+
this.canvas.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
|
|
1443
|
+
}
|
|
1444
|
+
eachCursor(cursor, list, level = 0) {
|
|
1445
|
+
level++;
|
|
1446
|
+
if (cursor instanceof Array) {
|
|
1447
|
+
cursor.forEach(item => this.eachCursor(item, list, level));
|
|
1448
|
+
}
|
|
1449
|
+
else {
|
|
1450
|
+
const custom = typeof cursor === 'string' && Cursor.get(cursor);
|
|
1451
|
+
if (custom && level < 2) {
|
|
1452
|
+
this.eachCursor(custom, list, level);
|
|
1453
|
+
}
|
|
1454
|
+
else {
|
|
1455
|
+
list.push(cursor);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1307
1459
|
destroy() {
|
|
1308
1460
|
if (this.view) {
|
|
1309
1461
|
super.destroy();
|
|
@@ -1313,151 +1465,381 @@ class Interaction extends InteractionBase {
|
|
|
1313
1465
|
}
|
|
1314
1466
|
}
|
|
1315
1467
|
|
|
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;
|
|
1468
|
+
function fillText(ui, canvas) {
|
|
1469
|
+
let row;
|
|
1470
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1471
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1472
|
+
row = rows[i];
|
|
1473
|
+
if (row.text) {
|
|
1474
|
+
canvas.fillText(row.text, row.x, row.y);
|
|
1475
|
+
}
|
|
1476
|
+
else if (row.data) {
|
|
1477
|
+
row.data.forEach(charData => {
|
|
1478
|
+
canvas.fillText(charData.char, charData.x, row.y);
|
|
1354
1479
|
});
|
|
1355
1480
|
}
|
|
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';
|
|
1481
|
+
if (decorationY)
|
|
1482
|
+
canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1483
|
+
}
|
|
1387
1484
|
}
|
|
1388
1485
|
|
|
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;
|
|
1405
|
-
}
|
|
1406
|
-
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1407
|
-
const transform = get$4();
|
|
1408
|
-
translate$1(transform, box.x, box.y);
|
|
1409
|
-
if (x || y)
|
|
1410
|
-
translate$1(transform, x, y);
|
|
1411
|
-
if (scaleX) {
|
|
1412
|
-
scaleHelper(transform, scaleX, scaleY);
|
|
1413
|
-
data.scaleX = transform.a;
|
|
1414
|
-
data.scaleY = transform.d;
|
|
1415
|
-
}
|
|
1416
|
-
if (rotation)
|
|
1417
|
-
rotate(transform, rotation);
|
|
1418
|
-
data.transform = transform;
|
|
1486
|
+
function fill(fill, ui, canvas) {
|
|
1487
|
+
canvas.fillStyle = fill;
|
|
1488
|
+
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1419
1489
|
}
|
|
1420
|
-
function
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1490
|
+
function fills(fills, ui, canvas) {
|
|
1491
|
+
let item;
|
|
1492
|
+
const { windingRule, __font } = ui.__;
|
|
1493
|
+
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1494
|
+
item = fills[i];
|
|
1495
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
1496
|
+
continue;
|
|
1497
|
+
if (item.style) {
|
|
1498
|
+
canvas.fillStyle = item.style;
|
|
1499
|
+
if (item.transform) {
|
|
1500
|
+
canvas.save();
|
|
1501
|
+
canvas.transform(item.transform);
|
|
1502
|
+
if (item.blendMode)
|
|
1503
|
+
canvas.blendMode = item.blendMode;
|
|
1504
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1505
|
+
canvas.restore();
|
|
1506
|
+
}
|
|
1507
|
+
else {
|
|
1508
|
+
if (item.blendMode) {
|
|
1509
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1510
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1511
|
+
canvas.restoreBlendMode();
|
|
1512
|
+
}
|
|
1513
|
+
else {
|
|
1514
|
+
__font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
function strokeText(stroke, ui, canvas) {
|
|
1522
|
+
const { strokeAlign } = ui.__;
|
|
1523
|
+
const isStrokes = typeof stroke !== 'string';
|
|
1524
|
+
switch (strokeAlign) {
|
|
1525
|
+
case 'center':
|
|
1526
|
+
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1527
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1528
|
+
break;
|
|
1529
|
+
case 'inside':
|
|
1530
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1531
|
+
break;
|
|
1532
|
+
case 'outside':
|
|
1533
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1538
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1539
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1540
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1541
|
+
out.font = __font;
|
|
1542
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1543
|
+
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1544
|
+
fillText(ui, out);
|
|
1545
|
+
out.blendMode = 'normal';
|
|
1546
|
+
if (ui.__worldFlipped) {
|
|
1547
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1548
|
+
}
|
|
1549
|
+
else {
|
|
1550
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1551
|
+
}
|
|
1552
|
+
out.recycle(ui.__nowWorld);
|
|
1553
|
+
}
|
|
1554
|
+
function drawTextStroke(ui, canvas) {
|
|
1555
|
+
let row;
|
|
1556
|
+
const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
|
|
1557
|
+
for (let i = 0, len = rows.length; i < len; i++) {
|
|
1558
|
+
row = rows[i];
|
|
1559
|
+
if (row.text) {
|
|
1560
|
+
canvas.strokeText(row.text, row.x, row.y);
|
|
1561
|
+
}
|
|
1562
|
+
else if (row.data) {
|
|
1563
|
+
row.data.forEach(charData => {
|
|
1564
|
+
canvas.strokeText(charData.char, charData.x, row.y);
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
if (decorationY)
|
|
1568
|
+
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1572
|
+
let item;
|
|
1573
|
+
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1574
|
+
item = strokes[i];
|
|
1575
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1576
|
+
continue;
|
|
1577
|
+
if (item.style) {
|
|
1578
|
+
canvas.strokeStyle = item.style;
|
|
1579
|
+
if (item.blendMode) {
|
|
1580
|
+
canvas.saveBlendMode(item.blendMode);
|
|
1581
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1582
|
+
canvas.restoreBlendMode();
|
|
1583
|
+
}
|
|
1584
|
+
else {
|
|
1585
|
+
isText ? drawTextStroke(ui, canvas) : canvas.stroke();
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
function stroke(stroke, ui, canvas) {
|
|
1592
|
+
const options = ui.__;
|
|
1593
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1594
|
+
if (!__strokeWidth)
|
|
1595
|
+
return;
|
|
1596
|
+
if (__font) {
|
|
1597
|
+
strokeText(stroke, ui, canvas);
|
|
1598
|
+
}
|
|
1599
|
+
else {
|
|
1600
|
+
switch (strokeAlign) {
|
|
1601
|
+
case 'center':
|
|
1602
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1603
|
+
canvas.stroke();
|
|
1604
|
+
break;
|
|
1605
|
+
case 'inside':
|
|
1606
|
+
canvas.save();
|
|
1607
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1608
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1609
|
+
canvas.stroke();
|
|
1610
|
+
canvas.restore();
|
|
1611
|
+
break;
|
|
1612
|
+
case 'outside':
|
|
1613
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1614
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1615
|
+
ui.__drawRenderPath(out);
|
|
1616
|
+
out.stroke();
|
|
1617
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1618
|
+
out.clearWorld(ui.__layout.renderBounds);
|
|
1619
|
+
if (ui.__worldFlipped) {
|
|
1620
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1621
|
+
}
|
|
1622
|
+
else {
|
|
1623
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1624
|
+
}
|
|
1625
|
+
out.recycle(ui.__nowWorld);
|
|
1433
1626
|
break;
|
|
1434
1627
|
}
|
|
1435
1628
|
}
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1629
|
+
}
|
|
1630
|
+
function strokes(strokes, ui, canvas) {
|
|
1631
|
+
const options = ui.__;
|
|
1632
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1633
|
+
if (!__strokeWidth)
|
|
1634
|
+
return;
|
|
1635
|
+
if (__font) {
|
|
1636
|
+
strokeText(strokes, ui, canvas);
|
|
1637
|
+
}
|
|
1638
|
+
else {
|
|
1639
|
+
switch (strokeAlign) {
|
|
1640
|
+
case 'center':
|
|
1641
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1642
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1643
|
+
break;
|
|
1644
|
+
case 'inside':
|
|
1645
|
+
canvas.save();
|
|
1646
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1647
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1648
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1649
|
+
canvas.restore();
|
|
1650
|
+
break;
|
|
1651
|
+
case 'outside':
|
|
1652
|
+
const { renderBounds } = ui.__layout;
|
|
1653
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1654
|
+
ui.__drawRenderPath(out);
|
|
1655
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1656
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1657
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1658
|
+
out.clearWorld(renderBounds);
|
|
1659
|
+
if (ui.__worldFlipped) {
|
|
1660
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1661
|
+
}
|
|
1662
|
+
else {
|
|
1663
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1664
|
+
}
|
|
1665
|
+
out.recycle(ui.__nowWorld);
|
|
1666
|
+
break;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
|
|
1671
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1672
|
+
function shape(ui, current, options) {
|
|
1673
|
+
const canvas = current.getSameCanvas();
|
|
1674
|
+
const nowWorld = ui.__nowWorld;
|
|
1675
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1676
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1677
|
+
if (scaleX < 0)
|
|
1678
|
+
scaleX = -scaleX;
|
|
1679
|
+
if (scaleY < 0)
|
|
1680
|
+
scaleY = -scaleY;
|
|
1681
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1682
|
+
worldCanvas = canvas;
|
|
1683
|
+
bounds = shapeBounds = nowWorld;
|
|
1684
|
+
}
|
|
1685
|
+
else {
|
|
1686
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1687
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
|
|
1688
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1689
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1690
|
+
if (fitMatrix.a < 1) {
|
|
1691
|
+
worldCanvas = current.getSameCanvas();
|
|
1692
|
+
ui.__renderShape(worldCanvas, options);
|
|
1693
|
+
scaleX *= fitScaleX;
|
|
1694
|
+
scaleY *= fitScaleY;
|
|
1695
|
+
}
|
|
1696
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1697
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1698
|
+
if (options.matrix) {
|
|
1699
|
+
const { matrix } = options;
|
|
1700
|
+
fitMatrix.multiply(matrix);
|
|
1701
|
+
fitScaleX *= matrix.scaleX;
|
|
1702
|
+
fitScaleY *= matrix.scaleY;
|
|
1703
|
+
}
|
|
1704
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1705
|
+
}
|
|
1706
|
+
ui.__renderShape(canvas, options);
|
|
1707
|
+
return {
|
|
1708
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1709
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
let recycleMap;
|
|
1714
|
+
function compute(attrName, ui) {
|
|
1715
|
+
const data = ui.__, leafPaints = [];
|
|
1716
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1717
|
+
if (!(paints instanceof Array))
|
|
1718
|
+
paints = [paints];
|
|
1719
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1720
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1721
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1722
|
+
if (item)
|
|
1723
|
+
leafPaints.push(item);
|
|
1724
|
+
}
|
|
1725
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1726
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1727
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1728
|
+
if (attrName === 'fill') {
|
|
1729
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1730
|
+
}
|
|
1731
|
+
else {
|
|
1732
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1736
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1737
|
+
return undefined;
|
|
1738
|
+
const { boxBounds } = ui.__layout;
|
|
1739
|
+
switch (paint.type) {
|
|
1740
|
+
case 'solid':
|
|
1741
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1742
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1743
|
+
case 'image':
|
|
1744
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1745
|
+
case 'linear':
|
|
1746
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1747
|
+
case 'radial':
|
|
1748
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1749
|
+
case 'angular':
|
|
1750
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1751
|
+
default:
|
|
1752
|
+
return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1445
1753
|
}
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
const PaintModule = {
|
|
1757
|
+
compute,
|
|
1758
|
+
fill,
|
|
1759
|
+
fills,
|
|
1760
|
+
fillText,
|
|
1761
|
+
stroke,
|
|
1762
|
+
strokes,
|
|
1763
|
+
strokeText,
|
|
1764
|
+
drawTextStroke,
|
|
1765
|
+
shape
|
|
1766
|
+
};
|
|
1767
|
+
|
|
1768
|
+
let origin = {};
|
|
1769
|
+
const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1770
|
+
function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1771
|
+
const transform = get$3();
|
|
1772
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1773
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1774
|
+
if (rotation)
|
|
1775
|
+
rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1776
|
+
data.transform = transform;
|
|
1777
|
+
}
|
|
1778
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1779
|
+
const transform = get$3();
|
|
1780
|
+
translate$1(transform, box.x + x, box.y + y);
|
|
1781
|
+
if (scaleX)
|
|
1782
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1783
|
+
if (rotation)
|
|
1784
|
+
rotate(transform, rotation);
|
|
1785
|
+
data.transform = transform;
|
|
1786
|
+
}
|
|
1787
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
|
|
1788
|
+
const transform = get$3();
|
|
1789
|
+
if (rotation) {
|
|
1790
|
+
if (align === 'center') {
|
|
1791
|
+
rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
|
|
1792
|
+
}
|
|
1793
|
+
else {
|
|
1794
|
+
rotate(transform, rotation);
|
|
1795
|
+
switch (rotation) {
|
|
1796
|
+
case 90:
|
|
1797
|
+
translate$1(transform, height, 0);
|
|
1798
|
+
break;
|
|
1799
|
+
case 180:
|
|
1800
|
+
translate$1(transform, width, height);
|
|
1801
|
+
break;
|
|
1802
|
+
case 270:
|
|
1803
|
+
translate$1(transform, 0, width);
|
|
1804
|
+
break;
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
origin.x = box.x + x;
|
|
1809
|
+
origin.y = box.y + y;
|
|
1810
|
+
translate$1(transform, origin.x, origin.y);
|
|
1811
|
+
if (scaleX)
|
|
1812
|
+
scaleOfOuter$1(transform, origin, scaleX, scaleY);
|
|
1446
1813
|
data.transform = transform;
|
|
1447
1814
|
}
|
|
1448
1815
|
|
|
1449
|
-
const { get: get$
|
|
1816
|
+
const { get: get$2, translate } = MatrixHelper;
|
|
1817
|
+
const tempBox = new Bounds();
|
|
1818
|
+
const tempPoint = {};
|
|
1450
1819
|
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;
|
|
1820
|
+
const { blendMode } = paint;
|
|
1454
1821
|
if (blendMode)
|
|
1455
1822
|
leafPaint.blendMode = blendMode;
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
if (
|
|
1823
|
+
leafPaint.data = getPatternData(paint, box, image);
|
|
1824
|
+
}
|
|
1825
|
+
function getPatternData(paint, box, image) {
|
|
1826
|
+
let { width, height } = image;
|
|
1827
|
+
if (paint.padding)
|
|
1828
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1829
|
+
const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
|
|
1830
|
+
const sameBox = box.width === width && box.height === height;
|
|
1831
|
+
const data = { mode };
|
|
1832
|
+
const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
|
|
1833
|
+
const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
|
|
1834
|
+
let x = 0, y = 0, scaleX, scaleY;
|
|
1835
|
+
if (!mode || mode === 'cover' || mode === 'fit') {
|
|
1836
|
+
if (!sameBox || rotation) {
|
|
1837
|
+
const sw = box.width / swapWidth, sh = box.height / swapHeight;
|
|
1838
|
+
scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1839
|
+
x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
else if (size) {
|
|
1461
1843
|
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1462
1844
|
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1463
1845
|
}
|
|
@@ -1465,30 +1847,46 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1465
1847
|
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1466
1848
|
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1467
1849
|
}
|
|
1850
|
+
if (align) {
|
|
1851
|
+
const imageBounds = { x, y, width: swapWidth, height: swapHeight };
|
|
1852
|
+
if (scaleX)
|
|
1853
|
+
imageBounds.width *= scaleX, imageBounds.height *= scaleY;
|
|
1854
|
+
AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
|
|
1855
|
+
x += tempPoint.x, y += tempPoint.y;
|
|
1856
|
+
}
|
|
1857
|
+
if (offset)
|
|
1858
|
+
x += offset.x, y += offset.y;
|
|
1468
1859
|
switch (mode) {
|
|
1469
1860
|
case 'strench':
|
|
1470
1861
|
if (!sameBox)
|
|
1471
1862
|
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
1863
|
break;
|
|
1864
|
+
case 'normal':
|
|
1477
1865
|
case 'clip':
|
|
1478
|
-
if (
|
|
1866
|
+
if (x || y || scaleX || rotation)
|
|
1479
1867
|
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1480
1868
|
break;
|
|
1481
1869
|
case 'repeat':
|
|
1482
1870
|
if (!sameBox || scaleX || rotation)
|
|
1483
|
-
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1871
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
|
|
1484
1872
|
if (!repeat)
|
|
1485
1873
|
data.repeat = 'repeat';
|
|
1486
1874
|
break;
|
|
1487
1875
|
case 'fit':
|
|
1488
1876
|
case 'cover':
|
|
1489
1877
|
default:
|
|
1490
|
-
if (
|
|
1491
|
-
fillOrFitMode(data,
|
|
1878
|
+
if (scaleX)
|
|
1879
|
+
fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1880
|
+
}
|
|
1881
|
+
if (!data.transform) {
|
|
1882
|
+
if (box.x || box.y) {
|
|
1883
|
+
data.transform = get$2();
|
|
1884
|
+
translate(data.transform, box.x, box.y);
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
if (scaleX && mode !== 'strench') {
|
|
1888
|
+
data.scaleX = scaleX;
|
|
1889
|
+
data.scaleY = scaleY;
|
|
1492
1890
|
}
|
|
1493
1891
|
data.width = width;
|
|
1494
1892
|
data.height = height;
|
|
@@ -1496,112 +1894,108 @@ function createData(leafPaint, image, paint, box) {
|
|
|
1496
1894
|
data.opacity = opacity;
|
|
1497
1895
|
if (repeat)
|
|
1498
1896
|
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1897
|
+
return data;
|
|
1499
1898
|
}
|
|
1500
1899
|
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1900
|
+
let cache, box = new Bounds();
|
|
1901
|
+
const { isSame } = BoundsHelper;
|
|
1902
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1903
|
+
let leafPaint, event;
|
|
1904
|
+
const image = ImageManager.get(paint);
|
|
1905
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1906
|
+
leafPaint = cache.leafPaint;
|
|
1907
|
+
}
|
|
1908
|
+
else {
|
|
1909
|
+
leafPaint = { type: paint.type, image };
|
|
1910
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1911
|
+
}
|
|
1912
|
+
if (firstUse || image.loading)
|
|
1913
|
+
event = { image, attrName, attrValue: paint };
|
|
1505
1914
|
if (image.ready) {
|
|
1506
|
-
|
|
1507
|
-
createData(leafPaint, image, attrValue, box);
|
|
1915
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1508
1916
|
if (firstUse) {
|
|
1509
|
-
|
|
1510
|
-
|
|
1917
|
+
onLoad(ui, event);
|
|
1918
|
+
onLoadSuccess(ui, event);
|
|
1511
1919
|
}
|
|
1512
1920
|
}
|
|
1513
1921
|
else if (image.error) {
|
|
1514
|
-
if (firstUse)
|
|
1515
|
-
ui.
|
|
1516
|
-
event.error = image.error;
|
|
1517
|
-
emit(ImageEvent.ERROR, event);
|
|
1518
|
-
}
|
|
1922
|
+
if (firstUse)
|
|
1923
|
+
onLoadError(ui, event, image.error);
|
|
1519
1924
|
}
|
|
1520
1925
|
else {
|
|
1926
|
+
ignoreRender(ui, true);
|
|
1521
1927
|
if (firstUse)
|
|
1522
|
-
|
|
1928
|
+
onLoad(ui, event);
|
|
1523
1929
|
leafPaint.loadId = image.load(() => {
|
|
1930
|
+
ignoreRender(ui, false);
|
|
1524
1931
|
if (!ui.destroyed) {
|
|
1525
|
-
if (
|
|
1526
|
-
|
|
1932
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1933
|
+
if (image.hasOpacityPixel)
|
|
1934
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1527
1935
|
ui.forceUpdate('surface');
|
|
1528
1936
|
}
|
|
1529
|
-
|
|
1937
|
+
onLoadSuccess(ui, event);
|
|
1530
1938
|
}
|
|
1939
|
+
leafPaint.loadId = null;
|
|
1531
1940
|
}, (error) => {
|
|
1532
|
-
ui
|
|
1533
|
-
event
|
|
1534
|
-
|
|
1941
|
+
ignoreRender(ui, false);
|
|
1942
|
+
onLoadError(ui, event, error);
|
|
1943
|
+
leafPaint.loadId = null;
|
|
1535
1944
|
});
|
|
1536
1945
|
}
|
|
1537
1946
|
return leafPaint;
|
|
1538
1947
|
}
|
|
1539
|
-
function
|
|
1948
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1540
1949
|
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1541
|
-
const
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
if (
|
|
1950
|
+
const data = ui.__;
|
|
1951
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1952
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1953
|
+
if (data.__autoSide) {
|
|
1545
1954
|
ui.forceUpdate('width');
|
|
1546
1955
|
if (ui.__proxyData) {
|
|
1547
|
-
ui.setProxyAttr('width',
|
|
1548
|
-
ui.setProxyAttr('height',
|
|
1956
|
+
ui.setProxyAttr('width', data.width);
|
|
1957
|
+
ui.setProxyAttr('height', data.height);
|
|
1549
1958
|
}
|
|
1550
1959
|
return false;
|
|
1551
1960
|
}
|
|
1552
1961
|
}
|
|
1962
|
+
if (!leafPaint.data)
|
|
1963
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1553
1964
|
return true;
|
|
1554
1965
|
}
|
|
1555
|
-
function
|
|
1556
|
-
|
|
1557
|
-
|
|
1966
|
+
function onLoad(ui, event) {
|
|
1967
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1968
|
+
}
|
|
1969
|
+
function onLoadSuccess(ui, event) {
|
|
1970
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1971
|
+
}
|
|
1972
|
+
function onLoadError(ui, event, error) {
|
|
1973
|
+
event.error = error;
|
|
1974
|
+
ui.forceUpdate('surface');
|
|
1975
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1976
|
+
}
|
|
1977
|
+
function emit(ui, type, data) {
|
|
1978
|
+
if (ui.hasEvent(type))
|
|
1979
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1980
|
+
}
|
|
1981
|
+
function ignoreRender(ui, value) {
|
|
1982
|
+
const { leafer } = ui;
|
|
1983
|
+
if (leafer && leafer.viewReady)
|
|
1984
|
+
leafer.renderer.ignore = value;
|
|
1558
1985
|
}
|
|
1559
1986
|
|
|
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;
|
|
1987
|
+
const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
|
|
1988
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1595
1989
|
function createPattern(ui, paint, pixelRatio) {
|
|
1596
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1990
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1597
1991
|
const id = scaleX + '-' + scaleY;
|
|
1598
1992
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
1599
|
-
scaleX =
|
|
1600
|
-
scaleY =
|
|
1993
|
+
scaleX = abs$1(scaleX);
|
|
1994
|
+
scaleY = abs$1(scaleY);
|
|
1601
1995
|
const { image, data } = paint;
|
|
1602
1996
|
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1603
1997
|
if (sx) {
|
|
1604
|
-
imageMatrix = get$
|
|
1998
|
+
imageMatrix = get$1();
|
|
1605
1999
|
copy$1(imageMatrix, transform);
|
|
1606
2000
|
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1607
2001
|
scaleX *= sx;
|
|
@@ -1636,22 +2030,14 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1636
2030
|
}
|
|
1637
2031
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1638
2032
|
if (!imageMatrix) {
|
|
1639
|
-
imageMatrix = get$
|
|
2033
|
+
imageMatrix = get$1();
|
|
1640
2034
|
if (transform)
|
|
1641
2035
|
copy$1(imageMatrix, transform);
|
|
1642
2036
|
}
|
|
1643
2037
|
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1644
2038
|
}
|
|
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
|
-
}
|
|
2039
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
2040
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1655
2041
|
paint.style = pattern;
|
|
1656
2042
|
paint.patternId = id;
|
|
1657
2043
|
return true;
|
|
@@ -1661,10 +2047,42 @@ function createPattern(ui, paint, pixelRatio) {
|
|
|
1661
2047
|
}
|
|
1662
2048
|
}
|
|
1663
2049
|
|
|
2050
|
+
/******************************************************************************
|
|
2051
|
+
Copyright (c) Microsoft Corporation.
|
|
2052
|
+
|
|
2053
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
2054
|
+
purpose with or without fee is hereby granted.
|
|
2055
|
+
|
|
2056
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
2057
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
2058
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
2059
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
2060
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
2061
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
2062
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
2063
|
+
***************************************************************************** */
|
|
2064
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
2065
|
+
|
|
2066
|
+
|
|
2067
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
2068
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
2069
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
2070
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
2071
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
2072
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
2073
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
2074
|
+
});
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
2078
|
+
var e = new Error(message);
|
|
2079
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
2080
|
+
};
|
|
2081
|
+
|
|
1664
2082
|
const { abs } = Math;
|
|
1665
2083
|
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1666
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1667
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
2084
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
2085
|
+
if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
|
|
1668
2086
|
return false;
|
|
1669
2087
|
}
|
|
1670
2088
|
else {
|
|
@@ -1678,7 +2096,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1678
2096
|
width *= data.scaleX;
|
|
1679
2097
|
height *= data.scaleY;
|
|
1680
2098
|
}
|
|
1681
|
-
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
2099
|
+
allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
|
|
1682
2100
|
}
|
|
1683
2101
|
else {
|
|
1684
2102
|
allowPaint = false;
|
|
@@ -1697,307 +2115,72 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1697
2115
|
canvas.restore();
|
|
1698
2116
|
return true;
|
|
1699
2117
|
}
|
|
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();
|
|
2118
|
+
else {
|
|
2119
|
+
if (!paint.style || Export.running) {
|
|
2120
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1861
2121
|
}
|
|
1862
2122
|
else {
|
|
1863
|
-
|
|
2123
|
+
if (!paint.patternTask) {
|
|
2124
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
2125
|
+
paint.patternTask = null;
|
|
2126
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
2127
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
2128
|
+
ui.forceUpdate('surface');
|
|
2129
|
+
}), 300);
|
|
2130
|
+
}
|
|
1864
2131
|
}
|
|
2132
|
+
return false;
|
|
1865
2133
|
}
|
|
1866
2134
|
}
|
|
1867
2135
|
}
|
|
1868
2136
|
|
|
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);
|
|
2137
|
+
function recycleImage(attrName, data) {
|
|
2138
|
+
const paints = data['_' + attrName];
|
|
2139
|
+
if (paints instanceof Array) {
|
|
2140
|
+
let image, recycleMap, input, url;
|
|
2141
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
2142
|
+
image = paints[i].image;
|
|
2143
|
+
url = image && image.url;
|
|
2144
|
+
if (url) {
|
|
2145
|
+
if (!recycleMap)
|
|
2146
|
+
recycleMap = {};
|
|
2147
|
+
recycleMap[url] = true;
|
|
2148
|
+
ImageManager.recycle(image);
|
|
2149
|
+
if (image.loading) {
|
|
2150
|
+
if (!input) {
|
|
2151
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
2152
|
+
if (!(input instanceof Array))
|
|
2153
|
+
input = [input];
|
|
2154
|
+
}
|
|
2155
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1942
2156
|
}
|
|
1943
|
-
|
|
1944
|
-
break;
|
|
2157
|
+
}
|
|
1945
2158
|
}
|
|
2159
|
+
return recycleMap;
|
|
1946
2160
|
}
|
|
2161
|
+
return null;
|
|
1947
2162
|
}
|
|
1948
2163
|
|
|
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
|
-
}
|
|
2164
|
+
const PaintImageModule = {
|
|
2165
|
+
image,
|
|
2166
|
+
checkImage,
|
|
2167
|
+
createPattern,
|
|
2168
|
+
recycleImage,
|
|
2169
|
+
createData,
|
|
2170
|
+
getPatternData,
|
|
2171
|
+
fillOrFitMode,
|
|
2172
|
+
clipMode,
|
|
2173
|
+
repeatMode
|
|
2174
|
+
};
|
|
1993
2175
|
|
|
1994
|
-
const
|
|
1995
|
-
const
|
|
2176
|
+
const { toPoint: toPoint$2 } = AroundHelper;
|
|
2177
|
+
const realFrom$2 = {};
|
|
2178
|
+
const realTo$2 = {};
|
|
1996
2179
|
function linearGradient(paint, box) {
|
|
1997
2180
|
let { from, to, type, blendMode, opacity } = paint;
|
|
1998
|
-
from ||
|
|
1999
|
-
to ||
|
|
2000
|
-
const style = Platform.canvas.createLinearGradient(
|
|
2181
|
+
toPoint$2(from || 'top', box, realFrom$2);
|
|
2182
|
+
toPoint$2(to || 'bottom', box, realTo$2);
|
|
2183
|
+
const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
|
|
2001
2184
|
applyStops(style, paint.stops, opacity);
|
|
2002
2185
|
const data = { type, style };
|
|
2003
2186
|
if (blendMode)
|
|
@@ -2008,137 +2191,84 @@ function applyStops(gradient, stops, opacity) {
|
|
|
2008
2191
|
let stop;
|
|
2009
2192
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
2010
2193
|
stop = stops[i];
|
|
2011
|
-
|
|
2194
|
+
if (typeof stop === 'string') {
|
|
2195
|
+
gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
|
|
2196
|
+
}
|
|
2197
|
+
else {
|
|
2198
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
2199
|
+
}
|
|
2012
2200
|
}
|
|
2013
2201
|
}
|
|
2014
2202
|
|
|
2015
|
-
const {
|
|
2016
|
-
const { get
|
|
2017
|
-
const
|
|
2018
|
-
const defaultTo$1 = { x: 0.5, y: 1 };
|
|
2203
|
+
const { getAngle, getDistance: getDistance$1 } = PointHelper;
|
|
2204
|
+
const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
|
|
2205
|
+
const { toPoint: toPoint$1 } = AroundHelper;
|
|
2019
2206
|
const realFrom$1 = {};
|
|
2020
2207
|
const realTo$1 = {};
|
|
2021
2208
|
function radialGradient(paint, box) {
|
|
2022
2209
|
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
|
-
}
|
|
2210
|
+
toPoint$1(from || 'center', box, realFrom$1);
|
|
2211
|
+
toPoint$1(to || 'bottom', box, realTo$1);
|
|
2034
2212
|
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
2213
|
applyStops(style, paint.stops, opacity);
|
|
2036
|
-
const data = { type, style
|
|
2214
|
+
const data = { type, style };
|
|
2215
|
+
const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
|
|
2216
|
+
if (transform)
|
|
2217
|
+
data.transform = transform;
|
|
2037
2218
|
if (blendMode)
|
|
2038
2219
|
data.blendMode = blendMode;
|
|
2039
2220
|
return data;
|
|
2040
2221
|
}
|
|
2222
|
+
function getTransform(box, from, to, stretch, rotate90) {
|
|
2223
|
+
let transform;
|
|
2224
|
+
const { width, height } = box;
|
|
2225
|
+
if (width !== height || stretch) {
|
|
2226
|
+
const angle = getAngle(from, to);
|
|
2227
|
+
transform = get();
|
|
2228
|
+
if (rotate90) {
|
|
2229
|
+
scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
|
|
2230
|
+
rotateOfOuter(transform, from, angle + 90);
|
|
2231
|
+
}
|
|
2232
|
+
else {
|
|
2233
|
+
scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
|
|
2234
|
+
rotateOfOuter(transform, from, angle);
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
return transform;
|
|
2238
|
+
}
|
|
2041
2239
|
|
|
2042
|
-
const {
|
|
2043
|
-
const {
|
|
2044
|
-
const defaultFrom = { x: 0.5, y: 0.5 };
|
|
2045
|
-
const defaultTo = { x: 0.5, y: 1 };
|
|
2240
|
+
const { getDistance } = PointHelper;
|
|
2241
|
+
const { toPoint } = AroundHelper;
|
|
2046
2242
|
const realFrom = {};
|
|
2047
2243
|
const realTo = {};
|
|
2048
2244
|
function conicGradient(paint, box) {
|
|
2049
2245
|
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
|
-
}
|
|
2246
|
+
toPoint(from || 'center', box, realFrom);
|
|
2247
|
+
toPoint(to || 'bottom', box, realTo);
|
|
2065
2248
|
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
2249
|
applyStops(style, paint.stops, opacity);
|
|
2067
|
-
const data = { type, style
|
|
2250
|
+
const data = { type, style };
|
|
2251
|
+
const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
|
|
2252
|
+
if (transform)
|
|
2253
|
+
data.transform = transform;
|
|
2068
2254
|
if (blendMode)
|
|
2069
2255
|
data.blendMode = blendMode;
|
|
2070
2256
|
return data;
|
|
2071
2257
|
}
|
|
2072
2258
|
|
|
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
|
-
});
|
|
2259
|
+
const PaintGradientModule = {
|
|
2260
|
+
linearGradient,
|
|
2261
|
+
radialGradient,
|
|
2262
|
+
conicGradient,
|
|
2263
|
+
getTransform
|
|
2264
|
+
};
|
|
2135
2265
|
|
|
2136
2266
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
2137
2267
|
const tempBounds = {};
|
|
2138
2268
|
const offsetOutBounds$1 = {};
|
|
2139
|
-
function shadow(ui, current, shape
|
|
2269
|
+
function shadow(ui, current, shape) {
|
|
2140
2270
|
let copyBounds, spreadScale;
|
|
2141
|
-
const {
|
|
2271
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
2142
2272
|
const { shadow } = ui.__;
|
|
2143
2273
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2144
2274
|
const other = current.getSameCanvas();
|
|
@@ -2153,21 +2283,21 @@ function shadow(ui, current, shape, renderOptions) {
|
|
|
2153
2283
|
other.restore();
|
|
2154
2284
|
other.save();
|
|
2155
2285
|
if (worldCanvas) {
|
|
2156
|
-
other.copyWorld(other, bounds,
|
|
2157
|
-
copyBounds =
|
|
2286
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2287
|
+
copyBounds = nowWorld;
|
|
2158
2288
|
}
|
|
2159
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
2289
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
2160
2290
|
}
|
|
2161
|
-
if (ui.__worldFlipped
|
|
2162
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2291
|
+
if (ui.__worldFlipped) {
|
|
2292
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2163
2293
|
}
|
|
2164
2294
|
else {
|
|
2165
2295
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2166
2296
|
}
|
|
2167
2297
|
if (end && index < end)
|
|
2168
|
-
other.
|
|
2298
|
+
other.clearWorld(copyBounds, true);
|
|
2169
2299
|
});
|
|
2170
|
-
other.recycle();
|
|
2300
|
+
other.recycle(copyBounds);
|
|
2171
2301
|
}
|
|
2172
2302
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
2173
2303
|
const { bounds, shapeBounds } = shape;
|
|
@@ -2198,9 +2328,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
2198
2328
|
|
|
2199
2329
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
2200
2330
|
const offsetOutBounds = {};
|
|
2201
|
-
function innerShadow(ui, current, shape
|
|
2331
|
+
function innerShadow(ui, current, shape) {
|
|
2202
2332
|
let copyBounds, spreadScale;
|
|
2203
|
-
const {
|
|
2333
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
2204
2334
|
const { innerShadow } = ui.__;
|
|
2205
2335
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2206
2336
|
const other = current.getSameCanvas();
|
|
@@ -2213,40 +2343,115 @@ function innerShadow(ui, current, shape, renderOptions) {
|
|
|
2213
2343
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
2214
2344
|
other.restore();
|
|
2215
2345
|
if (worldCanvas) {
|
|
2216
|
-
other.copyWorld(other, bounds,
|
|
2217
|
-
other.copyWorld(worldCanvas,
|
|
2218
|
-
copyBounds =
|
|
2346
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2347
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
2348
|
+
copyBounds = nowWorld;
|
|
2219
2349
|
}
|
|
2220
2350
|
else {
|
|
2221
2351
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
2222
2352
|
copyBounds = bounds;
|
|
2223
2353
|
}
|
|
2224
2354
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
2225
|
-
if (ui.__worldFlipped
|
|
2226
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2355
|
+
if (ui.__worldFlipped) {
|
|
2356
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
2227
2357
|
}
|
|
2228
2358
|
else {
|
|
2229
2359
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
2230
2360
|
}
|
|
2231
2361
|
if (end && index < end)
|
|
2232
|
-
other.
|
|
2362
|
+
other.clearWorld(copyBounds, true);
|
|
2233
2363
|
});
|
|
2234
|
-
other.recycle();
|
|
2364
|
+
other.recycle(copyBounds);
|
|
2235
2365
|
}
|
|
2236
2366
|
|
|
2237
2367
|
function blur(ui, current, origin) {
|
|
2238
2368
|
const { blur } = ui.__;
|
|
2239
|
-
origin.setWorldBlur(blur * ui.
|
|
2240
|
-
origin.copyWorldToInner(current, ui.
|
|
2369
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
2370
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
2241
2371
|
origin.filter = 'none';
|
|
2242
2372
|
}
|
|
2243
2373
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
shadow
|
|
2249
|
-
|
|
2374
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
const EffectModule = {
|
|
2378
|
+
shadow,
|
|
2379
|
+
innerShadow,
|
|
2380
|
+
blur,
|
|
2381
|
+
backgroundBlur
|
|
2382
|
+
};
|
|
2383
|
+
|
|
2384
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
2385
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
2386
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
2387
|
+
const { children } = this;
|
|
2388
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
2389
|
+
child = children[i];
|
|
2390
|
+
if (child.__.mask) {
|
|
2391
|
+
if (currentMask) {
|
|
2392
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2393
|
+
maskCanvas = contentCanvas = null;
|
|
2394
|
+
}
|
|
2395
|
+
if (child.__.mask === 'path') {
|
|
2396
|
+
if (child.opacity < 1) {
|
|
2397
|
+
currentMask = 'opacity-path';
|
|
2398
|
+
maskOpacity = child.opacity;
|
|
2399
|
+
if (!contentCanvas)
|
|
2400
|
+
contentCanvas = getCanvas(canvas);
|
|
2401
|
+
}
|
|
2402
|
+
else {
|
|
2403
|
+
currentMask = 'path';
|
|
2404
|
+
canvas.save();
|
|
2405
|
+
}
|
|
2406
|
+
child.__clip(contentCanvas || canvas, options);
|
|
2407
|
+
}
|
|
2408
|
+
else {
|
|
2409
|
+
currentMask = 'alpha';
|
|
2410
|
+
if (!maskCanvas)
|
|
2411
|
+
maskCanvas = getCanvas(canvas);
|
|
2412
|
+
if (!contentCanvas)
|
|
2413
|
+
contentCanvas = getCanvas(canvas);
|
|
2414
|
+
child.__render(maskCanvas, options);
|
|
2415
|
+
}
|
|
2416
|
+
if (child.__.mask !== 'clipping')
|
|
2417
|
+
continue;
|
|
2418
|
+
}
|
|
2419
|
+
if (excludeRenderBounds(child, options))
|
|
2420
|
+
continue;
|
|
2421
|
+
child.__render(contentCanvas || canvas, options);
|
|
2422
|
+
}
|
|
2423
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2424
|
+
};
|
|
2425
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
2426
|
+
switch (maskMode) {
|
|
2427
|
+
case 'alpha':
|
|
2428
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
2429
|
+
break;
|
|
2430
|
+
case 'opacity-path':
|
|
2431
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
2432
|
+
break;
|
|
2433
|
+
case 'path':
|
|
2434
|
+
canvas.restore();
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
function getCanvas(canvas) {
|
|
2438
|
+
return canvas.getSameCanvas(false, true);
|
|
2439
|
+
}
|
|
2440
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
2441
|
+
const realBounds = leaf.__nowWorld;
|
|
2442
|
+
content.resetTransform();
|
|
2443
|
+
content.opacity = 1;
|
|
2444
|
+
content.useMask(mask, realBounds);
|
|
2445
|
+
mask.recycle(realBounds);
|
|
2446
|
+
copyContent(leaf, canvas, content, 1);
|
|
2447
|
+
}
|
|
2448
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
2449
|
+
const realBounds = leaf.__nowWorld;
|
|
2450
|
+
canvas.resetTransform();
|
|
2451
|
+
canvas.opacity = maskOpacity;
|
|
2452
|
+
canvas.copyWorld(content, realBounds);
|
|
2453
|
+
content.recycle(realBounds);
|
|
2454
|
+
}
|
|
2250
2455
|
|
|
2251
2456
|
const money = '¥¥$€££¢¢';
|
|
2252
2457
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -2403,7 +2608,8 @@ function createRows(drawData, content, style) {
|
|
|
2403
2608
|
if (breakAll) {
|
|
2404
2609
|
if (wordWidth)
|
|
2405
2610
|
addWord();
|
|
2406
|
-
|
|
2611
|
+
if (rowWidth)
|
|
2612
|
+
addRow();
|
|
2407
2613
|
}
|
|
2408
2614
|
else {
|
|
2409
2615
|
if (!afterBreak)
|
|
@@ -2411,10 +2617,12 @@ function createRows(drawData, content, style) {
|
|
|
2411
2617
|
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2412
2618
|
if (wordWidth)
|
|
2413
2619
|
addWord();
|
|
2414
|
-
|
|
2620
|
+
if (rowWidth)
|
|
2621
|
+
addRow();
|
|
2415
2622
|
}
|
|
2416
2623
|
else {
|
|
2417
|
-
|
|
2624
|
+
if (rowWidth)
|
|
2625
|
+
addRow();
|
|
2418
2626
|
}
|
|
2419
2627
|
}
|
|
2420
2628
|
}
|
|
@@ -2509,11 +2717,11 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2509
2717
|
if (mode === WordMode) {
|
|
2510
2718
|
wordChar = { char: '', x: charX };
|
|
2511
2719
|
charX = toWordChar(word.data, charX, wordChar);
|
|
2512
|
-
if (wordChar.char !== ' ')
|
|
2720
|
+
if (row.isOverflow || wordChar.char !== ' ')
|
|
2513
2721
|
row.data.push(wordChar);
|
|
2514
2722
|
}
|
|
2515
2723
|
else {
|
|
2516
|
-
charX = toChar(word.data, charX, row.data);
|
|
2724
|
+
charX = toChar(word.data, charX, row.data, row.isOverflow);
|
|
2517
2725
|
}
|
|
2518
2726
|
if (!row.paraEnd && addWordWidth) {
|
|
2519
2727
|
charX += addWordWidth;
|
|
@@ -2540,9 +2748,9 @@ function toWordChar(data, charX, wordChar) {
|
|
|
2540
2748
|
});
|
|
2541
2749
|
return charX;
|
|
2542
2750
|
}
|
|
2543
|
-
function toChar(data, charX, rowData) {
|
|
2751
|
+
function toChar(data, charX, rowData, isOverflow) {
|
|
2544
2752
|
data.forEach(char => {
|
|
2545
|
-
if (char.char !== ' ') {
|
|
2753
|
+
if (isOverflow || char.char !== ' ') {
|
|
2546
2754
|
char.x = charX;
|
|
2547
2755
|
rowData.push(char);
|
|
2548
2756
|
}
|
|
@@ -2574,12 +2782,14 @@ function layoutText(drawData, style) {
|
|
|
2574
2782
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2575
2783
|
row = rows[i];
|
|
2576
2784
|
row.x = x;
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2785
|
+
if (row.width < width || (row.width > width && !__clipText)) {
|
|
2786
|
+
switch (textAlign) {
|
|
2787
|
+
case 'center':
|
|
2788
|
+
row.x += (width - row.width) / 2;
|
|
2789
|
+
break;
|
|
2790
|
+
case 'right':
|
|
2791
|
+
row.x += width - row.width;
|
|
2792
|
+
}
|
|
2583
2793
|
}
|
|
2584
2794
|
if (row.paraStart && paraSpacing && i > 0)
|
|
2585
2795
|
starY += paraSpacing;
|
|
@@ -2615,16 +2825,20 @@ function layoutText(drawData, style) {
|
|
|
2615
2825
|
bounds.height = realHeight;
|
|
2616
2826
|
}
|
|
2617
2827
|
|
|
2618
|
-
function clipText(drawData, style) {
|
|
2828
|
+
function clipText(drawData, style, x, width) {
|
|
2829
|
+
if (!width)
|
|
2830
|
+
return;
|
|
2619
2831
|
const { rows, overflow } = drawData;
|
|
2620
2832
|
let { textOverflow } = style;
|
|
2621
2833
|
rows.splice(overflow);
|
|
2622
|
-
if (textOverflow !== '
|
|
2623
|
-
if (textOverflow === '
|
|
2834
|
+
if (textOverflow && textOverflow !== 'show') {
|
|
2835
|
+
if (textOverflow === 'hide')
|
|
2836
|
+
textOverflow = '';
|
|
2837
|
+
else if (textOverflow === 'ellipsis')
|
|
2624
2838
|
textOverflow = '...';
|
|
2625
2839
|
let char, charRight;
|
|
2626
|
-
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2627
|
-
const right =
|
|
2840
|
+
const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
|
|
2841
|
+
const right = x + width - ellipsisWidth;
|
|
2628
2842
|
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2629
2843
|
list.forEach(row => {
|
|
2630
2844
|
if (row.isOverflow && row.data) {
|
|
@@ -2671,42 +2885,40 @@ function decorationText(drawData, style) {
|
|
|
2671
2885
|
}
|
|
2672
2886
|
|
|
2673
2887
|
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
|
-
};
|
|
2888
|
+
function getDrawData(content, style) {
|
|
2889
|
+
if (typeof content !== 'string')
|
|
2890
|
+
content = String(content);
|
|
2891
|
+
let x = 0, y = 0;
|
|
2892
|
+
let width = style.__getInput('width') || 0;
|
|
2893
|
+
let height = style.__getInput('height') || 0;
|
|
2894
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2895
|
+
if (padding) {
|
|
2896
|
+
if (width) {
|
|
2897
|
+
x = padding[left];
|
|
2898
|
+
width -= (padding[right] + padding[left]);
|
|
2899
|
+
}
|
|
2900
|
+
if (height) {
|
|
2901
|
+
y = padding[top];
|
|
2902
|
+
height -= (padding[top] + padding[bottom]);
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
const drawData = {
|
|
2906
|
+
bounds: { x, y, width, height },
|
|
2907
|
+
rows: [],
|
|
2908
|
+
paraNumber: 0,
|
|
2909
|
+
font: Platform.canvas.font = __font
|
|
2910
|
+
};
|
|
2911
|
+
createRows(drawData, content, style);
|
|
2912
|
+
if (padding)
|
|
2913
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2914
|
+
layoutText(drawData, style);
|
|
2915
|
+
layoutChar(drawData, style, width);
|
|
2916
|
+
if (drawData.overflow)
|
|
2917
|
+
clipText(drawData, style, x, width);
|
|
2918
|
+
if (textDecoration !== 'none')
|
|
2919
|
+
decorationText(drawData, style);
|
|
2920
|
+
return drawData;
|
|
2921
|
+
}
|
|
2710
2922
|
function padAutoText(padding, drawData, style, width, height) {
|
|
2711
2923
|
if (!width) {
|
|
2712
2924
|
switch (style.textAlign) {
|
|
@@ -2734,67 +2946,157 @@ function offsetText(drawData, attrName, value) {
|
|
|
2734
2946
|
rows[i][attrName] += value;
|
|
2735
2947
|
}
|
|
2736
2948
|
|
|
2737
|
-
const
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2949
|
+
const TextConvertModule = {
|
|
2950
|
+
getDrawData
|
|
2951
|
+
};
|
|
2952
|
+
|
|
2953
|
+
function string(color, opacity) {
|
|
2954
|
+
if (typeof color === 'string')
|
|
2955
|
+
return color;
|
|
2956
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2957
|
+
if (opacity)
|
|
2958
|
+
a *= opacity;
|
|
2959
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2960
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2961
|
+
}
|
|
2962
|
+
|
|
2963
|
+
const ColorConvertModule = {
|
|
2964
|
+
string
|
|
2747
2965
|
};
|
|
2748
2966
|
|
|
2749
|
-
const
|
|
2967
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2968
|
+
function getTrimBounds(canvas) {
|
|
2969
|
+
const { width, height } = canvas.view;
|
|
2970
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2971
|
+
let x, y, pointBounds, index = 0;
|
|
2972
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2973
|
+
if (data[i + 3] !== 0) {
|
|
2974
|
+
x = index % width;
|
|
2975
|
+
y = (index - x) / width;
|
|
2976
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2977
|
+
}
|
|
2978
|
+
index++;
|
|
2979
|
+
}
|
|
2980
|
+
const bounds = new Bounds();
|
|
2981
|
+
toBounds(pointBounds, bounds);
|
|
2982
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2983
|
+
}
|
|
2984
|
+
|
|
2985
|
+
const ExportModule = {
|
|
2750
2986
|
export(leaf, filename, options) {
|
|
2751
|
-
|
|
2987
|
+
this.running = true;
|
|
2988
|
+
const fileType = FileHelper.fileType(filename);
|
|
2989
|
+
options = FileHelper.getExportOptions(options);
|
|
2752
2990
|
return addTask((success) => new Promise((resolve) => {
|
|
2991
|
+
const over = (result) => {
|
|
2992
|
+
success(result);
|
|
2993
|
+
resolve();
|
|
2994
|
+
this.running = false;
|
|
2995
|
+
};
|
|
2996
|
+
const { toURL } = Platform;
|
|
2997
|
+
const { download } = Platform.origin;
|
|
2998
|
+
if (filename === 'json') {
|
|
2999
|
+
return over({ data: leaf.toJSON(options.json) });
|
|
3000
|
+
}
|
|
3001
|
+
else if (fileType === 'json') {
|
|
3002
|
+
download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
|
|
3003
|
+
return over({ data: true });
|
|
3004
|
+
}
|
|
3005
|
+
if (filename === 'svg') {
|
|
3006
|
+
return over({ data: leaf.toSVG() });
|
|
3007
|
+
}
|
|
3008
|
+
else if (fileType === 'svg') {
|
|
3009
|
+
download(toURL(leaf.toSVG(), 'svg'), filename);
|
|
3010
|
+
return over({ data: true });
|
|
3011
|
+
}
|
|
2753
3012
|
const { leafer } = leaf;
|
|
2754
3013
|
if (leafer) {
|
|
3014
|
+
checkLazy(leaf);
|
|
2755
3015
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2756
|
-
let
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
3016
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
3017
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
3018
|
+
const { slice, trim, onCanvas } = options;
|
|
3019
|
+
let scale = options.scale || 1;
|
|
3020
|
+
let pixelRatio = options.pixelRatio || 1;
|
|
3021
|
+
const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
|
|
3022
|
+
const contextSettings = options.contextSettings || leafer.config.contextSettings;
|
|
3023
|
+
if (leaf.isApp) {
|
|
3024
|
+
scale *= pixelRatio;
|
|
3025
|
+
pixelRatio = leaf.app.pixelRatio;
|
|
3026
|
+
}
|
|
3027
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
3028
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
3029
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
3030
|
+
if (screenshot) {
|
|
3031
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2763
3032
|
}
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
3033
|
+
else {
|
|
3034
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
3035
|
+
scaleX = worldTransform.scaleX;
|
|
3036
|
+
scaleY = worldTransform.scaleY;
|
|
3037
|
+
switch (relative) {
|
|
3038
|
+
case 'inner':
|
|
3039
|
+
matrix.set(worldTransform);
|
|
3040
|
+
break;
|
|
3041
|
+
case 'local':
|
|
3042
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
3043
|
+
scaleX /= leaf.scaleX;
|
|
3044
|
+
scaleY /= leaf.scaleY;
|
|
3045
|
+
break;
|
|
3046
|
+
case 'world':
|
|
3047
|
+
scaleX = 1;
|
|
3048
|
+
scaleY = 1;
|
|
3049
|
+
break;
|
|
3050
|
+
case 'page':
|
|
3051
|
+
relative = leaf.leafer;
|
|
3052
|
+
default:
|
|
3053
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
3054
|
+
const l = relative.worldTransform;
|
|
3055
|
+
scaleX /= scaleX / l.scaleX;
|
|
3056
|
+
scaleY /= scaleY / l.scaleY;
|
|
3057
|
+
}
|
|
3058
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2776
3059
|
}
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
3060
|
+
const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
|
|
3061
|
+
let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
|
|
3062
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
3063
|
+
let sliceLeaf;
|
|
3064
|
+
if (slice) {
|
|
3065
|
+
sliceLeaf = leaf;
|
|
3066
|
+
sliceLeaf.__worldOpacity = 0;
|
|
3067
|
+
leaf = leafer;
|
|
3068
|
+
renderOptions.bounds = canvas.bounds;
|
|
2780
3069
|
}
|
|
2781
|
-
|
|
2782
|
-
|
|
3070
|
+
canvas.save();
|
|
3071
|
+
if (isFrame && fill !== undefined) {
|
|
3072
|
+
const oldFill = leaf.get('fill');
|
|
3073
|
+
leaf.fill = '';
|
|
3074
|
+
leaf.__render(canvas, renderOptions);
|
|
3075
|
+
leaf.fill = oldFill;
|
|
2783
3076
|
}
|
|
2784
3077
|
else {
|
|
2785
|
-
|
|
3078
|
+
leaf.__render(canvas, renderOptions);
|
|
2786
3079
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
if (
|
|
2791
|
-
canvas
|
|
3080
|
+
canvas.restore();
|
|
3081
|
+
if (sliceLeaf)
|
|
3082
|
+
sliceLeaf.__updateWorldOpacity();
|
|
3083
|
+
if (trim) {
|
|
3084
|
+
trimBounds = getTrimBounds(canvas);
|
|
3085
|
+
const old = canvas, { width, height } = trimBounds;
|
|
3086
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
3087
|
+
canvas = Creator.canvas(config);
|
|
3088
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
3089
|
+
}
|
|
3090
|
+
if (needFill)
|
|
3091
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
3092
|
+
if (onCanvas)
|
|
3093
|
+
onCanvas(canvas);
|
|
3094
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
3095
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2792
3096
|
}));
|
|
2793
3097
|
}
|
|
2794
3098
|
else {
|
|
2795
|
-
|
|
2796
|
-
resolve();
|
|
2797
|
-
Export.running = false;
|
|
3099
|
+
over({ data: false });
|
|
2798
3100
|
}
|
|
2799
3101
|
}));
|
|
2800
3102
|
}
|
|
@@ -2807,13 +3109,64 @@ function addTask(task) {
|
|
|
2807
3109
|
tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
|
|
2808
3110
|
});
|
|
2809
3111
|
}
|
|
3112
|
+
function checkLazy(leaf) {
|
|
3113
|
+
if (leaf.__.__needComputePaint)
|
|
3114
|
+
leaf.__.__computePaint();
|
|
3115
|
+
if (leaf.isBranch)
|
|
3116
|
+
leaf.children.forEach(child => checkLazy(child));
|
|
3117
|
+
}
|
|
3118
|
+
|
|
3119
|
+
const canvas = LeaferCanvasBase.prototype;
|
|
3120
|
+
const debug = Debug.get('@leafer-ui/export');
|
|
3121
|
+
canvas.export = function (filename, options) {
|
|
3122
|
+
const { quality, blob } = FileHelper.getExportOptions(options);
|
|
3123
|
+
if (filename.includes('.')) {
|
|
3124
|
+
return this.saveAs(filename, quality);
|
|
3125
|
+
}
|
|
3126
|
+
else if (blob) {
|
|
3127
|
+
return this.toBlob(filename, quality);
|
|
3128
|
+
}
|
|
3129
|
+
else {
|
|
3130
|
+
return this.toDataURL(filename, quality);
|
|
3131
|
+
}
|
|
3132
|
+
};
|
|
3133
|
+
canvas.toBlob = function (type, quality) {
|
|
3134
|
+
return new Promise((resolve) => {
|
|
3135
|
+
Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
3136
|
+
resolve(blob);
|
|
3137
|
+
}).catch((e) => {
|
|
3138
|
+
debug.error(e);
|
|
3139
|
+
resolve(null);
|
|
3140
|
+
});
|
|
3141
|
+
});
|
|
3142
|
+
};
|
|
3143
|
+
canvas.toDataURL = function (type, quality) {
|
|
3144
|
+
return Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
3145
|
+
};
|
|
3146
|
+
canvas.saveAs = function (filename, quality) {
|
|
3147
|
+
return new Promise((resolve) => {
|
|
3148
|
+
Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
3149
|
+
resolve(true);
|
|
3150
|
+
}).catch((e) => {
|
|
3151
|
+
debug.error(e);
|
|
3152
|
+
resolve(false);
|
|
3153
|
+
});
|
|
3154
|
+
});
|
|
3155
|
+
};
|
|
2810
3156
|
|
|
2811
|
-
Object.assign(
|
|
2812
|
-
Object.assign(
|
|
2813
|
-
Object.assign(
|
|
2814
|
-
Object.assign(
|
|
2815
|
-
Object.assign(
|
|
3157
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
3158
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
3159
|
+
Object.assign(Paint, PaintModule);
|
|
3160
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
3161
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
3162
|
+
Object.assign(Effect, EffectModule);
|
|
3163
|
+
Object.assign(Export, ExportModule);
|
|
2816
3164
|
|
|
3165
|
+
Object.assign(Creator, {
|
|
3166
|
+
interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
|
|
3167
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
3168
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
3169
|
+
});
|
|
2817
3170
|
useCanvas();
|
|
2818
3171
|
|
|
2819
3172
|
export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
|