@leafer-draw/worker 1.8.0 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,27 @@ 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
- 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;
873
- if (current.bounds.includes(nowWorld)) {
848
+ const nowWorld = ui.__nowWorld, currentBounds = current.bounds;
849
+ let bounds, matrix, fitMatrix, shapeBounds, worldCanvas;
850
+ let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true);
851
+ if (currentBounds.includes(nowWorld)) {
874
852
  worldCanvas = canvas;
875
853
  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);
880
- fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
881
- let { a: fitScaleX, d: fitScaleY } = fitMatrix;
854
+ } else {
855
+ const {renderShapeSpread: spread} = ui.__layout;
856
+ let worldClipBounds;
857
+ if (Platform.fullImageShadow) {
858
+ worldClipBounds = nowWorld;
859
+ } else {
860
+ const spreadBounds = spread ? getSpread(currentBounds, scaleX === scaleY ? spread * scaleX : [ spread * scaleY, spread * scaleX ]) : currentBounds;
861
+ worldClipBounds = getIntersectData(spreadBounds, nowWorld);
862
+ }
863
+ fitMatrix = currentBounds.getFitMatrix(worldClipBounds);
864
+ let {a: fitScaleX, d: fitScaleY} = fitMatrix;
882
865
  if (fitMatrix.a < 1) {
883
866
  worldCanvas = current.getSameCanvas();
884
867
  ui.__renderShape(worldCanvas, options);
@@ -887,28 +870,39 @@ function shape(ui, current, options) {
887
870
  }
888
871
  shapeBounds = getOuterOf(nowWorld, fitMatrix);
889
872
  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) });
873
+ const userMatrix = options.matrix;
874
+ if (userMatrix) {
875
+ matrix = new Matrix(fitMatrix);
876
+ matrix.multiply(userMatrix);
877
+ fitScaleX *= userMatrix.scaleX;
878
+ fitScaleY *= userMatrix.scaleY;
879
+ } else matrix = fitMatrix;
880
+ matrix.withScale(fitScaleX, fitScaleY);
881
+ options = Object.assign(Object.assign({}, options), {
882
+ matrix: matrix
883
+ });
897
884
  }
898
885
  ui.__renderShape(canvas, options);
899
886
  return {
900
- canvas, matrix: fitMatrix, bounds,
901
- worldCanvas, shapeBounds, scaleX, scaleY
887
+ canvas: canvas,
888
+ matrix: matrix,
889
+ fitMatrix: fitMatrix,
890
+ bounds: bounds,
891
+ worldCanvas: worldCanvas,
892
+ shapeBounds: shapeBounds,
893
+ scaleX: scaleX,
894
+ scaleY: scaleY
902
895
  };
903
896
  }
904
897
 
905
898
  let recycleMap;
906
- const { stintSet } = DataHelper, { hasTransparent: hasTransparent$1 } = ColorConvert;
899
+
900
+ const {stintSet: stintSet} = DataHelper, {hasTransparent: hasTransparent$1} = ColorConvert;
901
+
907
902
  function compute(attrName, ui) {
908
903
  const data = ui.__, leafPaints = [];
909
904
  let paints = data.__input[attrName], isAlphaPixel, isTransparent;
910
- if (!(paints instanceof Array))
911
- paints = [paints];
905
+ if (!isArray(paints)) paints = [ paints ];
912
906
  recycleMap = PaintImage.recycleImage(attrName, data);
913
907
  let maxChildStrokeWidth;
914
908
  for (let i = 0, len = paints.length, item; i < len; i++) {
@@ -916,206 +910,222 @@ function compute(attrName, ui) {
916
910
  leafPaints.push(item);
917
911
  if (item.strokeStyle) {
918
912
  maxChildStrokeWidth || (maxChildStrokeWidth = 1);
919
- if (item.strokeStyle.strokeWidth)
920
- maxChildStrokeWidth = Math.max(maxChildStrokeWidth, item.strokeStyle.strokeWidth);
913
+ if (item.strokeStyle.strokeWidth) maxChildStrokeWidth = Math.max(maxChildStrokeWidth, item.strokeStyle.strokeWidth);
921
914
  }
922
915
  }
923
916
  }
924
- data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
917
+ data["_" + attrName] = leafPaints.length ? leafPaints : undefined;
925
918
  if (leafPaints.length) {
926
919
  if (leafPaints.every(item => item.isTransparent)) {
927
- if (leafPaints.some(item => item.image))
928
- isAlphaPixel = true;
920
+ if (leafPaints.some(item => item.image)) isAlphaPixel = true;
929
921
  isTransparent = true;
930
922
  }
931
923
  }
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);
924
+ if (attrName === "fill") {
925
+ stintSet(data, "__isAlphaPixelFill", isAlphaPixel);
926
+ stintSet(data, "__isTransparentFill", isTransparent);
927
+ } else {
928
+ stintSet(data, "__isAlphaPixelStroke", isAlphaPixel);
929
+ stintSet(data, "__isTransparentStroke", isTransparent);
930
+ stintSet(data, "__hasMultiStrokeStyle", maxChildStrokeWidth);
940
931
  }
941
932
  }
933
+
942
934
  function getLeafPaint(attrName, paint, ui) {
943
- if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
944
- return undefined;
935
+ if (!isObject(paint) || paint.visible === false || paint.opacity === 0) return undefined;
945
936
  let data;
946
- const { boxBounds } = ui.__layout;
937
+ const {boxBounds: boxBounds} = ui.__layout;
947
938
  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) };
939
+ case "image":
940
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
941
+ break;
942
+
943
+ case "linear":
944
+ data = PaintGradient.linearGradient(paint, boxBounds);
945
+ break;
946
+
947
+ case "radial":
948
+ data = PaintGradient.radialGradient(paint, boxBounds);
949
+ break;
950
+
951
+ case "angular":
952
+ data = PaintGradient.conicGradient(paint, boxBounds);
953
+ break;
954
+
955
+ case "solid":
956
+ const {type: type, color: color, opacity: opacity} = paint;
957
+ data = {
958
+ type: type,
959
+ style: ColorConvert.string(color, opacity)
960
+ };
961
+ break;
962
+
963
+ default:
964
+ if (!isUndefined(paint.r)) data = {
965
+ type: "solid",
966
+ style: ColorConvert.string(paint)
967
+ };
967
968
  }
968
969
  if (data) {
969
- if (typeof data.style === 'string' && hasTransparent$1(data.style))
970
- data.isTransparent = true;
970
+ if (isString(data.style) && hasTransparent$1(data.style)) data.isTransparent = true;
971
971
  if (paint.style) {
972
- if (paint.style.strokeWidth === 0)
973
- return undefined;
972
+ if (paint.style.strokeWidth === 0) return undefined;
974
973
  data.strokeStyle = paint.style;
975
974
  }
976
- if (paint.blendMode)
977
- data.blendMode = paint.blendMode;
975
+ if (paint.editing) data.editing = paint.editing;
976
+ if (paint.blendMode) data.blendMode = paint.blendMode;
978
977
  }
979
978
  return data;
980
979
  }
981
980
 
982
981
  const PaintModule = {
983
- compute,
984
- fill,
985
- fills,
986
- fillPathOrText,
987
- fillText,
988
- stroke,
989
- strokes,
990
- strokeText,
991
- drawTextStroke,
992
- shape
982
+ compute: compute,
983
+ fill: fill,
984
+ fills: fills,
985
+ fillPathOrText: fillPathOrText,
986
+ fillText: fillText,
987
+ stroke: stroke,
988
+ strokes: strokes,
989
+ strokeText: strokeText,
990
+ drawTextStroke: drawTextStroke,
991
+ shape: shape
993
992
  };
994
993
 
995
994
  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;
995
+
996
+ const {get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, multiplyParent: multiplyParent, scale: scaleHelper, rotate: rotate, skew: skewHelper} = MatrixHelper;
997
+
997
998
  function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
998
999
  const transform = get$3();
999
1000
  translate$1(transform, box.x + x, box.y + y);
1000
1001
  scaleHelper(transform, scaleX, scaleY);
1001
- if (rotation)
1002
- rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1002
+ if (rotation) rotateOfOuter$1(transform, {
1003
+ x: box.x + box.width / 2,
1004
+ y: box.y + box.height / 2
1005
+ }, rotation);
1003
1006
  data.transform = transform;
1004
1007
  }
1008
+
1005
1009
  function clipMode(data, box, x, y, scaleX, scaleY, rotation, skew, clipSize) {
1006
1010
  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);
1011
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1014
1012
  if (clipSize) {
1015
1013
  tempMatrix.a = box.width / clipSize.width, tempMatrix.d = box.height / clipSize.height;
1016
1014
  multiplyParent(transform, tempMatrix);
1017
1015
  }
1018
1016
  data.transform = transform;
1019
1017
  }
1020
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
1018
+
1019
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, skew, align, freeTransform) {
1021
1020
  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:
1021
+ if (freeTransform) {
1022
+ layout(transform, box, x, y, scaleX, scaleY, rotation, skew);
1023
+ } else {
1024
+ if (rotation) {
1025
+ if (align === "center") {
1026
+ rotateOfOuter$1(transform, {
1027
+ x: width / 2,
1028
+ y: height / 2
1029
+ }, rotation);
1030
+ } else {
1031
+ rotate(transform, rotation);
1032
+ switch (rotation) {
1033
+ case 90:
1030
1034
  translate$1(transform, height, 0);
1031
1035
  break;
1032
- case 180:
1036
+
1037
+ case 180:
1033
1038
  translate$1(transform, width, height);
1034
1039
  break;
1035
- case 270:
1040
+
1041
+ case 270:
1036
1042
  translate$1(transform, 0, width);
1037
1043
  break;
1044
+ }
1038
1045
  }
1039
1046
  }
1047
+ origin.x = box.x + x;
1048
+ origin.y = box.y + y;
1049
+ translate$1(transform, origin.x, origin.y);
1050
+ if (scaleX) scaleOfOuter$1(transform, origin, scaleX, scaleY);
1040
1051
  }
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
1052
  data.transform = transform;
1047
1053
  }
