@leafer-ui/worker 1.8.0 → 1.9.0

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