@leafer-draw/worker 1.8.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,17 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, BoundsHelper, getMatrixData, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4 } from '@leafer/core';
2
- export * from '@leafer/core';
3
- export { LeaferImage } from '@leafer/core';
4
- import { PaintImage, Paint, ColorConvert, PaintGradient, Export, Group, TextConvert, Effect } from '@leafer-ui/draw';
5
- export * from '@leafer-ui/draw';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, FileHelper, Creator, LeaferImage, defineKey, LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, LeafBoundsHelper, Bounds, isArray, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, ResizeEvent, isObject, BoundsHelper, Matrix, isUndefined, isString, getMatrixData, MatrixHelper, MathHelper, AlignHelper, PointHelper, ImageEvent, AroundHelper, Direction4, isNumber } from "@leafer/core";
2
+
3
+ export * from "@leafer/core";
4
+
5
+ export { LeaferImage } from "@leafer/core";
6
+
7
+ import { PaintImage, Paint, ColorConvert, PaintGradient, Export, Group, TextConvert, Effect } from "@leafer-ui/draw";
8
+
9
+ export * from "@leafer-ui/draw";
6
10
 
7
11
  class LeaferCanvas extends LeaferCanvasBase {
8
- get allowBackgroundColor() { return true; }
12
+ get allowBackgroundColor() {
13
+ return true;
14
+ }
9
15
  init() {
10
16
  this.__createView();
11
17
  this.__createContext();
@@ -15,7 +21,7 @@ class LeaferCanvas extends LeaferCanvasBase {
15
21
  this.view = Platform.origin.createCanvas(1, 1);
16
22
  }
17
23
  updateViewSize() {
18
- const { width, height, pixelRatio } = this;
24
+ const {width: width, height: height, pixelRatio: pixelRatio} = this;
19
25
  this.view.width = Math.ceil(width * pixelRatio);
20
26
  this.view.height = Math.ceil(height * pixelRatio);
21
27
  this.clientBounds = this.bounds;
@@ -23,35 +29,44 @@ class LeaferCanvas extends LeaferCanvasBase {
23
29
  }
24
30
 
25
31
  canvasPatch(OffscreenCanvasRenderingContext2D.prototype);
32
+
26
33
  canvasPatch(Path2D.prototype);
27
34
 
28
- const { mineType } = FileHelper;
35
+ const {mineType: mineType} = FileHelper;
36
+
29
37
  Object.assign(Creator, {
30
38
  canvas: (options, manager) => new LeaferCanvas(options, manager),
31
- image: (options) => new LeaferImage(options)
39
+ image: options => new LeaferImage(options)
32
40
  });
41
+
33
42
  function useCanvas(_canvasType, _power) {
34
43
  Platform.origin = {
35
44
  createCanvas: (width, height) => new OffscreenCanvas(width, height),
36
- canvasToDataURL: (canvas, type, quality) => {
37
- return new Promise((resolve, reject) => {
38
- canvas.convertToBlob({ type: mineType(type), quality }).then((blob) => {
39
- var reader = new FileReader();
40
- reader.onload = (e) => resolve(e.target.result);
41
- reader.onerror = (e) => reject(e);
42
- reader.readAsDataURL(blob);
43
- }).catch((e) => {
44
- reject(e);
45
- });
45
+ canvasToDataURL: (canvas, type, quality) => new Promise((resolve, reject) => {
46
+ canvas.convertToBlob({
47
+ type: mineType(type),
48
+ quality: quality
49
+ }).then(blob => {
50
+ var reader = new FileReader;
51
+ reader.onload = e => resolve(e.target.result);
52
+ reader.onerror = e => reject(e);
53
+ reader.readAsDataURL(blob);
54
+ }).catch(e => {
55
+ reject(e);
46
56
  });
57
+ }),
58
+ canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({
59
+ type: mineType(type),
60
+ quality: quality
61
+ }),
62
+ canvasSaveAs: (_canvas, _filename, _quality) => new Promise(resolve => resolve()),
63
+ download(_url, _filename) {
64
+ return undefined;
47
65
  },
48
- canvasToBolb: (canvas, type, quality) => canvas.convertToBlob({ type: mineType(type), quality }),
49
- canvasSaveAs: (_canvas, _filename, _quality) => new Promise((resolve) => resolve()),
50
- download(_url, _filename) { return undefined; },
51
66
  loadImage(src) {
52
67
  return new Promise((resolve, reject) => {
53
- let req = new XMLHttpRequest();
54
- req.open('GET', Platform.image.getRealURL(src), true);
68
+ let req = new XMLHttpRequest;
69
+ req.open("GET", Platform.image.getRealURL(src), true);
55
70
  req.responseType = "blob";
56
71
  req.onload = () => {
57
72
  createImageBitmap(req.response).then(img => {
@@ -60,7 +75,7 @@ function useCanvas(_canvasType, _power) {
60
75
  reject(e);
61
76
  });
62
77
  };
63
- req.onerror = (e) => reject(e);
78
+ req.onerror = e => reject(e);
64
79
  req.send();
65
80
  });
66
81
  }
@@ -68,55 +83,66 @@ function useCanvas(_canvasType, _power) {
68
83
  Platform.canvas = Creator.canvas();
69
84
  Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
70
85
  }
71
- Platform.name = 'web';
86
+
87
+ Platform.name = "web";
88
+
72
89
  Platform.isWorker = true;
90
+
73
91
  Platform.backgrounder = true;
74
- Platform.requestRender = function (render) { requestAnimationFrame(render); };
75
- defineKey(Platform, 'devicePixelRatio', { get() { return 1; } });
76
- const { userAgent } = navigator;
92
+
93
+ Platform.requestRender = function(render) {
94
+ requestAnimationFrame(render);
95
+ };
96
+
97
+ defineKey(Platform, "devicePixelRatio", {
98
+ get() {
99
+ return 1;
100
+ }
101
+ });
102
+
103
+ const {userAgent: userAgent} = navigator;
104
+
77
105
  if (userAgent.indexOf("Firefox") > -1) {
78
106
  Platform.conicGradientRotate90 = true;
79
107
  Platform.intWheelDeltaY = true;
80
- }
81
- else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
108
+ } else if (/iPhone|iPad|iPod/.test(navigator.userAgent) || /Macintosh/.test(navigator.userAgent) && /Version\/[\d.]+.*Safari/.test(navigator.userAgent)) {
82
109
  Platform.fullImageShadow = true;
83
110
  }
84
- if (userAgent.indexOf('Windows') > -1) {
85
- Platform.os = 'Windows';
111
+
112
+ if (userAgent.indexOf("Windows") > -1) {
113
+ Platform.os = "Windows";
86
114
  Platform.intWheelDeltaY = true;
87
- }
88
- else if (userAgent.indexOf('Mac') > -1) {
89
- Platform.os = 'Mac';
90
- }
91
- else if (userAgent.indexOf('Linux') > -1) {
92
- Platform.os = 'Linux';
115
+ } else if (userAgent.indexOf("Mac") > -1) {
116
+ Platform.os = "Mac";
117
+ } else if (userAgent.indexOf("Linux") > -1) {
118
+ Platform.os = "Linux";
93
119
  }
94
120
 
95
121
  class Watcher {
96
- get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
122
+ get childrenChanged() {
123
+ return this.hasAdd || this.hasRemove || this.hasVisible;
124
+ }
97
125
  get updatedList() {
98
126
  if (this.hasRemove) {
99
- const updatedList = new LeafList();
100
- this.__updatedList.list.forEach(item => { if (item.leafer)
101
- updatedList.add(item); });
127
+ const updatedList = new LeafList;
128
+ this.__updatedList.list.forEach(item => {
129
+ if (item.leafer) updatedList.add(item);
130
+ });
102
131
  return updatedList;
103
- }
104
- else {
132
+ } else {
105
133
  return this.__updatedList;
106
134
  }
107
135
  }
108
136
  constructor(target, userConfig) {
109
137
  this.totalTimes = 0;
110
138
  this.config = {};
111
- this.__updatedList = new LeafList();
139
+ this.__updatedList = new LeafList;
112
140
  this.target = target;
113
- if (userConfig)
114
- this.config = DataHelper.default(userConfig, this.config);
141
+ if (userConfig) this.config = DataHelper.default(userConfig, this.config);
115
142
  this.__listenEvents();
116
143
  }
117
144
  start() {
118
- if (this.disabled)
119
- return;
145
+ if (this.disabled) return;
120
146
  this.running = true;
121
147
  }
122
148
  stop() {
@@ -129,8 +155,7 @@ class Watcher {
129
155
  }
130
156
  update() {
131
157
  this.changed = true;
132
- if (this.running)
133
- this.target.emit(RenderEvent.REQUEST);
158
+ if (this.running) this.target.emit(RenderEvent.REQUEST);
134
159
  }
135
160
  __onAttrChange(event) {
136
161
  this.__updatedList.add(event.target);
@@ -140,8 +165,7 @@ class Watcher {
140
165
  if (event.type === ChildEvent.ADD) {
141
166
  this.hasAdd = true;
142
167
  this.__pushChild(event.child);
143
- }
144
- else {
168
+ } else {
145
169
  this.hasRemove = true;
146
170
  this.__updatedList.add(event.parent);
147
171
  }
@@ -149,28 +173,22 @@ class Watcher {
149
173
  }
150
174
  __pushChild(child) {
151
175
  this.__updatedList.add(child);
152
- if (child.isBranch)
153
- this.__loopChildren(child);
176
+ if (child.isBranch) this.__loopChildren(child);
154
177
  }
155
178
  __loopChildren(parent) {
156
- const { children } = parent;
157
- for (let i = 0, len = children.length; i < len; i++)
158
- this.__pushChild(children[i]);
179
+ const {children: children} = parent;
180
+ for (let i = 0, len = children.length; i < len; i++) this.__pushChild(children[i]);
159
181
  }
160
182
  __onRquestData() {
161
- this.target.emitEvent(new WatchEvent(WatchEvent.DATA, { updatedList: this.updatedList }));
162
- this.__updatedList = new LeafList();
183
+ this.target.emitEvent(new WatchEvent(WatchEvent.DATA, {
184
+ updatedList: this.updatedList
185
+ }));
186
+ this.__updatedList = new LeafList;
163
187
  this.totalTimes++;
164
188
  this.changed = this.hasVisible = this.hasRemove = this.hasAdd = false;
165
189
  }
166
190
  __listenEvents() {
167
- this.__eventIds = [
168
- this.target.on_([
169
- [PropertyEvent.CHANGE, this.__onAttrChange, this],
170
- [[ChildEvent.ADD, ChildEvent.REMOVE], this.__onChildEvent, this],
171
- [WatchEvent.REQUEST, this.__onRquestData, this]
172
- ])
173
- ];
191
+ this.__eventIds = [ this.target.on_([ [ PropertyEvent.CHANGE, this.__onAttrChange, this ], [ [ ChildEvent.ADD, ChildEvent.REMOVE ], this.__onChildEvent, this ], [ WatchEvent.REQUEST, this.__onRquestData, this ] ]) ];
174
192
  }
175
193
  __removeListenEvents() {
176
194
  this.target.off_(this.__eventIds);
@@ -184,8 +202,10 @@ class Watcher {
184
202
  }
185
203
  }
186
204
 
187
- const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange } = LeafHelper;
188
- const { pushAllChildBranch, pushAllParent } = BranchHelper;
205
+ const {updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateChange: updateOneChange} = LeafHelper;
206
+
207
+ const {pushAllChildBranch: pushAllChildBranch, pushAllParent: pushAllParent} = BranchHelper;
208
+
189
209
  function updateMatrix(updateList, levelList) {
190
210
  let layout;
191
211
  updateList.list.forEach(leaf => {
@@ -194,19 +214,17 @@ function updateMatrix(updateList, levelList) {
194
214
  if (layout.matrixChanged) {
195
215
  updateAllMatrix$1(leaf, true);
196
216
  levelList.add(leaf);
197
- if (leaf.isBranch)
198
- pushAllChildBranch(leaf, levelList);
217
+ if (leaf.isBranch) pushAllChildBranch(leaf, levelList);
199
218
  pushAllParent(leaf, levelList);
200
- }
201
- else if (layout.boundsChanged) {
219
+ } else if (layout.boundsChanged) {
202
220
  levelList.add(leaf);
203
- if (leaf.isBranch)
204
- leaf.__tempNumber = 0;
221
+ if (leaf.isBranch) leaf.__tempNumber = 0;
205
222
  pushAllParent(leaf, levelList);
206
223
  }
207
224
  }
208
225
  });
209
226
  }
227
+
210
228
  function updateBounds(boundsList) {
211
229
  let list, branch, children;
212
230
  boundsList.sort(true);
@@ -226,18 +244,19 @@ function updateBounds(boundsList) {
226
244
  }
227
245
  });
228
246
  }
247
+
229
248
  function updateChange(updateList) {
230
249
  updateList.list.forEach(updateOneChange);
231
250
  }
232
251
 
233
- const { worldBounds } = LeafBoundsHelper;
252
+ const {worldBounds: worldBounds} = LeafBoundsHelper;
253
+
234
254
  class LayoutBlockData {
235
255
  constructor(list) {
236
- this.updatedBounds = new Bounds();
237
- this.beforeBounds = new Bounds();
238
- this.afterBounds = new Bounds();
239
- if (list instanceof Array)
240
- list = new LeafList(list);
256
+ this.updatedBounds = new Bounds;
257
+ this.beforeBounds = new Bounds;
258
+ this.afterBounds = new Bounds;
259
+ if (isArray(list)) list = new LeafList(list);
241
260
  this.updatedList = list;
242
261
  }
243
262
  setBefore() {
@@ -245,7 +264,7 @@ class LayoutBlockData {
245
264
  }
246
265
  setAfter() {
247
266
  this.afterBounds.setListWithFn(this.updatedList.list, worldBounds);
248
- this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
267
+ this.updatedBounds.setList([ this.beforeBounds, this.afterBounds ]);
249
268
  }
250
269
  merge(data) {
251
270
  this.updatedList.addList(data.updatedList.list);
@@ -258,21 +277,21 @@ class LayoutBlockData {
258
277
  }
259
278
  }
260
279
 
261
- const { updateAllMatrix, updateAllChange } = LeafHelper;
262
- const debug$1 = Debug.get('Layouter');
280
+ const {updateAllMatrix: updateAllMatrix, updateAllChange: updateAllChange} = LeafHelper;
281
+
282
+ const debug$1 = Debug.get("Layouter");
283
+
263
284
  class Layouter {
264
285
  constructor(target, userConfig) {
265
286
  this.totalTimes = 0;
266
287
  this.config = {};
267
- this.__levelList = new LeafLevelList();
288
+ this.__levelList = new LeafLevelList;
268
289
  this.target = target;
269
- if (userConfig)
270
- this.config = DataHelper.default(userConfig, this.config);
290
+ if (userConfig) this.config = DataHelper.default(userConfig, this.config);
271
291
  this.__listenEvents();
272
292
  }
273
293
  start() {
274
- if (this.disabled)
275
- return;
294
+ if (this.disabled) return;
276
295
  this.running = true;
277
296
  }
278
297
  stop() {
@@ -284,16 +303,14 @@ class Layouter {
284
303
  this.disabled = true;
285
304
  }
286
305
  layout() {
287
- if (this.layouting || !this.running)
288
- return;
289
- const { target } = this;
306
+ if (this.layouting || !this.running) return;
307
+ const {target: target} = this;
290
308
  this.times = 0;
291
309
  try {
292
310
  target.emit(LayoutEvent.START);
293
311
  this.layoutOnce();
294
312
  target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
295
- }
296
- catch (e) {
313
+ } catch (e) {
297
314
  debug$1.error(e);
298
315
  }
299
316
  this.layoutedBlocks = null;
@@ -301,24 +318,20 @@ class Layouter {
301
318
  layoutAgain() {
302
319
  if (this.layouting) {
303
320
  this.waitAgain = true;
304
- }
305
- else {
321
+ } else {
306
322
  this.layoutOnce();
307
323
  }
308
324
  }
309
325
  layoutOnce() {
310
- if (this.layouting)
311
- return debug$1.warn('layouting');
312
- if (this.times > 3)
313
- return debug$1.warn('layout max times');
326
+ if (this.layouting) return debug$1.warn("layouting");
327
+ if (this.times > 3) return debug$1.warn("layout max times");
314
328
  this.times++;
315
329
  this.totalTimes++;
316
330
  this.layouting = true;
317
331
  this.target.emit(WatchEvent.REQUEST);
318
332
  if (this.totalTimes > 1) {
319
333
  this.partLayout();
320
- }
321
- else {
334
+ } else {
322
335
  this.fullLayout();
323
336
  }
324
337
  this.layouting = false;
@@ -329,11 +342,10 @@ class Layouter {
329
342
  }
330
343
  partLayout() {
331
344
  var _a;
332
- if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length))
333
- return;
334
- const t = Run.start('PartLayout');
335
- const { target, __updatedList: updateList } = this;
336
- const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
345
+ if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length)) return;
346
+ const t = Run.start("PartLayout");
347
+ const {target: target, __updatedList: updateList} = this;
348
+ const {BEFORE: BEFORE, LAYOUT: LAYOUT, AFTER: AFTER} = LayoutEvent;
337
349
  const blocks = this.getBlocks(updateList);
338
350
  blocks.forEach(item => item.setBefore());
339
351
  target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
@@ -342,8 +354,7 @@ class Layouter {
342
354
  updateMatrix(updateList, this.__levelList);
343
355
  updateBounds(this.__levelList);
344
356
  updateChange(updateList);
345
- if (this.extraBlock)
346
- blocks.push(this.extraBlock);
357
+ if (this.extraBlock) blocks.push(this.extraBlock);
347
358
  blocks.forEach(item => item.setAfter());
348
359
  target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
349
360
  target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
@@ -353,13 +364,15 @@ class Layouter {
353
364
  Run.end(t);
354
365
  }
355
366
  fullLayout() {
356
- const t = Run.start('FullLayout');
357
- const { target } = this;
358
- const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
367
+ const t = Run.start("FullLayout");
368
+ const {target: target} = this;
369
+ const {BEFORE: BEFORE, LAYOUT: LAYOUT, AFTER: AFTER} = LayoutEvent;
359
370
  const blocks = this.getBlocks(new LeafList(target));
360
371
  target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
361
372
  Layouter.fullLayout(target);
362
- blocks.forEach(item => { item.setAfter(); });
373
+ blocks.forEach(item => {
374
+ item.setAfter();
375
+ });
363
376
  target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
364
377
  target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
365
378
  this.addBlocks(blocks);
@@ -367,15 +380,12 @@ class Layouter {
367
380
  }
368
381
  static fullLayout(target) {
369
382
  updateAllMatrix(target, true);
370
- if (target.isBranch)
371
- BranchHelper.updateBounds(target);
372
- else
373
- LeafHelper.updateBounds(target);
383
+ if (target.isBranch) BranchHelper.updateBounds(target); else LeafHelper.updateBounds(target);
374
384
  updateAllChange(target);
375
385
  }
376
386
  addExtra(leaf) {
377
387
  if (!this.__updatedList.has(leaf)) {
378
- const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
388
+ const {updatedList: updatedList, beforeBounds: beforeBounds} = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
379
389
  updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
380
390
  updatedList.add(leaf);
381
391
  }
@@ -384,7 +394,7 @@ class Layouter {
384
394
  return new LayoutBlockData(data);
385
395
  }
386
396
  getBlocks(list) {
387
- return [this.createBlock(list)];
397
+ return [ this.createBlock(list) ];
388
398
  }
389
399
  addBlocks(current) {
390
400
  this.layoutedBlocks ? this.layoutedBlocks.push(...current) : this.layoutedBlocks = current;
@@ -393,13 +403,7 @@ class Layouter {
393
403
  this.__updatedList = event.data.updatedList;
394
404
  }
395
405
  __listenEvents() {
396
- this.__eventIds = [
397
- this.target.on_([
398
- [LayoutEvent.REQUEST, this.layout, this],
399
- [LayoutEvent.AGAIN, this.layoutAgain, this],
400
- [WatchEvent.DATA, this.__onReceiveWatchData, this]
401
- ])
402
- ];
406
+ this.__eventIds = [ this.target.on_([ [ LayoutEvent.REQUEST, this.layout, this ], [ LayoutEvent.AGAIN, this.layoutAgain, this ], [ WatchEvent.DATA, this.__onReceiveWatchData, this ] ]) ];
403
407
  }
404
408
  __removeListenEvents() {
405
409
  this.target.off_(this.__eventIds);
@@ -413,9 +417,12 @@ class Layouter {
413
417
  }
414
418
  }
415
419
 
416
- const debug = Debug.get('Renderer');
420
+ const debug = Debug.get("Renderer");
421
+
417
422
  class Renderer {
418
- get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
423
+ get needFill() {
424
+ return !!(!this.canvas.allowBackgroundColor && this.config.fill);
425
+ }
419
426
  constructor(target, canvas, userConfig) {
420
427
  this.FPS = 60;
421
428
  this.totalTimes = 0;
@@ -426,8 +433,7 @@ class Renderer {
426
433
  };
427
434
  this.target = target;
428
435
  this.canvas = canvas;
429
- if (userConfig)
430
- this.config = DataHelper.default(userConfig, this.config);
436
+ if (userConfig) this.config = DataHelper.default(userConfig, this.config);
431
437
  this.__listenEvents();
432
438
  }
433
439
  start() {
@@ -438,8 +444,7 @@ class Renderer {
438
444
  this.running = false;
439
445
  }
440
446
  update(change = true) {
441
- if (!this.changed)
442
- this.changed = change;
447
+ if (!this.changed) this.changed = change;
443
448
  this.__requestRender();
444
449
  }
445
450
  requestLayout() {
@@ -447,7 +452,7 @@ class Renderer {
447
452
  }
448
453
  checkRender() {
449
454
  if (this.running) {
450
- const { target } = this;
455
+ const {target: target} = this;
451
456
  if (target.isApp) {
452
457
  target.emit(RenderEvent.CHILD_START, target);
453
458
  target.children.forEach(leafer => {
@@ -456,54 +461,47 @@ class Renderer {
456
461
  });
457
462
  target.emit(RenderEvent.CHILD_END, target);
458
463
  }
459
- if (this.changed && this.canvas.view)
460
- this.render();
464
+ if (this.changed && this.canvas.view) this.render();
461
465
  this.target.emit(RenderEvent.NEXT);
462
466
  }
463
467
  }
464
468
  render(callback) {
465
- if (!(this.running && this.canvas.view))
466
- return this.update();
467
- const { target } = this;
469
+ if (!(this.running && this.canvas.view)) return this.update();
470
+ const {target: target} = this;
468
471
  this.times = 0;
469
- this.totalBounds = new Bounds();
470
- debug.log(target.innerName, '--->');
472
+ this.totalBounds = new Bounds;
473
+ debug.log(target.innerName, "---\x3e");
471
474
  try {
472
475
  this.emitRender(RenderEvent.START);
473
476
  this.renderOnce(callback);
474
477
  this.emitRender(RenderEvent.END, this.totalBounds);
475
478
  ImageManager.clearRecycled();
476
- }
477
- catch (e) {
479
+ } catch (e) {
478
480
  this.rendering = false;
479
481
  debug.error(e);
480
482
  }
481
- debug.log('-------------|');
483
+ debug.log("-------------|");
482
484
  }
483
485
  renderAgain() {
484
486
  if (this.rendering) {
485
487
  this.waitAgain = true;
486
- }
487
- else {
488
+ } else {
488
489
  this.renderOnce();
489
490
  }
490
491
  }
491
492
  renderOnce(callback) {
492
- if (this.rendering)
493
- return debug.warn('rendering');
494
- if (this.times > 3)
495
- return debug.warn('render max times');
493
+ if (this.rendering) return debug.warn("rendering");
494
+ if (this.times > 3) return debug.warn("render max times");
496
495
  this.times++;
497
496
  this.totalTimes++;
498
497
  this.rendering = true;
499
498
  this.changed = false;
500
- this.renderBounds = new Bounds();
499
+ this.renderBounds = new Bounds;
501
500
  this.renderOptions = {};
502
501
  if (callback) {
503
502
  this.emitRender(RenderEvent.BEFORE);
504
503
  callback();
505
- }
506
- else {
504
+ } else {
507
505
  this.requestLayout();
508
506
  if (this.ignore) {
509
507
  this.ignore = this.rendering = false;
@@ -512,8 +510,7 @@ class Renderer {
512
510
  this.emitRender(RenderEvent.BEFORE);
513
511
  if (this.config.usePartRender && this.totalTimes > 1) {
514
512
  this.partRender();
515
- }
516
- else {
513
+ } else {
517
514
  this.fullRender();
518
515
  }
519
516
  }
@@ -527,16 +524,16 @@ class Renderer {
527
524
  }
528
525
  }
529
526
  partRender() {
530
- const { canvas, updateBlocks: list } = this;
531
- if (!list)
532
- return;
527
+ const {canvas: canvas, updateBlocks: list} = this;
528
+ if (!list) return;
533
529
  this.mergeBlocks();
534
- list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
535
- this.clipRender(block); });
530
+ list.forEach(block => {
531
+ if (canvas.bounds.hit(block) && !block.isEmpty()) this.clipRender(block);
532
+ });
536
533
  }
537
534
  clipRender(block) {
538
- const t = Run.start('PartRender');
539
- const { canvas } = this, bounds = block.getIntersect(canvas.bounds), realBounds = new Bounds(bounds);
535
+ const t = Run.start("PartRender");
536
+ const {canvas: canvas} = this, bounds = block.getIntersect(canvas.bounds), realBounds = new Bounds(bounds);
540
537
  canvas.save();
541
538
  bounds.spread(Renderer.clipSpread).ceil();
542
539
  canvas.clearWorld(bounds, true);
@@ -546,8 +543,8 @@ class Renderer {
546
543
  Run.end(t);
547
544
  }
548
545
  fullRender() {
549
- const t = Run.start('FullRender');
550
- const { canvas } = this;
546
+ const t = Run.start("FullRender");
547
+ const {canvas: canvas} = this;
551
548
  canvas.save();
552
549
  canvas.clear();
553
550
  this.__render(canvas.bounds);
@@ -555,11 +552,14 @@ class Renderer {
555
552
  Run.end(t);
556
553
  }
557
554
  __render(bounds, realBounds) {
558
- const { canvas } = this, includes = bounds.includes(this.target.__world), options = includes ? { includes } : { bounds, includes };
559
- if (this.needFill)
560
- canvas.fillWorld(bounds, this.config.fill);
561
- if (Debug.showRepaint)
562
- Debug.drawRepaint(canvas, bounds);
555
+ const {canvas: canvas} = this, includes = bounds.includes(this.target.__world), options = includes ? {
556
+ includes: includes
557
+ } : {
558
+ bounds: bounds,
559
+ includes: includes
560
+ };
561
+ if (this.needFill) canvas.fillWorld(bounds, this.config.fill);
562
+ if (Debug.showRepaint) Debug.drawRepaint(canvas, bounds);
563
563
  this.target.__render(canvas, options);
564
564
  this.renderBounds = realBounds = realBounds || bounds;
565
565
  this.renderOptions = options;
@@ -567,14 +567,13 @@ class Renderer {
567
567
  canvas.updateRender(realBounds);
568
568
  }
569
569
  addBlock(block) {
570
- if (!this.updateBlocks)
571
- this.updateBlocks = [];
570
+ if (!this.updateBlocks) this.updateBlocks = [];
572
571
  this.updateBlocks.push(block);
573
572
  }
574
573
  mergeBlocks() {
575
- const { updateBlocks: list } = this;
574
+ const {updateBlocks: list} = this;
576
575
  if (list) {
577
- const bounds = new Bounds();
576
+ const bounds = new Bounds;
578
577
  bounds.setList(list);
579
578
  list.length = 0;
580
579
  list.push(bounds);
@@ -582,26 +581,23 @@ class Renderer {
582
581
  }
583
582
  __requestRender() {
584
583
  const target = this.target;
585
- if (this.requestTime || !target)
586
- return;
587
- if (target.parentApp)
588
- return target.parentApp.requestRender(false);
584
+ if (this.requestTime || !target) return;
585
+ if (target.parentApp) return target.parentApp.requestRender(false);
589
586
  const requestTime = this.requestTime = Date.now();
590
587
  Platform.requestRender(() => {
591
- this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - requestTime)));
588
+ this.FPS = Math.min(60, Math.ceil(1e3 / (Date.now() - requestTime)));
592
589
  this.requestTime = 0;
593
590
  this.checkRender();
594
591
  });
595
592
  }
596
593
  __onResize(e) {
597
- if (this.canvas.unreal)
598
- return;
594
+ if (this.canvas.unreal) return;
599
595
  if (e.bigger || !e.samePixelRatio) {
600
- const { width, height } = e.old;
596
+ const {width: width, height: height} = e.old;
601
597
  const bounds = new Bounds(0, 0, width, height);
602
598
  if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
603
599
  this.addBlock(this.canvas.bounds);
604
- this.target.forceUpdate('surface');
600
+ this.target.forceUpdate("surface");
605
601
  return;
606
602
  }
607
603
  }
@@ -609,34 +605,24 @@ class Renderer {
609
605
  this.update();
610
606
  }
611
607
  __onLayoutEnd(event) {
612
- if (event.data)
613
- event.data.map(item => {
614
- let empty;
615
- if (item.updatedList)
616
- item.updatedList.list.some(leaf => {
617
- empty = (!leaf.__world.width || !leaf.__world.height);
618
- if (empty) {
619
- if (!leaf.isLeafer)
620
- debug.tip(leaf.innerName, ': empty');
621
- empty = (!leaf.isBranch || leaf.isBranchLeaf);
622
- }
623
- return empty;
624
- });
625
- this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
608
+ if (event.data) event.data.map(item => {
609
+ let empty;
610
+ if (item.updatedList) item.updatedList.list.some(leaf => {
611
+ empty = !leaf.__world.width || !leaf.__world.height;
612
+ if (empty) {
613
+ if (!leaf.isLeafer) debug.tip(leaf.innerName, ": empty");
614
+ empty = !leaf.isBranch || leaf.isBranchLeaf;
615
+ }
616
+ return empty;
626
617
  });
618
+ this.addBlock(empty ? this.canvas.bounds : item.updatedBounds);
619
+ });
627
620
  }
628
621
  emitRender(type, bounds, options) {
629
622
  this.target.emitEvent(new RenderEvent(type, this.times, bounds, options));
630
623
  }
631
624
  __listenEvents() {
632
- this.__eventIds = [
633
- this.target.on_([
634
- [RenderEvent.REQUEST, this.update, this],
635
- [LayoutEvent.END, this.__onLayoutEnd, this],
636
- [RenderEvent.AGAIN, this.renderAgain, this],
637
- [ResizeEvent.RESIZE, this.__onResize, this]
638
- ])
639
- ];
625
+ this.__eventIds = [ this.target.on_([ [ RenderEvent.REQUEST, this.update, this ], [ LayoutEvent.END, this.__onLayoutEnd, this ], [ RenderEvent.AGAIN, this.renderAgain, this ], [ ResizeEvent.RESIZE, this.__onResize, this ] ]) ];
640
626
  }
641
627
  __removeListenEvents() {
642
628
  this.target.off_(this.__eventIds);
@@ -649,6 +635,7 @@ class Renderer {
649
635
  }
650
636
  }
651
637
  }
638
+
652
639
  Renderer.clipSpread = 10;
653
640
 
654
641
  Object.assign(Creator, {
@@ -658,24 +645,22 @@ Object.assign(Creator, {
658
645
  selector: (_target, _options) => undefined,
659
646
  interaction: (_target, _canvas, _selector, _options) => undefined
660
647
  });
648
+
661
649
  Platform.layout = Layouter.fullLayout;
662
650
 
663
651
  function fillText(ui, canvas) {
664
- const data = ui.__, { rows, decorationY } = data.__textDrawData;
665
- if (data.__isPlacehold && data.placeholderColor)
666
- canvas.fillStyle = data.placeholderColor;
652
+ const data = ui.__, {rows: rows, decorationY: decorationY} = data.__textDrawData;
653
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor;
667
654
  let row;
668
655
  for (let i = 0, len = rows.length; i < len; i++) {
669
656
  row = rows[i];
670
- if (row.text)
671
- canvas.fillText(row.text, row.x, row.y);
672
- else if (row.data)
673
- row.data.forEach(charData => { canvas.fillText(charData.char, charData.x, row.y); });
657
+ if (row.text) canvas.fillText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
658
+ canvas.fillText(charData.char, charData.x, row.y);
659
+ });
674
660
  }
675
661
  if (decorationY) {
676
- const { decorationColor, decorationHeight } = data.__textDrawData;
677
- if (decorationColor)
678
- canvas.fillStyle = decorationColor;
662
+ const {decorationColor: decorationColor, decorationHeight: decorationHeight} = data.__textDrawData;
663
+ if (decorationColor) canvas.fillStyle = decorationColor;
679
664
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)));
680
665
  }
681
666
  }
@@ -684,117 +669,112 @@ function fill(fill, ui, canvas) {
684
669
  canvas.fillStyle = fill;
685
670
  fillPathOrText(ui, canvas);
686
671
  }
672
+
687
673
  function fills(fills, ui, canvas) {
688
674
  let item;
689
675
  for (let i = 0, len = fills.length; i < len; i++) {
690
676
  item = fills[i];
691
677
  if (item.image) {
692
- if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font))
693
- continue;
678
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue;
694
679
  if (!item.style) {
695
- if (!i && item.image.isPlacehold)
696
- ui.drawImagePlaceholder(canvas, item.image);
680
+ if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image);
697
681
  continue;
698
682
  }
699
683
  }
700
684
  canvas.fillStyle = item.style;
701
685
  if (item.transform || item.scaleFixed) {
702
686
  canvas.save();
703
- if (item.transform)
704
- canvas.transform(item.transform);
687
+ if (item.transform) canvas.transform(item.transform);
705
688
  if (item.scaleFixed) {
706
- const { scaleX, scaleY } = ui.getRenderScaleData(true);
707
- canvas.scale(1 / scaleX, 1 / scaleY);
689
+ const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
690
+ if (item.scaleFixed === true || item.scaleFixed === "zoom-in" && scaleX > 1 && scaleY > 1) canvas.scale(1 / scaleX, 1 / scaleY);
708
691
  }
709
- if (item.blendMode)
710
- canvas.blendMode = item.blendMode;
692
+ if (item.blendMode) canvas.blendMode = item.blendMode;
711
693
  fillPathOrText(ui, canvas);
712
694
  canvas.restore();
713
- }
714
- else {
695
+ } else {
715
696
  if (item.blendMode) {
716
697
  canvas.saveBlendMode(item.blendMode);
717
698
  fillPathOrText(ui, canvas);
718
699
  canvas.restoreBlendMode();
719
- }
720
- else
721
- fillPathOrText(ui, canvas);
700
+ } else fillPathOrText(ui, canvas);
722
701
  }
723
702
  }
724
703
  }
704
+
725
705
  function fillPathOrText(ui, canvas) {
726
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
706
+ ui.__.__font ? fillText(ui, canvas) : ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill();
727
707
  }
728
708
 
729
709
  function strokeText(stroke, ui, canvas) {
730
710
  switch (ui.__.strokeAlign) {
731
- case 'center':
732
- drawCenter$1(stroke, 1, ui, canvas);
733
- break;
734
- case 'inside':
735
- drawAlign(stroke, 'inside', ui, canvas);
736
- break;
737
- case 'outside':
738
- ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas);
739
- break;
711
+ case "center":
712
+ drawCenter$1(stroke, 1, ui, canvas);
713
+ break;
714
+
715
+ case "inside":
716
+ drawAlign(stroke, "inside", ui, canvas);
717
+ break;
718
+
719
+ case "outside":
720
+ ui.__.__fillAfterStroke ? drawCenter$1(stroke, 2, ui, canvas) : drawAlign(stroke, "outside", ui, canvas);
721
+ break;
740
722
  }
741
723
  }
724
+
742
725
  function drawCenter$1(stroke, strokeWidthScale, ui, canvas) {
743
726
  const data = ui.__;
744
- if (typeof stroke === 'object') {
727
+ if (isObject(stroke)) {
745
728
  drawStrokesStyle(stroke, strokeWidthScale, true, ui, canvas);
746
- }
747
- else {
729
+ } else {
748
730
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
749
731
  drawTextStroke(ui, canvas);
750
732
  }
751
733
  }
734
+
752
735
  function drawAlign(stroke, align, ui, canvas) {
753
736
  const out = canvas.getSameCanvas(true, true);
754
737
  out.font = ui.__.__font;
755
738
  drawCenter$1(stroke, 2, ui, out);
756
- out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
739
+ out.blendMode = align === "outside" ? "destination-out" : "destination-in";
757
740
  fillText(ui, out);
758
- out.blendMode = 'normal';
741
+ out.blendMode = "normal";
759
742
  LeafHelper.copyCanvasByWorld(ui, canvas, out);
760
743
  out.recycle(ui.__nowWorld);
761
744
  }
745
+
762
746
  function drawTextStroke(ui, canvas) {
763
747
  let row, data = ui.__.__textDrawData;
764
- const { rows, decorationY } = data;
748
+ const {rows: rows, decorationY: decorationY} = data;
765
749
  for (let i = 0, len = rows.length; i < len; i++) {
766
750
  row = rows[i];
767
- if (row.text)
768
- canvas.strokeText(row.text, row.x, row.y);
769
- else if (row.data)
770
- row.data.forEach(charData => { canvas.strokeText(charData.char, charData.x, row.y); });
751
+ if (row.text) canvas.strokeText(row.text, row.x, row.y); else if (row.data) row.data.forEach(charData => {
752
+ canvas.strokeText(charData.char, charData.x, row.y);
753
+ });
771
754
  }
772
755
  if (decorationY) {
773
- const { decorationHeight } = data;
756
+ const {decorationHeight: decorationHeight} = data;
774
757
  rows.forEach(row => decorationY.forEach(value => canvas.strokeRect(row.x, row.y + value, row.width, decorationHeight)));
775
758
  }
776
759
  }
760
+
777
761
  function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
778
762
  let item;
779
- const data = ui.__, { __hasMultiStrokeStyle } = data;
763
+ const data = ui.__, {__hasMultiStrokeStyle: __hasMultiStrokeStyle} = data;
780
764
  __hasMultiStrokeStyle || canvas.setStroke(undefined, data.__strokeWidth * strokeWidthScale, data);
781
765
  for (let i = 0, len = strokes.length; i < len; i++) {
782
766
  item = strokes[i];
783
- if (item.image && PaintImage.checkImage(ui, canvas, item, false))
784
- continue;
767
+ if (item.image && PaintImage.checkImage(ui, canvas, item, false)) continue;
785
768
  if (item.style) {
786
769
  if (__hasMultiStrokeStyle) {
787
- const { strokeStyle } = item;
770
+ const {strokeStyle: strokeStyle} = item;
788
771
  strokeStyle ? canvas.setStroke(item.style, data.__getRealStrokeWidth(strokeStyle) * strokeWidthScale, data, strokeStyle) : canvas.setStroke(item.style, data.__strokeWidth * strokeWidthScale, data);
789
- }
790
- else
791
- canvas.strokeStyle = item.style;
772
+ } else canvas.strokeStyle = item.style;
792
773
  if (item.blendMode) {
793
774
  canvas.saveBlendMode(item.blendMode);
794
775
  isText ? drawTextStroke(ui, canvas) : canvas.stroke();
795
776
  canvas.restoreBlendMode();
796
- }
797
- else {
777
+ } else {
798
778
  isText ? drawTextStroke(ui, canvas) : canvas.stroke();
799
779
  }
800
780
  }
@@ -803,53 +783,54 @@ function drawStrokesStyle(strokes, strokeWidthScale, isText, ui, canvas) {
803
783
 
804
784
  function stroke(stroke, ui, canvas) {
805
785
  const data = ui.__;
806
- if (!data.__strokeWidth)
807
- return;
786
+ if (!data.__strokeWidth) return;
808
787
  if (data.__font) {
809
788
  strokeText(stroke, ui, canvas);
810
- }
811
- else {
789
+ } else {
812
790
  switch (data.strokeAlign) {
813
- case 'center':
814
- drawCenter(stroke, 1, ui, canvas);
815
- break;
816
- case 'inside':
817
- drawInside(stroke, ui, canvas);
818
- break;
819
- case 'outside':
820
- drawOutside(stroke, ui, canvas);
821
- break;
791
+ case "center":
792
+ drawCenter(stroke, 1, ui, canvas);
793
+ break;
794
+
795
+ case "inside":
796
+ drawInside(stroke, ui, canvas);
797
+ break;
798
+
799
+ case "outside":
800
+ drawOutside(stroke, ui, canvas);
801
+ break;
822
802
  }
823
803
  }
824
804
  }
805
+
825
806
  function strokes(strokes, ui, canvas) {
826
807
  stroke(strokes, ui, canvas);
827
808
  }
809
+
828
810
  function drawCenter(stroke, strokeWidthScale, ui, canvas) {
829
811
  const data = ui.__;
830
- if (typeof stroke === 'object') {
812
+ if (isObject(stroke)) {
831
813
  drawStrokesStyle(stroke, strokeWidthScale, false, ui, canvas);
832
- }
833
- else {
814
+ } else {
834
815
  canvas.setStroke(stroke, data.__strokeWidth * strokeWidthScale, data);
835
816
  canvas.stroke();
836
817
  }
837
- if (data.__useArrow)
838
- Paint.strokeArrow(stroke, ui, canvas);
818
+ if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas);
839
819
  }
820
+
840
821
  function drawInside(stroke, ui, canvas) {
841
822
  canvas.save();
842
823
  canvas.clipUI(ui);
843
824
  drawCenter(stroke, 2, ui, canvas);
844
825
  canvas.restore();
845
826
  }
827
+
846
828
  function drawOutside(stroke, ui, canvas) {
847
829
  const data = ui.__;
848
830
  if (data.__fillAfterStroke) {
849
831
  drawCenter(stroke, 2, ui, canvas);
850
- }
851
- else {
852
- const { renderBounds } = ui.__layout;
832
+ } else {
833
+ const {renderBounds: renderBounds} = ui.__layout;
853
834
  const out = canvas.getSameCanvas(true, true);
854
835
  ui.__drawRenderPath(out);
855
836
  drawCenter(stroke, 2, ui, out);
@@ -860,25 +841,23 @@ function drawOutside(stroke, ui, canvas) {
860
841
  }
861
842
  }
862
843
 
863
- const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
844
+ const {getSpread: getSpread, getOuterOf: getOuterOf, getByMove: getByMove, getIntersectData: getIntersectData} = BoundsHelper;
845
+
864
846
  function shape(ui, current, options) {
865
847
  const canvas = current.getSameCanvas();
866
848
  const nowWorld = ui.__nowWorld;
867
- let bounds, fitMatrix, shapeBounds, worldCanvas;
868
- let { scaleX, scaleY } = nowWorld;
869
- if (scaleX < 0)
870
- scaleX = -scaleX;
871
- if (scaleY < 0)
872
- scaleY = -scaleY;
849
+ let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
850
+ let {scaleX: scaleX, scaleY: scaleY} = nowWorld;
851
+ if (scaleX < 0) scaleX = -scaleX;
852
+ if (scaleY < 0) scaleY = -scaleY;
873
853
  if (current.bounds.includes(nowWorld)) {
874
854
  worldCanvas = canvas;
875
855
  bounds = shapeBounds = nowWorld;
876
- }
877
- else {
878
- const { renderShapeSpread: spread } = ui.__layout;
879
- const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
856
+ } else {
857
+ const {renderShapeSpread: spread} = ui.__layout;
858
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : current.bounds, nowWorld);
880
859
  fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
881
- let { a: fitScaleX, d: fitScaleY } = fitMatrix;
860
+ let {a: fitScaleX, d: fitScaleY} = fitMatrix;
882
861
  if (fitMatrix.a < 1) {
883
862
  worldCanvas = current.getSameCanvas();
884
863
  ui.__renderShape(worldCanvas, options);
@@ -887,28 +866,39 @@ function shape(ui, current, options) {
887
866
  }
888
867
  shapeBounds = getOuterOf(nowWorld, fitMatrix);
889
868
  bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
890
- if (options.matrix) {
891
- const { matrix } = options;
892
- fitMatrix.multiply(matrix);
893
- fitScaleX *= matrix.scaleX;
894
- fitScaleY *= matrix.scaleY;
895
- }
896
- options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
869
+ const userMatrix = options.matrix;
870
+ if (userMatrix) {
871
+ matrix = new Matrix(fitMatrix);
872
+ matrix.multiply(userMatrix);
873
+ fitScaleX *= userMatrix.scaleX;
874
+ fitScaleY *= userMatrix.scaleY;
875
+ } else matrix = fitMatrix;
876
+ matrix.withScale(fitScaleX, fitScaleY);
877
+ options = Object.assign(Object.assign({}, options), {
878
+ matrix: matrix
879
+ });
897
880
  }
898
881
  ui.__renderShape(canvas, options);
899
882
  return {
900
- canvas, matrix: fitMatrix, bounds,
901
- worldCanvas, shapeBounds, scaleX, scaleY
883
+ canvas: canvas,
884
+ matrix: matrix,
885
+ fitMatrix: fitMatrix,
886
+ bounds: bounds,
887
+ worldCanvas: worldCanvas,
888
+ shapeBounds: shapeBounds,
889
+ scaleX: scaleX,
890
+ scaleY: scaleY
902
891
  };
903
892
  }
904
893
 
905
894
  let recycleMap;
906
- const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
895
+
896
+ const {stintSet: stintSet} = DataHelper, {hasTransparent: hasTransparent$1} = ColorConvert;
897
+
907
898
  function compute(attrName, ui) {
908
899
  const data = ui.__, leafPaints = [];
909
900
  let paints = data.__input[attrName], isAlphaPixel, isTransparent;
910
- if (!(paints instanceof Array))
911
- paints = [paints];
901
+ if (!isArray(paints)) paints = [ paints ];
912
902
  recycleMap = PaintImage.recycleImage(attrName, data);
913
903
  let maxChildStrokeWidth;
914
904
  for (let i = 0, len = paints.length, item; i < len; i++) {
@@ -916,206 +906,222 @@ function compute(attrName, ui) {
916
906
  leafPaints.push(item);
917
907
  if (item.strokeStyle) {
918
908
  maxChildStrokeWidth || (maxChildStrokeWidth = 1);
919
- if (item.strokeStyle.strokeWidth)
920
- maxChildStrokeWidth = Math.max(maxChildStrokeWidth, item.strokeStyle.strokeWidth);
909
+ if (item.strokeStyle.strokeWidth) maxChildStrokeWidth = Math.max(maxChildStrokeWidth, item.strokeStyle.strokeWidth);
921
910
  }
922
911
  }
923
912
  }
924
- data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
913
+ data["_" + attrName] = leafPaints.length ? leafPaints : undefined;
925
914
  if (leafPaints.length) {
926
915
  if (leafPaints.every(item => item.isTransparent)) {
927
- if (leafPaints.some(item => item.image))
928
- isAlphaPixel = true;
916
+ if (leafPaints.some(item => item.image)) isAlphaPixel = true;
929
917
  isTransparent = true;
930
918
  }
931
919
  }
932
- if (attrName === 'fill') {
933
- stintSet(data, '__isAlphaPixelFill', isAlphaPixel);
934
- stintSet(data, '__isTransparentFill', isTransparent);
935
- }
936
- else {
937
- stintSet(data, '__isAlphaPixelStroke', isAlphaPixel);
938
- stintSet(data, '__isTransparentStroke', isTransparent);
939
- stintSet(data, '__hasMultiStrokeStyle', maxChildStrokeWidth);
920
+ if (attrName === "fill") {
921
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
922
+ stintSet(data, "__isTransparentFill", isTransparent);
923
+ } else {
924
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
925
+ stintSet(data, "__isTransparentStroke", isTransparent);
926
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
940
927
  }
941
928
  }
929
+
942
930
  function getLeafPaint(attrName, paint, ui) {
943
- if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
944
- return undefined;
931
+ if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
945
932
  let data;
946
- const { boxBounds } = ui.__layout;
933
+ const {boxBounds: boxBounds} = ui.__layout;
947
934
  switch (paint.type) {
948
- case 'image':
949
- data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
950
- break;
951
- case 'linear':
952
- data = PaintGradient.linearGradient(paint, boxBounds);
953
- break;
954
- case 'radial':
955
- data = PaintGradient.radialGradient(paint, boxBounds);
956
- break;
957
- case 'angular':
958
- data = PaintGradient.conicGradient(paint, boxBounds);
959
- break;
960
- case 'solid':
961
- const { type, color, opacity } = paint;
962
- data = { type, style: ColorConvert.string(color, opacity) };
963
- break;
964
- default:
965
- if (paint.r !== undefined)
966
- data = { type: 'solid', style: ColorConvert.string(paint) };
935
+ case "image":
936
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
937
+ break;
938
+
939
+ case "linear":
940
+ data = PaintGradient.linearGradient(paint, boxBounds);
941
+ break;
942
+
943
+ case "radial":
944
+ data = PaintGradient.radialGradient(paint, boxBounds);
945
+ break;
946
+
947
+ case "angular":
948
+ data = PaintGradient.conicGradient(paint, boxBounds);
949
+ break;
950
+
951
+ case "solid":
952
+ const {type: type, color: color, opacity: opacity} = paint;
953
+ data = {
954
+ type: type,
955
+ style: ColorConvert.string(color, opacity)
956
+ };
957
+ break;
958
+
959
+ default:
960
+ if (!isUndefined(paint.r)) data = {
961
+ type: "solid",
962
+ style: ColorConvert.string(paint)
963
+ };
967
964
  }
968
965
  if (data) {
969
- if (typeof data.style === 'string' && hasTransparent$1(data.style))
970
- data.isTransparent = true;
966
+ if (isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
971
967
  if (paint.style) {
972
- if (paint.style.strokeWidth === 0)
973
- return undefined;
968
+ if (paint.style.strokeWidth === 0) return undefined;
974
969
  data.strokeStyle = paint.style;
975
970
  }
976
- if (paint.blendMode)
977
- data.blendMode = paint.blendMode;
971
+ if (paint.editing) data.editing = paint.editing;
972
+ if (paint.blendMode) data.blendMode = paint.blendMode;
978
973
  }
979
974
  return data;
980
975
  }
981
976
 
982
977
  const PaintModule = {
983
- compute,
984
- fill,
985
- fills,
986
- fillPathOrText,
987
- fillText,
988
- stroke,
989
- strokes,
990
- strokeText,
991
- drawTextStroke,
992
- shape
978
+ compute: compute,
979
+ fill: fill,
980
+ fills: fills,
981
+ fillPathOrText: fillPathOrText,
982
+ fillText: fillText,
983
+ stroke: stroke,
984
+ strokes: strokes,
985
+ strokeText: strokeText,
986
+ drawTextStroke: drawTextStroke,
987
+ shape: shape
993
988
  };
994
989
 
995
990
  let origin = {}, tempMatrix = getMatrixData();
996
- const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent, scale: scaleHelper, rotate, skew: skewHelper } = MatrixHelper;
991
+
992
+ const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
993
+
997
994
  function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
998
995
  const transform = get$3();
999
996
  translate$1(transform, box.x + x, box.y + y);
1000
997
  scaleHelper(transform, scaleX, scaleY);
1001
- if (rotation)
1002
- rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
998
+ if (rotation) rotateOfOuter$1(transform, {
999
+ x: box.x + box.width / 2,
1000
+ y: box.y + box.height / 2
1001
+ }, rotation);
1003
1002
  data.transform = transform;
1004
1003
  }
1004
+
1005
1005
  function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1006
1006
  const transform = get$3();
1007
- if (rotation)
1008
- rotate(transform, rotation);
1009
- if (skew)
1010
- skewHelper(transform, skew.x, skew.y);
1011
- if (scaleX)
1012
- scaleHelper(transform, scaleX, scaleY);
1013
- translate$1(transform, box.x + x, box.y + y);
1007
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1014
1008
  if (clipSize) {
1015
1009
  tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1016
1010
  multiplyParent(transform, tempMatrix);
1017
1011
  }
1018
1012
  data.transform = transform;
1019
1013
  }
1020
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
1014
+
1015
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1021
1016
  const transform = get$3();
1022
- if (rotation) {
1023
- if (align === 'center') {
1024
- rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
1025
- }
1026
- else {
1027
- rotate(transform, rotation);
1028
- switch (rotation) {
1029
- case 90:
1017
+ if (freeTransform) {
1018
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1019
+ } else {
1020
+ if (rotation) {
1021
+ if (align === "center") {
1022
+ rotateOfOuter$1(transform, {
1023
+ x: width / 2,
1024
+ y: height / 2
1025
+ }, rotation);
1026
+ } else {
1027
+ rotate(transform, rotation);
1028
+ switch (rotation) {
1029
+ case 90:
1030
1030
  translate$1(transform, height, 0);
1031
1031
  break;
1032
- case 180:
1032
+
1033
+ case 180:
1033
1034
  translate$1(transform, width, height);
1034
1035
  break;
1035
- case 270:
1036
+
1037
+ case 270:
1036
1038
  translate$1(transform, 0, width);
1037
1039
  break;
1040
+ }
1038
1041
  }
1039
1042
  }
1043
+ origin.x = box.x + x;
1044
+ origin.y = box.y + y;
1045
+ translate$1(transform, origin.x, origin.y);
1046
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1040
1047
  }
1041
- origin.x = box.x + x;
1042
- origin.y = box.y + y;
1043
- translate$1(transform, origin.x, origin.y);
1044
- if (scaleX)
1045
- scaleOfOuter$1(transform, origin, scaleX, scaleY);
1046
1048
  data.transform = transform;
1047
1049
  }
1048
1050
 
1049
- const { get: get$2, translate } = MatrixHelper;
1050
- const tempBox = new Bounds();
1051
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1052
+ if (rotation) rotate(transform, rotation);
1053
+ if (skew) skewHelper(transform, skew.x, skew.y);
1054
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1055
+ translate$1(transform, box.x + x, box.y + y);
1056
+ }
1057
+
1058
+ const {get: get$2, translate: translate} = MatrixHelper;
1059
+
1060
+ const tempBox = new Bounds;
1061
+
1051
1062
  const tempScaleData = {};
1063
+
1052
1064
  const tempImage = {};
1065
+
1053
1066
  function createData(leafPaint, image, paint, box) {
1054
- const { changeful, sync, editing, scaleFixed } = paint;
1055
- if (changeful)
1056
- leafPaint.changeful = changeful;
1057
- if (sync)
1058
- leafPaint.sync = sync;
1059
- if (editing)
1060
- leafPaint.editing = editing;
1061
- if (scaleFixed)
1062
- leafPaint.scaleFixed = scaleFixed;
1067
+ const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1068
+ if (changeful) leafPaint.changeful = changeful;
1069
+ if (sync) leafPaint.sync = sync;
1070
+ if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1063
1071
  leafPaint.data = getPatternData(paint, box, image);
1064
1072
  }
1073
+
1065
1074
  function getPatternData(paint, box, image) {
1066
- if (paint.padding)
1067
- box = tempBox.set(box).shrink(paint.padding);
1068
- if (paint.mode === 'strench')
1069
- paint.mode = 'stretch';
1070
- let { width, height } = image;
1071
- const { opacity, mode, align, offset, scale, size, rotation, skew, clipSize, repeat, filters } = paint;
1075
+ if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1076
+ if (paint.mode === "strench") paint.mode = "stretch";
1077
+ let {width: width, height: height} = image;
1078
+ const {opacity: opacity, mode: mode, align: align, offset: offset, scale: scale, size: size, rotation: rotation, skew: skew, clipSize: clipSize, repeat: repeat, gap: gap, filters: filters} = paint;
1072
1079
  const sameBox = box.width === width && box.height === height;
1073
- const data = { mode };
1074
- const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1080
+ const data = {
1081
+ mode: mode
1082
+ };
1083
+ const swapSize = align !== "center" && (rotation || 0) % 180 === 90;
1075
1084
  BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1076
1085
  let scaleX, scaleY;
1077
- if (!mode || mode === 'cover' || mode === 'fit') {
1086
+ if (!mode || mode === "cover" || mode === "fit") {
1078
1087
  if (!sameBox || rotation) {
1079
- scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1088
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== "fit");
1080
1089
  BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1081
1090
  BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1082
1091
  }
1083
- }
1084
- else {
1092
+ } else {
1085
1093
  if (scale || size) {
1086
1094
  MathHelper.getScaleData(scale, size, image, tempScaleData);
1087
1095
  scaleX = tempScaleData.scaleX;
1088
1096
  scaleY = tempScaleData.scaleY;
1089
1097
  }
1090
- if (align) {
1091
- if (scaleX)
1092
- BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1093
- AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1098
+ if (align || gap || repeat) {
1099
+ if (scaleX) BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1100
+ if (align) AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1094
1101
  }
1095
1102
  }
1096
- if (offset)
1097
- PointHelper.move(tempImage, offset);
1103
+ if (offset) PointHelper.move(tempImage, offset);
1098
1104
  switch (mode) {
1099
- case 'stretch':
1100
- if (!sameBox)
1101
- width = box.width, height = box.height;
1102
- break;
1103
- case 'normal':
1104
- case 'clip':
1105
- if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew)
1106
- clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1107
- break;
1108
- case 'repeat':
1109
- if (!sameBox || scaleX || rotation)
1110
- repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, align);
1111
- if (!repeat)
1112
- data.repeat = 'repeat';
1113
- break;
1114
- case 'fit':
1115
- case 'cover':
1116
- default:
1117
- if (scaleX)
1118
- fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1105
+ case "stretch":
1106
+ if (!sameBox) width = box.width, height = box.height;
1107
+ break;
1108
+
1109
+ case "normal":
1110
+ case "clip":
1111
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1112
+ break;
1113
+
1114
+ case "repeat":
1115
+ if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1116
+ if (!repeat) data.repeat = "repeat";
1117
+ const count = isObject(repeat);
1118
+ if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
1119
+ break;
1120
+
1121
+ case "fit":
1122
+ case "cover":
1123
+ default:
1124
+ if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1119
1125
  }
1120
1126
  if (!data.transform) {
1121
1127
  if (box.x || box.y) {
@@ -1123,49 +1129,69 @@ function getPatternData(paint, box, image) {
1123
1129
  translate(data.transform, box.x, box.y);
1124
1130
  }
1125
1131
  }
1126
- if (scaleX && mode !== 'stretch') {
1132
+ if (scaleX && mode !== "stretch") {
1127
1133
  data.scaleX = scaleX;
1128
1134
  data.scaleY = scaleY;
1129
1135
  }
1130
1136
  data.width = width;
1131
1137
  data.height = height;
1132
- if (opacity)
1133
- data.opacity = opacity;
1134
- if (filters)
1135
- data.filters = filters;
1136
- if (repeat)
1137
- data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1138
+ if (opacity) data.opacity = opacity;
1139
+ if (filters) data.filters = filters;
1140
+ if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1138
1141
  return data;
1139
1142
  }
1140
1143
 
1141
- let cache, box = new Bounds();
1142
- const { isSame } = BoundsHelper;
1144
+ function getGapData(gap, repeat, width, height, box) {
1145
+ let xGap, yGap;
1146
+ if (isObject(gap)) xGap = gap.x, yGap = gap.y; else xGap = yGap = gap;
1147
+ return {
1148
+ x: getGapValue(xGap, width, box.width, repeat && repeat.x),
1149
+ y: getGapValue(yGap, height, box.height, repeat && repeat.y)
1150
+ };
1151
+ }
1152
+
1153
+ function getGapValue(gap, size, totalSize, rows) {
1154
+ const auto = isString(gap) || rows;
1155
+ const remain = rows ? totalSize - rows * size : totalSize % size;
1156
+ const value = auto ? remain / ((rows || Math.floor(totalSize / size)) - 1) : gap;
1157
+ return gap === "auto" ? value < 0 ? 0 : value : value;
1158
+ }
1159
+
1160
+ let cache, box = new Bounds;
1161
+
1162
+ const {isSame: isSame} = BoundsHelper;
1163
+
1143
1164
  function image(ui, attrName, paint, boxBounds, firstUse) {
1144
1165
  let leafPaint, event;
1145
1166
  const image = ImageManager.get(paint);
1146
1167
  if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1147
1168
  leafPaint = cache.leafPaint;
1148
- }
1149
- else {
1150
- leafPaint = { type: paint.type, image };
1151
- if (image.hasAlphaPixel)
1152
- leafPaint.isTransparent = true;
1153
- cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1154
- }
1155
- if (firstUse || image.loading)
1156
- event = { image, attrName, attrValue: paint };
1169
+ } else {
1170
+ leafPaint = {
1171
+ type: paint.type,
1172
+ image: image
1173
+ };
1174
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1175
+ cache = image.use > 1 ? {
1176
+ leafPaint: leafPaint,
1177
+ paint: paint,
1178
+ boxBounds: box.set(boxBounds)
1179
+ } : null;
1180
+ }
1181
+ if (firstUse || image.loading) event = {
1182
+ image: image,
1183
+ attrName: attrName,
1184
+ attrValue: paint
1185
+ };
1157
1186
  if (image.ready) {
1158
1187
  checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1159
1188
  if (firstUse) {
1160
1189
  onLoad(ui, event);
1161
1190
  onLoadSuccess(ui, event);
1162
1191
  }
1163
- }
1164
- else if (image.error) {
1165
- if (firstUse)
1166
- onLoadError(ui, event, image.error);
1167
- }
1168
- else {
1192
+ } else if (image.error) {
1193
+ if (firstUse) onLoadError(ui, event, image.error);
1194
+ } else {
1169
1195
  if (firstUse) {
1170
1196
  ignoreRender(ui, true);
1171
1197
  onLoad(ui, event);
@@ -1174,79 +1200,84 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1174
1200
  ignoreRender(ui, false);
1175
1201
  if (!ui.destroyed) {
1176
1202
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1177
- if (image.hasAlphaPixel)
1178
- ui.__layout.hitCanvasChanged = true;
1179
- ui.forceUpdate('surface');
1203
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1204
+ ui.forceUpdate("surface");
1180
1205
  }
1181
1206
  onLoadSuccess(ui, event);
1182
1207
  }
1183
1208
  leafPaint.loadId = undefined;
1184
- }, (error) => {
1209
+ }, error => {
1185
1210
  ignoreRender(ui, false);
1186
1211
  onLoadError(ui, event, error);
1187
1212
  leafPaint.loadId = undefined;
1188
1213
  });
1189
1214
  if (ui.placeholderColor) {
1190
- if (!ui.placeholderDelay)
1191
- image.isPlacehold = true;
1192
- else
1193
- setTimeout(() => {
1194
- if (!image.ready) {
1195
- image.isPlacehold = true;
1196
- ui.forceUpdate('surface');
1197
- }
1198
- }, ui.placeholderDelay);
1215
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1216
+ if (!image.ready) {
1217
+ image.isPlacehold = true;
1218
+ ui.forceUpdate("surface");
1219
+ }
1220
+ }, ui.placeholderDelay);
1199
1221
  }
1200
1222
  }
1201
1223
  return leafPaint;
1202
1224
  }
1225
+
1203
1226
  function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1204
- if (attrName === 'fill' && !ui.__.__naturalWidth) {
1227
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1205
1228
  const data = ui.__;
1206
1229
  data.__naturalWidth = image.width / data.pixelRatio;
1207
1230
  data.__naturalHeight = image.height / data.pixelRatio;
1208
1231
  if (data.__autoSide) {
1209
- ui.forceUpdate('width');
1232
+ ui.forceUpdate("width");
1210
1233
  if (ui.__proxyData) {
1211
- ui.setProxyAttr('width', data.width);
1212
- ui.setProxyAttr('height', data.height);
1234
+ ui.setProxyAttr("width", data.width);
1235
+ ui.setProxyAttr("height", data.height);
1213
1236
  }
1214
1237
  return false;
1215
1238
  }
1216
1239
  }
1217
- if (!leafPaint.data)
1218
- createData(leafPaint, image, paint, boxBounds);
1240
+ if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1219
1241
  return true;
1220
1242
  }
1243
+
1221
1244
  function onLoad(ui, event) {
1222
1245
  emit(ui, ImageEvent.LOAD, event);
1223
1246
  }
1247
+
1224
1248
  function onLoadSuccess(ui, event) {
1225
1249
  emit(ui, ImageEvent.LOADED, event);
1226
1250
  }
1251
+
1227
1252
  function onLoadError(ui, event, error) {
1228
1253
  event.error = error;
1229
- ui.forceUpdate('surface');
1254
+ ui.forceUpdate("surface");
1230
1255
  emit(ui, ImageEvent.ERROR, event);
1231
1256
  }
1257
+
1232
1258
  function emit(ui, type, data) {
1233
- if (ui.hasEvent(type))
1234
- ui.emitEvent(new ImageEvent(type, data));
1259
+ if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1235
1260
  }
1261
+
1236
1262
  function ignoreRender(ui, value) {
1237
- const { leafer } = ui;
1238
- if (leafer && leafer.viewReady)
1239
- leafer.renderer.ignore = value;
1263
+ const {leafer: leafer} = ui;
1264
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1240
1265
  }
1241
1266
 
1242
- const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
1243
- const { ceil, abs } = Math;
1267
+ const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1268
+
1269
+ const {floor: floor, max: max, abs: abs} = Math;
1270
+
1244
1271
  function createPattern(ui, paint, pixelRatio) {
1245
- let { scaleX, scaleY } = ui.getRenderScaleData(true, paint.scaleFixed);
1246
- const id = scaleX + '-' + scaleY + '-' + pixelRatio;
1272
+ let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1273
+ const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1247
1274
  if (paint.patternId !== id && !ui.destroyed) {
1248
- const { image, data } = paint;
1249
- let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, transform, repeat } = data;
1275
+ const {image: image, data: data} = paint;
1276
+ let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1277
+ scaleX *= pixelRatio;
1278
+ scaleY *= pixelRatio;
1279
+ const xGap = gap && gap.x * scaleX;
1280
+ const yGap = gap && gap.y * scaleY;
1250
1281
  if (sx) {
1251
1282
  sx = abs(sx);
1252
1283
  sy = abs(sy);
@@ -1256,23 +1287,18 @@ function createPattern(ui, paint, pixelRatio) {
1256
1287
  scaleX *= sx;
1257
1288
  scaleY *= sy;
1258
1289
  }
1259
- scaleX *= pixelRatio;
1260
- scaleY *= pixelRatio;
1261
1290
  width *= scaleX;
1262
1291
  height *= scaleY;
1263
1292
  const size = width * height;
1264
1293
  if (!repeat) {
1265
- if (size > Platform.image.maxCacheSize)
1266
- return false;
1294
+ if (size > Platform.image.maxCacheSize) return false;
1267
1295
  }
1268
1296
  let maxSize = Platform.image.maxPatternSize;
1269
1297
  if (!image.isSVG) {
1270
1298
  const imageSize = image.width * image.height;
1271
- if (maxSize > imageSize)
1272
- maxSize = imageSize;
1299
+ if (maxSize > imageSize) maxSize = imageSize;
1273
1300
  }
1274
- if (size > maxSize)
1275
- imageScale = Math.sqrt(size / maxSize);
1301
+ if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1276
1302
  if (imageScale) {
1277
1303
  scaleX /= imageScale;
1278
1304
  scaleY /= imageScale;
@@ -1286,97 +1312,95 @@ function createPattern(ui, paint, pixelRatio) {
1286
1312
  if (transform || scaleX !== 1 || scaleY !== 1) {
1287
1313
  if (!imageMatrix) {
1288
1314
  imageMatrix = get$1();
1289
- if (transform)
1290
- copy$1(imageMatrix, transform);
1315
+ if (transform) copy$1(imageMatrix, transform);
1291
1316
  }
1292
1317
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1293
1318
  }
1294
- const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, data.opacity, data.filters);
1295
- const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1319
+ if (imageMatrix) {
1320
+ const canvasWidth = width + (xGap || 0), canvasHeight = height + (yGap || 0);
1321
+ scale(imageMatrix, canvasWidth / max(floor(canvasWidth), 1), canvasHeight / max(floor(canvasHeight), 1));
1322
+ }
1323
+ const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap);
1324
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1296
1325
  paint.style = pattern;
1297
1326
  paint.patternId = id;
1298
1327
  return true;
1299
- }
1300
- else {
1328
+ } else {
1301
1329
  return false;
1302
1330
  }
1303
1331
  }
1304
1332
 
1305
- /******************************************************************************
1306
- Copyright (c) Microsoft Corporation.
1307
-
1308
- Permission to use, copy, modify, and/or distribute this software for any
1309
- purpose with or without fee is hereby granted.
1310
-
1311
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1312
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1313
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1314
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1315
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1316
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1317
- PERFORMANCE OF THIS SOFTWARE.
1318
- ***************************************************************************** */
1319
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
1320
-
1321
-
1322
- function __awaiter(thisArg, _arguments, P, generator) {
1323
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1324
- return new (P || (P = Promise))(function (resolve, reject) {
1325
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1326
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1327
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1328
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1329
- });
1330
- }
1331
-
1332
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1333
- var e = new Error(message);
1334
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1333
+ function __awaiter(thisArg, _arguments, P, generator) {
1334
+ function adopt(value) {
1335
+ return value instanceof P ? value : new P(function(resolve) {
1336
+ resolve(value);
1337
+ });
1338
+ }
1339
+ return new (P || (P = Promise))(function(resolve, reject) {
1340
+ function fulfilled(value) {
1341
+ try {
1342
+ step(generator.next(value));
1343
+ } catch (e) {
1344
+ reject(e);
1345
+ }
1346
+ }
1347
+ function rejected(value) {
1348
+ try {
1349
+ step(generator["throw"](value));
1350
+ } catch (e) {
1351
+ reject(e);
1352
+ }
1353
+ }
1354
+ function step(result) {
1355
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1356
+ }
1357
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1358
+ });
1359
+ }
1360
+
1361
+ typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
1362
+ var e = new Error(message);
1363
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1335
1364
  };
1336
1365
 
1337
1366
  function checkImage(ui, canvas, paint, allowDraw) {
1338
- const { scaleX, scaleY } = ui.getRenderScaleData(true, paint.scaleFixed);
1339
- const { pixelRatio } = canvas, { data } = paint;
1340
- if (!data || (paint.patternId === scaleX + '-' + scaleY + '-' + pixelRatio && !Export.running)) {
1367
+ const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1368
+ const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1369
+ if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !Export.running) {
1341
1370
  return false;
1342
- }
1343
- else {
1371
+ } else {
1344
1372
  if (allowDraw) {
1345
1373
  if (data.repeat) {
1346
1374
  allowDraw = false;
1347
- }
1348
- else {
1349
- if (!(paint.changeful || ResizeEvent.isResizing(ui) || Export.running)) {
1350
- let { width, height } = data;
1375
+ } else {
1376
+ if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
1377
+ let {width: width, height: height} = data;
1351
1378
  width *= scaleX * pixelRatio;
1352
1379
  height *= scaleY * pixelRatio;
1353
1380
  if (data.scaleX) {
1354
1381
  width *= data.scaleX;
1355
1382
  height *= data.scaleY;
1356
1383
  }
1357
- allowDraw = (width * height > Platform.image.maxCacheSize);
1384
+ allowDraw = width * height > Platform.image.maxCacheSize;
1358
1385
  }
1359
1386
  }
1360
1387
  }
1361
1388
  if (allowDraw) {
1362
1389
  if (ui.__.__isFastShadow) {
1363
- canvas.fillStyle = paint.style || '#000';
1390
+ canvas.fillStyle = paint.style || "#000";
1364
1391
  canvas.fill();
1365
1392
  }
1366
1393
  drawImage(ui, canvas, paint, data);
1367
1394
  return true;
1368
- }
1369
- else {
1395
+ } else {
1370
1396
  if (!paint.style || paint.sync || Export.running) {
1371
1397
  createPattern(ui, paint, pixelRatio);
1372
- }
1373
- else {
1398
+ } else {
1374
1399
  if (!paint.patternTask) {
1375
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1400
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1376
1401
  paint.patternTask = null;
1377
- if (canvas.bounds.hit(ui.__nowWorld))
1378
- createPattern(ui, paint, pixelRatio);
1379
- ui.forceUpdate('surface');
1402
+ if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1403
+ ui.forceUpdate("surface");
1380
1404
  }), 300);
1381
1405
  }
1382
1406
  }
@@ -1384,39 +1408,35 @@ function checkImage(ui, canvas, paint, allowDraw) {
1384
1408
  }
1385
1409
  }
1386
1410
  }
1411
+
1387
1412
  function drawImage(ui, canvas, paint, data) {
1388
1413
  canvas.save();
1389
1414
  canvas.clipUI(ui);
1390
- if (paint.blendMode)
1391
- canvas.blendMode = paint.blendMode;
1392
- if (data.opacity)
1393
- canvas.opacity *= data.opacity;
1394
- if (data.transform)
1395
- canvas.transform(data.transform);
1415
+ if (paint.blendMode) canvas.blendMode = paint.blendMode;
1416
+ if (data.opacity) canvas.opacity *= data.opacity;
1417
+ if (data.transform) canvas.transform(data.transform);
1396
1418
  canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1397
1419
  canvas.restore();
1398
1420
  }
1399
1421
 
1400
1422
  function recycleImage(attrName, data) {
1401
- const paints = data['_' + attrName];
1402
- if (paints instanceof Array) {
1423
+ const paints = data["_" + attrName];
1424
+ if (isArray(paints)) {
1403
1425
  let paint, image, recycleMap, input, url;
1404
1426
  for (let i = 0, len = paints.length; i < len; i++) {
1405
1427
  paint = paints[i];
1406
1428
  image = paint.image;
1407
1429
  url = image && image.url;
1408
1430
  if (url) {
1409
- if (!recycleMap)
1410
- recycleMap = {};
1431
+ if (!recycleMap) recycleMap = {};
1411
1432
  recycleMap[url] = true;
1412
1433
  ImageManager.recycle(image);
1413
1434
  if (image.loading) {
1414
1435
  if (!input) {
1415
- input = (data.__input && data.__input[attrName]) || [];
1416
- if (!(input instanceof Array))
1417
- input = [input];
1436
+ input = data.__input && data.__input[attrName] || [];
1437
+ if (!isArray(input)) input = [ input ];
1418
1438
  }
1419
- image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1439
+ image.unload(paints[i].loadId, !input.some(item => item.url === url));
1420
1440
  }
1421
1441
  }
1422
1442
  }
@@ -1426,75 +1446,85 @@ function recycleImage(attrName, data) {
1426
1446
  }
1427
1447
 
1428
1448
  const PaintImageModule = {
1429
- image,
1430
- checkImage,
1431
- createPattern,
1432
- recycleImage,
1433
- createData,
1434
- getPatternData,
1435
- fillOrFitMode,
1436
- clipMode,
1437
- repeatMode
1449
+ image: image,
1450
+ checkImage: checkImage,
1451
+ createPattern: createPattern,
1452
+ recycleImage: recycleImage,
1453
+ createData: createData,
1454
+ getPatternData: getPatternData,
1455
+ fillOrFitMode: fillOrFitMode,
1456
+ clipMode: clipMode,
1457
+ repeatMode: repeatMode
1438
1458
  };
1439
1459
 
1440
- const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1460
+ const {toPoint: toPoint$2} = AroundHelper, {hasTransparent: hasTransparent} = ColorConvert;
1461
+
1441
1462
  const realFrom$2 = {};
1463
+
1442
1464
  const realTo$2 = {};
1465
+
1443
1466
  function linearGradient(paint, box) {
1444
- let { from, to, type, opacity } = paint;
1445
- toPoint$2(from || 'top', box, realFrom$2);
1446
- toPoint$2(to || 'bottom', box, realTo$2);
1467
+ let {from: from, to: to, type: type, opacity: opacity} = paint;
1468
+ toPoint$2(from || "top", box, realFrom$2);
1469
+ toPoint$2(to || "bottom", box, realTo$2);
1447
1470
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1448
- const data = { type, style };
1471
+ const data = {
1472
+ type: type,
1473
+ style: style
1474
+ };
1449
1475
  applyStops(data, style, paint.stops, opacity);
1450
1476
  return data;
1451
1477
  }
1478
+
1452
1479
  function applyStops(data, gradient, stops, opacity) {
1453
1480
  if (stops) {
1454
1481
  let stop, color, offset, isTransparent;
1455
1482
  for (let i = 0, len = stops.length; i < len; i++) {
1456
1483
  stop = stops[i];
1457
- if (typeof stop === 'string')
1458
- offset = i / (len - 1), color = ColorConvert.string(stop, opacity);
1459
- else
1460
- offset = stop.offset, color = ColorConvert.string(stop.color, opacity);
1484
+ if (isString(stop)) offset = i / (len - 1), color = ColorConvert.string(stop, opacity); else offset = stop.offset,
1485
+ color = ColorConvert.string(stop.color, opacity);
1461
1486
  gradient.addColorStop(offset, color);
1462
- if (!isTransparent && hasTransparent(color))
1463
- isTransparent = true;
1487
+ if (!isTransparent && hasTransparent(color)) isTransparent = true;
1464
1488
  }
1465
- if (isTransparent)
1466
- data.isTransparent = true;
1489
+ if (isTransparent) data.isTransparent = true;
1467
1490
  }
1468
1491
  }
1469
1492
 
1470
- const { getAngle, getDistance: getDistance$1 } = PointHelper;
1471
- const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
1472
- const { toPoint: toPoint$1 } = AroundHelper;
1493
+ const {getAngle: getAngle, getDistance: getDistance$1} = PointHelper;
1494
+
1495
+ const {get: get, rotateOfOuter: rotateOfOuter, scaleOfOuter: scaleOfOuter} = MatrixHelper;
1496
+
1497
+ const {toPoint: toPoint$1} = AroundHelper;
1498
+
1473
1499
  const realFrom$1 = {};
1500
+
1474
1501
  const realTo$1 = {};
1502
+
1475
1503
  function radialGradient(paint, box) {
1476
- let { from, to, type, opacity, stretch } = paint;
1477
- toPoint$1(from || 'center', box, realFrom$1);
1478
- toPoint$1(to || 'bottom', box, realTo$1);
1504
+ let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
1505
+ toPoint$1(from || "center", box, realFrom$1);
1506
+ toPoint$1(to || "bottom", box, realTo$1);
1479
1507
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1480
- const data = { type, style };
1508
+ const data = {
1509
+ type: type,
1510
+ style: style
1511
+ };
1481
1512
  applyStops(data, style, paint.stops, opacity);
1482
1513
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1483
- if (transform)
1484
- data.transform = transform;
1514
+ if (transform) data.transform = transform;
1485
1515
  return data;
1486
1516
  }
1517
+
1487
1518
  function getTransform(box, from, to, stretch, rotate90) {
1488
1519
  let transform;
1489
- const { width, height } = box;
1520
+ const {width: width, height: height} = box;
1490
1521
  if (width !== height || stretch) {
1491
1522
  const angle = getAngle(from, to);
1492
1523
  transform = get();
1493
1524
  if (rotate90) {
1494
1525
  scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
1495
1526
  rotateOfOuter(transform, from, angle + 90);
1496
- }
1497
- else {
1527
+ } else {
1498
1528
  scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
1499
1529
  rotateOfOuter(transform, from, angle);
1500
1530
  }
@@ -1502,81 +1532,94 @@ function getTransform(box, from, to, stretch, rotate90) {
1502
1532
  return transform;
1503
1533
  }
1504
1534
 
1505
- const { getDistance } = PointHelper;
1506
- const { toPoint } = AroundHelper;
1535
+ const {getDistance: getDistance} = PointHelper;
1536
+
1537
+ const {toPoint: toPoint} = AroundHelper;
1538
+
1507
1539
  const realFrom = {};
1540
+
1508
1541
  const realTo = {};
1542
+
1509
1543
  function conicGradient(paint, box) {
1510
- let { from, to, type, opacity, stretch } = paint;
1511
- toPoint(from || 'center', box, realFrom);
1512
- toPoint(to || 'bottom', box, realTo);
1544
+ let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
1545
+ toPoint(from || "center", box, realFrom);
1546
+ toPoint(to || "bottom", box, realTo);
1513
1547
  const style = Platform.conicGradientSupport ? Platform.canvas.createConicGradient(0, realFrom.x, realFrom.y) : Platform.canvas.createRadialGradient(realFrom.x, realFrom.y, 0, realFrom.x, realFrom.y, getDistance(realFrom, realTo));
1514
- const data = { type, style };
1548
+ const data = {
1549
+ type: type,
1550
+ style: style
1551
+ };
1515
1552
  applyStops(data, style, paint.stops, opacity);
1516
1553
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1517
- if (transform)
1518
- data.transform = transform;
1554
+ if (transform) data.transform = transform;
1519
1555
  return data;
1520
1556
  }
1521
1557
 
1522
1558
  const PaintGradientModule = {
1523
- linearGradient,
1524
- radialGradient,
1525
- conicGradient,
1526
- getTransform
1559
+ linearGradient: linearGradient,
1560
+ radialGradient: radialGradient,
1561
+ conicGradient: conicGradient,
1562
+ getTransform: getTransform
1527
1563
  };
1528
1564
 
1529
- const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
1565
+ const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = BoundsHelper;
1566
+
1530
1567
  const tempBounds = {};
1568
+
1531
1569
  const offsetOutBounds$1 = {};
1570
+
1532
1571
  function shadow(ui, current, shape) {
1533
1572
  let copyBounds, spreadScale;
1534
- const { __nowWorld: nowWorld, __layout } = ui;
1535
- const { shadow } = ui.__;
1536
- const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1573
+ const {__nowWorld: nowWorld, __layout: __layout} = ui;
1574
+ const {shadow: shadow} = ui.__;
1575
+ const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1537
1576
  const other = current.getSameCanvas();
1538
1577
  const end = shadow.length - 1;
1539
1578
  toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1540
1579
  shadow.forEach((item, index) => {
1541
- other.setWorldShadow((offsetOutBounds$1.offsetX + item.x * scaleX), (offsetOutBounds$1.offsetY + item.y * scaleY), item.blur * scaleX, ColorConvert.string(item.color));
1542
- spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
1580
+ let otherScale = 1;
1581
+ if (item.scaleFixed) {
1582
+ const sx = Math.abs(nowWorld.scaleX);
1583
+ if (sx > 1) otherScale = 1 / sx;
1584
+ }
1585
+ other.setWorldShadow(offsetOutBounds$1.offsetX + item.x * scaleX * otherScale, offsetOutBounds$1.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale, ColorConvert.string(item.color));
1586
+ spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1543
1587
  drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1544
1588
  copyBounds = bounds;
1545
1589
  if (item.box) {
1546
1590
  other.restore();
1547
1591
  other.save();
1548
1592
  if (worldCanvas) {
1549
- other.copyWorld(other, bounds, nowWorld, 'copy');
1593
+ other.copyWorld(other, bounds, nowWorld, "copy");
1550
1594
  copyBounds = nowWorld;
1551
1595
  }
1552
- worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
1596
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
1553
1597
  }
1554
1598
  LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1555
- if (end && index < end)
1556
- other.clearWorld(copyBounds, true);
1599
+ if (end && index < end) other.clearWorld(copyBounds, true);
1557
1600
  });
1558
1601
  other.recycle(copyBounds);
1559
1602
  }
1603
+
1560
1604
  function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1561
- const { bounds, shapeBounds } = shape;
1605
+ const {bounds: bounds, shapeBounds: shapeBounds} = shape;
1562
1606
  if (Platform.fullImageShadow) {
1563
1607
  copy(tempBounds, canvas.bounds);
1564
- tempBounds.x += (outBounds.x - shapeBounds.x);
1565
- tempBounds.y += (outBounds.y - shapeBounds.y);
1608
+ tempBounds.x += outBounds.x - shapeBounds.x;
1609
+ tempBounds.y += outBounds.y - shapeBounds.y;
1566
1610
  if (spreadScale) {
1567
- const { matrix } = shape;
1568
- tempBounds.x -= (bounds.x + (matrix ? matrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1569
- tempBounds.y -= (bounds.y + (matrix ? matrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1611
+ const {fitMatrix: fitMatrix} = shape;
1612
+ tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1613
+ tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1570
1614
  tempBounds.width *= spreadScale;
1571
1615
  tempBounds.height *= spreadScale;
1572
1616
  }
1573
1617
  canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1574
- }
1575
- else {
1618
+ } else {
1576
1619
  if (spreadScale) {
1577
1620
  copy(tempBounds, outBounds);
1578
- tempBounds.x -= (outBounds.width / 2) * (spreadScale - 1);
1579
- tempBounds.y -= (outBounds.height / 2) * (spreadScale - 1);
1621
+ tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
1622
+ tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
1580
1623
  tempBounds.width *= spreadScale;
1581
1624
  tempBounds.height *= spreadScale;
1582
1625
  }
@@ -1584,174 +1627,184 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1584
1627
  }
1585
1628
  }
1586
1629
 
1587
- const { toOffsetOutBounds } = BoundsHelper;
1630
+ const {toOffsetOutBounds: toOffsetOutBounds} = BoundsHelper;
1631
+
1588
1632
  const offsetOutBounds = {};
1633
+
1589
1634
  function innerShadow(ui, current, shape) {
1590
1635
  let copyBounds, spreadScale;
1591
- const { __nowWorld: nowWorld, __layout } = ui;
1592
- const { innerShadow } = ui.__;
1593
- const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1636
+ const {__nowWorld: nowWorld, __layout: __layout} = ui;
1637
+ const {innerShadow: innerShadow} = ui.__;
1638
+ const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1594
1639
  const other = current.getSameCanvas();
1595
1640
  const end = innerShadow.length - 1;
1596
1641
  toOffsetOutBounds(bounds, offsetOutBounds);
1597
1642
  innerShadow.forEach((item, index) => {
1643
+ let otherScale = 1;
1644
+ if (item.scaleFixed) {
1645
+ const sx = Math.abs(nowWorld.scaleX);
1646
+ if (sx > 1) otherScale = 1 / sx;
1647
+ }
1598
1648
  other.save();
1599
- other.setWorldShadow((offsetOutBounds.offsetX + item.x * scaleX), (offsetOutBounds.offsetY + item.y * scaleY), item.blur * scaleX);
1600
- spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) : 0;
1649
+ other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
1650
+ spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1601
1651
  drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1602
1652
  other.restore();
1603
1653
  if (worldCanvas) {
1604
- other.copyWorld(other, bounds, nowWorld, 'copy');
1605
- other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
1654
+ other.copyWorld(other, bounds, nowWorld, "copy");
1655
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
1606
1656
  copyBounds = nowWorld;
1607
- }
1608
- else {
1609
- other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
1657
+ } else {
1658
+ other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
1610
1659
  copyBounds = bounds;
1611
1660
  }
1612
- other.fillWorld(copyBounds, ColorConvert.string(item.color), 'source-in');
1661
+ other.fillWorld(copyBounds, ColorConvert.string(item.color), "source-in");
1613
1662
  LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1614
- if (end && index < end)
1615
- other.clearWorld(copyBounds, true);
1663
+ if (end && index < end) other.clearWorld(copyBounds, true);
1616
1664
  });
1617
1665
  other.recycle(copyBounds);
1618
1666
  }
1619
1667
 
1620
1668
  function blur(ui, current, origin) {
1621
- const { blur } = ui.__;
1669
+ const {blur: blur} = ui.__;
1622
1670
  origin.setWorldBlur(blur * ui.__nowWorld.a);
1623
1671
  origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
1624
- origin.filter = 'none';
1672
+ origin.filter = "none";
1625
1673
  }
1626
1674
 
1627
- function backgroundBlur(_ui, _current, _shape) {
1628
- }
1675
+ function backgroundBlur(_ui, _current, _shape) {}
1629
1676
 
1630
1677
  const EffectModule = {
1631
- shadow,
1632
- innerShadow,
1633
- blur,
1634
- backgroundBlur
1678
+ shadow: shadow,
1679
+ innerShadow: innerShadow,
1680
+ blur: blur,
1681
+ backgroundBlur: backgroundBlur
1635
1682
  };
1636
1683
 
1637
- const { excludeRenderBounds } = LeafBoundsHelper;
1638
- Group.prototype.__renderMask = function (canvas, options) {
1684
+ const {excludeRenderBounds: excludeRenderBounds} = LeafBoundsHelper;
1685
+
1686
+ let usedGrayscaleAlpha;
1687
+
1688
+ Group.prototype.__renderMask = function(canvas, options) {
1639
1689
  let child, maskCanvas, contentCanvas, maskOpacity, currentMask, mask;
1640
- const { children } = this;
1690
+ const {children: children} = this;
1641
1691
  for (let i = 0, len = children.length; i < len; i++) {
1642
1692
  child = children[i], mask = child.__.mask;
1643
1693
  if (mask) {
1644
1694
  if (currentMask) {
1645
- maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1695
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1646
1696
  maskCanvas = contentCanvas = null;
1647
1697
  }
1648
- if (mask === 'path' || mask === 'clipping-path') {
1649
- if (child.opacity < 1) {
1650
- currentMask = 'opacity-path';
1651
- maskOpacity = child.opacity;
1652
- if (!contentCanvas)
1653
- contentCanvas = getCanvas(canvas);
1654
- }
1655
- else {
1656
- currentMask = 'path';
1698
+ maskOpacity = child.__.opacity;
1699
+ usedGrayscaleAlpha = false;
1700
+ if (mask === "path" || mask === "clipping-path") {
1701
+ if (maskOpacity < 1) {
1702
+ currentMask = "opacity-path";
1703
+ if (!contentCanvas) contentCanvas = getCanvas(canvas);
1704
+ } else {
1705
+ currentMask = "path";
1657
1706
  canvas.save();
1658
1707
  }
1659
1708
  child.__clip(contentCanvas || canvas, options);
1660
- }
1661
- else {
1662
- currentMask = mask === 'grayscale' ? 'grayscale' : 'alpha';
1663
- if (!maskCanvas)
1664
- maskCanvas = getCanvas(canvas);
1665
- if (!contentCanvas)
1666
- contentCanvas = getCanvas(canvas);
1709
+ } else {
1710
+ currentMask = mask === "grayscale" ? "grayscale" : "alpha";
1711
+ if (!maskCanvas) maskCanvas = getCanvas(canvas);
1712
+ if (!contentCanvas) contentCanvas = getCanvas(canvas);
1667
1713
  child.__render(maskCanvas, options);
1668
1714
  }
1669
- if (mask === 'clipping' || mask === 'clipping-path')
1670
- excludeRenderBounds(child, options) || child.__render(canvas, options);
1715
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1671
1716
  continue;
1672
1717
  }
1718
+ const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
1719
+ if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, false);
1673
1720
  excludeRenderBounds(child, options) || child.__render(contentCanvas || canvas, options);
1721
+ if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, childBlendMode, false);
1674
1722
  }
1675
- maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1723
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1676
1724
  };
1677
- function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
1725
+
1726
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity, blendMode, recycle) {
1678
1727
  switch (maskMode) {
1679
- case 'grayscale':
1680
- maskCanvas.useGrayscaleAlpha(leaf.__nowWorld);
1681
- case 'alpha':
1682
- usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
1683
- break;
1684
- case 'opacity-path':
1685
- copyContent(leaf, canvas, contentCanvas, maskOpacity);
1686
- break;
1687
- case 'path':
1688
- canvas.restore();
1728
+ case "grayscale":
1729
+ if (!usedGrayscaleAlpha) usedGrayscaleAlpha = true, maskCanvas.useGrayscaleAlpha(leaf.__nowWorld);
1730
+
1731
+ case "alpha":
1732
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas, blendMode, recycle);
1733
+ break;
1734
+
1735
+ case "opacity-path":
1736
+ copyContent(leaf, canvas, contentCanvas, maskOpacity, blendMode, recycle);
1737
+ break;
1738
+
1739
+ case "path":
1740
+ if (recycle) canvas.restore();
1689
1741
  }
1690
1742
  }
1743
+
1691
1744
  function getCanvas(canvas) {
1692
1745
  return canvas.getSameCanvas(false, true);
1693
1746
  }
1694
- function usePixelMask(leaf, canvas, content, mask) {
1747
+
1748
+ function usePixelMask(leaf, canvas, content, mask, blendMode, recycle) {
1695
1749
  const realBounds = leaf.__nowWorld;
1696
1750
  content.resetTransform();
1697
1751
  content.opacity = 1;
1698
1752
  content.useMask(mask, realBounds);
1699
- mask.recycle(realBounds);
1700
- copyContent(leaf, canvas, content, 1);
1753
+ if (recycle) mask.recycle(realBounds);
1754
+ copyContent(leaf, canvas, content, 1, blendMode, recycle);
1701
1755
  }
1702
- function copyContent(leaf, canvas, content, maskOpacity) {
1756
+
1757
+ function copyContent(leaf, canvas, content, maskOpacity, blendMode, recycle) {
1703
1758
  const realBounds = leaf.__nowWorld;
1704
1759
  canvas.resetTransform();
1705
1760
  canvas.opacity = maskOpacity;
1706
- canvas.copyWorld(content, realBounds);
1707
- content.recycle(realBounds);
1708
- }
1709
-
1710
- const money = '¥¥$€££¢¢';
1711
- const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
1712
- const langBefore = '《(「〈『〖【〔{┌<‘“=' + money;
1713
- const langAfter = '》)」〉』〗】〕}┐>’”!?,、。:;‰';
1714
- const langSymbol = '≮≯≈≠=…';
1715
- const langBreak$1 = '—/~|┆·';
1716
- const beforeChar = '{[(<\'"' + langBefore;
1717
- const afterChar = '>)]}%!?,.:;\'"' + langAfter;
1718
- const symbolChar = afterChar + '_#~&*+\\=|' + langSymbol;
1719
- const breakChar = '- ' + langBreak$1;
1720
- const cjkRangeList = [
1721
- [0x4E00, 0x9FFF],
1722
- [0x3400, 0x4DBF],
1723
- [0x20000, 0x2A6DF],
1724
- [0x2A700, 0x2B73F],
1725
- [0x2B740, 0x2B81F],
1726
- [0x2B820, 0x2CEAF],
1727
- [0x2CEB0, 0x2EBEF],
1728
- [0x30000, 0x3134F],
1729
- [0x31350, 0x323AF],
1730
- [0x2E80, 0x2EFF],
1731
- [0x2F00, 0x2FDF],
1732
- [0x2FF0, 0x2FFF],
1733
- [0x3000, 0x303F],
1734
- [0x31C0, 0x31EF],
1735
- [0x3200, 0x32FF],
1736
- [0x3300, 0x33FF],
1737
- [0xF900, 0xFAFF],
1738
- [0xFE30, 0xFE4F],
1739
- [0x1F200, 0x1F2FF],
1740
- [0x2F800, 0x2FA1F],
1741
- ];
1742
- const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join('|'));
1761
+ canvas.copyWorld(content, realBounds, undefined, blendMode);
1762
+ recycle ? content.recycle(realBounds) : content.clearWorld(realBounds, true);
1763
+ }
1764
+
1765
+ const money = "¥¥$€££¢¢";
1766
+
1767
+ const letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
1768
+
1769
+ const langBefore = "《(「〈『〖【〔{┌<‘“=" + money;
1770
+
1771
+ const langAfter = "》)」〉』〗】〕}┐>’”!?,、。:;‰";
1772
+
1773
+ const langSymbol = "≮≯≈≠=…";
1774
+
1775
+ const langBreak$1 = "—/~|┆·";
1776
+
1777
+ const beforeChar = "{[(<'\"" + langBefore;
1778
+
1779
+ const afterChar = ">)]}%!?,.:;'\"" + langAfter;
1780
+
1781
+ const symbolChar = afterChar + "_#~&*+\\=|" + langSymbol;
1782
+
1783
+ const breakChar = "- " + langBreak$1;
1784
+
1785
+ const cjkRangeList = [ [ 19968, 40959 ], [ 13312, 19903 ], [ 131072, 173791 ], [ 173824, 177983 ], [ 177984, 178207 ], [ 178208, 183983 ], [ 183984, 191471 ], [ 196608, 201551 ], [ 201552, 205743 ], [ 11904, 12031 ], [ 12032, 12255 ], [ 12272, 12287 ], [ 12288, 12351 ], [ 12736, 12783 ], [ 12800, 13055 ], [ 13056, 13311 ], [ 63744, 64255 ], [ 65072, 65103 ], [ 127488, 127743 ], [ 194560, 195103 ] ];
1786
+
1787
+ const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join("|"));
1788
+
1743
1789
  function mapChar(str) {
1744
1790
  const map = {};
1745
- str.split('').forEach(char => map[char] = true);
1791
+ str.split("").forEach(char => map[char] = true);
1746
1792
  return map;
1747
1793
  }
1794
+
1748
1795
  const letterMap = mapChar(letter);
1796
+
1749
1797
  const beforeMap = mapChar(beforeChar);
1798
+
1750
1799
  const afterMap = mapChar(afterChar);
1800
+
1751
1801
  const symbolMap = mapChar(symbolChar);
1802
+
1752
1803
  const breakMap = mapChar(breakChar);
1804
+
1753
1805
  var CharType;
1754
- (function (CharType) {
1806
+
1807
+ (function(CharType) {
1755
1808
  CharType[CharType["Letter"] = 0] = "Letter";
1756
1809
  CharType[CharType["Single"] = 1] = "Single";
1757
1810
  CharType[CharType["Before"] = 2] = "Before";
@@ -1759,179 +1812,175 @@ var CharType;
1759
1812
  CharType[CharType["Symbol"] = 4] = "Symbol";
1760
1813
  CharType[CharType["Break"] = 5] = "Break";
1761
1814
  })(CharType || (CharType = {}));
1762
- const { Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1 } = CharType;
1815
+
1816
+ const {Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1} = CharType;
1817
+
1763
1818
  function getCharType(char) {
1764
1819
  if (letterMap[char]) {
1765
1820
  return Letter$1;
1766
- }
1767
- else if (breakMap[char]) {
1821
+ } else if (breakMap[char]) {
1768
1822
  return Break$1;
1769
- }
1770
- else if (beforeMap[char]) {
1823
+ } else if (beforeMap[char]) {
1771
1824
  return Before$1;
1772
- }
1773
- else if (afterMap[char]) {
1825
+ } else if (afterMap[char]) {
1774
1826
  return After$1;
1775
- }
1776
- else if (symbolMap[char]) {
1827
+ } else if (symbolMap[char]) {
1777
1828
  return Symbol$1;
1778
- }
1779
- else if (cjkReg.test(char)) {
1829
+ } else if (cjkReg.test(char)) {
1780
1830
  return Single$1;
1781
- }
1782
- else {
1831
+ } else {
1783
1832
  return Letter$1;
1784
1833
  }
1785
1834
  }
1786
1835
 
1787
1836
  const TextRowHelper = {
1788
1837
  trimRight(row) {
1789
- const { words } = row;
1838
+ const {words: words} = row;
1790
1839
  let trimRight = 0, len = words.length, char;
1791
1840
  for (let i = len - 1; i > -1; i--) {
1792
1841
  char = words[i].data[0];
1793
- if (char.char === ' ') {
1842
+ if (char.char === " ") {
1794
1843
  trimRight++;
1795
1844
  row.width -= char.width;
1796
- }
1797
- else {
1845
+ } else {
1798
1846
  break;
1799
1847
  }
1800
1848
  }
1801
- if (trimRight)
1802
- words.splice(len - trimRight, trimRight);
1849
+ if (trimRight) words.splice(len - trimRight, trimRight);
1803
1850
  }
1804
1851
  };
1805
1852
 
1806
1853
  function getTextCase(char, textCase, firstChar) {
1807
1854
  switch (textCase) {
1808
- case 'title':
1809
- return firstChar ? char.toUpperCase() : char;
1810
- case 'upper':
1811
- return char.toUpperCase();
1812
- case 'lower':
1813
- return char.toLowerCase();
1814
- default:
1815
- return char;
1855
+ case "title":
1856
+ return firstChar ? char.toUpperCase() : char;
1857
+
1858
+ case "upper":
1859
+ return char.toUpperCase();
1860
+
1861
+ case "lower":
1862
+ return char.toLowerCase();
1863
+
1864
+ default:
1865
+ return char;
1816
1866
  }
1817
1867
  }
1818
1868
 
1819
- const { trimRight } = TextRowHelper;
1820
- const { Letter, Single, Before, After, Symbol, Break } = CharType;
1869
+ const {trimRight: trimRight} = TextRowHelper;
1870
+
1871
+ const {Letter: Letter, Single: Single, Before: Before, After: After, Symbol: Symbol, Break: Break} = CharType;
1872
+
1821
1873
  let word, row, wordWidth, rowWidth, realWidth;
1874
+
1822
1875
  let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
1876
+
1823
1877
  let textDrawData, rows = [], bounds, findMaxWidth;
1878
+
1824
1879
  function createRows(drawData, content, style) {
1825
1880
  textDrawData = drawData;
1826
1881
  rows = drawData.rows;
1827
1882
  bounds = drawData.bounds;
1828
1883
  findMaxWidth = !bounds.width && !style.autoSizeAlign;
1829
- const { __letterSpacing, paraIndent, textCase } = style;
1830
- const { canvas } = Platform;
1831
- const { width, height } = bounds;
1832
- const charMode = width || height || __letterSpacing || (textCase !== 'none');
1884
+ const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
1885
+ const {canvas: canvas} = Platform;
1886
+ const {width: width, height: height} = bounds;
1887
+ const charMode = width || height || __letterSpacing || textCase !== "none";
1833
1888
  if (charMode) {
1834
- const wrap = style.textWrap !== 'none';
1835
- const breakAll = style.textWrap === 'break';
1889
+ const wrap = style.textWrap !== "none";
1890
+ const breakAll = style.textWrap === "break";
1836
1891
  paraStart = true;
1837
1892
  lastCharType = null;
1838
1893
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1839
- word = { data: [] }, row = { words: [] };
1840
- if (__letterSpacing)
1841
- content = [...content];
1894
+ word = {
1895
+ data: []
1896
+ }, row = {
1897
+ words: []
1898
+ };
1899
+ if (__letterSpacing) content = [ ...content ];
1842
1900
  for (let i = 0, len = content.length; i < len; i++) {
1843
1901
  char = content[i];
1844
- if (char === '\n') {
1845
- if (wordWidth)
1846
- addWord();
1902
+ if (char === "\n") {
1903
+ if (wordWidth) addWord();
1847
1904
  row.paraEnd = true;
1848
1905
  addRow();
1849
1906
  paraStart = true;
1850
- }
1851
- else {
1907
+ } else {
1852
1908
  charType = getCharType(char);
1853
- if (charType === Letter && textCase !== 'none')
1854
- char = getTextCase(char, textCase, !wordWidth);
1909
+ if (charType === Letter && textCase !== "none") char = getTextCase(char, textCase, !wordWidth);
1855
1910
  charWidth = canvas.measureText(char).width;
1856
1911
  if (__letterSpacing) {
1857
- if (__letterSpacing < 0)
1858
- charSize = charWidth;
1912
+ if (__letterSpacing < 0) charSize = charWidth;
1859
1913
  charWidth += __letterSpacing;
1860
1914
  }
1861
- langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
1862
- afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
1915
+ langBreak = charType === Single && (lastCharType === Single || lastCharType === Letter) || lastCharType === Single && charType !== After;
1916
+ afterBreak = (charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After);
1863
1917
  realWidth = paraStart && paraIndent ? width - paraIndent : width;
1864
1918
  if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
1865
1919
  if (breakAll) {
1866
- if (wordWidth)
1867
- addWord();
1868
- if (rowWidth)
1869
- addRow();
1870
- }
1871
- else {
1872
- if (!afterBreak)
1873
- afterBreak = charType === Letter && lastCharType == After;
1874
- if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
1875
- if (wordWidth)
1876
- addWord();
1877
- if (rowWidth)
1878
- addRow();
1879
- }
1880
- else {
1881
- if (rowWidth)
1882
- addRow();
1920
+ if (wordWidth) addWord();
1921
+ if (rowWidth) addRow();
1922
+ } else {
1923
+ if (!afterBreak) afterBreak = charType === Letter && lastCharType == After;
1924
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || wordWidth + charWidth > realWidth) {
1925
+ if (wordWidth) addWord();
1926
+ if (rowWidth) addRow();
1927
+ } else {
1928
+ if (rowWidth) addRow();
1883
1929
  }
1884
1930
  }
1885
1931
  }
1886
- if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
1887
- else {
1932
+ if (char === " " && paraStart !== true && rowWidth + wordWidth === 0) ; else {
1888
1933
  if (charType === Break) {
1889
- if (char === ' ' && wordWidth)
1890
- addWord();
1934
+ if (char === " " && wordWidth) addWord();
1891
1935
  addChar(char, charWidth);
1892
1936
  addWord();
1893
- }
1894
- else if (langBreak || afterBreak) {
1895
- if (wordWidth)
1896
- addWord();
1937
+ } else if (langBreak || afterBreak) {
1938
+ if (wordWidth) addWord();
1897
1939
  addChar(char, charWidth);
1898
- }
1899
- else {
1940
+ } else {
1900
1941
  addChar(char, charWidth);
1901
1942
  }
1902
1943
  }
1903
1944
  lastCharType = charType;
1904
1945
  }
1905
1946
  }
1906
- if (wordWidth)
1907
- addWord();
1908
- if (rowWidth)
1909
- addRow();
1947
+ if (wordWidth) addWord();
1948
+ if (rowWidth) addRow();
1910
1949
  rows.length > 0 && (rows[rows.length - 1].paraEnd = true);
1911
- }
1912
- else {
1913
- content.split('\n').forEach(content => {
1950
+ } else {
1951
+ content.split("\n").forEach(content => {
1914
1952
  textDrawData.paraNumber++;
1915
1953
  rowWidth = canvas.measureText(content).width;
1916
- rows.push({ x: paraIndent || 0, text: content, width: rowWidth, paraStart: true });
1917
- if (findMaxWidth)
1918
- setMaxWidth();
1954
+ rows.push({
1955
+ x: paraIndent || 0,
1956
+ text: content,
1957
+ width: rowWidth,
1958
+ paraStart: true
1959
+ });
1960
+ if (findMaxWidth) setMaxWidth();
1919
1961
  });
1920
1962
  }
1921
1963
  }
1964
+
1922
1965
  function addChar(char, width) {
1923
- if (charSize && !startCharSize)
1924
- startCharSize = charSize;
1925
- word.data.push({ char, width });
1966
+ if (charSize && !startCharSize) startCharSize = charSize;
1967
+ word.data.push({
1968
+ char: char,
1969
+ width: width
1970
+ });
1926
1971
  wordWidth += width;
1927
1972
  }
1973
+
1928
1974
  function addWord() {
1929
1975
  rowWidth += wordWidth;
1930
1976
  word.width = wordWidth;
1931
1977
  row.words.push(word);
1932
- word = { data: [] };
1978
+ word = {
1979
+ data: []
1980
+ };
1933
1981
  wordWidth = 0;
1934
1982
  }
1983
+
1935
1984
  function addRow() {
1936
1985
  if (paraStart) {
1937
1986
  textDrawData.paraNumber++;
@@ -1944,52 +1993,53 @@ function addRow() {
1944
1993
  startCharSize = 0;
1945
1994
  }
1946
1995
  row.width = rowWidth;
1947
- if (bounds.width)
1948
- trimRight(row);
1949
- else if (findMaxWidth)
1950
- setMaxWidth();
1996
+ if (bounds.width) trimRight(row); else if (findMaxWidth) setMaxWidth();
1951
1997
  rows.push(row);
1952
- row = { words: [] };
1998
+ row = {
1999
+ words: []
2000
+ };
1953
2001
  rowWidth = 0;
1954
2002
  }
2003
+
1955
2004
  function setMaxWidth() {
1956
- if (rowWidth > (textDrawData.maxWidth || 0))
1957
- textDrawData.maxWidth = rowWidth;
2005
+ if (rowWidth > (textDrawData.maxWidth || 0)) textDrawData.maxWidth = rowWidth;
1958
2006
  }
1959
2007
 
1960
2008
  const CharMode = 0;
2009
+
1961
2010
  const WordMode = 1;
2011
+
1962
2012
  const TextMode = 2;
2013
+
1963
2014
  function layoutChar(drawData, style, width, _height) {
1964
- const { rows } = drawData;
1965
- const { textAlign, paraIndent, letterSpacing } = style;
2015
+ const {rows: rows} = drawData;
2016
+ const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
1966
2017
  let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
1967
2018
  rows.forEach(row => {
1968
2019
  if (row.words) {
1969
2020
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
1970
- addWordWidth = (width && (textAlign === 'justify' || textAlign === 'both') && wordsLength > 1) ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
1971
- mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
1972
- if (row.isOverflow && !letterSpacing)
1973
- row.textMode = true;
2021
+ addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2022
+ mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2023
+ if (row.isOverflow && !letterSpacing) row.textMode = true;
1974
2024
  if (mode === TextMode) {
1975
2025
  row.x += indentWidth;
1976
2026
  toTextChar$1(row);
1977
- }
1978
- else {
2027
+ } else {
1979
2028
  row.x += indentWidth;
1980
2029
  charX = row.x;
1981
2030
  row.data = [];
1982
2031
  row.words.forEach((word, index) => {
1983
2032
  if (mode === WordMode) {
1984
- wordChar = { char: '', x: charX };
2033
+ wordChar = {
2034
+ char: "",
2035
+ x: charX
2036
+ };
1985
2037
  charX = toWordChar(word.data, charX, wordChar);
1986
- if (row.isOverflow || wordChar.char !== ' ')
1987
- row.data.push(wordChar);
1988
- }
1989
- else {
2038
+ if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2039
+ } else {
1990
2040
  charX = toChar(word.data, charX, row.data, row.isOverflow);
1991
2041
  }
1992
- if (addWordWidth && (!row.paraEnd || textAlign === 'both') && (index !== wordsLength - 1)) {
2042
+ if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
1993
2043
  charX += addWordWidth;
1994
2044
  row.width += addWordWidth;
1995
2045
  }
@@ -1999,14 +2049,16 @@ function layoutChar(drawData, style, width, _height) {
1999
2049
  }
2000
2050
  });
2001
2051
  }
2052
+
2002
2053
  function toTextChar$1(row) {
2003
- row.text = '';
2054
+ row.text = "";
2004
2055
  row.words.forEach(word => {
2005
2056
  word.data.forEach(char => {
2006
2057
  row.text += char.char;
2007
2058
  });
2008
2059
  });
2009
2060
  }
2061
+
2010
2062
  function toWordChar(data, charX, wordChar) {
2011
2063
  data.forEach(char => {
2012
2064
  wordChar.char += char.char;
@@ -2014,9 +2066,10 @@ function toWordChar(data, charX, wordChar) {
2014
2066
  });
2015
2067
  return charX;
2016
2068
  }
2069
+
2017
2070
  function toChar(data, charX, rowData, isOverflow) {
2018
2071
  data.forEach(char => {
2019
- if (isOverflow || char.char !== ' ') {
2072
+ if (isOverflow || char.char !== " ") {
2020
2073
  char.x = charX;
2021
2074
  rowData.push(char);
2022
2075
  }
@@ -2026,38 +2079,39 @@ function toChar(data, charX, rowData, isOverflow) {
2026
2079
  }
2027
2080
 
2028
2081
  function layoutText(drawData, style) {
2029
- const { rows, bounds } = drawData, countRows = rows.length;
2030
- const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
2031
- let { x, y, width, height } = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2082
+ const {rows: rows, bounds: bounds} = drawData, countRows = rows.length;
2083
+ const {__lineHeight: __lineHeight, __baseLine: __baseLine, __letterSpacing: __letterSpacing, __clipText: __clipText, textAlign: textAlign, verticalAlign: verticalAlign, paraSpacing: paraSpacing, autoSizeAlign: autoSizeAlign} = style;
2084
+ let {x: x, y: y, width: width, height: height} = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2032
2085
  let starY = __baseLine;
2033
2086
  if (__clipText && realHeight > height) {
2034
2087
  realHeight = Math.max(height, __lineHeight);
2035
- if (countRows > 1)
2036
- drawData.overflow = countRows;
2037
- }
2038
- else if (height || autoSizeAlign) {
2088
+ if (countRows > 1) drawData.overflow = countRows;
2089
+ } else if (height || autoSizeAlign) {
2039
2090
  switch (verticalAlign) {
2040
- case 'middle':
2041
- y += (height - realHeight) / 2;
2042
- break;
2043
- case 'bottom': y += (height - realHeight);
2091
+ case "middle":
2092
+ y += (height - realHeight) / 2;
2093
+ break;
2094
+
2095
+ case "bottom":
2096
+ y += height - realHeight;
2044
2097
  }
2045
2098
  }
2046
2099
  starY += y;
2047
- let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
2100
+ let row, rowX, rowWidth, layoutWidth = width || autoSizeAlign ? width : drawData.maxWidth;
2048
2101
  for (let i = 0, len = countRows; i < len; i++) {
2049
2102
  row = rows[i];
2050
2103
  row.x = x;
2051
- if (row.width < width || (row.width > width && !__clipText)) {
2104
+ if (row.width < width || row.width > width && !__clipText) {
2052
2105
  switch (textAlign) {
2053
- case 'center':
2054
- row.x += (layoutWidth - row.width) / 2;
2055
- break;
2056
- case 'right': row.x += layoutWidth - row.width;
2106
+ case "center":
2107
+ row.x += (layoutWidth - row.width) / 2;
2108
+ break;
2109
+
2110
+ case "right":
2111
+ row.x += layoutWidth - row.width;
2057
2112
  }
2058
2113
  }
2059
- if (row.paraStart && paraSpacing && i > 0)
2060
- starY += paraSpacing;
2114
+ if (row.paraStart && paraSpacing && i > 0) starY += paraSpacing;
2061
2115
  row.y = starY;
2062
2116
  starY += __lineHeight;
2063
2117
  if (drawData.overflow > i && starY > realHeight) {
@@ -2071,19 +2125,15 @@ function layoutText(drawData, style) {
2071
2125
  rowWidth = -row.width + style.fontSize + __letterSpacing;
2072
2126
  rowX -= rowWidth;
2073
2127
  rowWidth += style.fontSize;
2074
- }
2075
- else {
2128
+ } else {
2076
2129
  rowWidth -= __letterSpacing;
2077
2130
  }
2078
2131
  }
2079
- if (rowX < bounds.x)
2080
- bounds.x = rowX;
2081
- if (rowWidth > bounds.width)
2082
- bounds.width = rowWidth;
2132
+ if (rowX < bounds.x) bounds.x = rowX;
2133
+ if (rowWidth > bounds.width) bounds.width = rowWidth;
2083
2134
  if (__clipText && width && width < rowWidth) {
2084
2135
  row.isOverflow = true;
2085
- if (!drawData.overflow)
2086
- drawData.overflow = rows.length;
2136
+ if (!drawData.overflow) drawData.overflow = rows.length;
2087
2137
  }
2088
2138
  }
2089
2139
  bounds.y = y;
@@ -2091,20 +2141,16 @@ function layoutText(drawData, style) {
2091
2141
  }
2092
2142
 
2093
2143
  function clipText(drawData, style, x, width) {
2094
- if (!width)
2095
- return;
2096
- const { rows, overflow } = drawData;
2097
- let { textOverflow } = style;
2144
+ if (!width) return;
2145
+ const {rows: rows, overflow: overflow} = drawData;
2146
+ let {textOverflow: textOverflow} = style;
2098
2147
  rows.splice(overflow);
2099
- if (textOverflow && textOverflow !== 'show') {
2100
- if (textOverflow === 'hide')
2101
- textOverflow = '';
2102
- else if (textOverflow === 'ellipsis')
2103
- textOverflow = '...';
2148
+ if (textOverflow && textOverflow !== "show") {
2149
+ if (textOverflow === "hide") textOverflow = ""; else if (textOverflow === "ellipsis") textOverflow = "...";
2104
2150
  let char, charRight;
2105
2151
  const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
2106
2152
  const right = x + width - ellipsisWidth;
2107
- const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2153
+ const list = style.textWrap === "none" ? rows : [ rows[overflow - 1] ];
2108
2154
  list.forEach(row => {
2109
2155
  if (row.isOverflow && row.data) {
2110
2156
  let end = row.data.length - 1;
@@ -2113,8 +2159,7 @@ function clipText(drawData, style, x, width) {
2113
2159
  charRight = char.x + char.width;
2114
2160
  if (i === end && charRight < right) {
2115
2161
  break;
2116
- }
2117
- else if ((charRight < right && char.char !== ' ') || !i) {
2162
+ } else if (charRight < right && char.char !== " " || !i) {
2118
2163
  row.data.splice(i + 1);
2119
2164
  row.width -= char.width;
2120
2165
  break;
@@ -2122,15 +2167,18 @@ function clipText(drawData, style, x, width) {
2122
2167
  row.width -= char.width;
2123
2168
  }
2124
2169
  row.width += ellipsisWidth;
2125
- row.data.push({ char: textOverflow, x: charRight });
2126
- if (row.textMode)
2127
- toTextChar(row);
2170
+ row.data.push({
2171
+ char: textOverflow,
2172
+ x: charRight
2173
+ });
2174
+ if (row.textMode) toTextChar(row);
2128
2175
  }
2129
2176
  });
2130
2177
  }
2131
2178
  }
2179
+
2132
2180
  function toTextChar(row) {
2133
- row.text = '';
2181
+ row.text = "";
2134
2182
  row.data.forEach(char => {
2135
2183
  row.text += char.char;
2136
2184
  });
@@ -2139,115 +2187,116 @@ function toTextChar(row) {
2139
2187
 
2140
2188
  function decorationText(drawData, style) {
2141
2189
  let type;
2142
- const { fontSize, textDecoration } = style;
2190
+ const {fontSize: fontSize, textDecoration: textDecoration} = style;
2143
2191
  drawData.decorationHeight = fontSize / 11;
2144
- if (typeof textDecoration === 'object') {
2192
+ if (isObject(textDecoration)) {
2145
2193
  type = textDecoration.type;
2146
- if (textDecoration.color)
2147
- drawData.decorationColor = ColorConvert.string(textDecoration.color);
2148
- }
2149
- else
2150
- type = textDecoration;
2194
+ if (textDecoration.color) drawData.decorationColor = ColorConvert.string(textDecoration.color);
2195
+ } else type = textDecoration;
2151
2196
  switch (type) {
2152
- case 'under':
2153
- drawData.decorationY = [fontSize * 0.15];
2154
- break;
2155
- case 'delete':
2156
- drawData.decorationY = [-fontSize * 0.35];
2157
- break;
2158
- case 'under-delete':
2159
- drawData.decorationY = [fontSize * 0.15, -fontSize * 0.35];
2197
+ case "under":
2198
+ drawData.decorationY = [ fontSize * .15 ];
2199
+ break;
2200
+
2201
+ case "delete":
2202
+ drawData.decorationY = [ -fontSize * .35 ];
2203
+ break;
2204
+
2205
+ case "under-delete":
2206
+ drawData.decorationY = [ fontSize * .15, -fontSize * .35 ];
2160
2207
  }
2161
2208
  }
2162
2209
 
2163
- const { top, right, bottom, left } = Direction4;
2210
+ const {top: top, right: right, bottom: bottom, left: left} = Direction4;
2211
+
2164
2212
  function getDrawData(content, style) {
2165
- if (typeof content !== 'string')
2166
- content = String(content);
2213
+ if (!isString(content)) content = String(content);
2167
2214
  let x = 0, y = 0;
2168
- let width = style.__getInput('width') || 0;
2169
- let height = style.__getInput('height') || 0;
2170
- const { textDecoration, __font, __padding: padding } = style;
2215
+ let width = style.__getInput("width") || 0;
2216
+ let height = style.__getInput("height") || 0;
2217
+ const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2171
2218
  if (padding) {
2172
- if (width)
2173
- x = padding[left], width -= (padding[right] + padding[left]);
2174
- else if (!style.autoSizeAlign)
2175
- x = padding[left];
2176
- if (height)
2177
- y = padding[top], height -= (padding[top] + padding[bottom]);
2178
- else if (!style.autoSizeAlign)
2179
- y = padding[top];
2219
+ if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2220
+ if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2180
2221
  }
2181
2222
  const drawData = {
2182
- bounds: { x, y, width, height },
2223
+ bounds: {
2224
+ x: x,
2225
+ y: y,
2226
+ width: width,
2227
+ height: height
2228
+ },
2183
2229
  rows: [],
2184
2230
  paraNumber: 0,
2185
2231
  font: Platform.canvas.font = __font
2186
2232
  };
2187
2233
  createRows(drawData, content, style);
2188
- if (padding)
2189
- padAutoText(padding, drawData, style, width, height);
2234
+ if (padding) padAutoText(padding, drawData, style, width, height);
2190
2235
  layoutText(drawData, style);
2191
2236
  layoutChar(drawData, style, width);
2192
- if (drawData.overflow)
2193
- clipText(drawData, style, x, width);
2194
- if (textDecoration !== 'none')
2195
- decorationText(drawData, style);
2237
+ if (drawData.overflow) clipText(drawData, style, x, width);
2238
+ if (textDecoration !== "none") decorationText(drawData, style);
2196
2239
  return drawData;
2197
2240
  }
2241
+
2198
2242
  function padAutoText(padding, drawData, style, width, height) {
2199
2243
  if (!width && style.autoSizeAlign) {
2200
2244
  switch (style.textAlign) {
2201
- case 'left':
2202
- offsetText(drawData, 'x', padding[left]);
2203
- break;
2204
- case 'right': offsetText(drawData, 'x', -padding[right]);
2245
+ case "left":
2246
+ offsetText(drawData, "x", padding[left]);
2247
+ break;
2248
+
2249
+ case "right":
2250
+ offsetText(drawData, "x", -padding[right]);
2205
2251
  }
2206
2252
  }
2207
2253
  if (!height && style.autoSizeAlign) {
2208
2254
  switch (style.verticalAlign) {
2209
- case 'top':
2210
- offsetText(drawData, 'y', padding[top]);
2211
- break;
2212
- case 'bottom': offsetText(drawData, 'y', -padding[bottom]);
2255
+ case "top":
2256
+ offsetText(drawData, "y", padding[top]);
2257
+ break;
2258
+
2259
+ case "bottom":
2260
+ offsetText(drawData, "y", -padding[bottom]);
2213
2261
  }
2214
2262
  }
2215
2263
  }
2264
+
2216
2265
  function offsetText(drawData, attrName, value) {
2217
- const { bounds, rows } = drawData;
2266
+ const {bounds: bounds, rows: rows} = drawData;
2218
2267
  bounds[attrName] += value;
2219
- for (let i = 0; i < rows.length; i++)
2220
- rows[i][attrName] += value;
2268
+ for (let i = 0; i < rows.length; i++) rows[i][attrName] += value;
2221
2269
  }
2222
2270
 
2223
2271
  const TextConvertModule = {
2224
- getDrawData
2272
+ getDrawData: getDrawData
2225
2273
  };
2226
2274
 
2227
2275
  function string(color, opacity) {
2228
- const doOpacity = typeof opacity === 'number' && opacity !== 1;
2229
- if (typeof color === 'string') {
2230
- if (doOpacity && ColorConvert.object)
2231
- color = ColorConvert.object(color);
2232
- else
2233
- return color;
2276
+ const doOpacity = isNumber(opacity) && opacity < 1;
2277
+ if (isString(color)) {
2278
+ if (doOpacity && ColorConvert.object) color = ColorConvert.object(color); else return color;
2234
2279
  }
2235
- let a = color.a === undefined ? 1 : color.a;
2236
- if (doOpacity)
2237
- a *= opacity;
2238
- const rgb = color.r + ',' + color.g + ',' + color.b;
2239
- return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2280
+ let a = isUndefined(color.a) ? 1 : color.a;
2281
+ if (doOpacity) a *= opacity;
2282
+ const rgb = color.r + "," + color.g + "," + color.b;
2283
+ return a === 1 ? "rgb(" + rgb + ")" : "rgba(" + rgb + "," + a + ")";
2240
2284
  }
2241
2285
 
2242
2286
  const ColorConvertModule = {
2243
- string
2287
+ string: string
2244
2288
  };
2245
2289
 
2246
2290
  Object.assign(TextConvert, TextConvertModule);
2291
+
2247
2292
  Object.assign(ColorConvert, ColorConvertModule);
2293
+
2248
2294
  Object.assign(Paint, PaintModule);
2295
+
2249
2296
  Object.assign(PaintImage, PaintImageModule);
2297
+
2250
2298
  Object.assign(PaintGradient, PaintGradientModule);
2299
+
2251
2300
  Object.assign(Effect, EffectModule);
2252
2301
 
2253
2302
  useCanvas();