1048
1054
 
1049
- const { get: get$2, translate } = MatrixHelper;
1050
- const tempBox = new Bounds();
1055
+ function layout(transform, box, x, y, scaleX, scaleY, rotation, skew) {
1056
+ if (rotation) rotate(transform, rotation);
1057
+ if (skew) skewHelper(transform, skew.x, skew.y);
1058
+ if (scaleX) scaleHelper(transform, scaleX, scaleY);
1059
+ translate$1(transform, box.x + x, box.y + y);
1060
+ }
1061
+
1062
+ const {get: get$2, translate: translate} = MatrixHelper;
1063
+
1064
+ const tempBox = new Bounds;
1065
+
1051
1066
  const tempScaleData = {};
1067
+
1052
1068
  const tempImage = {};
1069
+
1053
1070
  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;
1071
+ const {changeful: changeful, sync: sync, scaleFixed: scaleFixed} = paint;
1072
+ if (changeful) leafPaint.changeful = changeful;
1073
+ if (sync) leafPaint.sync = sync;
1074
+ if (scaleFixed) leafPaint.scaleFixed = scaleFixed;
1063
1075
  leafPaint.data = getPatternData(paint, box, image);
1064
1076
  }
1077
+
1065
1078
  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;
1079
+ if (paint.padding) box = tempBox.set(box).shrink(paint.padding);
1080
+ if (paint.mode === "strench") paint.mode = "stretch";
1081
+ let {width: width, height: height} = image;
1082
+ 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
1083
  const sameBox = box.width === width && box.height === height;
1073
- const data = { mode };
1074
- const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1084
+ const data = {
1085
+ mode: mode
1086
+ };
1087
+ const swapSize = align !== "center" && (rotation || 0) % 180 === 90;
1075
1088
  BoundsHelper.set(tempImage, 0, 0, swapSize ? height : width, swapSize ? width : height);
1076
1089
  let scaleX, scaleY;
1077
- if (!mode || mode === 'cover' || mode === 'fit') {
1090
+ if (!mode || mode === "cover" || mode === "fit") {
1078
1091
  if (!sameBox || rotation) {
1079
- scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== 'fit');
1092
+ scaleX = scaleY = BoundsHelper.getFitScale(box, tempImage, mode !== "fit");
1080
1093
  BoundsHelper.put(box, image, align, scaleX, false, tempImage);
1081
1094
  BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1082
1095
  }
1083
- }
1084
- else {
1096
+ } else {
1085
1097
  if (scale || size) {
1086
1098
  MathHelper.getScaleData(scale, size, image, tempScaleData);
1087
1099
  scaleX = tempScaleData.scaleX;
1088
1100
  scaleY = tempScaleData.scaleY;
1089
1101
  }
1090
- if (align) {
1091
- if (scaleX)
1092
- BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1093
- AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1102
+ if (align || gap || repeat) {
1103
+ if (scaleX) BoundsHelper.scale(tempImage, scaleX, scaleY, true);
1104
+ if (align) AlignHelper.toPoint(align, tempImage, box, tempImage, true, true);
1094
1105
  }
1095
1106
  }
1096
- if (offset)
1097
- PointHelper.move(tempImage, offset);
1107
+ if (offset) PointHelper.move(tempImage, offset);
1098
1108
  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);
1109
+ case "stretch":
1110
+ if (!sameBox) width = box.width, height = box.height;
1111
+ break;
1112
+
1113
+ case "normal":
1114
+ case "clip":
1115
+ if (tempImage.x || tempImage.y || scaleX || clipSize || rotation || skew) clipMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, paint.clipSize);
1116
+ break;
1117
+
1118
+ case "repeat":
1119
+ if (!sameBox || scaleX || rotation || skew) repeatMode(data, box, width, height, tempImage.x, tempImage.y, scaleX, scaleY, rotation, skew, align, paint.freeTransform);
1120
+ if (!repeat) data.repeat = "repeat";
1121
+ const count = isObject(repeat);
1122
+ if (gap || count) data.gap = getGapData(gap, count && repeat, tempImage.width, tempImage.height, box);
1123
+ break;
1124
+
1125
+ case "fit":
1126
+ case "cover":
1127
+ default:
1128
+ if (scaleX) fillOrFitMode(data, box, tempImage.x, tempImage.y, scaleX, scaleY, rotation);
1119
1129
  }
1120
1130
  if (!data.transform) {
1121
1131
  if (box.x || box.y) {
@@ -1123,49 +1133,69 @@ function getPatternData(paint, box, image) {
1123
1133
  translate(data.transform, box.x, box.y);
1124
1134
  }
1125
1135
  }
1126
- if (scaleX && mode !== 'stretch') {
1136
+ if (scaleX && mode !== "stretch") {
1127
1137
  data.scaleX = scaleX;
1128
1138
  data.scaleY = scaleY;
1129
1139
  }
1130
1140
  data.width = width;
1131
1141
  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';
1142
+ if (opacity) data.opacity = opacity;
1143
+ if (filters) data.filters = filters;
1144
+ if (repeat) data.repeat = isString(repeat) ? repeat === "x" ? "repeat-x" : "repeat-y" : "repeat";
1138
1145
  return data;
1139
1146
  }
1140
1147
 
1141
- let cache, box = new Bounds();
1142
- const { isSame } = BoundsHelper;
1148
+ function getGapData(gap, repeat, width, height, box) {
1149
+ let xGap, yGap;
1150
+ if (isObject(gap)) xGap = gap.x, yGap = gap.y; else xGap = yGap = gap;
1151
+ return {
1152
+ x: getGapValue(xGap, width, box.width, repeat && repeat.x),
1153
+ y: getGapValue(yGap, height, box.height, repeat && repeat.y)
1154
+ };
1155
+ }
1156
+
1157
+ function getGapValue(gap, size, totalSize, rows) {
1158
+ const auto = isString(gap) || rows;
1159
+ const remain = rows ? totalSize - rows * size : totalSize % size;
1160
+ const value = auto ? remain / ((rows || Math.floor(totalSize / size)) - 1) : gap;
1161
+ return gap === "auto" ? value < 0 ? 0 : value : value;
1162
+ }
1163
+
1164
+ let cache, box = new Bounds;
1165
+
1166
+ const {isSame: isSame} = BoundsHelper;
1167
+
1143
1168
  function image(ui, attrName, paint, boxBounds, firstUse) {
1144
1169
  let leafPaint, event;
1145
1170
  const image = ImageManager.get(paint);
1146
1171
  if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1147
1172
  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 };
1173
+ } else {
1174
+ leafPaint = {
1175
+ type: paint.type,
1176
+ image: image
1177
+ };
1178
+ if (image.hasAlphaPixel) leafPaint.isTransparent = true;
1179
+ cache = image.use > 1 ? {
1180
+ leafPaint: leafPaint,
1181
+ paint: paint,
1182
+ boxBounds: box.set(boxBounds)
1183
+ } : null;
1184
+ }
1185
+ if (firstUse || image.loading) event = {
1186
+ image: image,
1187
+ attrName: attrName,
1188
+ attrValue: paint
1189
+ };
1157
1190
  if (image.ready) {
1158
1191
  checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1159
1192
  if (firstUse) {
1160
1193
  onLoad(ui, event);
1161
1194
  onLoadSuccess(ui, event);
1162
1195
  }
1163
- }
1164
- else if (image.error) {
1165
- if (firstUse)
1166
- onLoadError(ui, event, image.error);
1167
- }
1168
- else {
1196
+ } else if (image.error) {
1197
+ if (firstUse) onLoadError(ui, event, image.error);
1198
+ } else {
1169
1199
  if (firstUse) {
1170
1200
  ignoreRender(ui, true);
1171
1201
  onLoad(ui, event);
@@ -1174,79 +1204,84 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1174
1204
  ignoreRender(ui, false);
1175
1205
  if (!ui.destroyed) {
1176
1206
  if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1177
- if (image.hasAlphaPixel)
1178
- ui.__layout.hitCanvasChanged = true;
1179
- ui.forceUpdate('surface');
1207
+ if (image.hasAlphaPixel) ui.__layout.hitCanvasChanged = true;
1208
+ ui.forceUpdate("surface");
1180
1209
  }
1181
1210
  onLoadSuccess(ui, event);
1182
1211
  }
1183
1212
  leafPaint.loadId = undefined;
1184
- }, (error) => {
1213
+ }, error => {
1185
1214
  ignoreRender(ui, false);
1186
1215
  onLoadError(ui, event, error);
1187
1216
  leafPaint.loadId = undefined;
1188
1217
  });
1189
1218
  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);
1219
+ if (!ui.placeholderDelay) image.isPlacehold = true; else setTimeout(() => {
1220
+ if (!image.ready) {
1221
+ image.isPlacehold = true;
1222
+ ui.forceUpdate("surface");
1223
+ }
1224
+ }, ui.placeholderDelay);
1199
1225
  }
1200
1226
  }
1201
1227
  return leafPaint;
1202
1228
  }
1229
+
1203
1230
  function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1204
