@leafer-ui/miniapp 1.0.0-rc.2 → 1.0.0-rc.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/miniapp.esm.js +1397 -1032
- package/dist/miniapp.esm.min.js +1 -1
- package/dist/miniapp.module.js +7657 -6125
- package/dist/miniapp.module.min.js +1 -1
- package/package.json +10 -6
- package/src/index.ts +14 -1
- package/types/index.d.ts +5 -3
package/dist/miniapp.esm.js
CHANGED
|
@@ -1,8 +1,217 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, Creator, LeaferImage, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, Answer, MatrixHelper, ImageEvent, 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, HitCanvasManager, Platform as Platform$1 } 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
|
+
class LeaferCanvas extends LeaferCanvasBase {
|
|
9
|
+
get allowBackgroundColor() { return false; }
|
|
10
|
+
init() {
|
|
11
|
+
let { view } = this.config;
|
|
12
|
+
if (view) {
|
|
13
|
+
if (typeof view === 'string') {
|
|
14
|
+
if (view[0] !== '#')
|
|
15
|
+
view = '#' + view;
|
|
16
|
+
this.viewSelect = Platform.miniapp.select(view);
|
|
17
|
+
}
|
|
18
|
+
else if (view.fields) {
|
|
19
|
+
this.viewSelect = view;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.initView(view);
|
|
23
|
+
}
|
|
24
|
+
if (this.viewSelect)
|
|
25
|
+
Platform.miniapp.getSizeView(this.viewSelect).then(sizeView => {
|
|
26
|
+
this.initView(sizeView);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
this.initView();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
initView(view) {
|
|
34
|
+
if (!view) {
|
|
35
|
+
view = {};
|
|
36
|
+
this.__createView();
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.view = view.view || view;
|
|
40
|
+
}
|
|
41
|
+
this.__createContext();
|
|
42
|
+
const { width, height, pixelRatio } = this.config;
|
|
43
|
+
const size = { width: width || view.width, height: height || view.height, pixelRatio };
|
|
44
|
+
this.resize(size);
|
|
45
|
+
if (this.context.roundRect) {
|
|
46
|
+
this.roundRect = function (x, y, width, height, radius) {
|
|
47
|
+
this.context.roundRect(x, y, width, height, typeof radius === 'number' ? [radius] : radius);
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
canvasPatch(this.context.__proto__);
|
|
51
|
+
}
|
|
52
|
+
__createView() {
|
|
53
|
+
this.view = Platform.origin.createCanvas(1, 1);
|
|
54
|
+
}
|
|
55
|
+
updateViewSize() {
|
|
56
|
+
const { width, height, pixelRatio } = this;
|
|
57
|
+
this.view.width = Math.ceil(width * pixelRatio);
|
|
58
|
+
this.view.height = Math.ceil(height * pixelRatio);
|
|
59
|
+
}
|
|
60
|
+
updateClientBounds(callback) {
|
|
61
|
+
if (this.viewSelect)
|
|
62
|
+
Platform.miniapp.getBounds(this.viewSelect).then(bounds => {
|
|
63
|
+
this.clientBounds = bounds;
|
|
64
|
+
if (callback)
|
|
65
|
+
callback();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
startAutoLayout(_autoBounds, listener) {
|
|
69
|
+
this.resizeListener = listener;
|
|
70
|
+
this.checkSize = this.checkSize.bind(this);
|
|
71
|
+
Platform.miniapp.onWindowResize(this.checkSize);
|
|
72
|
+
}
|
|
73
|
+
checkSize() {
|
|
74
|
+
if (this.viewSelect) {
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
this.updateClientBounds(() => {
|
|
77
|
+
const { width, height } = this.clientBounds;
|
|
78
|
+
const { pixelRatio } = this;
|
|
79
|
+
const size = { width, height, pixelRatio };
|
|
80
|
+
if (!this.isSameSize(size)) {
|
|
81
|
+
const oldSize = {};
|
|
82
|
+
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
83
|
+
this.resize(size);
|
|
84
|
+
if (this.width !== undefined)
|
|
85
|
+
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}, 500);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
stopAutoLayout() {
|
|
92
|
+
this.autoLayout = false;
|
|
93
|
+
this.resizeListener = null;
|
|
94
|
+
Platform.miniapp.offWindowResize(this.checkSize);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const { mineType, fileType } = FileHelper;
|
|
99
|
+
Object.assign(Creator, {
|
|
100
|
+
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
101
|
+
image: (options) => new LeaferImage(options)
|
|
102
|
+
});
|
|
103
|
+
function useCanvas(_canvasType, app) {
|
|
104
|
+
if (!Platform.origin) {
|
|
105
|
+
Platform.origin = {
|
|
106
|
+
createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
|
|
107
|
+
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
108
|
+
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
109
|
+
canvasSaveAs: (canvas, filePath, quality) => {
|
|
110
|
+
let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
|
|
111
|
+
data = data.substring(data.indexOf('64,') + 3);
|
|
112
|
+
return Platform.origin.download(data, filePath);
|
|
113
|
+
},
|
|
114
|
+
download(data, filePath) {
|
|
115
|
+
return new Promise((resolve, reject) => {
|
|
116
|
+
let toAlbum;
|
|
117
|
+
if (!filePath.includes('/')) {
|
|
118
|
+
filePath = `${app.env.USER_DATA_PATH}/` + filePath;
|
|
119
|
+
toAlbum = true;
|
|
120
|
+
}
|
|
121
|
+
const fs = app.getFileSystemManager();
|
|
122
|
+
fs.writeFile({
|
|
123
|
+
filePath,
|
|
124
|
+
data,
|
|
125
|
+
encoding: 'base64',
|
|
126
|
+
success() {
|
|
127
|
+
if (toAlbum) {
|
|
128
|
+
Platform.miniapp.saveToAlbum(filePath).then(() => {
|
|
129
|
+
fs.unlink({ filePath });
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
resolve();
|
|
133
|
+
},
|
|
134
|
+
fail(error) {
|
|
135
|
+
reject(error);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
loadImage(url) {
|
|
141
|
+
return new Promise((resolve, reject) => {
|
|
142
|
+
const img = Platform.canvas.view.createImage();
|
|
143
|
+
img.onload = () => { resolve(img); };
|
|
144
|
+
img.onerror = (error) => { reject(error); };
|
|
145
|
+
img.src = url;
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
noRepeat: 'repeat-x'
|
|
149
|
+
};
|
|
150
|
+
Platform.miniapp = {
|
|
151
|
+
select(name) {
|
|
152
|
+
return app.createSelectorQuery().select(name);
|
|
153
|
+
},
|
|
154
|
+
getBounds(select) {
|
|
155
|
+
return new Promise((resolve) => {
|
|
156
|
+
select.boundingClientRect().exec((res) => {
|
|
157
|
+
const rect = res[1];
|
|
158
|
+
resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
getSizeView(select) {
|
|
163
|
+
return new Promise((resolve) => {
|
|
164
|
+
select.fields({ node: true, size: true }).exec((res) => {
|
|
165
|
+
const data = res[0];
|
|
166
|
+
resolve({ view: data.node, width: data.width, height: data.height });
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
},
|
|
170
|
+
saveToAlbum(path) {
|
|
171
|
+
return new Promise((resolve) => {
|
|
172
|
+
app.getSetting({
|
|
173
|
+
success: (res) => {
|
|
174
|
+
if (res.authSetting['scope.writePhotosAlbum']) {
|
|
175
|
+
app.saveImageToPhotosAlbum({
|
|
176
|
+
filePath: path,
|
|
177
|
+
success() { resolve(true); }
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
app.authorize({
|
|
182
|
+
scope: 'scope.writePhotosAlbum',
|
|
183
|
+
success: () => {
|
|
184
|
+
app.saveImageToPhotosAlbum({
|
|
185
|
+
filePath: path,
|
|
186
|
+
success() { resolve(true); }
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
fail: () => { }
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
},
|
|
196
|
+
onWindowResize(fun) {
|
|
197
|
+
app.onWindowResize(fun);
|
|
198
|
+
},
|
|
199
|
+
offWindowResize(fun) {
|
|
200
|
+
app.offWindowResize(fun);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
Platform.event = {
|
|
204
|
+
stopDefault(_origin) { },
|
|
205
|
+
stopNow(_origin) { },
|
|
206
|
+
stop(_origin) { }
|
|
207
|
+
};
|
|
208
|
+
Platform.canvas = Creator.canvas();
|
|
209
|
+
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
Platform.name = 'miniapp';
|
|
213
|
+
Platform.requestRender = function (render) { Platform.canvas.view.requestAnimationFrame(render); };
|
|
214
|
+
Platform.devicePixelRatio = wx.getSystemInfoSync().pixelRatio;
|
|
6
215
|
|
|
7
216
|
class Watcher {
|
|
8
217
|
get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
|
|
@@ -10,7 +219,7 @@ class Watcher {
|
|
|
10
219
|
if (this.hasRemove) {
|
|
11
220
|
const updatedList = new LeafList();
|
|
12
221
|
this.__updatedList.list.forEach(item => { if (item.leafer)
|
|
13
|
-
updatedList.
|
|
222
|
+
updatedList.add(item); });
|
|
14
223
|
return updatedList;
|
|
15
224
|
}
|
|
16
225
|
else {
|
|
@@ -45,7 +254,7 @@ class Watcher {
|
|
|
45
254
|
this.target.emit(RenderEvent.REQUEST);
|
|
46
255
|
}
|
|
47
256
|
__onAttrChange(event) {
|
|
48
|
-
this.__updatedList.
|
|
257
|
+
this.__updatedList.add(event.target);
|
|
49
258
|
this.update();
|
|
50
259
|
}
|
|
51
260
|
__onChildEvent(event) {
|
|
@@ -55,12 +264,12 @@ class Watcher {
|
|
|
55
264
|
}
|
|
56
265
|
else {
|
|
57
266
|
this.hasRemove = true;
|
|
58
|
-
this.__updatedList.
|
|
267
|
+
this.__updatedList.add(event.parent);
|
|
59
268
|
}
|
|
60
269
|
this.update();
|
|
61
270
|
}
|
|
62
271
|
__pushChild(child) {
|
|
63
|
-
this.__updatedList.
|
|
272
|
+
this.__updatedList.add(child);
|
|
64
273
|
if (child.isBranch)
|
|
65
274
|
this.__loopChildren(child);
|
|
66
275
|
}
|
|
@@ -99,22 +308,22 @@ class Watcher {
|
|
|
99
308
|
}
|
|
100
309
|
}
|
|
101
310
|
|
|
102
|
-
const {
|
|
311
|
+
const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
|
|
103
312
|
const { pushAllChildBranch, pushAllParent } = BranchHelper;
|
|
104
313
|
function updateMatrix(updateList, levelList) {
|
|
105
314
|
let layout;
|
|
106
315
|
updateList.list.forEach(leaf => {
|
|
107
316
|
layout = leaf.__layout;
|
|
108
|
-
if (levelList.without(leaf) && !layout.
|
|
317
|
+
if (levelList.without(leaf) && !layout.proxyZoom) {
|
|
109
318
|
if (layout.matrixChanged) {
|
|
110
|
-
|
|
111
|
-
levelList.
|
|
319
|
+
updateAllMatrix$1(leaf, true);
|
|
320
|
+
levelList.add(leaf);
|
|
112
321
|
if (leaf.isBranch)
|
|
113
322
|
pushAllChildBranch(leaf, levelList);
|
|
114
323
|
pushAllParent(leaf, levelList);
|
|
115
324
|
}
|
|
116
325
|
else if (layout.boundsChanged) {
|
|
117
|
-
levelList.
|
|
326
|
+
levelList.add(leaf);
|
|
118
327
|
if (leaf.isBranch)
|
|
119
328
|
leaf.__tempNumber = 0;
|
|
120
329
|
pushAllParent(leaf, levelList);
|
|
@@ -123,20 +332,21 @@ function updateMatrix(updateList, levelList) {
|
|
|
123
332
|
});
|
|
124
333
|
}
|
|
125
334
|
function updateBounds(boundsList) {
|
|
126
|
-
let
|
|
335
|
+
let list, branch, children;
|
|
127
336
|
boundsList.sort(true);
|
|
128
337
|
boundsList.levels.forEach(level => {
|
|
129
|
-
|
|
130
|
-
for (let i = 0, len =
|
|
131
|
-
branch =
|
|
338
|
+
list = boundsList.levelMap[level];
|
|
339
|
+
for (let i = 0, len = list.length; i < len; i++) {
|
|
340
|
+
branch = list[i];
|
|
132
341
|
if (branch.isBranch && branch.__tempNumber) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
342
|
+
children = branch.children;
|
|
343
|
+
for (let j = 0, jLen = children.length; j < jLen; j++) {
|
|
344
|
+
if (!children[j].isBranch) {
|
|
345
|
+
updateOneBounds(children[j]);
|
|
136
346
|
}
|
|
137
347
|
}
|
|
138
348
|
}
|
|
139
|
-
branch
|
|
349
|
+
updateOneBounds(branch);
|
|
140
350
|
}
|
|
141
351
|
});
|
|
142
352
|
}
|
|
@@ -149,7 +359,7 @@ function updateChange(updateList) {
|
|
|
149
359
|
}
|
|
150
360
|
|
|
151
361
|
const { worldBounds } = LeafBoundsHelper;
|
|
152
|
-
const {
|
|
362
|
+
const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
|
|
153
363
|
class LayoutBlockData {
|
|
154
364
|
constructor(list) {
|
|
155
365
|
this.updatedBounds = new Bounds();
|
|
@@ -160,14 +370,20 @@ class LayoutBlockData {
|
|
|
160
370
|
this.updatedList = list;
|
|
161
371
|
}
|
|
162
372
|
setBefore() {
|
|
163
|
-
|
|
373
|
+
this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
164
374
|
}
|
|
165
375
|
setAfter() {
|
|
166
|
-
|
|
167
|
-
|
|
376
|
+
const { list } = this.updatedList;
|
|
377
|
+
if (list.some(leaf => leaf.noBounds)) {
|
|
378
|
+
this.afterBounds.set(bigBounds);
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
this.afterBounds.setListWithFn(list, worldBounds);
|
|
382
|
+
}
|
|
383
|
+
this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
|
|
168
384
|
}
|
|
169
385
|
merge(data) {
|
|
170
|
-
this.updatedList.
|
|
386
|
+
this.updatedList.addList(data.updatedList.list);
|
|
171
387
|
this.beforeBounds.add(data.beforeBounds);
|
|
172
388
|
this.afterBounds.add(data.afterBounds);
|
|
173
389
|
this.updatedBounds.add(data.updatedBounds);
|
|
@@ -177,9 +393,8 @@ class LayoutBlockData {
|
|
|
177
393
|
}
|
|
178
394
|
}
|
|
179
395
|
|
|
180
|
-
const {
|
|
181
|
-
const
|
|
182
|
-
const debug$1 = Debug.get('Layouter');
|
|
396
|
+
const { updateAllMatrix, updateAllChange } = LeafHelper;
|
|
397
|
+
const debug$2 = Debug.get('Layouter');
|
|
183
398
|
class Layouter {
|
|
184
399
|
constructor(target, userConfig) {
|
|
185
400
|
this.totalTimes = 0;
|
|
@@ -214,7 +429,7 @@ class Layouter {
|
|
|
214
429
|
target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
|
|
215
430
|
}
|
|
216
431
|
catch (e) {
|
|
217
|
-
debug$
|
|
432
|
+
debug$2.error(e);
|
|
218
433
|
}
|
|
219
434
|
this.layoutedBlocks = null;
|
|
220
435
|
}
|
|
@@ -228,9 +443,9 @@ class Layouter {
|
|
|
228
443
|
}
|
|
229
444
|
layoutOnce() {
|
|
230
445
|
if (this.layouting)
|
|
231
|
-
return debug$
|
|
446
|
+
return debug$2.warn('layouting');
|
|
232
447
|
if (this.times > 3)
|
|
233
|
-
return debug$
|
|
448
|
+
return debug$2.warn('layout max times');
|
|
234
449
|
this.times++;
|
|
235
450
|
this.totalTimes++;
|
|
236
451
|
this.layouting = true;
|
|
@@ -255,12 +470,15 @@ class Layouter {
|
|
|
255
470
|
const { target, __updatedList: updateList } = this;
|
|
256
471
|
const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
|
|
257
472
|
const blocks = this.getBlocks(updateList);
|
|
258
|
-
blocks.forEach(item =>
|
|
473
|
+
blocks.forEach(item => item.setBefore());
|
|
259
474
|
target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
|
|
475
|
+
this.extraBlock = null;
|
|
260
476
|
updateList.sort();
|
|
261
477
|
updateMatrix(updateList, this.__levelList);
|
|
262
478
|
updateBounds(this.__levelList);
|
|
263
479
|
updateChange(updateList);
|
|
480
|
+
if (this.extraBlock)
|
|
481
|
+
blocks.push(this.extraBlock);
|
|
264
482
|
blocks.forEach(item => item.setAfter());
|
|
265
483
|
target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
|
|
266
484
|
target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
|
|
@@ -283,17 +501,22 @@ class Layouter {
|
|
|
283
501
|
Run.end(t);
|
|
284
502
|
}
|
|
285
503
|
static fullLayout(target) {
|
|
286
|
-
|
|
504
|
+
updateAllMatrix(target, true);
|
|
287
505
|
if (target.isBranch) {
|
|
288
|
-
|
|
289
|
-
pushAllBranchStack(target, branchStack);
|
|
290
|
-
updateWorldBoundsByBranchStack(branchStack);
|
|
506
|
+
BranchHelper.updateBounds(target);
|
|
291
507
|
}
|
|
292
508
|
else {
|
|
293
|
-
|
|
509
|
+
LeafHelper.updateBounds(target);
|
|
294
510
|
}
|
|
295
511
|
updateAllChange(target);
|
|
296
512
|
}
|
|
513
|
+
addExtra(leaf) {
|
|
514
|
+
if (!this.__updatedList.has(leaf)) {
|
|
515
|
+
const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
|
|
516
|
+
updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
|
|
517
|
+
updatedList.add(leaf);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
297
520
|
createBlock(data) {
|
|
298
521
|
return new LayoutBlockData(data);
|
|
299
522
|
}
|
|
@@ -321,13 +544,12 @@ class Layouter {
|
|
|
321
544
|
if (this.target) {
|
|
322
545
|
this.stop();
|
|
323
546
|
this.__removeListenEvents();
|
|
324
|
-
this.target = null;
|
|
325
|
-
this.config = null;
|
|
547
|
+
this.target = this.config = null;
|
|
326
548
|
}
|
|
327
549
|
}
|
|
328
550
|
}
|
|
329
551
|
|
|
330
|
-
const debug = Debug.get('Renderer');
|
|
552
|
+
const debug$1 = Debug.get('Renderer');
|
|
331
553
|
class Renderer {
|
|
332
554
|
get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
|
|
333
555
|
constructor(target, canvas, userConfig) {
|
|
@@ -365,7 +587,7 @@ class Renderer {
|
|
|
365
587
|
const { target } = this;
|
|
366
588
|
this.times = 0;
|
|
367
589
|
this.totalBounds = new Bounds();
|
|
368
|
-
debug.log(target.innerName, '--->');
|
|
590
|
+
debug$1.log(target.innerName, '--->');
|
|
369
591
|
try {
|
|
370
592
|
this.emitRender(RenderEvent.START);
|
|
371
593
|
this.renderOnce(callback);
|
|
@@ -374,9 +596,9 @@ class Renderer {
|
|
|
374
596
|
}
|
|
375
597
|
catch (e) {
|
|
376
598
|
this.rendering = false;
|
|
377
|
-
debug.error(e);
|
|
599
|
+
debug$1.error(e);
|
|
378
600
|
}
|
|
379
|
-
debug.log('-------------|');
|
|
601
|
+
debug$1.log('-------------|');
|
|
380
602
|
}
|
|
381
603
|
renderAgain() {
|
|
382
604
|
if (this.rendering) {
|
|
@@ -388,9 +610,9 @@ class Renderer {
|
|
|
388
610
|
}
|
|
389
611
|
renderOnce(callback) {
|
|
390
612
|
if (this.rendering)
|
|
391
|
-
return debug.warn('rendering');
|
|
613
|
+
return debug$1.warn('rendering');
|
|
392
614
|
if (this.times > 3)
|
|
393
|
-
return debug.warn('render max times');
|
|
615
|
+
return debug$1.warn('render max times');
|
|
394
616
|
this.times++;
|
|
395
617
|
this.totalTimes++;
|
|
396
618
|
this.rendering = true;
|
|
@@ -403,6 +625,10 @@ class Renderer {
|
|
|
403
625
|
}
|
|
404
626
|
else {
|
|
405
627
|
this.requestLayout();
|
|
628
|
+
if (this.ignore) {
|
|
629
|
+
this.ignore = this.rendering = false;
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
406
632
|
this.emitRender(RenderEvent.BEFORE);
|
|
407
633
|
if (this.config.usePartRender && this.totalTimes > 1) {
|
|
408
634
|
this.partRender();
|
|
@@ -423,9 +649,8 @@ class Renderer {
|
|
|
423
649
|
partRender() {
|
|
424
650
|
const { canvas, updateBlocks: list } = this;
|
|
425
651
|
if (!list)
|
|
426
|
-
return debug.warn('PartRender: need update attr');
|
|
427
|
-
|
|
428
|
-
this.mergeBlocks();
|
|
652
|
+
return debug$1.warn('PartRender: need update attr');
|
|
653
|
+
this.mergeBlocks();
|
|
429
654
|
list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
|
|
430
655
|
this.clipRender(block); });
|
|
431
656
|
}
|
|
@@ -434,7 +659,7 @@ class Renderer {
|
|
|
434
659
|
const { canvas } = this;
|
|
435
660
|
const bounds = block.getIntersect(canvas.bounds);
|
|
436
661
|
const includes = block.includes(this.target.__world);
|
|
437
|
-
const realBounds = new Bounds(
|
|
662
|
+
const realBounds = new Bounds(bounds);
|
|
438
663
|
canvas.save();
|
|
439
664
|
if (includes && !Debug.showRepaint) {
|
|
440
665
|
canvas.clear();
|
|
@@ -444,7 +669,7 @@ class Renderer {
|
|
|
444
669
|
canvas.clearWorld(bounds, true);
|
|
445
670
|
canvas.clipWorld(bounds, true);
|
|
446
671
|
}
|
|
447
|
-
this.__render(bounds, realBounds);
|
|
672
|
+
this.__render(bounds, includes, realBounds);
|
|
448
673
|
canvas.restore();
|
|
449
674
|
Run.end(t);
|
|
450
675
|
}
|
|
@@ -453,12 +678,12 @@ class Renderer {
|
|
|
453
678
|
const { canvas } = this;
|
|
454
679
|
canvas.save();
|
|
455
680
|
canvas.clear();
|
|
456
|
-
this.__render(canvas.bounds);
|
|
681
|
+
this.__render(canvas.bounds, true);
|
|
457
682
|
canvas.restore();
|
|
458
683
|
Run.end(t);
|
|
459
684
|
}
|
|
460
|
-
__render(bounds, realBounds) {
|
|
461
|
-
const options =
|
|
685
|
+
__render(bounds, includes, realBounds) {
|
|
686
|
+
const options = bounds.includes(this.target.__world) ? { includes } : { bounds, includes };
|
|
462
687
|
if (this.needFill)
|
|
463
688
|
this.canvas.fillWorld(bounds, this.config.fill);
|
|
464
689
|
if (Debug.showRepaint)
|
|
@@ -484,7 +709,7 @@ class Renderer {
|
|
|
484
709
|
const { updateBlocks: list } = this;
|
|
485
710
|
if (list) {
|
|
486
711
|
const bounds = new Bounds();
|
|
487
|
-
bounds.
|
|
712
|
+
bounds.setList(list);
|
|
488
713
|
list.length = 0;
|
|
489
714
|
list.push(bounds);
|
|
490
715
|
}
|
|
@@ -493,12 +718,12 @@ class Renderer {
|
|
|
493
718
|
const startTime = Date.now();
|
|
494
719
|
Platform.requestRender(() => {
|
|
495
720
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
|
|
496
|
-
if (this.
|
|
497
|
-
|
|
721
|
+
if (this.running) {
|
|
722
|
+
this.target.emit(AnimateEvent.FRAME);
|
|
723
|
+
if (this.changed && this.canvas.view)
|
|
498
724
|
this.render();
|
|
725
|
+
this.target.emit(RenderEvent.NEXT);
|
|
499
726
|
}
|
|
500
|
-
if (this.running)
|
|
501
|
-
this.target.emit(AnimateEvent.FRAME);
|
|
502
727
|
if (this.target)
|
|
503
728
|
this.__requestRender();
|
|
504
729
|
});
|
|
@@ -511,7 +736,7 @@ class Renderer {
|
|
|
511
736
|
const bounds = new Bounds(0, 0, width, height);
|
|
512
737
|
if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
|
|
513
738
|
this.addBlock(this.canvas.bounds);
|
|
514
|
-
this.target.forceUpdate('
|
|
739
|
+
this.target.forceUpdate('surface');
|
|
515
740
|
}
|
|
516
741
|
}
|
|
517
742
|
}
|
|
@@ -524,7 +749,7 @@ class Renderer {
|
|
|
524
749
|
empty = (!leaf.__world.width || !leaf.__world.height);
|
|
525
750
|
if (empty) {
|
|
526
751
|
if (!leaf.isLeafer)
|
|
527
|
-
debug.
|
|
752
|
+
debug$1.tip(leaf.innerName, ': empty');
|
|
528
753
|
empty = (!leaf.isBranch || leaf.isBranchLeaf);
|
|
529
754
|
}
|
|
530
755
|
return empty;
|
|
@@ -551,15 +776,13 @@ class Renderer {
|
|
|
551
776
|
if (this.target) {
|
|
552
777
|
this.stop();
|
|
553
778
|
this.__removeListenEvents();
|
|
554
|
-
this.target = null;
|
|
555
|
-
this.canvas = null;
|
|
556
|
-
this.config = null;
|
|
779
|
+
this.target = this.canvas = this.config = null;
|
|
557
780
|
}
|
|
558
781
|
}
|
|
559
782
|
}
|
|
560
783
|
|
|
561
784
|
const { hitRadiusPoint } = BoundsHelper;
|
|
562
|
-
class
|
|
785
|
+
class Picker {
|
|
563
786
|
constructor(target, selector) {
|
|
564
787
|
this.target = target;
|
|
565
788
|
this.selector = selector;
|
|
@@ -571,15 +794,17 @@ class FindPath {
|
|
|
571
794
|
options = {};
|
|
572
795
|
const through = options.through || false;
|
|
573
796
|
const ignoreHittable = options.ignoreHittable || false;
|
|
797
|
+
const target = options.target || this.target;
|
|
574
798
|
this.exclude = options.exclude || null;
|
|
575
799
|
this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
|
|
576
|
-
this.findList = [];
|
|
577
|
-
|
|
800
|
+
this.findList = options.findList || [];
|
|
801
|
+
if (!options.findList)
|
|
802
|
+
this.eachFind(target.children, target.__onlyHitMask);
|
|
578
803
|
const list = this.findList;
|
|
579
804
|
const leaf = this.getBestMatchLeaf();
|
|
580
805
|
const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
|
|
581
806
|
this.clear();
|
|
582
|
-
return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
|
|
807
|
+
return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
|
|
583
808
|
}
|
|
584
809
|
getBestMatchLeaf() {
|
|
585
810
|
const { findList: targets } = this;
|
|
@@ -602,20 +827,20 @@ class FindPath {
|
|
|
602
827
|
getPath(leaf) {
|
|
603
828
|
const path = new LeafList();
|
|
604
829
|
while (leaf) {
|
|
605
|
-
path.
|
|
830
|
+
path.add(leaf);
|
|
606
831
|
leaf = leaf.parent;
|
|
607
832
|
}
|
|
608
|
-
path.
|
|
833
|
+
path.add(this.target);
|
|
609
834
|
return path;
|
|
610
835
|
}
|
|
611
836
|
getHitablePath(leaf) {
|
|
612
|
-
const path = this.getPath(leaf);
|
|
837
|
+
const path = this.getPath(leaf && leaf.hittable ? leaf : null);
|
|
613
838
|
let item, hittablePath = new LeafList();
|
|
614
839
|
for (let i = path.list.length - 1; i > -1; i--) {
|
|
615
840
|
item = path.list[i];
|
|
616
841
|
if (!item.__.hittable)
|
|
617
842
|
break;
|
|
618
|
-
hittablePath.
|
|
843
|
+
hittablePath.addAt(item, 0);
|
|
619
844
|
if (!item.__.hitChildren)
|
|
620
845
|
break;
|
|
621
846
|
}
|
|
@@ -634,7 +859,7 @@ class FindPath {
|
|
|
634
859
|
leaf = path.list[j];
|
|
635
860
|
if (nextPath && nextPath.has(leaf))
|
|
636
861
|
break;
|
|
637
|
-
throughPath.
|
|
862
|
+
throughPath.add(leaf);
|
|
638
863
|
}
|
|
639
864
|
}
|
|
640
865
|
return throughPath;
|
|
@@ -644,7 +869,7 @@ class FindPath {
|
|
|
644
869
|
const { point } = this, len = children.length;
|
|
645
870
|
for (let i = len - 1; i > -1; i--) {
|
|
646
871
|
child = children[i];
|
|
647
|
-
if (!child.__.visible || (hitMask && !child.__.
|
|
872
|
+
if (!child.__.visible || (hitMask && !child.__.mask))
|
|
648
873
|
continue;
|
|
649
874
|
hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
|
|
650
875
|
if (child.isBranch) {
|
|
@@ -676,120 +901,113 @@ class FindPath {
|
|
|
676
901
|
}
|
|
677
902
|
}
|
|
678
903
|
|
|
904
|
+
const { Yes, NoAndSkip, YesAndSkip } = Answer;
|
|
679
905
|
class Selector {
|
|
680
906
|
constructor(target, userConfig) {
|
|
681
907
|
this.config = {};
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
this.
|
|
685
|
-
|
|
908
|
+
this.innerIdMap = {};
|
|
909
|
+
this.idMap = {};
|
|
910
|
+
this.methods = {
|
|
911
|
+
id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
|
|
912
|
+
innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
|
|
913
|
+
className: (leaf, name) => leaf.className === name ? 1 : 0,
|
|
914
|
+
tag: (leaf, name) => leaf.__tag === name ? 1 : 0
|
|
915
|
+
};
|
|
686
916
|
this.target = target;
|
|
687
917
|
if (userConfig)
|
|
688
918
|
this.config = DataHelper.default(userConfig, this.config);
|
|
689
|
-
this.
|
|
919
|
+
this.picker = new Picker(target, this);
|
|
690
920
|
this.__listenEvents();
|
|
691
921
|
}
|
|
922
|
+
getBy(condition, branch, one, options) {
|
|
923
|
+
switch (typeof condition) {
|
|
924
|
+
case 'number':
|
|
925
|
+
const leaf = this.getByInnerId(condition, branch);
|
|
926
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
927
|
+
case 'string':
|
|
928
|
+
switch (condition[0]) {
|
|
929
|
+
case '#':
|
|
930
|
+
const leaf = this.getById(condition.substring(1), branch);
|
|
931
|
+
return one ? leaf : (leaf ? [leaf] : []);
|
|
932
|
+
case '.':
|
|
933
|
+
return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
|
|
934
|
+
default:
|
|
935
|
+
return this.getByMethod(this.methods.tag, branch, one, condition);
|
|
936
|
+
}
|
|
937
|
+
case 'function':
|
|
938
|
+
return this.getByMethod(condition, branch, one, options);
|
|
939
|
+
}
|
|
940
|
+
}
|
|
692
941
|
getByPoint(hitPoint, hitRadius, options) {
|
|
693
942
|
if (Platform.name === 'node')
|
|
694
943
|
this.target.emit(LayoutEvent.CHECK_UPDATE);
|
|
695
|
-
return this.
|
|
696
|
-
}
|
|
697
|
-
find(name, branch) {
|
|
698
|
-
if (typeof name === 'number') {
|
|
699
|
-
return this.getByInnerId(name, branch);
|
|
700
|
-
}
|
|
701
|
-
else if (name.startsWith('#')) {
|
|
702
|
-
return this.getById(name.substring(1), branch);
|
|
703
|
-
}
|
|
704
|
-
else if (name.startsWith('.')) {
|
|
705
|
-
return this.getByClassName(name.substring(1), branch);
|
|
706
|
-
}
|
|
707
|
-
else {
|
|
708
|
-
return this.getByTagName(name, branch);
|
|
709
|
-
}
|
|
944
|
+
return this.picker.getByPoint(hitPoint, hitRadius, options);
|
|
710
945
|
}
|
|
711
|
-
getByInnerId(
|
|
712
|
-
|
|
946
|
+
getByInnerId(innerId, branch) {
|
|
947
|
+
const cache = this.innerIdMap[innerId];
|
|
713
948
|
if (cache)
|
|
714
949
|
return cache;
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
let find;
|
|
718
|
-
this.loopFind(branch, (leaf) => {
|
|
719
|
-
if (leaf.innerId === name) {
|
|
720
|
-
find = leaf;
|
|
721
|
-
this.innerIdList[name] = find;
|
|
722
|
-
return true;
|
|
723
|
-
}
|
|
724
|
-
else {
|
|
725
|
-
return false;
|
|
726
|
-
}
|
|
727
|
-
});
|
|
728
|
-
return find;
|
|
950
|
+
this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
|
|
951
|
+
return this.findLeaf;
|
|
729
952
|
}
|
|
730
|
-
getById(
|
|
731
|
-
|
|
732
|
-
if (cache)
|
|
953
|
+
getById(id, branch) {
|
|
954
|
+
const cache = this.idMap[id];
|
|
955
|
+
if (cache && LeafHelper.hasParent(cache, branch || this.target))
|
|
733
956
|
return cache;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
let find;
|
|
737
|
-
this.loopFind(branch, (leaf) => {
|
|
738
|
-
if (leaf.id === name) {
|
|
739
|
-
find = leaf;
|
|
740
|
-
this.idList[name] = find;
|
|
741
|
-
return true;
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
return false;
|
|
745
|
-
}
|
|
746
|
-
});
|
|
747
|
-
return find;
|
|
748
|
-
}
|
|
749
|
-
getByClassName(name, branch) {
|
|
750
|
-
if (!branch)
|
|
751
|
-
branch = this.target;
|
|
752
|
-
let find = [];
|
|
753
|
-
this.loopFind(branch, (leaf) => {
|
|
754
|
-
if (leaf.className === name)
|
|
755
|
-
find.push(leaf);
|
|
756
|
-
return false;
|
|
757
|
-
});
|
|
758
|
-
return find;
|
|
759
|
-
}
|
|
760
|
-
getByTagName(name, branch) {
|
|
761
|
-
if (!branch)
|
|
762
|
-
branch = this.target;
|
|
763
|
-
let find = [];
|
|
764
|
-
this.loopFind(branch, (leaf) => {
|
|
765
|
-
if (leaf.__tag === name)
|
|
766
|
-
find.push(leaf);
|
|
767
|
-
return false;
|
|
768
|
-
});
|
|
769
|
-
return find;
|
|
957
|
+
this.eachFind(this.toChildren(branch), this.methods.id, null, id);
|
|
958
|
+
return this.findLeaf;
|
|
770
959
|
}
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
960
|
+
getByClassName(className, branch) {
|
|
961
|
+
return this.getByMethod(this.methods.className, branch, false, className);
|
|
962
|
+
}
|
|
963
|
+
getByTag(tag, branch) {
|
|
964
|
+
return this.getByMethod(this.methods.tag, branch, false, tag);
|
|
965
|
+
}
|
|
966
|
+
getByMethod(method, branch, one, options) {
|
|
967
|
+
const list = one ? null : [];
|
|
968
|
+
this.eachFind(this.toChildren(branch), method, list, options);
|
|
969
|
+
return list || this.findLeaf;
|
|
970
|
+
}
|
|
971
|
+
eachFind(children, method, list, options) {
|
|
972
|
+
let child, result;
|
|
775
973
|
for (let i = 0, len = children.length; i < len; i++) {
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
974
|
+
child = children[i];
|
|
975
|
+
result = method(child, options);
|
|
976
|
+
if (result === Yes || result === YesAndSkip) {
|
|
977
|
+
if (list) {
|
|
978
|
+
list.push(child);
|
|
979
|
+
}
|
|
980
|
+
else {
|
|
981
|
+
this.findLeaf = child;
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (child.isBranch && result < NoAndSkip)
|
|
986
|
+
this.eachFind(child.children, method, list, options);
|
|
781
987
|
}
|
|
782
988
|
}
|
|
989
|
+
toChildren(branch) {
|
|
990
|
+
this.findLeaf = null;
|
|
991
|
+
return [branch || this.target];
|
|
992
|
+
}
|
|
783
993
|
__onRemoveChild(event) {
|
|
784
|
-
const
|
|
785
|
-
if (this.
|
|
786
|
-
this.
|
|
787
|
-
if (this.
|
|
788
|
-
this.
|
|
994
|
+
const { id, innerId } = event.child;
|
|
995
|
+
if (this.idMap[id])
|
|
996
|
+
delete this.idMap[id];
|
|
997
|
+
if (this.innerIdMap[innerId])
|
|
998
|
+
delete this.innerIdMap[innerId];
|
|
999
|
+
}
|
|
1000
|
+
__checkIdChange(event) {
|
|
1001
|
+
if (event.attrName === 'id') {
|
|
1002
|
+
const id = event.oldValue;
|
|
1003
|
+
if (this.idMap[id])
|
|
1004
|
+
delete this.idMap[id];
|
|
1005
|
+
}
|
|
789
1006
|
}
|
|
790
1007
|
__listenEvents() {
|
|
791
1008
|
this.__eventIds = [
|
|
792
|
-
this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this)
|
|
1009
|
+
this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
|
|
1010
|
+
this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
|
|
793
1011
|
];
|
|
794
1012
|
}
|
|
795
1013
|
__removeListenEvents() {
|
|
@@ -799,11 +1017,10 @@ class Selector {
|
|
|
799
1017
|
destroy() {
|
|
800
1018
|
if (this.__eventIds.length) {
|
|
801
1019
|
this.__removeListenEvents();
|
|
802
|
-
this.
|
|
803
|
-
this.
|
|
804
|
-
this.
|
|
805
|
-
this.
|
|
806
|
-
this.tagNameList = {};
|
|
1020
|
+
this.picker.destroy();
|
|
1021
|
+
this.findLeaf = null;
|
|
1022
|
+
this.innerIdMap = {};
|
|
1023
|
+
this.idMap = {};
|
|
807
1024
|
}
|
|
808
1025
|
}
|
|
809
1026
|
}
|
|
@@ -816,96 +1033,6 @@ Object.assign(Creator, {
|
|
|
816
1033
|
});
|
|
817
1034
|
Platform.layout = Layouter.fullLayout;
|
|
818
1035
|
|
|
819
|
-
class LeaferCanvas extends LeaferCanvasBase {
|
|
820
|
-
get allowBackgroundColor() { return false; }
|
|
821
|
-
init() {
|
|
822
|
-
let { view } = this.config;
|
|
823
|
-
if (view) {
|
|
824
|
-
if (typeof view === 'string') {
|
|
825
|
-
if (view[0] !== '#')
|
|
826
|
-
view = '#' + view;
|
|
827
|
-
this.viewSelect = Platform.miniapp.select(view);
|
|
828
|
-
}
|
|
829
|
-
else if (view.fields) {
|
|
830
|
-
this.viewSelect = view;
|
|
831
|
-
}
|
|
832
|
-
else {
|
|
833
|
-
this.initView(view);
|
|
834
|
-
}
|
|
835
|
-
if (this.viewSelect)
|
|
836
|
-
Platform.miniapp.getSizeView(this.viewSelect).then(sizeView => {
|
|
837
|
-
this.initView(sizeView);
|
|
838
|
-
});
|
|
839
|
-
}
|
|
840
|
-
else {
|
|
841
|
-
this.initView();
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
initView(view) {
|
|
845
|
-
if (!view) {
|
|
846
|
-
view = {};
|
|
847
|
-
this.__createView();
|
|
848
|
-
}
|
|
849
|
-
else {
|
|
850
|
-
this.view = view.view || view;
|
|
851
|
-
}
|
|
852
|
-
this.__createContext();
|
|
853
|
-
const { width, height, pixelRatio } = this.config;
|
|
854
|
-
const size = { width: width || view.width, height: height || view.height, pixelRatio };
|
|
855
|
-
this.resize(size);
|
|
856
|
-
if (this.context.roundRect) {
|
|
857
|
-
this.roundRect = function (x, y, width, height, radius) {
|
|
858
|
-
this.context.roundRect(x, y, width, height, typeof radius === 'number' ? [radius] : radius);
|
|
859
|
-
};
|
|
860
|
-
}
|
|
861
|
-
canvasPatch(this.context.__proto__);
|
|
862
|
-
}
|
|
863
|
-
__createView() {
|
|
864
|
-
this.view = Platform.origin.createCanvas(1, 1);
|
|
865
|
-
}
|
|
866
|
-
updateViewSize() {
|
|
867
|
-
const { width, height, pixelRatio } = this;
|
|
868
|
-
this.view.width = width * pixelRatio;
|
|
869
|
-
this.view.height = height * pixelRatio;
|
|
870
|
-
}
|
|
871
|
-
updateClientBounds(callback) {
|
|
872
|
-
if (this.viewSelect)
|
|
873
|
-
Platform.miniapp.getBounds(this.viewSelect).then(bounds => {
|
|
874
|
-
this.clientBounds = bounds;
|
|
875
|
-
if (callback)
|
|
876
|
-
callback();
|
|
877
|
-
});
|
|
878
|
-
}
|
|
879
|
-
startAutoLayout(_autoBounds, listener) {
|
|
880
|
-
this.resizeListener = listener;
|
|
881
|
-
this.checkSize = this.checkSize.bind(this);
|
|
882
|
-
Platform.miniapp.onWindowResize(this.checkSize);
|
|
883
|
-
}
|
|
884
|
-
checkSize() {
|
|
885
|
-
if (this.viewSelect) {
|
|
886
|
-
setTimeout(() => {
|
|
887
|
-
this.updateClientBounds(() => {
|
|
888
|
-
const { width, height } = this.clientBounds;
|
|
889
|
-
const { pixelRatio } = this;
|
|
890
|
-
const size = { width, height, pixelRatio };
|
|
891
|
-
if (!this.isSameSize(size)) {
|
|
892
|
-
const oldSize = {};
|
|
893
|
-
DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
|
|
894
|
-
this.resize(size);
|
|
895
|
-
if (this.width !== undefined)
|
|
896
|
-
this.resizeListener(new ResizeEvent(size, oldSize));
|
|
897
|
-
}
|
|
898
|
-
});
|
|
899
|
-
}, 500);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
stopAutoLayout() {
|
|
903
|
-
this.autoLayout = false;
|
|
904
|
-
this.resizeListener = null;
|
|
905
|
-
Platform.miniapp.offWindowResize(this.checkSize);
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
1036
|
const PointerEventHelper = {
|
|
910
1037
|
convertTouch(e, local) {
|
|
911
1038
|
const touch = PointerEventHelper.getTouch(e);
|
|
@@ -971,473 +1098,47 @@ class Interaction extends InteractionBase {
|
|
|
971
1098
|
}
|
|
972
1099
|
onTouchCancel() {
|
|
973
1100
|
this.pointerCancel();
|
|
974
|
-
}
|
|
975
|
-
multiTouchStart(e) {
|
|
976
|
-
this.useMultiTouch = (e.touches.length >= 2);
|
|
977
|
-
this.touches = this.useMultiTouch ? this.getTouches(e.touches) : undefined;
|
|
978
|
-
if (this.useMultiTouch)
|
|
979
|
-
this.pointerCancel();
|
|
980
|
-
}
|
|
981
|
-
multiTouchMove(e) {
|
|
982
|
-
if (!this.useMultiTouch)
|
|
983
|
-
return;
|
|
984
|
-
if (e.touches.length > 1) {
|
|
985
|
-
const touches = this.getTouches(e.touches);
|
|
986
|
-
const list = this.getKeepTouchList(this.touches, touches);
|
|
987
|
-
if (list.length > 1) {
|
|
988
|
-
this.multiTouch(InteractionHelper.getBase(e), list);
|
|
989
|
-
this.touches = touches;
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
multiTouchEnd() {
|
|
994
|
-
this.touches = null;
|
|
995
|
-
this.useMultiTouch = false;
|
|
996
|
-
this.transformEnd();
|
|
997
|
-
}
|
|
998
|
-
getKeepTouchList(old, touches) {
|
|
999
|
-
let to;
|
|
1000
|
-
const list = [];
|
|
1001
|
-
old.forEach(from => {
|
|
1002
|
-
to = touches.find(touch => touch.identifier === from.identifier);
|
|
1003
|
-
if (to)
|
|
1004
|
-
list.push({ from: this.getLocal(from), to: this.getLocal(to) });
|
|
1005
|
-
});
|
|
1006
|
-
return list;
|
|
1007
|
-
}
|
|
1008
|
-
getLocalTouchs(points) {
|
|
1009
|
-
return points.map(point => this.getLocal(point));
|
|
1010
|
-
}
|
|
1011
|
-
destroy() {
|
|
1012
|
-
super.destroy();
|
|
1013
|
-
this.touches = null;
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
const { mineType, fileType } = FileHelper;
|
|
1018
|
-
Object.assign(Creator, {
|
|
1019
|
-
canvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
1020
|
-
image: (options) => new LeaferImage(options),
|
|
1021
|
-
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
1022
|
-
interaction: (target, canvas, selector, options) => { return new Interaction(target, canvas, selector, options); }
|
|
1023
|
-
});
|
|
1024
|
-
function useCanvas(_canvasType, app) {
|
|
1025
|
-
if (!Platform.origin) {
|
|
1026
|
-
Platform.origin = {
|
|
1027
|
-
createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
|
|
1028
|
-
canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
|
|
1029
|
-
canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
|
|
1030
|
-
canvasSaveAs: (canvas, filePath, quality) => {
|
|
1031
|
-
return new Promise((resolve, reject) => {
|
|
1032
|
-
let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
|
|
1033
|
-
data = data.substring(data.indexOf('64,') + 3);
|
|
1034
|
-
let toAlbum;
|
|
1035
|
-
if (!filePath.includes('/')) {
|
|
1036
|
-
filePath = `${app.env.USER_DATA_PATH}/` + filePath;
|
|
1037
|
-
toAlbum = true;
|
|
1038
|
-
}
|
|
1039
|
-
const fs = app.getFileSystemManager();
|
|
1040
|
-
fs.writeFile({
|
|
1041
|
-
filePath,
|
|
1042
|
-
data,
|
|
1043
|
-
encoding: 'base64',
|
|
1044
|
-
success() {
|
|
1045
|
-
if (toAlbum) {
|
|
1046
|
-
Platform.miniapp.saveToAlbum(filePath).then(() => {
|
|
1047
|
-
fs.unlink({ filePath });
|
|
1048
|
-
});
|
|
1049
|
-
}
|
|
1050
|
-
resolve();
|
|
1051
|
-
},
|
|
1052
|
-
fail(error) {
|
|
1053
|
-
reject(error);
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
});
|
|
1057
|
-
},
|
|
1058
|
-
loadImage(url) {
|
|
1059
|
-
return new Promise((resolve, reject) => {
|
|
1060
|
-
const img = Platform.canvas.view.createImage();
|
|
1061
|
-
img.onload = () => { resolve(img); };
|
|
1062
|
-
img.onerror = (error) => { reject(error); };
|
|
1063
|
-
img.src = url;
|
|
1064
|
-
});
|
|
1065
|
-
},
|
|
1066
|
-
noRepeat: 'repeat-x'
|
|
1067
|
-
};
|
|
1068
|
-
Platform.miniapp = {
|
|
1069
|
-
select(name) {
|
|
1070
|
-
return app.createSelectorQuery().select(name);
|
|
1071
|
-
},
|
|
1072
|
-
getBounds(select) {
|
|
1073
|
-
return new Promise((resolve) => {
|
|
1074
|
-
select.boundingClientRect().exec((res) => {
|
|
1075
|
-
const rect = res[1];
|
|
1076
|
-
resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
|
|
1077
|
-
});
|
|
1078
|
-
});
|
|
1079
|
-
},
|
|
1080
|
-
getSizeView(select) {
|
|
1081
|
-
return new Promise((resolve) => {
|
|
1082
|
-
select.fields({ node: true, size: true }).exec((res) => {
|
|
1083
|
-
const data = res[0];
|
|
1084
|
-
resolve({ view: data.node, width: data.width, height: data.height });
|
|
1085
|
-
});
|
|
1086
|
-
});
|
|
1087
|
-
},
|
|
1088
|
-
saveToAlbum(path) {
|
|
1089
|
-
return new Promise((resolve) => {
|
|
1090
|
-
app.getSetting({
|
|
1091
|
-
success: (res) => {
|
|
1092
|
-
if (res.authSetting['scope.writePhotosAlbum']) {
|
|
1093
|
-
app.saveImageToPhotosAlbum({
|
|
1094
|
-
filePath: path,
|
|
1095
|
-
success() { resolve(true); }
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
|
-
else {
|
|
1099
|
-
app.authorize({
|
|
1100
|
-
scope: 'scope.writePhotosAlbum',
|
|
1101
|
-
success: () => {
|
|
1102
|
-
app.saveImageToPhotosAlbum({
|
|
1103
|
-
filePath: path,
|
|
1104
|
-
success() { resolve(true); }
|
|
1105
|
-
});
|
|
1106
|
-
},
|
|
1107
|
-
fail: () => { }
|
|
1108
|
-
});
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
});
|
|
1112
|
-
});
|
|
1113
|
-
},
|
|
1114
|
-
onWindowResize(fun) {
|
|
1115
|
-
app.onWindowResize(fun);
|
|
1116
|
-
},
|
|
1117
|
-
offWindowResize(fun) {
|
|
1118
|
-
app.offWindowResize(fun);
|
|
1119
|
-
}
|
|
1120
|
-
};
|
|
1121
|
-
Platform.canvas = Creator.canvas();
|
|
1122
|
-
Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
|
|
1123
|
-
}
|
|
1124
|
-
}
|
|
1125
|
-
Platform.name = 'miniapp';
|
|
1126
|
-
Platform.requestRender = function (render) { Platform.canvas.view.requestAnimationFrame(render); };
|
|
1127
|
-
Platform.devicePixelRatio = wx.getSystemInfoSync().pixelRatio;
|
|
1128
|
-
Platform.realtimeLayout = true;
|
|
1129
|
-
|
|
1130
|
-
const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper$1, rotate } = MatrixHelper;
|
|
1131
|
-
function fillOrFitMode(data, mode, box, width, height, rotation) {
|
|
1132
|
-
const transform = get$4();
|
|
1133
|
-
const swap = rotation && rotation !== 180;
|
|
1134
|
-
const sw = box.width / (swap ? height : width);
|
|
1135
|
-
const sh = box.height / (swap ? width : height);
|
|
1136
|
-
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1137
|
-
const x = box.x + (box.width - width * scale) / 2;
|
|
1138
|
-
const y = box.y + (box.height - height * scale) / 2;
|
|
1139
|
-
translate$1(transform, x, y);
|
|
1140
|
-
scaleHelper$1(transform, scale);
|
|
1141
|
-
if (rotation)
|
|
1142
|
-
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1143
|
-
data.scaleX = data.scaleY = scale;
|
|
1144
|
-
data.transform = transform;
|
|
1145
|
-
}
|
|
1146
|
-
function clipMode(data, box, offset, scale, rotation) {
|
|
1147
|
-
const transform = get$4();
|
|
1148
|
-
translate$1(transform, box.x, box.y);
|
|
1149
|
-
if (offset)
|
|
1150
|
-
translate$1(transform, offset.x, offset.y);
|
|
1151
|
-
if (scale) {
|
|
1152
|
-
typeof scale === 'number' ? scaleHelper$1(transform, scale) : scaleHelper$1(transform, scale.x, scale.y);
|
|
1153
|
-
data.scaleX = transform.a;
|
|
1154
|
-
data.scaleY = transform.d;
|
|
1155
|
-
}
|
|
1156
|
-
if (rotation)
|
|
1157
|
-
rotate(transform, rotation);
|
|
1158
|
-
data.transform = transform;
|
|
1159
|
-
}
|
|
1160
|
-
function repeatMode(data, box, width, height, scale, rotation) {
|
|
1161
|
-
const transform = get$4();
|
|
1162
|
-
if (rotation) {
|
|
1163
|
-
rotate(transform, rotation);
|
|
1164
|
-
switch (rotation) {
|
|
1165
|
-
case 90:
|
|
1166
|
-
translate$1(transform, height, 0);
|
|
1167
|
-
break;
|
|
1168
|
-
case 180:
|
|
1169
|
-
translate$1(transform, width, height);
|
|
1170
|
-
break;
|
|
1171
|
-
case 270:
|
|
1172
|
-
translate$1(transform, 0, width);
|
|
1173
|
-
break;
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
translate$1(transform, box.x, box.y);
|
|
1177
|
-
if (scale) {
|
|
1178
|
-
scaleOfOuter$2(transform, box, scale);
|
|
1179
|
-
data.scaleX = data.scaleY = scale;
|
|
1180
|
-
}
|
|
1181
|
-
data.transform = transform;
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
const { get: get$3, translate } = MatrixHelper;
|
|
1185
|
-
function createData(leafPaint, image, paint, box) {
|
|
1186
|
-
let { width, height } = image;
|
|
1187
|
-
const { opacity, mode, offset, scale, rotation, blendMode } = paint;
|
|
1188
|
-
const sameBox = box.width === width && box.height === height;
|
|
1189
|
-
if (blendMode)
|
|
1190
|
-
leafPaint.blendMode = blendMode;
|
|
1191
|
-
const data = leafPaint.data = { mode };
|
|
1192
|
-
switch (mode) {
|
|
1193
|
-
case 'strench':
|
|
1194
|
-
if (!sameBox)
|
|
1195
|
-
width = box.width, height = box.height;
|
|
1196
|
-
if (box.x || box.y) {
|
|
1197
|
-
data.transform = get$3();
|
|
1198
|
-
translate(data.transform, box.x, box.y);
|
|
1199
|
-
}
|
|
1200
|
-
break;
|
|
1201
|
-
case 'clip':
|
|
1202
|
-
if (offset || scale || rotation)
|
|
1203
|
-
clipMode(data, box, offset, scale, rotation);
|
|
1204
|
-
break;
|
|
1205
|
-
case 'repeat':
|
|
1206
|
-
if (!sameBox || scale || rotation)
|
|
1207
|
-
repeatMode(data, box, width, height, scale, rotation);
|
|
1208
|
-
break;
|
|
1209
|
-
case 'fit':
|
|
1210
|
-
case 'cover':
|
|
1211
|
-
default:
|
|
1212
|
-
if (!sameBox || rotation)
|
|
1213
|
-
fillOrFitMode(data, mode, box, width, height, rotation);
|
|
1214
|
-
}
|
|
1215
|
-
data.width = width;
|
|
1216
|
-
data.height = height;
|
|
1217
|
-
if (opacity)
|
|
1218
|
-
data.opacity = opacity;
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
function image(ui, attrName, attrValue, box, firstUse) {
|
|
1222
|
-
const leafPaint = { type: attrValue.type };
|
|
1223
|
-
const image = leafPaint.image = ImageManager.get(attrValue);
|
|
1224
|
-
const event = (firstUse || image.loading) && { target: ui, image, attrName, attrValue };
|
|
1225
|
-
if (image.ready) {
|
|
1226
|
-
if (hasNaturalSize(ui, attrName, image))
|
|
1227
|
-
createData(leafPaint, image, attrValue, box);
|
|
1228
|
-
if (firstUse) {
|
|
1229
|
-
emit(ImageEvent.LOAD, event);
|
|
1230
|
-
emit(ImageEvent.LOADED, event);
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
else if (image.error) {
|
|
1234
|
-
if (firstUse) {
|
|
1235
|
-
ui.forceUpdate('surface');
|
|
1236
|
-
event.error = image.error;
|
|
1237
|
-
emit(ImageEvent.ERROR, event);
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
else {
|
|
1241
|
-
if (firstUse)
|
|
1242
|
-
emit(ImageEvent.LOAD, event);
|
|
1243
|
-
leafPaint.loadId = image.load(() => {
|
|
1244
|
-
if (!ui.destroyed) {
|
|
1245
|
-
if (hasNaturalSize(ui, attrName, image)) {
|
|
1246
|
-
createData(leafPaint, image, attrValue, box);
|
|
1247
|
-
ui.forceUpdate('surface');
|
|
1248
|
-
}
|
|
1249
|
-
emit(ImageEvent.LOADED, event);
|
|
1250
|
-
}
|
|
1251
|
-
}, (error) => {
|
|
1252
|
-
ui.forceUpdate('surface');
|
|
1253
|
-
event.error = error;
|
|
1254
|
-
emit(ImageEvent.ERROR, event);
|
|
1255
|
-
});
|
|
1256
|
-
}
|
|
1257
|
-
return leafPaint;
|
|
1258
|
-
}
|
|
1259
|
-
function hasNaturalSize(ui, attrName, image) {
|
|
1260
|
-
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1261
|
-
const { __: d } = ui;
|
|
1262
|
-
d.__naturalWidth = image.width;
|
|
1263
|
-
d.__naturalHeight = image.height;
|
|
1264
|
-
if (!d.__getInput('width') || !d.__getInput('height')) {
|
|
1265
|
-
ui.forceUpdate('width');
|
|
1266
|
-
return false;
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
return true;
|
|
1270
|
-
}
|
|
1271
|
-
function emit(type, data) {
|
|
1272
|
-
if (data.target.hasEvent(type))
|
|
1273
|
-
data.target.emitEvent(new ImageEvent(type, data));
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
/******************************************************************************
|
|
1277
|
-
Copyright (c) Microsoft Corporation.
|
|
1278
|
-
|
|
1279
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
1280
|
-
purpose with or without fee is hereby granted.
|
|
1281
|
-
|
|
1282
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1283
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1284
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1285
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1286
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1287
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1288
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
1289
|
-
***************************************************************************** */
|
|
1290
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1294
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1295
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1296
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1297
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1298
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1299
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1300
|
-
});
|
|
1301
|
-
}
|
|
1302
|
-
|
|
1303
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1304
|
-
var e = new Error(message);
|
|
1305
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1306
|
-
};
|
|
1307
|
-
|
|
1308
|
-
const { get: get$2, scale: scaleHelper, copy: copy$1 } = MatrixHelper;
|
|
1309
|
-
function createPattern(ui, paint, pixelRatio) {
|
|
1310
|
-
let { scaleX, scaleY } = ui.__world;
|
|
1311
|
-
const id = scaleX + '-' + scaleY;
|
|
1312
|
-
if (paint.patternId !== id && !ui.destroyed) {
|
|
1313
|
-
paint.patternId = id;
|
|
1314
|
-
scaleX = Math.abs(scaleX);
|
|
1315
|
-
scaleY = Math.abs(scaleY);
|
|
1316
|
-
const { image, data } = paint;
|
|
1317
|
-
const maxWidth = image.isSVG ? 4096 : Math.min(image.width, 4096);
|
|
1318
|
-
const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096);
|
|
1319
|
-
let scale, matrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data;
|
|
1320
|
-
if (sx) {
|
|
1321
|
-
matrix = get$2();
|
|
1322
|
-
copy$1(matrix, transform);
|
|
1323
|
-
scaleHelper(matrix, 1 / sx, 1 / sy);
|
|
1324
|
-
scaleX *= sx;
|
|
1325
|
-
scaleY *= sy;
|
|
1326
|
-
}
|
|
1327
|
-
scaleX *= pixelRatio;
|
|
1328
|
-
scaleY *= pixelRatio;
|
|
1329
|
-
width *= scaleX;
|
|
1330
|
-
height *= scaleY;
|
|
1331
|
-
if (width > maxWidth || height > maxHeight) {
|
|
1332
|
-
scale = Math.max(width / maxWidth, height / maxHeight);
|
|
1333
|
-
}
|
|
1334
|
-
if (scale) {
|
|
1335
|
-
scaleX /= scale;
|
|
1336
|
-
scaleY /= scale;
|
|
1337
|
-
width /= scale;
|
|
1338
|
-
height /= scale;
|
|
1339
|
-
}
|
|
1340
|
-
if (sx) {
|
|
1341
|
-
scaleX /= sx;
|
|
1342
|
-
scaleY /= sy;
|
|
1343
|
-
}
|
|
1344
|
-
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1345
|
-
if (!matrix) {
|
|
1346
|
-
matrix = get$2();
|
|
1347
|
-
if (transform)
|
|
1348
|
-
copy$1(matrix, transform);
|
|
1349
|
-
}
|
|
1350
|
-
scaleHelper(matrix, 1 / scaleX, 1 / scaleY);
|
|
1351
|
-
}
|
|
1352
|
-
const style = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'));
|
|
1353
|
-
try {
|
|
1354
|
-
if (paint.transform)
|
|
1355
|
-
paint.transform = null;
|
|
1356
|
-
if (matrix)
|
|
1357
|
-
style.setTransform ? style.setTransform(matrix) : paint.transform = matrix;
|
|
1358
|
-
}
|
|
1359
|
-
catch (_a) {
|
|
1360
|
-
paint.transform = matrix;
|
|
1361
|
-
}
|
|
1362
|
-
paint.style = style;
|
|
1363
|
-
return true;
|
|
1364
|
-
}
|
|
1365
|
-
else {
|
|
1366
|
-
return false;
|
|
1367
|
-
}
|
|
1368
|
-
}
|
|
1369
|
-
|
|
1370
|
-
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1371
|
-
const { scaleX, scaleY } = ui.__world;
|
|
1372
|
-
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1373
|
-
return false;
|
|
1374
|
-
}
|
|
1375
|
-
else {
|
|
1376
|
-
if (allowPaint) {
|
|
1377
|
-
if (paint.image.isSVG && paint.data.mode !== 'repeat') {
|
|
1378
|
-
let { width, height } = paint.data;
|
|
1379
|
-
width *= scaleX * canvas.pixelRatio;
|
|
1380
|
-
height *= scaleY * canvas.pixelRatio;
|
|
1381
|
-
allowPaint = width > 4096 || height > 4096;
|
|
1382
|
-
}
|
|
1383
|
-
else {
|
|
1384
|
-
allowPaint = false;
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
if (allowPaint) {
|
|
1388
|
-
canvas.save();
|
|
1389
|
-
canvas.clip();
|
|
1390
|
-
const { data } = paint;
|
|
1391
|
-
if (paint.blendMode)
|
|
1392
|
-
canvas.blendMode = paint.blendMode;
|
|
1393
|
-
if (data.opacity)
|
|
1394
|
-
canvas.opacity *= data.opacity;
|
|
1395
|
-
if (data.transform)
|
|
1396
|
-
canvas.transform(data.transform);
|
|
1397
|
-
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1398
|
-
canvas.restore();
|
|
1399
|
-
return true;
|
|
1400
|
-
}
|
|
1401
|
-
else {
|
|
1402
|
-
if (!paint.style) {
|
|
1403
|
-
createPattern(ui, paint, canvas.pixelRatio);
|
|
1404
|
-
}
|
|
1405
|
-
else {
|
|
1406
|
-
ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1407
|
-
if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
|
|
1408
|
-
ui.forceUpdate('surface');
|
|
1409
|
-
}), 300);
|
|
1410
|
-
}
|
|
1411
|
-
return false;
|
|
1412
|
-
}
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1415
|
-
|
|
1416
|
-
function recycleImage(data, attrName) {
|
|
1417
|
-
const paints = (attrName === 'fill' ? data._fill : data._stroke);
|
|
1418
|
-
if (paints instanceof Array) {
|
|
1419
|
-
let image, recycleMap, input, url;
|
|
1420
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1421
|
-
image = paints[i].image;
|
|
1422
|
-
url = image && image.url;
|
|
1423
|
-
if (url) {
|
|
1424
|
-
if (!recycleMap)
|
|
1425
|
-
recycleMap = {};
|
|
1426
|
-
recycleMap[url] = true;
|
|
1427
|
-
ImageManager.recycle(image);
|
|
1428
|
-
if (image.loading) {
|
|
1429
|
-
if (!input) {
|
|
1430
|
-
input = (data.__input && data.__input[attrName]) || [];
|
|
1431
|
-
if (!(input instanceof Array))
|
|
1432
|
-
input = [input];
|
|
1433
|
-
}
|
|
1434
|
-
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1435
|
-
}
|
|
1101
|
+
}
|
|
1102
|
+
multiTouchStart(e) {
|
|
1103
|
+
this.useMultiTouch = (e.touches.length >= 2);
|
|
1104
|
+
this.touches = this.useMultiTouch ? this.getTouches(e.touches) : undefined;
|
|
1105
|
+
if (this.useMultiTouch)
|
|
1106
|
+
this.pointerCancel();
|
|
1107
|
+
}
|
|
1108
|
+
multiTouchMove(e) {
|
|
1109
|
+
if (!this.useMultiTouch)
|
|
1110
|
+
return;
|
|
1111
|
+
if (e.touches.length > 1) {
|
|
1112
|
+
const touches = this.getTouches(e.touches);
|
|
1113
|
+
const list = this.getKeepTouchList(this.touches, touches);
|
|
1114
|
+
if (list.length > 1) {
|
|
1115
|
+
this.multiTouch(InteractionHelper.getBase(e), list);
|
|
1116
|
+
this.touches = touches;
|
|
1436
1117
|
}
|
|
1437
1118
|
}
|
|
1438
|
-
return recycleMap;
|
|
1439
1119
|
}
|
|
1440
|
-
|
|
1120
|
+
multiTouchEnd() {
|
|
1121
|
+
this.touches = null;
|
|
1122
|
+
this.useMultiTouch = false;
|
|
1123
|
+
this.transformEnd();
|
|
1124
|
+
}
|
|
1125
|
+
getKeepTouchList(old, touches) {
|
|
1126
|
+
let to;
|
|
1127
|
+
const list = [];
|
|
1128
|
+
old.forEach(from => {
|
|
1129
|
+
to = touches.find(touch => touch.identifier === from.identifier);
|
|
1130
|
+
if (to)
|
|
1131
|
+
list.push({ from: this.getLocal(from), to: this.getLocal(to) });
|
|
1132
|
+
});
|
|
1133
|
+
return list;
|
|
1134
|
+
}
|
|
1135
|
+
getLocalTouchs(points) {
|
|
1136
|
+
return points.map(point => this.getLocal(point));
|
|
1137
|
+
}
|
|
1138
|
+
destroy() {
|
|
1139
|
+
super.destroy();
|
|
1140
|
+
this.touches = null;
|
|
1141
|
+
}
|
|
1441
1142
|
}
|
|
1442
1143
|
|
|
1443
1144
|
function fillText(ui, canvas) {
|
|
@@ -1458,16 +1159,16 @@ function fillText(ui, canvas) {
|
|
|
1458
1159
|
}
|
|
1459
1160
|
}
|
|
1460
1161
|
|
|
1461
|
-
function fill(ui, canvas
|
|
1162
|
+
function fill(fill, ui, canvas) {
|
|
1462
1163
|
canvas.fillStyle = fill;
|
|
1463
1164
|
ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
|
|
1464
1165
|
}
|
|
1465
|
-
function fills(ui, canvas
|
|
1166
|
+
function fills(fills, ui, canvas) {
|
|
1466
1167
|
let item;
|
|
1467
1168
|
const { windingRule, __font } = ui.__;
|
|
1468
1169
|
for (let i = 0, len = fills.length; i < len; i++) {
|
|
1469
1170
|
item = fills[i];
|
|
1470
|
-
if (item.image && checkImage(ui, canvas, item, !__font))
|
|
1171
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
|
|
1471
1172
|
continue;
|
|
1472
1173
|
if (item.style) {
|
|
1473
1174
|
canvas.fillStyle = item.style;
|
|
@@ -1493,33 +1194,38 @@ function fills(ui, canvas, fills) {
|
|
|
1493
1194
|
}
|
|
1494
1195
|
}
|
|
1495
1196
|
|
|
1496
|
-
function strokeText(ui, canvas
|
|
1197
|
+
function strokeText(stroke, ui, canvas) {
|
|
1497
1198
|
const { strokeAlign } = ui.__;
|
|
1498
1199
|
const isStrokes = typeof stroke !== 'string';
|
|
1499
1200
|
switch (strokeAlign) {
|
|
1500
1201
|
case 'center':
|
|
1501
1202
|
canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
|
|
1502
|
-
isStrokes ? drawStrokesStyle(
|
|
1203
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
|
|
1503
1204
|
break;
|
|
1504
1205
|
case 'inside':
|
|
1505
|
-
drawAlignStroke(
|
|
1206
|
+
drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
|
|
1506
1207
|
break;
|
|
1507
1208
|
case 'outside':
|
|
1508
|
-
drawAlignStroke(
|
|
1209
|
+
drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
|
|
1509
1210
|
break;
|
|
1510
1211
|
}
|
|
1511
1212
|
}
|
|
1512
|
-
function drawAlignStroke(
|
|
1513
|
-
const {
|
|
1514
|
-
const out = canvas.getSameCanvas(true);
|
|
1515
|
-
out.setStroke(isStrokes ? undefined : stroke,
|
|
1213
|
+
function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
|
|
1214
|
+
const { __strokeWidth, __font } = ui.__;
|
|
1215
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1216
|
+
out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
|
|
1516
1217
|
out.font = __font;
|
|
1517
|
-
isStrokes ? drawStrokesStyle(
|
|
1218
|
+
isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
|
|
1518
1219
|
out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
|
|
1519
1220
|
fillText(ui, out);
|
|
1520
1221
|
out.blendMode = 'normal';
|
|
1521
|
-
|
|
1522
|
-
|
|
1222
|
+
if (ui.__worldFlipped) {
|
|
1223
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1224
|
+
}
|
|
1225
|
+
else {
|
|
1226
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1227
|
+
}
|
|
1228
|
+
out.recycle(ui.__nowWorld);
|
|
1523
1229
|
}
|
|
1524
1230
|
function drawTextStroke(ui, canvas) {
|
|
1525
1231
|
let row;
|
|
@@ -1538,11 +1244,11 @@ function drawTextStroke(ui, canvas) {
|
|
|
1538
1244
|
canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
|
|
1539
1245
|
}
|
|
1540
1246
|
}
|
|
1541
|
-
function drawStrokesStyle(
|
|
1247
|
+
function drawStrokesStyle(strokes, isText, ui, canvas) {
|
|
1542
1248
|
let item;
|
|
1543
1249
|
for (let i = 0, len = strokes.length; i < len; i++) {
|
|
1544
1250
|
item = strokes[i];
|
|
1545
|
-
if (item.image && checkImage(ui, canvas, item, false))
|
|
1251
|
+
if (item.image && PaintImage.checkImage(ui, canvas, item, false))
|
|
1546
1252
|
continue;
|
|
1547
1253
|
if (item.style) {
|
|
1548
1254
|
canvas.strokeStyle = item.style;
|
|
@@ -1558,121 +1264,575 @@ function drawStrokesStyle(ui, strokes, canvas, isText) {
|
|
|
1558
1264
|
}
|
|
1559
1265
|
}
|
|
1560
1266
|
|
|
1561
|
-
function stroke(ui, canvas
|
|
1267
|
+
function stroke(stroke, ui, canvas) {
|
|
1562
1268
|
const options = ui.__;
|
|
1563
|
-
const {
|
|
1564
|
-
if (!
|
|
1269
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1270
|
+
if (!__strokeWidth)
|
|
1565
1271
|
return;
|
|
1566
1272
|
if (__font) {
|
|
1567
|
-
strokeText(ui, canvas
|
|
1273
|
+
strokeText(stroke, ui, canvas);
|
|
1568
1274
|
}
|
|
1569
1275
|
else {
|
|
1570
1276
|
switch (strokeAlign) {
|
|
1571
1277
|
case 'center':
|
|
1572
|
-
canvas.setStroke(stroke,
|
|
1278
|
+
canvas.setStroke(stroke, __strokeWidth, options);
|
|
1573
1279
|
canvas.stroke();
|
|
1574
1280
|
break;
|
|
1575
1281
|
case 'inside':
|
|
1576
1282
|
canvas.save();
|
|
1577
|
-
canvas.setStroke(stroke,
|
|
1283
|
+
canvas.setStroke(stroke, __strokeWidth * 2, options);
|
|
1578
1284
|
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1579
1285
|
canvas.stroke();
|
|
1580
1286
|
canvas.restore();
|
|
1581
1287
|
break;
|
|
1582
1288
|
case 'outside':
|
|
1583
|
-
const out = canvas.getSameCanvas(true);
|
|
1584
|
-
out.setStroke(stroke,
|
|
1289
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1290
|
+
out.setStroke(stroke, __strokeWidth * 2, options);
|
|
1585
1291
|
ui.__drawRenderPath(out);
|
|
1586
1292
|
out.stroke();
|
|
1587
1293
|
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1588
1294
|
out.clearWorld(ui.__layout.renderBounds);
|
|
1589
|
-
|
|
1590
|
-
|
|
1295
|
+
if (ui.__worldFlipped) {
|
|
1296
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1297
|
+
}
|
|
1298
|
+
else {
|
|
1299
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1300
|
+
}
|
|
1301
|
+
out.recycle(ui.__nowWorld);
|
|
1302
|
+
break;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
function strokes(strokes, ui, canvas) {
|
|
1307
|
+
const options = ui.__;
|
|
1308
|
+
const { __strokeWidth, strokeAlign, __font } = options;
|
|
1309
|
+
if (!__strokeWidth)
|
|
1310
|
+
return;
|
|
1311
|
+
if (__font) {
|
|
1312
|
+
strokeText(strokes, ui, canvas);
|
|
1313
|
+
}
|
|
1314
|
+
else {
|
|
1315
|
+
switch (strokeAlign) {
|
|
1316
|
+
case 'center':
|
|
1317
|
+
canvas.setStroke(undefined, __strokeWidth, options);
|
|
1318
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1319
|
+
break;
|
|
1320
|
+
case 'inside':
|
|
1321
|
+
canvas.save();
|
|
1322
|
+
canvas.setStroke(undefined, __strokeWidth * 2, options);
|
|
1323
|
+
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1324
|
+
drawStrokesStyle(strokes, false, ui, canvas);
|
|
1325
|
+
canvas.restore();
|
|
1326
|
+
break;
|
|
1327
|
+
case 'outside':
|
|
1328
|
+
const { renderBounds } = ui.__layout;
|
|
1329
|
+
const out = canvas.getSameCanvas(true, true);
|
|
1330
|
+
ui.__drawRenderPath(out);
|
|
1331
|
+
out.setStroke(undefined, __strokeWidth * 2, options);
|
|
1332
|
+
drawStrokesStyle(strokes, false, ui, out);
|
|
1333
|
+
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1334
|
+
out.clearWorld(renderBounds);
|
|
1335
|
+
if (ui.__worldFlipped) {
|
|
1336
|
+
canvas.copyWorldByReset(out, ui.__nowWorld);
|
|
1337
|
+
}
|
|
1338
|
+
else {
|
|
1339
|
+
canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
|
|
1340
|
+
}
|
|
1341
|
+
out.recycle(ui.__nowWorld);
|
|
1342
|
+
break;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
|
|
1348
|
+
function shape(ui, current, options) {
|
|
1349
|
+
const canvas = current.getSameCanvas();
|
|
1350
|
+
const nowWorld = ui.__nowWorld;
|
|
1351
|
+
let bounds, fitMatrix, shapeBounds, worldCanvas;
|
|
1352
|
+
let { scaleX, scaleY } = nowWorld;
|
|
1353
|
+
if (scaleX < 0)
|
|
1354
|
+
scaleX = -scaleX;
|
|
1355
|
+
if (scaleY < 0)
|
|
1356
|
+
scaleY = -scaleY;
|
|
1357
|
+
if (current.bounds.includes(nowWorld)) {
|
|
1358
|
+
worldCanvas = canvas;
|
|
1359
|
+
bounds = shapeBounds = nowWorld;
|
|
1360
|
+
}
|
|
1361
|
+
else {
|
|
1362
|
+
const { renderShapeSpread: spread } = ui.__layout;
|
|
1363
|
+
const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, nowWorld);
|
|
1364
|
+
fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
|
|
1365
|
+
let { a: fitScaleX, d: fitScaleY } = fitMatrix;
|
|
1366
|
+
if (fitMatrix.a < 1) {
|
|
1367
|
+
worldCanvas = current.getSameCanvas();
|
|
1368
|
+
ui.__renderShape(worldCanvas, options);
|
|
1369
|
+
scaleX *= fitScaleX;
|
|
1370
|
+
scaleY *= fitScaleY;
|
|
1371
|
+
}
|
|
1372
|
+
shapeBounds = getOuterOf(nowWorld, fitMatrix);
|
|
1373
|
+
bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
|
|
1374
|
+
if (options.matrix) {
|
|
1375
|
+
const { matrix } = options;
|
|
1376
|
+
fitMatrix.multiply(matrix);
|
|
1377
|
+
fitScaleX *= matrix.scaleX;
|
|
1378
|
+
fitScaleY *= matrix.scaleY;
|
|
1379
|
+
}
|
|
1380
|
+
options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
|
|
1381
|
+
}
|
|
1382
|
+
ui.__renderShape(canvas, options);
|
|
1383
|
+
return {
|
|
1384
|
+
canvas, matrix: fitMatrix, bounds,
|
|
1385
|
+
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
let recycleMap;
|
|
1390
|
+
function compute(attrName, ui) {
|
|
1391
|
+
const data = ui.__, leafPaints = [];
|
|
1392
|
+
let paints = data.__input[attrName], hasOpacityPixel;
|
|
1393
|
+
if (!(paints instanceof Array))
|
|
1394
|
+
paints = [paints];
|
|
1395
|
+
recycleMap = PaintImage.recycleImage(attrName, data);
|
|
1396
|
+
for (let i = 0, len = paints.length, item; i < len; i++) {
|
|
1397
|
+
item = getLeafPaint(attrName, paints[i], ui);
|
|
1398
|
+
if (item)
|
|
1399
|
+
leafPaints.push(item);
|
|
1400
|
+
}
|
|
1401
|
+
data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
|
|
1402
|
+
if (leafPaints.length && leafPaints[0].image)
|
|
1403
|
+
hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
|
|
1404
|
+
if (attrName === 'fill') {
|
|
1405
|
+
data.__pixelFill = hasOpacityPixel;
|
|
1406
|
+
}
|
|
1407
|
+
else {
|
|
1408
|
+
data.__pixelStroke = hasOpacityPixel;
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
function getLeafPaint(attrName, paint, ui) {
|
|
1412
|
+
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1413
|
+
return undefined;
|
|
1414
|
+
const { boxBounds } = ui.__layout;
|
|
1415
|
+
switch (paint.type) {
|
|
1416
|
+
case 'solid':
|
|
1417
|
+
let { type, blendMode, color, opacity } = paint;
|
|
1418
|
+
return { type, blendMode, style: ColorConvert.string(color, opacity) };
|
|
1419
|
+
case 'image':
|
|
1420
|
+
return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1421
|
+
case 'linear':
|
|
1422
|
+
return PaintGradient.linearGradient(paint, boxBounds);
|
|
1423
|
+
case 'radial':
|
|
1424
|
+
return PaintGradient.radialGradient(paint, boxBounds);
|
|
1425
|
+
case 'angular':
|
|
1426
|
+
return PaintGradient.conicGradient(paint, boxBounds);
|
|
1427
|
+
default:
|
|
1428
|
+
return paint.r ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
|
|
1432
|
+
const PaintModule = {
|
|
1433
|
+
compute,
|
|
1434
|
+
fill,
|
|
1435
|
+
fills,
|
|
1436
|
+
fillText,
|
|
1437
|
+
stroke,
|
|
1438
|
+
strokes,
|
|
1439
|
+
strokeText,
|
|
1440
|
+
drawTextStroke,
|
|
1441
|
+
shape
|
|
1442
|
+
};
|
|
1443
|
+
|
|
1444
|
+
let origin = {};
|
|
1445
|
+
const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
|
|
1446
|
+
function fillOrFitMode(data, mode, box, width, height, rotation) {
|
|
1447
|
+
const transform = get$4();
|
|
1448
|
+
const swap = rotation && rotation !== 180;
|
|
1449
|
+
const sw = box.width / (swap ? height : width);
|
|
1450
|
+
const sh = box.height / (swap ? width : height);
|
|
1451
|
+
const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
|
|
1452
|
+
const x = box.x + (box.width - width * scale) / 2;
|
|
1453
|
+
const y = box.y + (box.height - height * scale) / 2;
|
|
1454
|
+
translate$1(transform, x, y);
|
|
1455
|
+
scaleHelper(transform, scale);
|
|
1456
|
+
if (rotation)
|
|
1457
|
+
rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
|
|
1458
|
+
data.scaleX = data.scaleY = scale;
|
|
1459
|
+
data.transform = transform;
|
|
1460
|
+
}
|
|
1461
|
+
function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
|
|
1462
|
+
const transform = get$4();
|
|
1463
|
+
translate$1(transform, box.x, box.y);
|
|
1464
|
+
if (x || y)
|
|
1465
|
+
translate$1(transform, x, y);
|
|
1466
|
+
if (scaleX) {
|
|
1467
|
+
scaleHelper(transform, scaleX, scaleY);
|
|
1468
|
+
data.scaleX = transform.a;
|
|
1469
|
+
data.scaleY = transform.d;
|
|
1470
|
+
}
|
|
1471
|
+
if (rotation)
|
|
1472
|
+
rotate(transform, rotation);
|
|
1473
|
+
data.transform = transform;
|
|
1474
|
+
}
|
|
1475
|
+
function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
|
|
1476
|
+
const transform = get$4();
|
|
1477
|
+
if (rotation) {
|
|
1478
|
+
rotate(transform, rotation);
|
|
1479
|
+
switch (rotation) {
|
|
1480
|
+
case 90:
|
|
1481
|
+
translate$1(transform, height, 0);
|
|
1482
|
+
break;
|
|
1483
|
+
case 180:
|
|
1484
|
+
translate$1(transform, width, height);
|
|
1591
1485
|
break;
|
|
1486
|
+
case 270:
|
|
1487
|
+
translate$1(transform, 0, width);
|
|
1488
|
+
break;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
origin.x = box.x;
|
|
1492
|
+
origin.y = box.y;
|
|
1493
|
+
if (x || y)
|
|
1494
|
+
origin.x += x, origin.y += y;
|
|
1495
|
+
translate$1(transform, origin.x, origin.y);
|
|
1496
|
+
if (scaleX) {
|
|
1497
|
+
scaleOfOuter$2(transform, origin, scaleX, scaleY);
|
|
1498
|
+
data.scaleX = scaleX;
|
|
1499
|
+
data.scaleY = scaleY;
|
|
1500
|
+
}
|
|
1501
|
+
data.transform = transform;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
const { get: get$3, translate } = MatrixHelper;
|
|
1505
|
+
const tempBox = new Bounds();
|
|
1506
|
+
function createData(leafPaint, image, paint, box) {
|
|
1507
|
+
let { width, height } = image;
|
|
1508
|
+
if (paint.padding)
|
|
1509
|
+
box = tempBox.set(box).shrink(paint.padding);
|
|
1510
|
+
const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
|
|
1511
|
+
const sameBox = box.width === width && box.height === height;
|
|
1512
|
+
if (blendMode)
|
|
1513
|
+
leafPaint.blendMode = blendMode;
|
|
1514
|
+
const data = leafPaint.data = { mode };
|
|
1515
|
+
let x, y, scaleX, scaleY;
|
|
1516
|
+
if (offset)
|
|
1517
|
+
x = offset.x, y = offset.y;
|
|
1518
|
+
if (size) {
|
|
1519
|
+
scaleX = (typeof size === 'number' ? size : size.width) / width;
|
|
1520
|
+
scaleY = (typeof size === 'number' ? size : size.height) / height;
|
|
1521
|
+
}
|
|
1522
|
+
else if (scale) {
|
|
1523
|
+
scaleX = typeof scale === 'number' ? scale : scale.x;
|
|
1524
|
+
scaleY = typeof scale === 'number' ? scale : scale.y;
|
|
1525
|
+
}
|
|
1526
|
+
switch (mode) {
|
|
1527
|
+
case 'strench':
|
|
1528
|
+
if (!sameBox)
|
|
1529
|
+
width = box.width, height = box.height;
|
|
1530
|
+
break;
|
|
1531
|
+
case 'clip':
|
|
1532
|
+
if (offset || scaleX || rotation)
|
|
1533
|
+
clipMode(data, box, x, y, scaleX, scaleY, rotation);
|
|
1534
|
+
break;
|
|
1535
|
+
case 'repeat':
|
|
1536
|
+
if (!sameBox || scaleX || rotation)
|
|
1537
|
+
repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
|
|
1538
|
+
if (!repeat)
|
|
1539
|
+
data.repeat = 'repeat';
|
|
1540
|
+
break;
|
|
1541
|
+
case 'fit':
|
|
1542
|
+
case 'cover':
|
|
1543
|
+
default:
|
|
1544
|
+
if (!sameBox || rotation)
|
|
1545
|
+
fillOrFitMode(data, mode, box, width, height, rotation);
|
|
1546
|
+
}
|
|
1547
|
+
if (!data.transform) {
|
|
1548
|
+
if (box.x || box.y) {
|
|
1549
|
+
data.transform = get$3();
|
|
1550
|
+
translate(data.transform, box.x, box.y);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
data.width = width;
|
|
1554
|
+
data.height = height;
|
|
1555
|
+
if (opacity)
|
|
1556
|
+
data.opacity = opacity;
|
|
1557
|
+
if (repeat)
|
|
1558
|
+
data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
let cache, box = new Bounds();
|
|
1562
|
+
const { isSame } = BoundsHelper;
|
|
1563
|
+
function image(ui, attrName, paint, boxBounds, firstUse) {
|
|
1564
|
+
let leafPaint, event;
|
|
1565
|
+
const image = ImageManager.get(paint);
|
|
1566
|
+
if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
|
|
1567
|
+
leafPaint = cache.leafPaint;
|
|
1568
|
+
}
|
|
1569
|
+
else {
|
|
1570
|
+
leafPaint = { type: paint.type, image };
|
|
1571
|
+
cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
|
|
1572
|
+
}
|
|
1573
|
+
if (firstUse || image.loading)
|
|
1574
|
+
event = { image, attrName, attrValue: paint };
|
|
1575
|
+
if (image.ready) {
|
|
1576
|
+
checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
|
|
1577
|
+
if (firstUse) {
|
|
1578
|
+
onLoad(ui, event);
|
|
1579
|
+
onLoadSuccess(ui, event);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
else if (image.error) {
|
|
1583
|
+
if (firstUse)
|
|
1584
|
+
onLoadError(ui, event, image.error);
|
|
1585
|
+
}
|
|
1586
|
+
else {
|
|
1587
|
+
ignoreRender(ui, true);
|
|
1588
|
+
if (firstUse)
|
|
1589
|
+
onLoad(ui, event);
|
|
1590
|
+
leafPaint.loadId = image.load(() => {
|
|
1591
|
+
ignoreRender(ui, false);
|
|
1592
|
+
if (!ui.destroyed) {
|
|
1593
|
+
if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
|
|
1594
|
+
if (image.hasOpacityPixel)
|
|
1595
|
+
ui.__layout.hitCanvasChanged = true;
|
|
1596
|
+
ui.forceUpdate('surface');
|
|
1597
|
+
}
|
|
1598
|
+
onLoadSuccess(ui, event);
|
|
1599
|
+
}
|
|
1600
|
+
leafPaint.loadId = null;
|
|
1601
|
+
}, (error) => {
|
|
1602
|
+
ignoreRender(ui, false);
|
|
1603
|
+
onLoadError(ui, event, error);
|
|
1604
|
+
leafPaint.loadId = null;
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
return leafPaint;
|
|
1608
|
+
}
|
|
1609
|
+
function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
|
|
1610
|
+
if (attrName === 'fill' && !ui.__.__naturalWidth) {
|
|
1611
|
+
const data = ui.__;
|
|
1612
|
+
data.__naturalWidth = image.width / data.pixelRatio;
|
|
1613
|
+
data.__naturalHeight = image.height / data.pixelRatio;
|
|
1614
|
+
if (data.__autoSide) {
|
|
1615
|
+
ui.forceUpdate('width');
|
|
1616
|
+
if (ui.__proxyData) {
|
|
1617
|
+
ui.setProxyAttr('width', data.width);
|
|
1618
|
+
ui.setProxyAttr('height', data.height);
|
|
1619
|
+
}
|
|
1620
|
+
return false;
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
if (!leafPaint.data)
|
|
1624
|
+
createData(leafPaint, image, paint, boxBounds);
|
|
1625
|
+
return true;
|
|
1626
|
+
}
|
|
1627
|
+
function onLoad(ui, event) {
|
|
1628
|
+
emit(ui, ImageEvent.LOAD, event);
|
|
1629
|
+
}
|
|
1630
|
+
function onLoadSuccess(ui, event) {
|
|
1631
|
+
emit(ui, ImageEvent.LOADED, event);
|
|
1632
|
+
}
|
|
1633
|
+
function onLoadError(ui, event, error) {
|
|
1634
|
+
event.error = error;
|
|
1635
|
+
ui.forceUpdate('surface');
|
|
1636
|
+
emit(ui, ImageEvent.ERROR, event);
|
|
1637
|
+
}
|
|
1638
|
+
function emit(ui, type, data) {
|
|
1639
|
+
if (ui.hasEvent(type))
|
|
1640
|
+
ui.emitEvent(new ImageEvent(type, data));
|
|
1641
|
+
}
|
|
1642
|
+
function ignoreRender(ui, value) {
|
|
1643
|
+
const { leafer } = ui;
|
|
1644
|
+
if (leafer && leafer.viewReady)
|
|
1645
|
+
leafer.renderer.ignore = value;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
|
|
1649
|
+
const { ceil, abs: abs$1 } = Math;
|
|
1650
|
+
function createPattern(ui, paint, pixelRatio) {
|
|
1651
|
+
let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1652
|
+
const id = scaleX + '-' + scaleY;
|
|
1653
|
+
if (paint.patternId !== id && !ui.destroyed) {
|
|
1654
|
+
scaleX = abs$1(scaleX);
|
|
1655
|
+
scaleY = abs$1(scaleY);
|
|
1656
|
+
const { image, data } = paint;
|
|
1657
|
+
let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
|
|
1658
|
+
if (sx) {
|
|
1659
|
+
imageMatrix = get$2();
|
|
1660
|
+
copy$1(imageMatrix, transform);
|
|
1661
|
+
scale(imageMatrix, 1 / sx, 1 / sy);
|
|
1662
|
+
scaleX *= sx;
|
|
1663
|
+
scaleY *= sy;
|
|
1664
|
+
}
|
|
1665
|
+
scaleX *= pixelRatio;
|
|
1666
|
+
scaleY *= pixelRatio;
|
|
1667
|
+
width *= scaleX;
|
|
1668
|
+
height *= scaleY;
|
|
1669
|
+
const size = width * height;
|
|
1670
|
+
if (!repeat) {
|
|
1671
|
+
if (size > Platform.image.maxCacheSize)
|
|
1672
|
+
return false;
|
|
1673
|
+
}
|
|
1674
|
+
let maxSize = Platform.image.maxPatternSize;
|
|
1675
|
+
if (!image.isSVG) {
|
|
1676
|
+
const imageSize = image.width * image.height;
|
|
1677
|
+
if (maxSize > imageSize)
|
|
1678
|
+
maxSize = imageSize;
|
|
1679
|
+
}
|
|
1680
|
+
if (size > maxSize)
|
|
1681
|
+
imageScale = Math.sqrt(size / maxSize);
|
|
1682
|
+
if (imageScale) {
|
|
1683
|
+
scaleX /= imageScale;
|
|
1684
|
+
scaleY /= imageScale;
|
|
1685
|
+
width /= imageScale;
|
|
1686
|
+
height /= imageScale;
|
|
1687
|
+
}
|
|
1688
|
+
if (sx) {
|
|
1689
|
+
scaleX /= sx;
|
|
1690
|
+
scaleY /= sy;
|
|
1691
|
+
}
|
|
1692
|
+
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
1693
|
+
if (!imageMatrix) {
|
|
1694
|
+
imageMatrix = get$2();
|
|
1695
|
+
if (transform)
|
|
1696
|
+
copy$1(imageMatrix, transform);
|
|
1697
|
+
}
|
|
1698
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
1592
1699
|
}
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
if (!strokeWidth)
|
|
1599
|
-
return;
|
|
1600
|
-
if (__font) {
|
|
1601
|
-
strokeText(ui, canvas, strokes);
|
|
1700
|
+
const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
|
|
1701
|
+
const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
|
|
1702
|
+
paint.style = pattern;
|
|
1703
|
+
paint.patternId = id;
|
|
1704
|
+
return true;
|
|
1602
1705
|
}
|
|
1603
1706
|
else {
|
|
1604
|
-
|
|
1605
|
-
case 'center':
|
|
1606
|
-
canvas.setStroke(undefined, strokeWidth, options);
|
|
1607
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1608
|
-
break;
|
|
1609
|
-
case 'inside':
|
|
1610
|
-
canvas.save();
|
|
1611
|
-
canvas.setStroke(undefined, strokeWidth * 2, options);
|
|
1612
|
-
options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
|
|
1613
|
-
drawStrokesStyle(ui, strokes, canvas);
|
|
1614
|
-
canvas.restore();
|
|
1615
|
-
break;
|
|
1616
|
-
case 'outside':
|
|
1617
|
-
const { renderBounds } = ui.__layout;
|
|
1618
|
-
const out = canvas.getSameCanvas(true);
|
|
1619
|
-
ui.__drawRenderPath(out);
|
|
1620
|
-
out.setStroke(undefined, strokeWidth * 2, ui.__);
|
|
1621
|
-
drawStrokesStyle(ui, strokes, out);
|
|
1622
|
-
options.windingRule ? out.clip(options.windingRule) : out.clip();
|
|
1623
|
-
out.clearWorld(renderBounds);
|
|
1624
|
-
canvas.copyWorldToInner(out, ui.__world, renderBounds);
|
|
1625
|
-
out.recycle();
|
|
1626
|
-
break;
|
|
1627
|
-
}
|
|
1707
|
+
return false;
|
|
1628
1708
|
}
|
|
1629
1709
|
}
|
|
1630
1710
|
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1711
|
+
/******************************************************************************
|
|
1712
|
+
Copyright (c) Microsoft Corporation.
|
|
1713
|
+
|
|
1714
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
1715
|
+
purpose with or without fee is hereby granted.
|
|
1716
|
+
|
|
1717
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
1718
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
1719
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
1720
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
1721
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
1722
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
1723
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
1724
|
+
***************************************************************************** */
|
|
1725
|
+
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
1726
|
+
|
|
1727
|
+
|
|
1728
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
1729
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1730
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1731
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1732
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1733
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1734
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1735
|
+
});
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1738
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
1739
|
+
var e = new Error(message);
|
|
1740
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
1741
|
+
};
|
|
1742
|
+
|
|
1743
|
+
const { abs } = Math;
|
|
1744
|
+
function checkImage(ui, canvas, paint, allowPaint) {
|
|
1745
|
+
const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1746
|
+
if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
|
|
1747
|
+
return false;
|
|
1657
1748
|
}
|
|
1658
1749
|
else {
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1750
|
+
const { data } = paint;
|
|
1751
|
+
if (allowPaint) {
|
|
1752
|
+
if (!data.repeat) {
|
|
1753
|
+
let { width, height } = data;
|
|
1754
|
+
width *= abs(scaleX) * canvas.pixelRatio;
|
|
1755
|
+
height *= abs(scaleY) * canvas.pixelRatio;
|
|
1756
|
+
if (data.scaleX) {
|
|
1757
|
+
width *= data.scaleX;
|
|
1758
|
+
height *= data.scaleY;
|
|
1759
|
+
}
|
|
1760
|
+
allowPaint = width * height > Platform.image.maxCacheSize;
|
|
1761
|
+
}
|
|
1762
|
+
else {
|
|
1763
|
+
allowPaint = false;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
if (allowPaint) {
|
|
1767
|
+
canvas.save();
|
|
1768
|
+
canvas.clip();
|
|
1769
|
+
if (paint.blendMode)
|
|
1770
|
+
canvas.blendMode = paint.blendMode;
|
|
1771
|
+
if (data.opacity)
|
|
1772
|
+
canvas.opacity *= data.opacity;
|
|
1773
|
+
if (data.transform)
|
|
1774
|
+
canvas.transform(data.transform);
|
|
1775
|
+
canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
|
|
1776
|
+
canvas.restore();
|
|
1777
|
+
return true;
|
|
1663
1778
|
}
|
|
1664
1779
|
else {
|
|
1665
|
-
|
|
1780
|
+
if (!paint.style || Export.running) {
|
|
1781
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1782
|
+
}
|
|
1783
|
+
else {
|
|
1784
|
+
if (!paint.patternTask) {
|
|
1785
|
+
paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
|
|
1786
|
+
paint.patternTask = null;
|
|
1787
|
+
if (canvas.bounds.hit(ui.__nowWorld))
|
|
1788
|
+
createPattern(ui, paint, canvas.pixelRatio);
|
|
1789
|
+
ui.forceUpdate('surface');
|
|
1790
|
+
}), 300);
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
return false;
|
|
1666
1794
|
}
|
|
1667
|
-
worldCanvas = canvas;
|
|
1668
1795
|
}
|
|
1669
|
-
ui.__renderShape(canvas, options);
|
|
1670
|
-
return {
|
|
1671
|
-
canvas, matrix, bounds,
|
|
1672
|
-
worldCanvas, shapeBounds, scaleX, scaleY
|
|
1673
|
-
};
|
|
1674
1796
|
}
|
|
1675
1797
|
|
|
1798
|
+
function recycleImage(attrName, data) {
|
|
1799
|
+
const paints = data['_' + attrName];
|
|
1800
|
+
if (paints instanceof Array) {
|
|
1801
|
+
let image, recycleMap, input, url;
|
|
1802
|
+
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1803
|
+
image = paints[i].image;
|
|
1804
|
+
url = image && image.url;
|
|
1805
|
+
if (url) {
|
|
1806
|
+
if (!recycleMap)
|
|
1807
|
+
recycleMap = {};
|
|
1808
|
+
recycleMap[url] = true;
|
|
1809
|
+
ImageManager.recycle(image);
|
|
1810
|
+
if (image.loading) {
|
|
1811
|
+
if (!input) {
|
|
1812
|
+
input = (data.__input && data.__input[attrName]) || [];
|
|
1813
|
+
if (!(input instanceof Array))
|
|
1814
|
+
input = [input];
|
|
1815
|
+
}
|
|
1816
|
+
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return recycleMap;
|
|
1821
|
+
}
|
|
1822
|
+
return null;
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
const PaintImageModule = {
|
|
1826
|
+
image,
|
|
1827
|
+
createData,
|
|
1828
|
+
fillOrFitMode,
|
|
1829
|
+
clipMode,
|
|
1830
|
+
repeatMode,
|
|
1831
|
+
createPattern,
|
|
1832
|
+
checkImage,
|
|
1833
|
+
recycleImage
|
|
1834
|
+
};
|
|
1835
|
+
|
|
1676
1836
|
const defaultFrom$2 = { x: 0.5, y: 0 };
|
|
1677
1837
|
const defaultTo$2 = { x: 0.5, y: 1 };
|
|
1678
1838
|
function linearGradient(paint, box) {
|
|
@@ -1690,7 +1850,7 @@ function applyStops(gradient, stops, opacity) {
|
|
|
1690
1850
|
let stop;
|
|
1691
1851
|
for (let i = 0, len = stops.length; i < len; i++) {
|
|
1692
1852
|
stop = stops[i];
|
|
1693
|
-
gradient.addColorStop(stop.offset, ColorConvert
|
|
1853
|
+
gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
|
|
1694
1854
|
}
|
|
1695
1855
|
}
|
|
1696
1856
|
|
|
@@ -1752,62 +1912,18 @@ function conicGradient(paint, box) {
|
|
|
1752
1912
|
return data;
|
|
1753
1913
|
}
|
|
1754
1914
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
if (!(paints instanceof Array))
|
|
1761
|
-
paints = [paints];
|
|
1762
|
-
recycleMap = recycleImage(ui.__, attrName);
|
|
1763
|
-
for (let i = 0, len = paints.length; i < len; i++) {
|
|
1764
|
-
item = getLeafPaint(ui, paints[i], attrName);
|
|
1765
|
-
if (item)
|
|
1766
|
-
value.push(item);
|
|
1767
|
-
}
|
|
1768
|
-
ui.__['_' + attrName] = value.length ? value : undefined;
|
|
1769
|
-
}
|
|
1770
|
-
function getLeafPaint(ui, paint, attrName) {
|
|
1771
|
-
if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
|
|
1772
|
-
return undefined;
|
|
1773
|
-
const { boxBounds } = ui.__layout;
|
|
1774
|
-
switch (paint.type) {
|
|
1775
|
-
case 'solid':
|
|
1776
|
-
let { type, blendMode, color, opacity } = paint;
|
|
1777
|
-
return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
|
|
1778
|
-
case 'image':
|
|
1779
|
-
return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
|
|
1780
|
-
case 'linear':
|
|
1781
|
-
return linearGradient(paint, boxBounds);
|
|
1782
|
-
case 'radial':
|
|
1783
|
-
return radialGradient(paint, boxBounds);
|
|
1784
|
-
case 'angular':
|
|
1785
|
-
return conicGradient(paint, boxBounds);
|
|
1786
|
-
default:
|
|
1787
|
-
return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
|
|
1791
|
-
var UIPaint = /*#__PURE__*/Object.freeze({
|
|
1792
|
-
__proto__: null,
|
|
1793
|
-
compute: compute,
|
|
1794
|
-
drawTextStroke: drawTextStroke,
|
|
1795
|
-
fill: fill,
|
|
1796
|
-
fillText: fillText,
|
|
1797
|
-
fills: fills,
|
|
1798
|
-
recycleImage: recycleImage,
|
|
1799
|
-
shape: shape,
|
|
1800
|
-
stroke: stroke,
|
|
1801
|
-
strokeText: strokeText,
|
|
1802
|
-
strokes: strokes
|
|
1803
|
-
});
|
|
1915
|
+
const PaintGradientModule = {
|
|
1916
|
+
linearGradient,
|
|
1917
|
+
radialGradient,
|
|
1918
|
+
conicGradient
|
|
1919
|
+
};
|
|
1804
1920
|
|
|
1805
1921
|
const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
|
|
1806
1922
|
const tempBounds = {};
|
|
1807
1923
|
const offsetOutBounds$1 = {};
|
|
1808
|
-
function shadow(ui, current, shape
|
|
1924
|
+
function shadow(ui, current, shape) {
|
|
1809
1925
|
let copyBounds, spreadScale;
|
|
1810
|
-
const {
|
|
1926
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
1811
1927
|
const { shadow } = ui.__;
|
|
1812
1928
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1813
1929
|
const other = current.getSameCanvas();
|
|
@@ -1822,21 +1938,21 @@ function shadow(ui, current, shape, _options) {
|
|
|
1822
1938
|
other.restore();
|
|
1823
1939
|
other.save();
|
|
1824
1940
|
if (worldCanvas) {
|
|
1825
|
-
other.copyWorld(other, bounds,
|
|
1826
|
-
copyBounds =
|
|
1941
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
1942
|
+
copyBounds = nowWorld;
|
|
1827
1943
|
}
|
|
1828
|
-
worldCanvas ? other.copyWorld(worldCanvas,
|
|
1944
|
+
worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
|
|
1829
1945
|
}
|
|
1830
|
-
if (ui.
|
|
1831
|
-
current.copyWorldByReset(other, copyBounds,
|
|
1946
|
+
if (ui.__worldFlipped) {
|
|
1947
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1832
1948
|
}
|
|
1833
1949
|
else {
|
|
1834
1950
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1835
1951
|
}
|
|
1836
1952
|
if (end && index < end)
|
|
1837
|
-
other.
|
|
1953
|
+
other.clearWorld(copyBounds, true);
|
|
1838
1954
|
});
|
|
1839
|
-
other.recycle();
|
|
1955
|
+
other.recycle(copyBounds);
|
|
1840
1956
|
}
|
|
1841
1957
|
function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
1842
1958
|
const { bounds, shapeBounds } = shape;
|
|
@@ -1867,9 +1983,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
|
|
|
1867
1983
|
|
|
1868
1984
|
const { toOffsetOutBounds } = BoundsHelper;
|
|
1869
1985
|
const offsetOutBounds = {};
|
|
1870
|
-
function innerShadow(ui, current, shape
|
|
1986
|
+
function innerShadow(ui, current, shape) {
|
|
1871
1987
|
let copyBounds, spreadScale;
|
|
1872
|
-
const {
|
|
1988
|
+
const { __nowWorld: nowWorld, __layout: __layout } = ui;
|
|
1873
1989
|
const { innerShadow } = ui.__;
|
|
1874
1990
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
1875
1991
|
const other = current.getSameCanvas();
|
|
@@ -1882,40 +1998,115 @@ function innerShadow(ui, current, shape, _options) {
|
|
|
1882
1998
|
drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
|
|
1883
1999
|
other.restore();
|
|
1884
2000
|
if (worldCanvas) {
|
|
1885
|
-
other.copyWorld(other, bounds,
|
|
1886
|
-
other.copyWorld(worldCanvas,
|
|
1887
|
-
copyBounds =
|
|
2001
|
+
other.copyWorld(other, bounds, nowWorld, 'copy');
|
|
2002
|
+
other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
|
|
2003
|
+
copyBounds = nowWorld;
|
|
1888
2004
|
}
|
|
1889
2005
|
else {
|
|
1890
2006
|
other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
|
|
1891
2007
|
copyBounds = bounds;
|
|
1892
2008
|
}
|
|
1893
2009
|
other.fillWorld(copyBounds, item.color, 'source-in');
|
|
1894
|
-
if (ui.
|
|
1895
|
-
current.copyWorldByReset(other, copyBounds,
|
|
2010
|
+
if (ui.__worldFlipped) {
|
|
2011
|
+
current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
|
|
1896
2012
|
}
|
|
1897
2013
|
else {
|
|
1898
2014
|
current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
|
|
1899
2015
|
}
|
|
1900
2016
|
if (end && index < end)
|
|
1901
|
-
other.
|
|
2017
|
+
other.clearWorld(copyBounds, true);
|
|
1902
2018
|
});
|
|
1903
|
-
other.recycle();
|
|
2019
|
+
other.recycle(copyBounds);
|
|
1904
2020
|
}
|
|
1905
2021
|
|
|
1906
2022
|
function blur(ui, current, origin) {
|
|
1907
2023
|
const { blur } = ui.__;
|
|
1908
|
-
origin.setWorldBlur(blur * ui.
|
|
1909
|
-
origin.copyWorldToInner(current, ui.
|
|
2024
|
+
origin.setWorldBlur(blur * ui.__nowWorld.a);
|
|
2025
|
+
origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
|
|
1910
2026
|
origin.filter = 'none';
|
|
1911
2027
|
}
|
|
1912
2028
|
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
shadow
|
|
1918
|
-
|
|
2029
|
+
function backgroundBlur(_ui, _current, _shape) {
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
const EffectModule = {
|
|
2033
|
+
shadow,
|
|
2034
|
+
innerShadow,
|
|
2035
|
+
blur,
|
|
2036
|
+
backgroundBlur
|
|
2037
|
+
};
|
|
2038
|
+
|
|
2039
|
+
const { excludeRenderBounds } = LeafBoundsHelper;
|
|
2040
|
+
Group.prototype.__renderMask = function (canvas, options) {
|
|
2041
|
+
let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
|
|
2042
|
+
const { children } = this;
|
|
2043
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
2044
|
+
child = children[i];
|
|
2045
|
+
if (child.__.mask) {
|
|
2046
|
+
if (currentMask) {
|
|
2047
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2048
|
+
maskCanvas = contentCanvas = null;
|
|
2049
|
+
}
|
|
2050
|
+
if (child.__.maskType === 'path') {
|
|
2051
|
+
if (child.opacity < 1) {
|
|
2052
|
+
currentMask = 'opacity-path';
|
|
2053
|
+
maskOpacity = child.opacity;
|
|
2054
|
+
if (!contentCanvas)
|
|
2055
|
+
contentCanvas = getCanvas(canvas);
|
|
2056
|
+
}
|
|
2057
|
+
else {
|
|
2058
|
+
currentMask = 'path';
|
|
2059
|
+
canvas.save();
|
|
2060
|
+
}
|
|
2061
|
+
child.__clip(contentCanvas || canvas, options);
|
|
2062
|
+
}
|
|
2063
|
+
else {
|
|
2064
|
+
currentMask = 'alpha';
|
|
2065
|
+
if (!maskCanvas)
|
|
2066
|
+
maskCanvas = getCanvas(canvas);
|
|
2067
|
+
if (!contentCanvas)
|
|
2068
|
+
contentCanvas = getCanvas(canvas);
|
|
2069
|
+
child.__render(maskCanvas, options);
|
|
2070
|
+
}
|
|
2071
|
+
if (child.__.maskType !== 'clipping')
|
|
2072
|
+
continue;
|
|
2073
|
+
}
|
|
2074
|
+
if (excludeRenderBounds(child, options))
|
|
2075
|
+
continue;
|
|
2076
|
+
child.__render(contentCanvas || canvas, options);
|
|
2077
|
+
}
|
|
2078
|
+
maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
|
|
2079
|
+
};
|
|
2080
|
+
function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
|
|
2081
|
+
switch (maskMode) {
|
|
2082
|
+
case 'alpha':
|
|
2083
|
+
usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
|
|
2084
|
+
break;
|
|
2085
|
+
case 'opacity-path':
|
|
2086
|
+
copyContent(leaf, canvas, contentCanvas, maskOpacity);
|
|
2087
|
+
break;
|
|
2088
|
+
case 'path':
|
|
2089
|
+
canvas.restore();
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
function getCanvas(canvas) {
|
|
2093
|
+
return canvas.getSameCanvas(false, true);
|
|
2094
|
+
}
|
|
2095
|
+
function usePixelMask(leaf, canvas, content, mask) {
|
|
2096
|
+
const realBounds = leaf.__nowWorld;
|
|
2097
|
+
content.resetTransform();
|
|
2098
|
+
content.opacity = 1;
|
|
2099
|
+
content.useMask(mask, realBounds);
|
|
2100
|
+
mask.recycle(realBounds);
|
|
2101
|
+
copyContent(leaf, canvas, content, 1);
|
|
2102
|
+
}
|
|
2103
|
+
function copyContent(leaf, canvas, content, maskOpacity) {
|
|
2104
|
+
const realBounds = leaf.__nowWorld;
|
|
2105
|
+
canvas.resetTransform();
|
|
2106
|
+
canvas.opacity = maskOpacity;
|
|
2107
|
+
canvas.copyWorld(content, realBounds);
|
|
2108
|
+
content.recycle(realBounds);
|
|
2109
|
+
}
|
|
1919
2110
|
|
|
1920
2111
|
const money = '¥¥$€££¢¢';
|
|
1921
2112
|
const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
|
|
@@ -2029,7 +2220,7 @@ function getTextCase(char, textCase, firstChar) {
|
|
|
2029
2220
|
const { trimRight } = TextRowHelper;
|
|
2030
2221
|
const { Letter, Single, Before, After, Symbol, Break } = CharType;
|
|
2031
2222
|
let word, row, wordWidth, rowWidth, realWidth;
|
|
2032
|
-
let char, charWidth, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
2223
|
+
let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
|
|
2033
2224
|
let textDrawData, rows = [], bounds;
|
|
2034
2225
|
function createRows(drawData, content, style) {
|
|
2035
2226
|
textDrawData = drawData;
|
|
@@ -2040,9 +2231,11 @@ function createRows(drawData, content, style) {
|
|
|
2040
2231
|
const { width, height } = bounds;
|
|
2041
2232
|
const charMode = width || height || __letterSpacing || (textCase !== 'none');
|
|
2042
2233
|
if (charMode) {
|
|
2234
|
+
const wrap = style.textWrap !== 'none';
|
|
2235
|
+
const breakAll = style.textWrap === 'break';
|
|
2043
2236
|
paraStart = true;
|
|
2044
2237
|
lastCharType = null;
|
|
2045
|
-
wordWidth = rowWidth = 0;
|
|
2238
|
+
startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
|
|
2046
2239
|
word = { data: [] }, row = { words: [] };
|
|
2047
2240
|
for (let i = 0, len = content.length; i < len; i++) {
|
|
2048
2241
|
char = content[i];
|
|
@@ -2058,21 +2251,31 @@ function createRows(drawData, content, style) {
|
|
|
2058
2251
|
if (charType === Letter && textCase !== 'none')
|
|
2059
2252
|
char = getTextCase(char, textCase, !wordWidth);
|
|
2060
2253
|
charWidth = canvas.measureText(char).width;
|
|
2061
|
-
if (__letterSpacing)
|
|
2254
|
+
if (__letterSpacing) {
|
|
2255
|
+
if (__letterSpacing < 0)
|
|
2256
|
+
charSize = charWidth;
|
|
2062
2257
|
charWidth += __letterSpacing;
|
|
2258
|
+
}
|
|
2063
2259
|
langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
|
|
2064
2260
|
afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
|
|
2065
2261
|
realWidth = paraStart && paraIndent ? width - paraIndent : width;
|
|
2066
|
-
if (width && rowWidth + wordWidth + charWidth > realWidth) {
|
|
2067
|
-
if (
|
|
2068
|
-
afterBreak = charType === Letter && lastCharType == After;
|
|
2069
|
-
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2262
|
+
if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
|
|
2263
|
+
if (breakAll) {
|
|
2070
2264
|
if (wordWidth)
|
|
2071
2265
|
addWord();
|
|
2072
2266
|
addRow();
|
|
2073
2267
|
}
|
|
2074
2268
|
else {
|
|
2075
|
-
|
|
2269
|
+
if (!afterBreak)
|
|
2270
|
+
afterBreak = charType === Letter && lastCharType == After;
|
|
2271
|
+
if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
|
|
2272
|
+
if (wordWidth)
|
|
2273
|
+
addWord();
|
|
2274
|
+
addRow();
|
|
2275
|
+
}
|
|
2276
|
+
else {
|
|
2277
|
+
addRow();
|
|
2278
|
+
}
|
|
2076
2279
|
}
|
|
2077
2280
|
}
|
|
2078
2281
|
if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
|
|
@@ -2109,6 +2312,8 @@ function createRows(drawData, content, style) {
|
|
|
2109
2312
|
}
|
|
2110
2313
|
}
|
|
2111
2314
|
function addChar(char, width) {
|
|
2315
|
+
if (charSize && !startCharSize)
|
|
2316
|
+
startCharSize = charSize;
|
|
2112
2317
|
word.data.push({ char, width });
|
|
2113
2318
|
wordWidth += width;
|
|
2114
2319
|
}
|
|
@@ -2125,6 +2330,11 @@ function addRow() {
|
|
|
2125
2330
|
row.paraStart = true;
|
|
2126
2331
|
paraStart = false;
|
|
2127
2332
|
}
|
|
2333
|
+
if (charSize) {
|
|
2334
|
+
row.startCharSize = startCharSize;
|
|
2335
|
+
row.endCharSize = charSize;
|
|
2336
|
+
startCharSize = 0;
|
|
2337
|
+
}
|
|
2128
2338
|
row.width = rowWidth;
|
|
2129
2339
|
if (bounds.width)
|
|
2130
2340
|
trimRight(row);
|
|
@@ -2135,7 +2345,7 @@ function addRow() {
|
|
|
2135
2345
|
|
|
2136
2346
|
const CharMode = 0;
|
|
2137
2347
|
const WordMode = 1;
|
|
2138
|
-
const
|
|
2348
|
+
const TextMode = 2;
|
|
2139
2349
|
function layoutChar(drawData, style, width, _height) {
|
|
2140
2350
|
const { rows } = drawData;
|
|
2141
2351
|
const { textAlign, paraIndent, letterSpacing } = style;
|
|
@@ -2144,15 +2354,12 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2144
2354
|
if (row.words) {
|
|
2145
2355
|
indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
|
|
2146
2356
|
addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
|
|
2147
|
-
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode :
|
|
2148
|
-
if (
|
|
2149
|
-
row.
|
|
2357
|
+
mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
|
|
2358
|
+
if (row.isOverflow && !letterSpacing)
|
|
2359
|
+
row.textMode = true;
|
|
2360
|
+
if (mode === TextMode) {
|
|
2150
2361
|
row.x += indentWidth;
|
|
2151
|
-
row
|
|
2152
|
-
word.data.forEach(char => {
|
|
2153
|
-
row.text += char.char;
|
|
2154
|
-
});
|
|
2155
|
-
});
|
|
2362
|
+
toTextChar$1(row);
|
|
2156
2363
|
}
|
|
2157
2364
|
else {
|
|
2158
2365
|
row.x += indentWidth;
|
|
@@ -2178,6 +2385,14 @@ function layoutChar(drawData, style, width, _height) {
|
|
|
2178
2385
|
}
|
|
2179
2386
|
});
|
|
2180
2387
|
}
|
|
2388
|
+
function toTextChar$1(row) {
|
|
2389
|
+
row.text = '';
|
|
2390
|
+
row.words.forEach(word => {
|
|
2391
|
+
word.data.forEach(char => {
|
|
2392
|
+
row.text += char.char;
|
|
2393
|
+
});
|
|
2394
|
+
});
|
|
2395
|
+
}
|
|
2181
2396
|
function toWordChar(data, charX, wordChar) {
|
|
2182
2397
|
data.forEach(char => {
|
|
2183
2398
|
wordChar.char += char.char;
|
|
@@ -2198,10 +2413,10 @@ function toChar(data, charX, rowData) {
|
|
|
2198
2413
|
|
|
2199
2414
|
function layoutText(drawData, style) {
|
|
2200
2415
|
const { rows, bounds } = drawData;
|
|
2201
|
-
const { __lineHeight, __baseLine, textAlign, verticalAlign, paraSpacing
|
|
2416
|
+
const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
|
|
2202
2417
|
let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
|
|
2203
2418
|
let starY = __baseLine;
|
|
2204
|
-
if (
|
|
2419
|
+
if (__clipText && realHeight > height) {
|
|
2205
2420
|
realHeight = Math.max(height, __lineHeight);
|
|
2206
2421
|
drawData.overflow = rows.length;
|
|
2207
2422
|
}
|
|
@@ -2215,7 +2430,7 @@ function layoutText(drawData, style) {
|
|
|
2215
2430
|
}
|
|
2216
2431
|
}
|
|
2217
2432
|
starY += y;
|
|
2218
|
-
let row;
|
|
2433
|
+
let row, rowX, rowWidth;
|
|
2219
2434
|
for (let i = 0, len = rows.length; i < len; i++) {
|
|
2220
2435
|
row = rows[i];
|
|
2221
2436
|
row.x = x;
|
|
@@ -2234,53 +2449,74 @@ function layoutText(drawData, style) {
|
|
|
2234
2449
|
row.isOverflow = true;
|
|
2235
2450
|
drawData.overflow = i + 1;
|
|
2236
2451
|
}
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
if (
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2452
|
+
rowX = row.x;
|
|
2453
|
+
rowWidth = row.width;
|
|
2454
|
+
if (__letterSpacing < 0) {
|
|
2455
|
+
if (row.width < 0) {
|
|
2456
|
+
rowWidth = -row.width + style.fontSize + __letterSpacing;
|
|
2457
|
+
rowX -= rowWidth;
|
|
2458
|
+
rowWidth += style.fontSize;
|
|
2459
|
+
}
|
|
2460
|
+
else {
|
|
2461
|
+
rowWidth -= __letterSpacing;
|
|
2462
|
+
}
|
|
2244
2463
|
}
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2464
|
+
if (rowX < bounds.x)
|
|
2465
|
+
bounds.x = rowX;
|
|
2466
|
+
if (rowWidth > bounds.width)
|
|
2467
|
+
bounds.width = rowWidth;
|
|
2468
|
+
if (__clipText && width && width < rowWidth) {
|
|
2469
|
+
row.isOverflow = true;
|
|
2470
|
+
if (!drawData.overflow)
|
|
2471
|
+
drawData.overflow = rows.length;
|
|
2250
2472
|
}
|
|
2251
2473
|
}
|
|
2252
2474
|
bounds.y = y;
|
|
2253
2475
|
bounds.height = realHeight;
|
|
2254
2476
|
}
|
|
2255
2477
|
|
|
2256
|
-
function clipText(drawData,
|
|
2478
|
+
function clipText(drawData, style) {
|
|
2257
2479
|
const { rows, overflow } = drawData;
|
|
2480
|
+
let { textOverflow } = style;
|
|
2258
2481
|
rows.splice(overflow);
|
|
2259
2482
|
if (textOverflow !== 'hide') {
|
|
2260
2483
|
if (textOverflow === 'ellipsis')
|
|
2261
2484
|
textOverflow = '...';
|
|
2485
|
+
let char, charRight;
|
|
2262
2486
|
const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
|
|
2263
|
-
const
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2487
|
+
const right = style.x + style.width - ellipsisWidth;
|
|
2488
|
+
const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
|
|
2489
|
+
list.forEach(row => {
|
|
2490
|
+
if (row.isOverflow && row.data) {
|
|
2491
|
+
let end = row.data.length - 1;
|
|
2492
|
+
for (let i = end; i > -1; i--) {
|
|
2493
|
+
char = row.data[i];
|
|
2494
|
+
charRight = char.x + char.width;
|
|
2495
|
+
if (i === end && charRight < right) {
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
else if (charRight < right && char.char !== ' ') {
|
|
2499
|
+
row.data.splice(i + 1);
|
|
2500
|
+
row.width -= char.width;
|
|
2501
|
+
break;
|
|
2502
|
+
}
|
|
2503
|
+
row.width -= char.width;
|
|
2504
|
+
}
|
|
2505
|
+
row.width += ellipsisWidth;
|
|
2506
|
+
row.data.push({ char: textOverflow, x: charRight });
|
|
2507
|
+
if (row.textMode)
|
|
2508
|
+
toTextChar(row);
|
|
2277
2509
|
}
|
|
2278
|
-
|
|
2279
|
-
}
|
|
2280
|
-
row.width += ellipsisWidth;
|
|
2281
|
-
row.data.push({ char: textOverflow, x: charRight });
|
|
2510
|
+
});
|
|
2282
2511
|
}
|
|
2283
2512
|
}
|
|
2513
|
+
function toTextChar(row) {
|
|
2514
|
+
row.text = '';
|
|
2515
|
+
row.data.forEach(char => {
|
|
2516
|
+
row.text += char.char;
|
|
2517
|
+
});
|
|
2518
|
+
row.data = null;
|
|
2519
|
+
}
|
|
2284
2520
|
|
|
2285
2521
|
function decorationText(drawData, style) {
|
|
2286
2522
|
const { fontSize } = style;
|
|
@@ -2294,101 +2530,190 @@ function decorationText(drawData, style) {
|
|
|
2294
2530
|
}
|
|
2295
2531
|
}
|
|
2296
2532
|
|
|
2297
|
-
const
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
if (
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2533
|
+
const { top, right, bottom, left } = Direction4;
|
|
2534
|
+
function getDrawData(content, style) {
|
|
2535
|
+
if (typeof content !== 'string')
|
|
2536
|
+
content = String(content);
|
|
2537
|
+
let x = 0, y = 0;
|
|
2538
|
+
let width = style.__getInput('width') || 0;
|
|
2539
|
+
let height = style.__getInput('height') || 0;
|
|
2540
|
+
const { textDecoration, __font, __padding: padding } = style;
|
|
2541
|
+
if (padding) {
|
|
2542
|
+
if (width) {
|
|
2543
|
+
x = padding[left];
|
|
2544
|
+
width -= (padding[right] + padding[left]);
|
|
2545
|
+
}
|
|
2546
|
+
if (height) {
|
|
2547
|
+
y = padding[top];
|
|
2548
|
+
height -= (padding[top] + padding[bottom]);
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
const drawData = {
|
|
2552
|
+
bounds: { x, y, width, height },
|
|
2553
|
+
rows: [],
|
|
2554
|
+
paraNumber: 0,
|
|
2555
|
+
font: Platform.canvas.font = __font
|
|
2556
|
+
};
|
|
2557
|
+
createRows(drawData, content, style);
|
|
2558
|
+
if (padding)
|
|
2559
|
+
padAutoText(padding, drawData, style, width, height);
|
|
2560
|
+
layoutText(drawData, style);
|
|
2561
|
+
layoutChar(drawData, style, width);
|
|
2562
|
+
if (drawData.overflow)
|
|
2563
|
+
clipText(drawData, style);
|
|
2564
|
+
if (textDecoration !== 'none')
|
|
2565
|
+
decorationText(drawData, style);
|
|
2566
|
+
return drawData;
|
|
2567
|
+
}
|
|
2568
|
+
function padAutoText(padding, drawData, style, width, height) {
|
|
2569
|
+
if (!width) {
|
|
2570
|
+
switch (style.textAlign) {
|
|
2571
|
+
case 'left':
|
|
2572
|
+
offsetText(drawData, 'x', padding[left]);
|
|
2573
|
+
break;
|
|
2574
|
+
case 'right':
|
|
2575
|
+
offsetText(drawData, 'x', -padding[right]);
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
if (!height) {
|
|
2579
|
+
switch (style.verticalAlign) {
|
|
2580
|
+
case 'top':
|
|
2581
|
+
offsetText(drawData, 'y', padding[top]);
|
|
2582
|
+
break;
|
|
2583
|
+
case 'bottom':
|
|
2584
|
+
offsetText(drawData, 'y', -padding[bottom]);
|
|
2316
2585
|
}
|
|
2317
|
-
const drawData = {
|
|
2318
|
-
bounds: { x, y, width, height },
|
|
2319
|
-
rows: [],
|
|
2320
|
-
paraNumber: 0,
|
|
2321
|
-
font: Platform.canvas.font = __font
|
|
2322
|
-
};
|
|
2323
|
-
createRows(drawData, content, style);
|
|
2324
|
-
layoutText(drawData, style);
|
|
2325
|
-
layoutChar(drawData, style, width);
|
|
2326
|
-
if (drawData.overflow)
|
|
2327
|
-
clipText(drawData, textOverflow);
|
|
2328
|
-
if (textDecoration !== 'none')
|
|
2329
|
-
decorationText(drawData, style);
|
|
2330
|
-
return drawData;
|
|
2331
2586
|
}
|
|
2587
|
+
}
|
|
2588
|
+
function offsetText(drawData, attrName, value) {
|
|
2589
|
+
const { bounds, rows } = drawData;
|
|
2590
|
+
bounds[attrName] += value;
|
|
2591
|
+
for (let i = 0; i < rows.length; i++)
|
|
2592
|
+
rows[i][attrName] += value;
|
|
2593
|
+
}
|
|
2594
|
+
|
|
2595
|
+
const TextConvertModule = {
|
|
2596
|
+
getDrawData
|
|
2332
2597
|
};
|
|
2333
2598
|
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2599
|
+
function string(color, opacity) {
|
|
2600
|
+
if (typeof color === 'string')
|
|
2601
|
+
return color;
|
|
2602
|
+
let a = color.a === undefined ? 1 : color.a;
|
|
2603
|
+
if (opacity)
|
|
2604
|
+
a *= opacity;
|
|
2605
|
+
const rgb = color.r + ',' + color.g + ',' + color.b;
|
|
2606
|
+
return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
const ColorConvertModule = {
|
|
2610
|
+
string
|
|
2344
2611
|
};
|
|
2345
2612
|
|
|
2346
|
-
const
|
|
2613
|
+
const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
|
|
2614
|
+
function getTrimBounds(canvas) {
|
|
2615
|
+
const { width, height } = canvas.view;
|
|
2616
|
+
const { data } = canvas.context.getImageData(0, 0, width, height);
|
|
2617
|
+
let x, y, pointBounds, index = 0;
|
|
2618
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
2619
|
+
if (data[i + 3] !== 0) {
|
|
2620
|
+
x = index % width;
|
|
2621
|
+
y = (index - x) / width;
|
|
2622
|
+
pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
|
|
2623
|
+
}
|
|
2624
|
+
index++;
|
|
2625
|
+
}
|
|
2626
|
+
const bounds = new Bounds();
|
|
2627
|
+
toBounds(pointBounds, bounds);
|
|
2628
|
+
return bounds.scale(1 / canvas.pixelRatio).ceil();
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
const ExportModule = {
|
|
2347
2632
|
export(leaf, filename, options) {
|
|
2633
|
+
this.running = true;
|
|
2348
2634
|
return addTask((success) => new Promise((resolve) => {
|
|
2635
|
+
const over = (result) => {
|
|
2636
|
+
success(result);
|
|
2637
|
+
resolve();
|
|
2638
|
+
this.running = false;
|
|
2639
|
+
};
|
|
2349
2640
|
const { leafer } = leaf;
|
|
2350
2641
|
if (leafer) {
|
|
2351
2642
|
leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
|
|
2352
|
-
|
|
2353
|
-
let
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2643
|
+
options = FileHelper.getExportOptions(options);
|
|
2644
|
+
let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
|
|
2645
|
+
const { worldTransform, isLeafer, isFrame } = leaf;
|
|
2646
|
+
const { slice, trim, onCanvas } = options;
|
|
2647
|
+
const scale = options.scale || 1;
|
|
2648
|
+
const pixelRatio = options.pixelRatio || 1;
|
|
2649
|
+
const screenshot = options.screenshot || leaf.isApp;
|
|
2650
|
+
const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
|
|
2651
|
+
const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
|
|
2652
|
+
if (screenshot) {
|
|
2653
|
+
renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
|
|
2359
2654
|
}
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2655
|
+
else {
|
|
2656
|
+
let relative = options.relative || (isLeafer ? 'inner' : 'local');
|
|
2657
|
+
scaleX = worldTransform.scaleX;
|
|
2658
|
+
scaleY = worldTransform.scaleY;
|
|
2659
|
+
switch (relative) {
|
|
2660
|
+
case 'inner':
|
|
2661
|
+
matrix.set(worldTransform);
|
|
2662
|
+
break;
|
|
2663
|
+
case 'local':
|
|
2664
|
+
matrix.set(worldTransform).divide(leaf.localTransform);
|
|
2665
|
+
scaleX /= leaf.scaleX;
|
|
2666
|
+
scaleY /= leaf.scaleY;
|
|
2667
|
+
break;
|
|
2668
|
+
case 'world':
|
|
2669
|
+
scaleX = 1;
|
|
2670
|
+
scaleY = 1;
|
|
2671
|
+
break;
|
|
2672
|
+
case 'page':
|
|
2673
|
+
relative = leaf.leafer;
|
|
2674
|
+
default:
|
|
2675
|
+
matrix.set(worldTransform).divide(leaf.getTransform(relative));
|
|
2676
|
+
const l = relative.worldTransform;
|
|
2677
|
+
scaleX /= scaleX / l.scaleX;
|
|
2678
|
+
scaleY /= scaleY / l.scaleY;
|
|
2679
|
+
}
|
|
2680
|
+
renderBounds = leaf.getBounds('render', relative);
|
|
2372
2681
|
}
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2682
|
+
const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
|
|
2683
|
+
let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio });
|
|
2684
|
+
const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
|
|
2685
|
+
if (slice) {
|
|
2686
|
+
leaf = leafer;
|
|
2687
|
+
renderOptions.bounds = canvas.bounds;
|
|
2376
2688
|
}
|
|
2377
|
-
|
|
2378
|
-
|
|
2689
|
+
canvas.save();
|
|
2690
|
+
if (isFrame && fill !== undefined) {
|
|
2691
|
+
const oldFill = leaf.get('fill');
|
|
2692
|
+
leaf.fill = '';
|
|
2693
|
+
leaf.__render(canvas, renderOptions);
|
|
2694
|
+
leaf.fill = oldFill;
|
|
2379
2695
|
}
|
|
2380
2696
|
else {
|
|
2381
|
-
|
|
2697
|
+
leaf.__render(canvas, renderOptions);
|
|
2382
2698
|
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
canvas
|
|
2699
|
+
canvas.restore();
|
|
2700
|
+
if (trim) {
|
|
2701
|
+
trimBounds = getTrimBounds(canvas);
|
|
2702
|
+
const old = canvas, { width, height } = trimBounds;
|
|
2703
|
+
const config = { x: 0, y: 0, width, height, pixelRatio };
|
|
2704
|
+
canvas = Creator.canvas(config);
|
|
2705
|
+
canvas.copyWorld(old, trimBounds, config);
|
|
2706
|
+
}
|
|
2707
|
+
if (needFill)
|
|
2708
|
+
canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
|
|
2709
|
+
if (onCanvas)
|
|
2710
|
+
onCanvas(canvas);
|
|
2711
|
+
const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
|
|
2712
|
+
over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
|
|
2387
2713
|
}));
|
|
2388
2714
|
}
|
|
2389
2715
|
else {
|
|
2390
|
-
|
|
2391
|
-
resolve();
|
|
2716
|
+
over({ data: false });
|
|
2392
2717
|
}
|
|
2393
2718
|
}));
|
|
2394
2719
|
}
|
|
@@ -2402,12 +2727,57 @@ function addTask(task) {
|
|
|
2402
2727
|
});
|
|
2403
2728
|
}
|
|
2404
2729
|
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2730
|
+
const canvas = LeaferCanvasBase.prototype;
|
|
2731
|
+
const debug = Debug.get('@leafer-ui/export');
|
|
2732
|
+
canvas.export = function (filename, options) {
|
|
2733
|
+
const { quality, blob } = FileHelper.getExportOptions(options);
|
|
2734
|
+
if (filename.includes('.')) {
|
|
2735
|
+
return this.saveAs(filename, quality);
|
|
2736
|
+
}
|
|
2737
|
+
else if (blob) {
|
|
2738
|
+
return this.toBlob(filename, quality);
|
|
2739
|
+
}
|
|
2740
|
+
else {
|
|
2741
|
+
return this.toDataURL(filename, quality);
|
|
2742
|
+
}
|
|
2743
|
+
};
|
|
2744
|
+
canvas.toBlob = function (type, quality) {
|
|
2745
|
+
return new Promise((resolve) => {
|
|
2746
|
+
Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
|
|
2747
|
+
resolve(blob);
|
|
2748
|
+
}).catch((e) => {
|
|
2749
|
+
debug.error(e);
|
|
2750
|
+
resolve(null);
|
|
2751
|
+
});
|
|
2752
|
+
});
|
|
2753
|
+
};
|
|
2754
|
+
canvas.toDataURL = function (type, quality) {
|
|
2755
|
+
return Platform.origin.canvasToDataURL(this.view, type, quality);
|
|
2756
|
+
};
|
|
2757
|
+
canvas.saveAs = function (filename, quality) {
|
|
2758
|
+
return new Promise((resolve) => {
|
|
2759
|
+
Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
|
|
2760
|
+
resolve(true);
|
|
2761
|
+
}).catch((e) => {
|
|
2762
|
+
debug.error(e);
|
|
2763
|
+
resolve(false);
|
|
2764
|
+
});
|
|
2765
|
+
});
|
|
2766
|
+
};
|
|
2767
|
+
|
|
2768
|
+
Object.assign(TextConvert, TextConvertModule);
|
|
2769
|
+
Object.assign(ColorConvert, ColorConvertModule);
|
|
2770
|
+
Object.assign(Paint, PaintModule);
|
|
2771
|
+
Object.assign(PaintImage, PaintImageModule);
|
|
2772
|
+
Object.assign(PaintGradient, PaintGradientModule);
|
|
2773
|
+
Object.assign(Effect, EffectModule);
|
|
2774
|
+
Object.assign(Export, ExportModule);
|
|
2410
2775
|
|
|
2776
|
+
Object.assign(Creator, {
|
|
2777
|
+
interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
|
|
2778
|
+
hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
|
|
2779
|
+
hitCanvasManager: () => new HitCanvasManager()
|
|
2780
|
+
});
|
|
2411
2781
|
try {
|
|
2412
2782
|
useCanvas('wx', wx);
|
|
2413
2783
|
}
|
|
@@ -2417,14 +2787,9 @@ LeaferCanvas.prototype.__createContext = function () {
|
|
|
2417
2787
|
if (this.viewSelect) {
|
|
2418
2788
|
const offscreenView = Platform$1.origin.createCanvas(1, 1);
|
|
2419
2789
|
const context = this.view.getContext('2d');
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
catch (e) {
|
|
2424
|
-
this.testView = this.view;
|
|
2425
|
-
this.testContext = context;
|
|
2426
|
-
this.view = offscreenView;
|
|
2427
|
-
}
|
|
2790
|
+
this.testView = this.view;
|
|
2791
|
+
this.testContext = context;
|
|
2792
|
+
this.view = offscreenView;
|
|
2428
2793
|
}
|
|
2429
2794
|
this.context = this.view.getContext('2d');
|
|
2430
2795
|
this.__bindContext();
|