- if (attrName === 'fill' && !ui.__.__naturalWidth) {
1231
+ if (attrName === "fill" && !ui.__.__naturalWidth) {
1205
1232
  const data = ui.__;
1206
1233
  data.__naturalWidth = image.width / data.pixelRatio;
1207
1234
  data.__naturalHeight = image.height / data.pixelRatio;
1208
1235
  if (data.__autoSide) {
1209
- ui.forceUpdate('width');
1236
+ ui.forceUpdate("width");
1210
1237
  if (ui.__proxyData) {
1211
- ui.setProxyAttr('width', data.width);
1212
- ui.setProxyAttr('height', data.height);
1238
+ ui.setProxyAttr("width", data.width);
1239
+ ui.setProxyAttr("height", data.height);
1213
1240
  }
1214
1241
  return false;
1215
1242
  }
1216
1243
  }
1217
- if (!leafPaint.data)
1218
- createData(leafPaint, image, paint, boxBounds);
1244
+ if (!leafPaint.data) createData(leafPaint, image, paint, boxBounds);
1219
1245
  return true;
1220
1246
  }
1247
+
1221
1248
  function onLoad(ui, event) {
1222
1249
  emit(ui, ImageEvent.LOAD, event);
1223
1250
  }
1251
+
1224
1252
  function onLoadSuccess(ui, event) {
1225
1253
  emit(ui, ImageEvent.LOADED, event);
1226
1254
  }
1255
+
1227
1256
  function onLoadError(ui, event, error) {
1228
1257
  event.error = error;
1229
- ui.forceUpdate('surface');
1258
+ ui.forceUpdate("surface");
1230
1259
  emit(ui, ImageEvent.ERROR, event);
1231
1260
  }
1261
+
1232
1262
  function emit(ui, type, data) {
1233
- if (ui.hasEvent(type))
1234
- ui.emitEvent(new ImageEvent(type, data));
1263
+ if (ui.hasEvent(type)) ui.emitEvent(new ImageEvent(type, data));
1235
1264
  }
1265
+
1236
1266
  function ignoreRender(ui, value) {
1237
- const { leafer } = ui;
1238
- if (leafer && leafer.viewReady)
1239
- leafer.renderer.ignore = value;
1267
+ const {leafer: leafer} = ui;
1268
+ if (leafer && leafer.viewReady) leafer.renderer.ignore = value;
1240
1269
  }
1241
1270
 
1242
- const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
1243
- const { ceil, abs } = Math;
1271
+ const {get: get$1, scale: scale, copy: copy$1} = MatrixHelper;
1272
+
1273
+ const {floor: floor, max: max, abs: abs} = Math;
1274
+
1244
1275
  function createPattern(ui, paint, pixelRatio) {
1245
- let { scaleX, scaleY } = ui.getRenderScaleData(true, paint.scaleFixed);
1246
- const id = scaleX + '-' + scaleY + '-' + pixelRatio;
1276
+ let {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1277
+ const id = scaleX + "-" + scaleY + "-" + pixelRatio;
1247
1278
  if (paint.patternId !== id && !ui.destroyed) {
1248
- const { image, data } = paint;
1249
- let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, transform, repeat } = data;
1279
+ const {image: image, data: data} = paint;
1280
+ let imageScale, imageMatrix, {width: width, height: height, scaleX: sx, scaleY: sy, transform: transform, repeat: repeat, gap: gap} = data;
1281
+ scaleX *= pixelRatio;
1282
+ scaleY *= pixelRatio;
1283
+ const xGap = gap && gap.x * scaleX;
1284
+ const yGap = gap && gap.y * scaleY;
1250
1285
  if (sx) {
1251
1286
  sx = abs(sx);
1252
1287
  sy = abs(sy);
@@ -1256,23 +1291,18 @@ function createPattern(ui, paint, pixelRatio) {
1256
1291
  scaleX *= sx;
1257
1292
  scaleY *= sy;
1258
1293
  }
1259
- scaleX *= pixelRatio;
1260
- scaleY *= pixelRatio;
1261
1294
  width *= scaleX;
1262
1295
  height *= scaleY;
1263
1296
  const size = width * height;
1264
1297
  if (!repeat) {
1265
- if (size > Platform.image.maxCacheSize)
1266
- return false;
1298
+ if (size > Platform.image.maxCacheSize) return false;
1267
1299
  }
1268
1300
  let maxSize = Platform.image.maxPatternSize;
1269
1301
  if (!image.isSVG) {
1270
1302
  const imageSize = image.width * image.height;
1271
- if (maxSize > imageSize)
1272
- maxSize = imageSize;
1303
+ if (maxSize > imageSize) maxSize = imageSize;
1273
1304
  }
1274
- if (size > maxSize)
1275
- imageScale = Math.sqrt(size / maxSize);
1305
+ if (size > maxSize) imageScale = Math.sqrt(size / maxSize);
1276
1306
  if (imageScale) {
1277
1307
  scaleX /= imageScale;
1278
1308
  scaleY /= imageScale;
@@ -1286,97 +1316,95 @@ function createPattern(ui, paint, pixelRatio) {
1286
1316
  if (transform || scaleX !== 1 || scaleY !== 1) {
1287
1317
  if (!imageMatrix) {
1288
1318
  imageMatrix = get$1();
1289
- if (transform)
1290
- copy$1(imageMatrix, transform);
1319
+ if (transform) copy$1(imageMatrix, transform);
1291
1320
  }
1292
1321
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1293
1322
  }
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);
1323
+ if (imageMatrix) {
1324
+ const canvasWidth = width + (xGap || 0), canvasHeight = height + (yGap || 0);
1325
+ scale(imageMatrix, canvasWidth / max(floor(canvasWidth), 1), canvasHeight / max(floor(canvasHeight), 1));
1326
+ }
1327
+ const canvas = image.getCanvas(width, height, data.opacity, data.filters, xGap, yGap);
1328
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || "no-repeat"), imageMatrix, paint);
1296
1329
  paint.style = pattern;
1297
1330
  paint.patternId = id;
1298
1331
  return true;
1299
- }
1300
- else {
1332
+ } else {
1301
1333
  return false;
1302
1334
  }
1303
1335
  }
1304
1336
 
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;
1337
+ function __awaiter(thisArg, _arguments, P, generator) {
1338
+ function adopt(value) {
1339
+ return value instanceof P ? value : new P(function(resolve) {
1340
+ resolve(value);
1341
+ });
1342
+ }
1343
+ return new (P || (P = Promise))(function(resolve, reject) {
1344
+ function fulfilled(value) {
1345
+ try {
1346
+ step(generator.next(value));
1347
+ } catch (e) {
1348
+ reject(e);
1349
+ }
1350
+ }
1351
+ function rejected(value) {
1352
+ try {
1353
+ step(generator["throw"](value));
1354
+ } catch (e) {
1355
+ reject(e);
1356
+ }
1357
+ }
1358
+ function step(result) {
1359
+ result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
1360
+ }
1361
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1362
+ });
1363
+ }
1364
+
1365
+ typeof SuppressedError === "function" ? SuppressedError : function(error, suppressed, message) {
1366
+ var e = new Error(message);
1367
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1335
1368
  };
1336
1369
 
1337
1370
  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)) {
1371
+ const {scaleX: scaleX, scaleY: scaleY} = ui.getRenderScaleData(true, paint.scaleFixed);
1372
+ const {pixelRatio: pixelRatio} = canvas, {data: data} = paint;
1373
+ if (!data || paint.patternId === scaleX + "-" + scaleY + "-" + pixelRatio && !Export.running) {
1341
1374
  return false;
1342
- }
1343
- else {
1375
+ } else {
1344
1376
  if (allowDraw) {
1345
1377
  if (data.repeat) {
1346
1378
  allowDraw = false;
1347
- }
1348
- else {
1349
- if (!(paint.changeful || ResizeEvent.isResizing(ui) || Export.running)) {
1350
- let { width, height } = data;
1379
+ } else {
1380
+ if (!(paint.changeful || Platform.name === "miniapp" && ResizeEvent.isResizing(ui) || Export.running)) {
1381
+ let {width: width, height: height} = data;
1351
1382
  width *= scaleX * pixelRatio;
1352
1383
  height *= scaleY * pixelRatio;
1353
1384
  if (data.scaleX) {
1354
1385
  width *= data.scaleX;
1355
1386
  height *= data.scaleY;
1356
1387
  }
1357
- allowDraw = (width * height > Platform.image.maxCacheSize);
1388
+ allowDraw = width * height > Platform.image.maxCacheSize;
1358
1389
  }
1359
1390
  }
1360
1391
  }
1361
1392
  if (allowDraw) {
1362
1393
  if (ui.__.__isFastShadow) {
1363
- canvas.fillStyle = paint.style || '#000';
1394
+ canvas.fillStyle = paint.style || "#000";
1364
1395
  canvas.fill();
1365
1396
  }
1366
1397
  drawImage(ui, canvas, paint, data);
1367
1398
  return true;
1368
- }
1369
- else {
1399
+ } else {
1370
1400
  if (!paint.style || paint.sync || Export.running) {
1371
1401
  createPattern(ui, paint, pixelRatio);
1372
- }
1373
- else {
1402
+ } else {
1374
1403
  if (!paint.patternTask) {
1375
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1404
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function*() {
1376
1405
  paint.patternTask = null;
1377
- if (canvas.bounds.hit(ui.__nowWorld))
1378
- createPattern(ui, paint, pixelRatio);
1379
- ui.forceUpdate('surface');
1406
+ if (canvas.bounds.hit(ui.__nowWorld)) createPattern(ui, paint, pixelRatio);
1407
+ ui.forceUpdate("surface");
1380
1408
  }), 300);
1381
1409
  }
1382
1410
  }
@@ -1384,39 +1412,35 @@ function checkImage(ui, canvas, paint, allowDraw) {
1384
1412
  }
1385
1413
  }
1386
1414
  }
1415
+
1387
1416
  function drawImage(ui, canvas, paint, data) {
1388
1417
  canvas.save();
1389
1418
  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);
1419
+ if (paint.blendMode) canvas.blendMode = paint.blendMode;
1420
+ if (data.opacity) canvas.opacity *= data.opacity;
1421
+ if (data.transform) canvas.transform(data.transform);
1396
1422
  canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1397
1423
  canvas.restore();
1398
1424
  }
1399
1425
 
1400
1426
  function recycleImage(attrName, data) {
1401
- const paints = data['_' + attrName];
1402
- if (paints instanceof Array) {
1427
+ const paints = data["_" + attrName];
1428
+ if (isArray(paints)) {
1403
1429
  let paint, image, recycleMap, input, url;
1404
1430
  for (let i = 0, len = paints.length; i < len; i++) {
1405
1431
  paint = paints[i];
1406
1432
  image = paint.image;
1407
1433
  url = image && image.url;
1408
1434
  if (url) {
1409
- if (!recycleMap)
1410
- recycleMap = {};
1435
+ if (!recycleMap) recycleMap = {};
1411
1436
  recycleMap[url] = true;
1412
1437
  ImageManager.recycle(image);
1413
1438
  if (image.loading) {
1414
1439
  if (!input) {
1415
- input = (data.__input && data.__input[attrName]) || [];
1416
- if (!(input instanceof Array))
1417
- input = [input];
1440
+ input = data.__input && data.__input[attrName] || [];
1441
+ if (!isArray(input)) input = [ input ];
1418
1442
  }
1419
- image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1443
+ image.unload(paints[i].loadId, !input.some(item => item.url === url));
1420
1444
  }
1421
1445
  }
1422
1446
  }
@@ -1426,75 +1450,85 @@ function recycleImage(attrName, data) {
1426
1450
  }
1427
1451
 
1428
1452
  const PaintImageModule = {
1429
- image,
1430
- checkImage,
1431
- createPattern,
1432
- recycleImage,
1433
- createData,
1434
- getPatternData,
1435
- fillOrFitMode,
1436
- clipMode,
1437
- repeatMode
1453
+ image: image,
1454
+ checkImage: checkImage,
1455
+ createPattern: createPattern,
1456
+ recycleImage: recycleImage,
1457
+ createData: createData,
1458
+ getPatternData: getPatternData,
1459
+ fillOrFitMode: fillOrFitMode,
1460
+ clipMode: clipMode,
1461
+ repeatMode: repeatMode
1438
1462
  };
1439
1463
 
1440
- const { toPoint: toPoint$2 } = AroundHelper, { hasTransparent } = ColorConvert;
1464
+ const {toPoint: toPoint$2} = AroundHelper, {hasTransparent: hasTransparent} = ColorConvert;
1465
+
1441
1466
  const realFrom$2 = {};
1467
+
1442
1468
  const realTo$2 = {};
1469
+
1443
1470
  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);
1471
+ let {from: from, to: to, type: type, opacity: opacity} = paint;
1472
+ toPoint$2(from || "top", box, realFrom$2);
1473
+ toPoint$2(to || "bottom", box, realTo$2);
1447
1474
  const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1448
- const data = { type, style };
1475
+ const data = {
1476
+ type: type,
1477
+ style: style
1478
+ };
1449
1479
  applyStops(data, style, paint.stops, opacity);
1450
1480
  return data;
1451
1481
  }
1482
+
1452
1483
  function applyStops(data, gradient, stops, opacity) {
1453
1484
  if (stops) {
1454
1485
  let stop, color, offset, isTransparent;
1455
1486
  for (let i = 0, len = stops.length; i < len; i++) {
1456
1487
  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);
1488
+ if (isString(stop)) offset = i / (len - 1), color = ColorConvert.string(stop, opacity); else offset = stop.offset,
1489
+ color = ColorConvert.string(stop.color, opacity);
1461
1490
  gradient.addColorStop(offset, color);
1462
- if (!isTransparent && hasTransparent(color))
1463
- isTransparent = true;
1491
+ if (!isTransparent && hasTransparent(color)) isTransparent = true;
1464
1492
  }
1465
- if (isTransparent)
1466
- data.isTransparent = true;
1493
+ if (isTransparent) data.isTransparent = true;
1467
1494
  }
1468
1495
  }
1469
1496
 
1470
- const { getAngle, getDistance: getDistance$1 } = PointHelper;
1471
- const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
1472
- const { toPoint: toPoint$1 } = AroundHelper;
1497
+ const {getAngle: getAngle, getDistance: getDistance$1} = PointHelper;
1498
+
1499
+ const {get: get, rotateOfOuter: rotateOfOuter, scaleOfOuter: scaleOfOuter} = MatrixHelper;
1500
+
1501
+ const {toPoint: toPoint$1} = AroundHelper;
1502
+
1473
1503
  const realFrom$1 = {};
1504
+
1474
1505
  const realTo$1 = {};
1506
+
1475
1507
  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);
1508
+ let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
1509
+ toPoint$1(from || "center", box, realFrom$1);
1510
+ toPoint$1(to || "bottom", box, realTo$1);
1479
1511
  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 };
1512
+ const data = {
1513
+ type: type,
1514
+ style: style
1515
+ };
1481
1516
  applyStops(data, style, paint.stops, opacity);
1482
1517
  const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1483
- if (transform)
1484
- data.transform = transform;
1518
+ if (transform) data.transform = transform;
1485
1519
  return data;
1486
1520
  }
1521
+
1487
1522
  function getTransform(box, from, to, stretch, rotate90) {
1488
1523
  let transform;
1489
- const { width, height } = box;
1524
+ const {width: width, height: height} = box;
1490
1525
  if (width !== height || stretch) {
1491
1526
  const angle = getAngle(from, to);
1492
1527
  transform = get();
1493
1528
  if (rotate90) {
1494
1529
  scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
1495
1530
  rotateOfOuter(transform, from, angle + 90);
1496
- }
1497
- else {
1531
+ } else {
1498
1532
  scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
1499
1533
  rotateOfOuter(transform, from, angle);
1500
1534
  }
@@ -1502,81 +1536,94 @@ function getTransform(box, from, to, stretch, rotate90) {
1502
1536
  return transform;
1503
1537
  }
1504
1538
 
1505
- const { getDistance } = PointHelper;
1506
- const { toPoint } = AroundHelper;
1539
+ const {getDistance: getDistance} = PointHelper;
1540
+
1541
+ const {toPoint: toPoint} = AroundHelper;
1542
+
1507
1543
  const realFrom = {};
1544
+
1508
1545
  const realTo = {};
1546
+
1509
1547
  function conicGradient(paint, box) {
1510
- let { from, to, type, opacity, stretch } = paint;
1511
- toPoint(from || 'center', box, realFrom);
1512
- toPoint(to || 'bottom', box, realTo);
1548
+ let {from: from, to: to, type: type, opacity: opacity, stretch: stretch} = paint;
1549
+ toPoint(from || "center", box, realFrom);
1550
+ toPoint(to || "bottom", box, realTo);
1513
1551
  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 };
1552
+ const data = {
1553
+ type: type,
1554
+ style: style
1555
+ };
1515
1556
  applyStops(data, style, paint.stops, opacity);
1516
1557
  const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1517
- if (transform)
1518
- data.transform = transform;
1558
+ if (transform) data.transform = transform;
1519
1559
  return data;
1520
1560
  }
1521
1561
 
1522
1562
  const PaintGradientModule = {
1523
- linearGradient,
1524
- radialGradient,
1525
- conicGradient,
1526
- getTransform
1563
+ linearGradient: linearGradient,
1564
+ radialGradient: radialGradient,
1565
+ conicGradient: conicGradient,
1566
+ getTransform: getTransform
1527
1567
  };
1528
1568
 
1529
- const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
1569
+ const {copy: copy, toOffsetOutBounds: toOffsetOutBounds$1} = BoundsHelper;
1570
+
1530
1571
  const tempBounds = {};
1572
+
1531
1573
  const offsetOutBounds$1 = {};
1574
+
1532
1575
  function shadow(ui, current, shape) {
1533
1576
  let copyBounds, spreadScale;
1534
- const { __nowWorld: nowWorld, __layout } = ui;
1535
- const { shadow } = ui.__;
1536
- const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1577
+ const {__nowWorld: nowWorld, __layout: __layout} = ui;
1578
+ const {shadow: shadow} = ui.__;
1579
+ const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1537
1580
  const other = current.getSameCanvas();
1538
1581
  const end = shadow.length - 1;
1539
1582
  toOffsetOutBounds$1(bounds, offsetOutBounds$1);
1540
1583
  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;
1584
+ let otherScale = 1;
1585
+ if (item.scaleFixed) {
1586
+ const sx = Math.abs(nowWorld.scaleX);
1587
+ if (sx > 1) otherScale = 1 / sx;
1588
+ }
1589
+ other.setWorldShadow(offsetOutBounds$1.offsetX + item.x * scaleX * otherScale, offsetOutBounds$1.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale, ColorConvert.string(item.color));
1590
+ spreadScale = item.spread ? 1 + item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1543
1591
  drawWorldShadow(other, offsetOutBounds$1, spreadScale, shape);
1544
1592
  copyBounds = bounds;
1545
1593
  if (item.box) {
1546
1594
  other.restore();
1547
1595
  other.save();
1548
1596
  if (worldCanvas) {
1549
- other.copyWorld(other, bounds, nowWorld, 'copy');
1597
+ other.copyWorld(other, bounds, nowWorld, "copy");
1550
1598
  copyBounds = nowWorld;
1551
1599
  }
1552
- worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
1600
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, "destination-out") : other.copyWorld(shape.canvas, shapeBounds, bounds, "destination-out");
1553
1601
  }
1554
1602
  LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1555
- if (end && index < end)
1556
- other.clearWorld(copyBounds, true);
1603
+ if (end && index < end) other.clearWorld(copyBounds, true);
1557
1604
  });
1558
1605
  other.recycle(copyBounds);
1559
1606
  }
1607
+
1560
1608
  function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1561
- const { bounds, shapeBounds } = shape;
1609
+ const {bounds: bounds, shapeBounds: shapeBounds} = shape;
1562
1610
  if (Platform.fullImageShadow) {
1563
1611
  copy(tempBounds, canvas.bounds);
1564
- tempBounds.x += (outBounds.x - shapeBounds.x);
1565
- tempBounds.y += (outBounds.y - shapeBounds.y);
1612
+ tempBounds.x += outBounds.x - shapeBounds.x;
1613
+ tempBounds.y += outBounds.y - shapeBounds.y;
1566
1614
  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);
1615
+ const {fitMatrix: fitMatrix} = shape;
1616
+ tempBounds.x -= (bounds.x + (fitMatrix ? fitMatrix.e : 0) + bounds.width / 2) * (spreadScale - 1);
1617
+ tempBounds.y -= (bounds.y + (fitMatrix ? fitMatrix.f : 0) + bounds.height / 2) * (spreadScale - 1);
1570
1618
  tempBounds.width *= spreadScale;
1571
1619
  tempBounds.height *= spreadScale;
1572
1620
  }
1573
1621
  canvas.copyWorld(shape.canvas, canvas.bounds, tempBounds);
1574
- }
1575
- else {
1622
+ } else {
1576
1623
  if (spreadScale) {
1577
1624
  copy(tempBounds, outBounds);
1578
- tempBounds.x -= (outBounds.width / 2) * (spreadScale - 1);
1579
- tempBounds.y -= (outBounds.height / 2) * (spreadScale - 1);
1625
+ tempBounds.x -= outBounds.width / 2 * (spreadScale - 1);
1626
+ tempBounds.y -= outBounds.height / 2 * (spreadScale - 1);
1580
1627
  tempBounds.width *= spreadScale;
1581
1628
  tempBounds.height *= spreadScale;
1582
1629
  }
@@ -1584,174 +1631,184 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1584
1631
  }
1585
1632
  }
1586
1633
 
1587
- const { toOffsetOutBounds } = BoundsHelper;
1634
+ const {toOffsetOutBounds: toOffsetOutBounds} = BoundsHelper;
1635
+
1588
1636
  const offsetOutBounds = {};
1637
+
1589
1638
  function innerShadow(ui, current, shape) {
1590
1639
  let copyBounds, spreadScale;
1591
- const { __nowWorld: nowWorld, __layout } = ui;
1592
- const { innerShadow } = ui.__;
1593
- const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1640
+ const {__nowWorld: nowWorld, __layout: __layout} = ui;
1641
+ const {innerShadow: innerShadow} = ui.__;
1642
+ const {worldCanvas: worldCanvas, bounds: bounds, shapeBounds: shapeBounds, scaleX: scaleX, scaleY: scaleY} = shape;
1594
1643
  const other = current.getSameCanvas();
1595
1644
  const end = innerShadow.length - 1;
1596
1645
  toOffsetOutBounds(bounds, offsetOutBounds);
1597
1646
  innerShadow.forEach((item, index) => {
1647
+ let otherScale = 1;
1648
+ if (item.scaleFixed) {
1649
+ const sx = Math.abs(nowWorld.scaleX);
1650
+ if (sx > 1) otherScale = 1 / sx;
1651
+ }
1598
1652
  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;
1653
+ other.setWorldShadow(offsetOutBounds.offsetX + item.x * scaleX * otherScale, offsetOutBounds.offsetY + item.y * scaleY * otherScale, item.blur * scaleX * otherScale);
1654
+ spreadScale = item.spread ? 1 - item.spread * 2 / (__layout.boxBounds.width + (__layout.strokeBoxSpread || 0) * 2) * otherScale : 0;
1601
1655
  drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1602
1656
  other.restore();
1603
1657
  if (worldCanvas) {
1604
- other.copyWorld(other, bounds, nowWorld, 'copy');
1605
- other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
1658
+ other.copyWorld(other, bounds, nowWorld, "copy");
1659
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, "source-out");
1606
1660
  copyBounds = nowWorld;
1607
- }
1608
- else {
1609
- other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
1661
+ } else {
1662
+ other.copyWorld(shape.canvas, shapeBounds, bounds, "source-out");
1610
1663
  copyBounds = bounds;
1611
1664
  }
1612
- other.fillWorld(copyBounds, ColorConvert.string(item.color), 'source-in');
1665
+ other.fillWorld(copyBounds, ColorConvert.string(item.color), "source-in");
1613
1666
  LeafHelper.copyCanvasByWorld(ui, current, other, copyBounds, item.blendMode);
1614
- if (end && index < end)
1615
- other.clearWorld(copyBounds, true);
1667
+ if (end && index < end) other.clearWorld(copyBounds, true);
1616
1668
  });
1617
1669
  other.recycle(copyBounds);
1618
1670
  }
1619
1671
 
1620
1672
  function blur(ui, current, origin) {
1621
- const { blur } = ui.__;
1673
+ const {blur: blur} = ui.__;
1622
1674
  origin.setWorldBlur(blur * ui.__nowWorld.a);
1623
1675
  origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
1624
- origin.filter = 'none';
1676
+ origin.filter = "none";
1625
1677
  }
1626
1678
 
1627
- function backgroundBlur(_ui, _current, _shape) {
1628
- }
1679
+ function backgroundBlur(_ui, _current, _shape) {}
1629
1680
 
1630
1681
  const EffectModule = {
1631
- shadow,
1632
- innerShadow,
1633
- blur,
1634
- backgroundBlur
1682
+ shadow: shadow,
1683
+ innerShadow: innerShadow,
1684
+ blur: blur,
1685
+ backgroundBlur: backgroundBlur
1635
1686
  };
1636
1687
 
1637
- const { excludeRenderBounds } = LeafBoundsHelper;
1638
- Group.prototype.__renderMask = function (canvas, options) {
1688
+ const {excludeRenderBounds: excludeRenderBounds} = LeafBoundsHelper;
1689
+
1690
+ let usedGrayscaleAlpha;
1691
+
1692
+ Group.prototype.__renderMask = function(canvas, options) {
1639
1693
  let child, maskCanvas, contentCanvas, maskOpacity, currentMask, mask;
1640
- const { children } = this;
1694
+ const {children: children} = this;
1641
1695
  for (let i = 0, len = children.length; i < len; i++) {
1642
1696
  child = children[i], mask = child.__.mask;
1643
1697
  if (mask) {
1644
1698
  if (currentMask) {
1645
- maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1699
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1646
1700
  maskCanvas = contentCanvas = null;
1647
1701
  }
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';
1702
+ maskOpacity = child.__.opacity;
1703
+ usedGrayscaleAlpha = false;
1704
+ if (mask === "path" || mask === "clipping-path") {
1705
+ if (maskOpacity < 1) {
1706
+ currentMask = "opacity-path";
1707
+ if (!contentCanvas) contentCanvas = getCanvas(canvas);
1708
+ } else {
1709
+ currentMask = "path";
1657
1710
  canvas.save();
1658
1711
  }
1659
1712
  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);
1713
+ } else {
1714
+ currentMask = mask === "grayscale" ? "grayscale" : "alpha";
1715
+ if (!maskCanvas) maskCanvas = getCanvas(canvas);
1716
+ if (!contentCanvas) contentCanvas = getCanvas(canvas);
1667
1717
  child.__render(maskCanvas, options);
1668
1718
  }
1669
- if (mask === 'clipping' || mask === 'clipping-path')
1670
- excludeRenderBounds(child, options) || child.__render(canvas, options);
1719
+ if (mask === "clipping" || mask === "clipping-path") excludeRenderBounds(child, options) || child.__render(canvas, options);
1671
1720
  continue;
1672
1721
  }
1722
+ const childBlendMode = maskOpacity === 1 && child.__.__blendMode;
1723
+ if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, false);
1673
1724
  excludeRenderBounds(child, options) || child.__render(contentCanvas || canvas, options);
1725
+ if (childBlendMode) maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, childBlendMode, false);
1674
1726
  }
1675
- maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
1727
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity, undefined, true);
1676
1728
  };
1677
- function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
1729
+
1730
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity, blendMode, recycle) {
1678
1731
  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();
1732
+ case "grayscale":
1733
+ if (!usedGrayscaleAlpha) usedGrayscaleAlpha = true, maskCanvas.useGrayscaleAlpha(leaf.__nowWorld);
1734
+
1735
+ case "alpha":
1736
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas, blendMode, recycle);
1737
+ break;
1738
+
1739
+ case "opacity-path":
1740
+ copyContent(leaf, canvas, contentCanvas, maskOpacity, blendMode, recycle);
1741
+ break;
1742
+
1743
+ case "path":
1744
+ if (recycle) canvas.restore();
1689
1745
  }
1690
1746
  }
1747
+
1691
1748
  function getCanvas(canvas) {
1692
1749
  return canvas.getSameCanvas(false, true);
1693
1750
  }
1694
- function usePixelMask(leaf, canvas, content, mask) {
1751
+
1752
+ function usePixelMask(leaf, canvas, content, mask, blendMode, recycle) {
1695
1753
  const realBounds = leaf.__nowWorld;
1696
1754
  content.resetTransform();
1697
1755
  content.opacity = 1;
1698
1756
  content.useMask(mask, realBounds);
1699
- mask.recycle(realBounds);
1700
- copyContent(leaf, canvas, content, 1);
1757
+ if (recycle) mask.recycle(realBounds);
1758
+ copyContent(leaf, canvas, content, 1, blendMode, recycle);
1701
1759
  }
1702
- function copyContent(leaf, canvas, content, maskOpacity) {
1760
+
1761
+ function copyContent(leaf, canvas, content, maskOpacity, blendMode, recycle) {
1703
1762
  const realBounds = leaf.__nowWorld;
1704
1763
  canvas.resetTransform();
1705
1764
  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('|'));
1765
+ canvas.copyWorld(content, realBounds, undefined, blendMode);
1766
+ recycle ? content.recycle(realBounds) : content.clearWorld(realBounds, true);
1767
+ }
1768
+
1769
+ const money = "¥¥$€££¢¢";
1770
+
1771
+ const letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
1772
+
1773
+ const langBefore = "《(「〈『〖【〔{┌<‘“=" + money;
1774
+
1775
+ const langAfter = "》)」〉』〗】〕}┐>’”!?,、。:;‰";
1776
+
1777
+ const langSymbol = "≮≯≈≠=…";
1778
+
1779
+ const langBreak$1 = "—/~|┆·";
1780
+
1781
+ const beforeChar = "{[(<'\"" + langBefore;
1782
+
1783
+ const afterChar = ">)]}%!?,.:;'\"" + langAfter;
1784
+
1785
+ const symbolChar = afterChar + "_#~&*+\\=|" + langSymbol;
1786
+
1787
+ const breakChar = "- " + langBreak$1;
1788
+
1789
+ 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 ] ];
1790
+
1791
+ const cjkReg = new RegExp(cjkRangeList.map(([start, end]) => `[\\u${start.toString(16)}-\\u${end.toString(16)}]`).join("|"));
1792
+
1743
1793
  function mapChar(str) {
1744
1794
  const map = {};
1745
- str.split('').forEach(char => map[char] = true);
1795
+ str.split("").forEach(char => map[char] = true);
1746
1796
  return map;
1747
1797
  }
1798
+
1748
1799
  const letterMap = mapChar(letter);
1800
+
1749
1801
  const beforeMap = mapChar(beforeChar);
1802
+
1750
1803
  const afterMap = mapChar(afterChar);
1804
+
1751
1805
  const symbolMap = mapChar(symbolChar);
1806
+
1752
1807
  const breakMap = mapChar(breakChar);
1808
+
1753
1809
  var CharType;
1754
- (function (CharType) {
1810
+
1811
+ (function(CharType) {
1755
1812
  CharType[CharType["Letter"] = 0] = "Letter";
1756
1813
  CharType[CharType["Single"] = 1] = "Single";
1757
1814
  CharType[CharType["Before"] = 2] = "Before";
@@ -1759,179 +1816,175 @@ var CharType;
1759
1816
  CharType[CharType["Symbol"] = 4] = "Symbol";
1760
1817
  CharType[CharType["Break"] = 5] = "Break";
1761
1818
  })(CharType || (CharType = {}));
1762
- const { Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1 } = CharType;
1819
+
1820
+ const {Letter: Letter$1, Single: Single$1, Before: Before$1, After: After$1, Symbol: Symbol$1, Break: Break$1} = CharType;
1821
+
1763
1822
  function getCharType(char) {
1764
1823
  if (letterMap[char]) {
1765
1824
  return Letter$1;
1766
- }
1767
- else if (breakMap[char]) {
1825
+ } else if (breakMap[char]) {
1768
1826
  return Break$1;
1769
- }
1770
- else if (beforeMap[char]) {
1827
+ } else if (beforeMap[char]) {
1771
1828
  return Before$1;
1772
- }
1773
- else if (afterMap[char]) {
1829
+ } else if (afterMap[char]) {
1774
1830
  return After$1;
1775
- }
1776
- else if (symbolMap[char]) {
1831
+ } else if (symbolMap[char]) {
1777
1832
  return Symbol$1;
1778
- }
1779
- else if (cjkReg.test(char)) {
1833
+ } else if (cjkReg.test(char)) {
1780
1834
  return Single$1;
1781
- }
1782
- else {
1835
+ } else {
1783
1836
  return Letter$1;
1784
1837
  }
1785
1838
  }
1786
1839
 
1787
1840
  const TextRowHelper = {
1788
1841
  trimRight(row) {
1789
- const { words } = row;
1842
+ const {words: words} = row;
1790
1843
  let trimRight = 0, len = words.length, char;
1791
1844
  for (let i = len - 1; i > -1; i--) {
1792
1845
  char = words[i].data[0];
1793
- if (char.char === ' ') {
1846
+ if (char.char === " ") {
1794
1847
  trimRight++;
1795
1848
  row.width -= char.width;
1796
- }
1797
- else {
1849
+ } else {
1798
1850
  break;
1799
1851
  }
1800
1852
  }
1801
- if (trimRight)
1802
- words.splice(len - trimRight, trimRight);
1853
+ if (trimRight) words.splice(len - trimRight, trimRight);
1803
1854
  }
1804
1855
  };
1805
1856
 
1806
1857
  function getTextCase(char, textCase, firstChar) {
1807
1858
  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;
1859
+ case "title":
1860
+ return firstChar ? char.toUpperCase() : char;
1861
+
1862
+ case "upper":
1863
+ return char.toUpperCase();
1864
+
1865
+ case "lower":
1866
+ return char.toLowerCase();
1867
+
1868
+ default:
1869
+ return char;
1816
1870
  }
1817
1871
  }
1818
1872
 
1819
- const { trimRight } = TextRowHelper;
1820
- const { Letter, Single, Before, After, Symbol, Break } = CharType;
1873
+ const {trimRight: trimRight} = TextRowHelper;
1874
+
1875
+ const {Letter: Letter, Single: Single, Before: Before, After: After, Symbol: Symbol, Break: Break} = CharType;
1876
+
1821
1877
  let word, row, wordWidth, rowWidth, realWidth;
1878
+
1822
1879
  let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
1880
+
1823
1881
  let textDrawData, rows = [], bounds, findMaxWidth;
1882
+
1824
1883
  function createRows(drawData, content, style) {
1825
1884
  textDrawData = drawData;
1826
1885
  rows = drawData.rows;
1827
1886
  bounds = drawData.bounds;
1828
1887
  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');
1888
+ const {__letterSpacing: __letterSpacing, paraIndent: paraIndent, textCase: textCase} = style;
1889
+ const {canvas: canvas} = Platform;
1890
+ const {width: width, height: height} = bounds;
1891
+ const charMode = width || height || __letterSpacing || textCase !== "none";
1833
1892
  if (charMode) {
1834
- const wrap = style.textWrap !== 'none';
1835
- const breakAll = style.textWrap === 'break';
1893
+ const wrap = style.textWrap !== "none";
1894
+ const breakAll = style.textWrap === "break";
1836
1895
  paraStart = true;
1837
1896
  lastCharType = null;
1838
1897
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
1839
- word = { data: [] }, row = { words: [] };
1840
- if (__letterSpacing)
1841
- content = [...content];
1898
+ word = {
1899
+ data: []
1900
+ }, row = {
1901
+ words: []
1902
+ };
1903
+ if (__letterSpacing) content = [ ...content ];
1842
1904
  for (let i = 0, len = content.length; i < len; i++) {
1843
1905
  char = content[i];
1844
- if (char === '\n') {
1845
- if (wordWidth)
1846
- addWord();
1906
+ if (char === "\n") {
1907
+ if (wordWidth) addWord();
1847
1908
  row.paraEnd = true;
1848
1909
  addRow();
1849
1910
  paraStart = true;
1850
- }
1851
- else {
1911
+ } else {
1852
1912
  charType = getCharType(char);
1853
- if (charType === Letter && textCase !== 'none')
1854
- char = getTextCase(char, textCase, !wordWidth);
1913
+ if (charType === Letter && textCase !== "none") char = getTextCase(char, textCase, !wordWidth);
1855
1914
  charWidth = canvas.measureText(char).width;
1856
1915
  if (__letterSpacing) {
1857
- if (__letterSpacing < 0)
1858
- charSize = charWidth;
1916
+ if (__letterSpacing < 0) charSize = charWidth;
1859
1917
  charWidth += __letterSpacing;
1860
1918
  }
1861
- langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
1862
- afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
1919
+ langBreak = charType === Single && (lastCharType === Single || lastCharType === Letter) || lastCharType === Single && charType !== After;
1920
+ afterBreak = (charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After);
1863
1921
  realWidth = paraStart && paraIndent ? width - paraIndent : width;
1864
1922
  if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
1865
1923
  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();
1924
+ if (wordWidth) addWord();
1925
+ if (rowWidth) addRow();
1926
+ } else {
1927
+ if (!afterBreak) afterBreak = charType === Letter && lastCharType == After;
1928
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || wordWidth + charWidth > realWidth) {
1929
+ if (wordWidth) addWord();
1930
+ if (rowWidth) addRow();
1931
+ } else {
1932
+ if (rowWidth) addRow();
1883
1933
  }
1884
1934
  }
1885
1935
  }
1886
- if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
1887
- else {
1936
+ if (char === " " && paraStart !== true && rowWidth + wordWidth === 0) ; else {
1888
1937
  if (charType === Break) {
1889
- if (char === ' ' && wordWidth)
1890
- addWord();
1938
+ if (char === " " && wordWidth) addWord();
1891
1939
  addChar(char, charWidth);
1892
1940
  addWord();
1893
- }
1894
- else if (langBreak || afterBreak) {
1895
- if (wordWidth)
1896
- addWord();
1941
+ } else if (langBreak || afterBreak) {
1942
+ if (wordWidth) addWord();
1897
1943
  addChar(char, charWidth);
1898
- }
1899
- else {
1944
+ } else {
1900
1945
  addChar(char, charWidth);
1901
1946
  }
1902
1947
  }
1903
1948
  lastCharType = charType;
1904
1949
  }
1905
1950
  }
1906
- if (wordWidth)
1907
- addWord();
1908
- if (rowWidth)
1909
- addRow();
1951
+ if (wordWidth) addWord();
1952
+ if (rowWidth) addRow();
1910
1953
  rows.length > 0 && (rows[rows.length - 1].paraEnd = true);
1911
- }
1912
- else {
1913
- content.split('\n').forEach(content => {
1954
+ } else {
1955
+ content.split("\n").forEach(content => {
1914
1956
  textDrawData.paraNumber++;
1915
1957
  rowWidth = canvas.measureText(content).width;
1916
- rows.push({ x: paraIndent || 0, text: content, width: rowWidth, paraStart: true });
1917
- if (findMaxWidth)
1918
- setMaxWidth();
1958
+ rows.push({
1959
+ x: paraIndent || 0,
1960
+ text: content,
1961
+ width: rowWidth,
1962
+ paraStart: true
1963
+ });
1964
+ if (findMaxWidth) setMaxWidth();
1919
1965
  });
1920
1966
  }
1921
1967
  }
1968
+
1922
1969
  function addChar(char, width) {
1923
- if (charSize && !startCharSize)
1924
- startCharSize = charSize;
1925
- word.data.push({ char, width });
1970
+ if (charSize && !startCharSize) startCharSize = charSize;
1971
+ word.data.push({
1972
+ char: char,
1973
+ width: width
1974
+ });
1926
1975
  wordWidth += width;
1927
1976
  }
1977
+
1928
1978
  function addWord() {
1929
1979
  rowWidth += wordWidth;
1930
1980
  word.width = wordWidth;
1931
1981
  row.words.push(word);
1932
- word = { data: [] };
1982
+ word = {
1983
+ data: []
1984
+ };
1933
1985
  wordWidth = 0;
1934
1986
  }
1987
+
1935
1988
  function addRow() {
1936
1989
  if (paraStart) {
1937
1990
  textDrawData.paraNumber++;
@@ -1944,52 +1997,53 @@ function addRow() {
1944
1997
  startCharSize = 0;
1945
1998
  }
1946
1999
  row.width = rowWidth;
1947
- if (bounds.width)
1948
- trimRight(row);
1949
- else if (findMaxWidth)
1950
- setMaxWidth();
2000
+ if (bounds.width) trimRight(row); else if (findMaxWidth) setMaxWidth();
1951
2001
  rows.push(row);
1952
- row = { words: [] };
2002
+ row = {
2003
+ words: []
2004
+ };
1953
2005
  rowWidth = 0;
1954
2006
  }
2007
+
1955
2008
  function setMaxWidth() {
1956
- if (rowWidth > (textDrawData.maxWidth || 0))
1957
- textDrawData.maxWidth = rowWidth;
2009
+ if (rowWidth > (textDrawData.maxWidth || 0)) textDrawData.maxWidth = rowWidth;
1958
2010
  }
1959
2011
 
1960
2012
  const CharMode = 0;
2013
+
1961
2014
  const WordMode = 1;
2015
+
1962
2016
  const TextMode = 2;
2017
+
1963
2018
  function layoutChar(drawData, style, width, _height) {
1964
- const { rows } = drawData;
1965
- const { textAlign, paraIndent, letterSpacing } = style;
2019
+ const {rows: rows} = drawData;
2020
+ const {textAlign: textAlign, paraIndent: paraIndent, letterSpacing: letterSpacing} = style;
1966
2021
  let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
1967
2022
  rows.forEach(row => {
1968
2023
  if (row.words) {
1969
2024
  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;
2025
+ addWordWidth = width && (textAlign === "justify" || textAlign === "both") && wordsLength > 1 ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2026
+ mode = letterSpacing || row.isOverflow ? CharMode : addWordWidth > .01 ? WordMode : TextMode;
2027
+ if (row.isOverflow && !letterSpacing) row.textMode = true;
1974
2028
  if (mode === TextMode) {
1975
2029
  row.x += indentWidth;
1976
2030
  toTextChar$1(row);
1977
- }
1978
- else {
2031
+ } else {
1979
2032
  row.x += indentWidth;
1980
2033
  charX = row.x;
1981
2034
  row.data = [];
1982
2035
  row.words.forEach((word, index) => {
1983
2036
  if (mode === WordMode) {
1984
- wordChar = { char: '', x: charX };
2037
+ wordChar = {
2038
+ char: "",
2039
+ x: charX
2040
+ };
1985
2041
  charX = toWordChar(word.data, charX, wordChar);
1986
- if (row.isOverflow || wordChar.char !== ' ')
1987
- row.data.push(wordChar);
1988
- }
1989
- else {
2042
+ if (row.isOverflow || wordChar.char !== " ") row.data.push(wordChar);
2043
+ } else {
1990
2044
  charX = toChar(word.data, charX, row.data, row.isOverflow);
1991
2045
  }
1992
- if (addWordWidth && (!row.paraEnd || textAlign === 'both') && (index !== wordsLength - 1)) {
2046
+ if (addWordWidth && (!row.paraEnd || textAlign === "both") && index !== wordsLength - 1) {
1993
2047
  charX += addWordWidth;
1994
2048
  row.width += addWordWidth;
1995
2049
  }
@@ -1999,14 +2053,16 @@ function layoutChar(drawData, style, width, _height) {
1999
2053
  }
2000
2054
  });
2001
2055
  }
2056
+
2002
2057
  function toTextChar$1(row) {
2003
- row.text = '';
2058
+ row.text = "";
2004
2059
  row.words.forEach(word => {
2005
2060
  word.data.forEach(char => {
2006
2061
  row.text += char.char;
2007
2062
  });
2008
2063
  });
2009
2064
  }
2065
+
2010
2066
  function toWordChar(data, charX, wordChar) {
2011
2067
  data.forEach(char => {
2012
2068
  wordChar.char += char.char;
@@ -2014,9 +2070,10 @@ function toWordChar(data, charX, wordChar) {
2014
2070
  });
2015
2071
  return charX;
2016
2072
  }
2073
+
2017
2074
  function toChar(data, charX, rowData, isOverflow) {
2018
2075
  data.forEach(char => {
2019
- if (isOverflow || char.char !== ' ') {
2076
+ if (isOverflow || char.char !== " ") {
2020
2077
  char.x = charX;
2021
2078
  rowData.push(char);
2022
2079
  }
@@ -2026,38 +2083,39 @@ function toChar(data, charX, rowData, isOverflow) {
2026
2083
  }
2027
2084
 
2028
2085
  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);
2086
+ const {rows: rows, bounds: bounds} = drawData, countRows = rows.length;
2087
+ const {__lineHeight: __lineHeight, __baseLine: __baseLine, __letterSpacing: __letterSpacing, __clipText: __clipText, textAlign: textAlign, verticalAlign: verticalAlign, paraSpacing: paraSpacing, autoSizeAlign: autoSizeAlign} = style;
2088
+ let {x: x, y: y, width: width, height: height} = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2032
2089
  let starY = __baseLine;
2033
2090
  if (__clipText && realHeight > height) {
2034
2091
  realHeight = Math.max(height, __lineHeight);
2035
- if (countRows > 1)
2036
- drawData.overflow = countRows;
2037
- }
2038
- else if (height || autoSizeAlign) {
2092
+ if (countRows > 1) drawData.overflow = countRows;
2093
+ } else if (height || autoSizeAlign) {
2039
2094
  switch (verticalAlign) {
2040
- case 'middle':
2041
- y += (height - realHeight) / 2;
2042
- break;
2043
- case 'bottom': y += (height - realHeight);
2095
+ case "middle":
2096
+ y += (height - realHeight) / 2;
2097
+ break;
2098
+
2099
+ case "bottom":
2100
+ y += height - realHeight;
2044
2101
  }
2045
2102
  }
2046
2103
  starY += y;
2047
- let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
2104
+ let row, rowX, rowWidth, layoutWidth = width || autoSizeAlign ? width : drawData.maxWidth;
2048
2105
  for (let i = 0, len = countRows; i < len; i++) {
2049
2106
  row = rows[i];
2050
2107
  row.x = x;
2051
- if (row.width < width || (row.width > width && !__clipText)) {
2108
+ if (row.width < width || row.width > width && !__clipText) {
2052
2109
  switch (textAlign) {
2053
- case 'center':
2054
- row.x += (layoutWidth - row.width) / 2;
2055
- break;
2056
- case 'right': row.x += layoutWidth - row.width;
2110
+ case "center":
2111
+ row.x += (layoutWidth - row.width) / 2;
2112
+ break;
2113
+
2114
+ case "right":
2115
+ row.x += layoutWidth - row.width;
2057
2116
  }
2058
2117
  }
2059
- if (row.paraStart && paraSpacing && i > 0)
2060
- starY += paraSpacing;
2118
+ if (row.paraStart && paraSpacing && i > 0) starY += paraSpacing;
2061
2119
  row.y = starY;
2062
2120
  starY += __lineHeight;
2063
2121
  if (drawData.overflow > i && starY > realHeight) {
@@ -2071,19 +2129,15 @@ function layoutText(drawData, style) {
2071
2129
  rowWidth = -row.width + style.fontSize + __letterSpacing;
2072
2130
  rowX -= rowWidth;
2073
2131
  rowWidth += style.fontSize;
2074
- }
2075
- else {
2132
+ } else {
2076
2133
  rowWidth -= __letterSpacing;
2077
2134
  }
2078
2135
  }
2079
- if (rowX < bounds.x)
2080
- bounds.x = rowX;
2081
- if (rowWidth > bounds.width)
2082
- bounds.width = rowWidth;
2136
+ if (rowX < bounds.x) bounds.x = rowX;
2137
+ if (rowWidth > bounds.width) bounds.width = rowWidth;
2083
2138
  if (__clipText && width && width < rowWidth) {
2084
2139
  row.isOverflow = true;
2085
- if (!drawData.overflow)
2086
- drawData.overflow = rows.length;
2140
+ if (!drawData.overflow) drawData.overflow = rows.length;
2087
2141
  }
2088
2142
  }
2089
2143
  bounds.y = y;
@@ -2091,20 +2145,16 @@ function layoutText(drawData, style) {
2091
2145
  }
2092
2146
 
2093
2147
  function clipText(drawData, style, x, width) {
2094
- if (!width)
2095
- return;
2096
- const { rows, overflow } = drawData;
2097
- let { textOverflow } = style;
2148
+ if (!width) return;
2149
+ const {rows: rows, overflow: overflow} = drawData;
2150
+ let {textOverflow: textOverflow} = style;
2098
2151
  rows.splice(overflow);
2099
- if (textOverflow && textOverflow !== 'show') {
2100
- if (textOverflow === 'hide')
2101
- textOverflow = '';
2102
- else if (textOverflow === 'ellipsis')
2103
- textOverflow = '...';
2152
+ if (textOverflow && textOverflow !== "show") {
2153
+ if (textOverflow === "hide") textOverflow = ""; else if (textOverflow === "ellipsis") textOverflow = "...";
2104
2154
  let char, charRight;
2105
2155
  const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
2106
2156
  const right = x + width - ellipsisWidth;
2107
- const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2157
+ const list = style.textWrap === "none" ? rows : [ rows[overflow - 1] ];
2108
2158
  list.forEach(row => {
2109
2159
  if (row.isOverflow && row.data) {
2110
2160
  let end = row.data.length - 1;
@@ -2113,8 +2163,7 @@ function clipText(drawData, style, x, width) {
2113
2163
  charRight = char.x + char.width;
2114
2164
  if (i === end && charRight < right) {
2115
2165
  break;
2116
- }
2117
- else if ((charRight < right && char.char !== ' ') || !i) {
2166
+ } else if (charRight < right && char.char !== " " || !i) {
2118
2167
  row.data.splice(i + 1);
2119
2168
  row.width -= char.width;
2120
2169
  break;
@@ -2122,15 +2171,18 @@ function clipText(drawData, style, x, width) {
2122
2171
  row.width -= char.width;
2123
2172
  }
2124
2173
  row.width += ellipsisWidth;
2125
- row.data.push({ char: textOverflow, x: charRight });
2126
- if (row.textMode)
2127
- toTextChar(row);
2174
+ row.data.push({
2175
+ char: textOverflow,
2176
+ x: charRight
2177
+ });
2178
+ if (row.textMode) toTextChar(row);
2128
2179
  }
2129
2180
  });
2130
2181
  }
2131
2182
  }
2183
+
2132
2184
  function toTextChar(row) {
2133
- row.text = '';
2185
+ row.text = "";
2134
2186
  row.data.forEach(char => {
2135
2187
  row.text += char.char;
2136
2188
  });
@@ -2139,115 +2191,116 @@ function toTextChar(row) {
2139
2191
 
2140
2192
  function decorationText(drawData, style) {
2141
2193
  let type;
2142
- const { fontSize, textDecoration } = style;
2194
+ const {fontSize: fontSize, textDecoration: textDecoration} = style;
2143
2195
  drawData.decorationHeight = fontSize / 11;
2144
- if (typeof textDecoration === 'object') {
2196
+ if (isObject(textDecoration)) {
2145
2197
  type = textDecoration.type;
2146
- if (textDecoration.color)
2147
- drawData.decorationColor = ColorConvert.string(textDecoration.color);
2148
- }
2149
- else
2150
- type = textDecoration;
2198
+ if (textDecoration.color) drawData.decorationColor = ColorConvert.string(textDecoration.color);
2199
+ } else type = textDecoration;
2151
2200
  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];
2201
+ case "under":
2202
+ drawData.decorationY = [ fontSize * .15 ];
2203
+ break;
2204
+
2205
+ case "delete":
2206
+ drawData.decorationY = [ -fontSize * .35 ];
2207
+ break;
2208
+
2209
+ case "under-delete":
2210
+ drawData.decorationY = [ fontSize * .15, -fontSize * .35 ];
2160
2211
  }
2161
2212
  }
2162
2213
 
2163
- const { top, right, bottom, left } = Direction4;
2214
+ const {top: top, right: right, bottom: bottom, left: left} = Direction4;
2215
+
2164
2216
  function getDrawData(content, style) {
2165
- if (typeof content !== 'string')
2166
- content = String(content);
2217
+ if (!isString(content)) content = String(content);
2167
2218
  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;
2219
+ let width = style.__getInput("width") || 0;
2220
+ let height = style.__getInput("height") || 0;
2221
+ const {textDecoration: textDecoration, __font: __font, __padding: padding} = style;
2171
2222
  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];
2223
+ if (width) x = padding[left], width -= padding[right] + padding[left]; else if (!style.autoSizeAlign) x = padding[left];
2224
+ if (height) y = padding[top], height -= padding[top] + padding[bottom]; else if (!style.autoSizeAlign) y = padding[top];
2180
2225
  }
2181
2226
  const drawData = {
2182
- bounds: { x, y, width, height },
2227
+ bounds: {
2228
+ x: x,
2229
+ y: y,
2230
+ width: width,
2231
+ height: height
2232
+ },
2183
2233
  rows: [],
2184
2234
  paraNumber: 0,
2185
2235
  font: Platform.canvas.font = __font
2186
2236
  };
2187
2237
  createRows(drawData, content, style);
2188
- if (padding)
2189
- padAutoText(padding, drawData, style, width, height);
2238
+ if (padding) padAutoText(padding, drawData, style, width, height);
2190
2239
  layoutText(drawData, style);
2191
2240
  layoutChar(drawData, style, width);
2192
- if (drawData.overflow)
2193
- clipText(drawData, style, x, width);
2194
- if (textDecoration !== 'none')
2195
- decorationText(drawData, style);
2241
+ if (drawData.overflow) clipText(drawData, style, x, width);
2242
+ if (textDecoration !== "none") decorationText(drawData, style);
2196
2243
  return drawData;
2197
2244
  }
2245
+
2198
2246
  function padAutoText(padding, drawData, style, width, height) {
2199
2247
  if (!width && style.autoSizeAlign) {
2200
2248
  switch (style.textAlign) {
2201
- case 'left':
2202
- offsetText(drawData, 'x', padding[left]);
2203
- break;
2204
- case 'right': offsetText(drawData, 'x', -padding[right]);
2249
+ case "left":
2250
+ offsetText(drawData, "x", padding[left]);
2251
+ break;
2252
+
2253
+ case "right":
2254
+ offsetText(drawData, "x", -padding[right]);
2205
2255
  }
2206
2256
  }
2207
2257
  if (!height && style.autoSizeAlign) {
2208
2258
  switch (style.verticalAlign) {
2209
- case 'top':
2210
- offsetText(drawData, 'y', padding[top]);
2211
- break;
2212
- case 'bottom': offsetText(drawData, 'y', -padding[bottom]);
2259
+ case "top":
2260
+ offsetText(drawData, "y", padding[top]);
2261
+ break;
2262
+
2263
+ case "bottom":
2264
+ offsetText(drawData, "y", -padding[bottom]);
2213
2265
  }
2214
2266
  }
2215
2267
  }
2268
+
2216
2269
  function offsetText(drawData, attrName, value) {
2217
- const { bounds, rows } = drawData;
2270
+ const {bounds: bounds, rows: rows} = drawData;
2218
2271
  bounds[attrName] += value;
2219
- for (let i = 0; i < rows.length; i++)
2220
- rows[i][attrName] += value;
2272
+ for (let i = 0; i < rows.length; i++) rows[i][attrName] += value;
2221
2273
  }
2222
2274
 
2223
2275
  const TextConvertModule = {
2224
- getDrawData
2276
+ getDrawData: getDrawData
2225
2277
  };
2226
2278
 
2227
2279
  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;
2280
+ const doOpacity = isNumber(opacity) && opacity < 1;
2281
+ if (isString(color)) {
2282
+ if (doOpacity && ColorConvert.object) color = ColorConvert.object(color); else return color;
2234
2283
  }
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 + ')';
2284
+ let a = isUndefined(color.a) ? 1 : color.a;
2285
+ if (doOpacity) a *= opacity;
2286
+ const rgb = color.r + "," + color.g + "," + color.b;
2287
+ return a === 1 ? "rgb(" + rgb + ")" : "rgba(" + rgb + "," + a + ")";
2240
2288
  }
2241
2289
 
2242
2290
  const ColorConvertModule = {
2243
- string
2291
+ string: string
2244
2292
  };
2245
2293
 
2246
2294
  Object.assign(TextConvert, TextConvertModule);
2295
+
2247
2296
  Object.assign(ColorConvert, ColorConvertModule);
2297
+
2248
2298
  Object.assign(Paint, PaintModule);
2299
+
2249
2300
  Object.assign(PaintImage, PaintImageModule);
2301
+
2250
2302
  Object.assign(PaintGradient, PaintGradientModule);
2303
+
2251
2304
  Object.assign(Effect, EffectModule);
2252
2305
 
2253
2306
  useCanvas();