@leafer-ui/miniapp 1.0.0-rc.9 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,230 @@
1
- import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, Platform, AnimateEvent, ResizeEvent, BoundsHelper, Creator, LeaferCanvasBase, canvasPatch, canvasSizeAttrs, InteractionHelper, InteractionBase, LeaferImage, FileHelper, MatrixHelper, ImageEvent, PointHelper, Direction4, TaskProcessor } from '@leafer/core';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, Answer, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
- import { ColorConvert as ColorConvert$1, ImageManager as ImageManager$1, Paint, Effect, TextConvert as TextConvert$1, Export as Export$2, Platform as Platform$1 } from '@leafer-ui/core';
4
+ import { InteractionHelper, InteractionBase, HitCanvasManager, Platform as Platform$1, MatrixHelper as MatrixHelper$1 } from '@leafer-ui/core';
5
5
  export * from '@leafer-ui/core';
6
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
7
+
8
+ class LeaferCanvas extends LeaferCanvasBase {
9
+ get allowBackgroundColor() { return false; }
10
+ init() {
11
+ const { config } = this;
12
+ let view = config.view || config.canvas;
13
+ if (view) {
14
+ if (typeof view === 'string') {
15
+ if (view[0] !== '#')
16
+ view = '#' + view;
17
+ this.viewSelect = Platform.miniapp.select(view);
18
+ }
19
+ else if (view.fields) {
20
+ this.viewSelect = view;
21
+ }
22
+ else {
23
+ this.initView(view);
24
+ }
25
+ if (this.viewSelect)
26
+ Platform.miniapp.getSizeView(this.viewSelect).then(sizeView => {
27
+ this.initView(sizeView);
28
+ });
29
+ }
30
+ else {
31
+ this.initView();
32
+ }
33
+ }
34
+ initView(view) {
35
+ if (!view) {
36
+ view = {};
37
+ this.__createView();
38
+ }
39
+ else {
40
+ this.view = view.view || view;
41
+ }
42
+ this.view.getContext ? this.__createContext() : this.unrealCanvas();
43
+ const { width, height, pixelRatio } = this.config;
44
+ const size = { width: width || view.width, height: height || view.height, pixelRatio };
45
+ this.resize(size);
46
+ if (this.context) {
47
+ if (this.context.roundRect) {
48
+ this.roundRect = function (x, y, width, height, radius) {
49
+ this.context.roundRect(x, y, width, height, typeof radius === 'number' ? [radius] : radius);
50
+ };
51
+ }
52
+ canvasPatch(this.context.__proto__);
53
+ }
54
+ }
55
+ __createView() {
56
+ this.view = Platform.origin.createCanvas(1, 1);
57
+ }
58
+ updateViewSize() {
59
+ const { width, height, pixelRatio } = this;
60
+ this.view.width = Math.ceil(width * pixelRatio);
61
+ this.view.height = Math.ceil(height * pixelRatio);
62
+ }
63
+ updateClientBounds(callback) {
64
+ if (this.viewSelect)
65
+ Platform.miniapp.getBounds(this.viewSelect).then(bounds => {
66
+ this.clientBounds = bounds;
67
+ if (callback)
68
+ callback();
69
+ });
70
+ }
71
+ startAutoLayout(autoBounds, listener) {
72
+ this.resizeListener = listener;
73
+ if (autoBounds) {
74
+ this.checkSize = this.checkSize.bind(this);
75
+ Platform.miniapp.onWindowResize(this.checkSize);
76
+ }
77
+ }
78
+ checkSize() {
79
+ if (this.viewSelect) {
80
+ setTimeout(() => {
81
+ this.updateClientBounds(() => {
82
+ const { width, height } = this.clientBounds;
83
+ const { pixelRatio } = this;
84
+ const size = { width, height, pixelRatio };
85
+ if (!this.isSameSize(size))
86
+ this.emitResize(size);
87
+ });
88
+ }, 500);
89
+ }
90
+ }
91
+ stopAutoLayout() {
92
+ this.autoLayout = false;
93
+ this.resizeListener = null;
94
+ Platform.miniapp.offWindowResize(this.checkSize);
95
+ }
96
+ unrealCanvas() {
97
+ this.unreal = true;
98
+ }
99
+ emitResize(size) {
100
+ const oldSize = {};
101
+ DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
102
+ this.resize(size);
103
+ if (this.width !== undefined)
104
+ this.resizeListener(new ResizeEvent(size, oldSize));
105
+ }
106
+ }
107
+
108
+ const { mineType, fileType } = FileHelper;
109
+ Object.assign(Creator, {
110
+ canvas: (options, manager) => new LeaferCanvas(options, manager),
111
+ image: (options) => new LeaferImage(options)
112
+ });
113
+ function useCanvas(_canvasType, app) {
114
+ if (!Platform.origin) {
115
+ Platform.origin = {
116
+ createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
117
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
118
+ canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
119
+ canvasSaveAs: (canvas, filePath, quality) => {
120
+ let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
121
+ data = data.substring(data.indexOf('64,') + 3);
122
+ return Platform.origin.download(data, filePath);
123
+ },
124
+ download(data, filePath) {
125
+ return new Promise((resolve, reject) => {
126
+ let toAlbum;
127
+ if (!filePath.includes('/')) {
128
+ filePath = `${app.env.USER_DATA_PATH}/` + filePath;
129
+ toAlbum = true;
130
+ }
131
+ const fs = app.getFileSystemManager();
132
+ fs.writeFile({
133
+ filePath,
134
+ data,
135
+ encoding: 'base64',
136
+ success() {
137
+ if (toAlbum) {
138
+ Platform.miniapp.saveToAlbum(filePath).then(() => {
139
+ fs.unlink({ filePath });
140
+ resolve();
141
+ });
142
+ }
143
+ else {
144
+ resolve();
145
+ }
146
+ },
147
+ fail(error) {
148
+ reject(error);
149
+ }
150
+ });
151
+ });
152
+ },
153
+ loadImage(src) {
154
+ return new Promise((resolve, reject) => {
155
+ const img = Platform.canvas.view.createImage();
156
+ img.onload = () => { resolve(img); };
157
+ img.onerror = (error) => { reject(error); };
158
+ img.src = Platform.image.getRealURL(src);
159
+ });
160
+ },
161
+ noRepeat: 'repeat-x'
162
+ };
163
+ Platform.miniapp = {
164
+ select(name) {
165
+ return app.createSelectorQuery().select(name);
166
+ },
167
+ getBounds(select) {
168
+ return new Promise((resolve) => {
169
+ select.boundingClientRect().exec((res) => {
170
+ const rect = res[1];
171
+ resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
172
+ });
173
+ });
174
+ },
175
+ getSizeView(select) {
176
+ return new Promise((resolve) => {
177
+ select.fields({ node: true, size: true }).exec((res) => {
178
+ const data = res[0];
179
+ resolve({ view: data.node, width: data.width, height: data.height });
180
+ });
181
+ });
182
+ },
183
+ saveToAlbum(path) {
184
+ return new Promise((resolve) => {
185
+ app.getSetting({
186
+ success: (res) => {
187
+ if (res.authSetting['scope.writePhotosAlbum']) {
188
+ app.saveImageToPhotosAlbum({
189
+ filePath: path,
190
+ success() { resolve(true); }
191
+ });
192
+ }
193
+ else {
194
+ app.authorize({
195
+ scope: 'scope.writePhotosAlbum',
196
+ success: () => {
197
+ app.saveImageToPhotosAlbum({
198
+ filePath: path,
199
+ success() { resolve(true); }
200
+ });
201
+ },
202
+ fail: () => { }
203
+ });
204
+ }
205
+ }
206
+ });
207
+ });
208
+ },
209
+ onWindowResize(fun) {
210
+ app.onWindowResize(fun);
211
+ },
212
+ offWindowResize(fun) {
213
+ app.offWindowResize(fun);
214
+ }
215
+ };
216
+ Platform.event = {
217
+ stopDefault(_origin) { },
218
+ stopNow(_origin) { },
219
+ stop(_origin) { }
220
+ };
221
+ Platform.canvas = Creator.canvas();
222
+ Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
223
+ }
224
+ }
225
+ Platform.name = 'miniapp';
226
+ Platform.requestRender = function (render) { Platform.canvas.view.requestAnimationFrame(render); };
227
+ defineKey(Platform, 'devicePixelRatio', { get() { return Math.max(1, wx.getSystemInfoSync().pixelRatio); } });
6
228
 
7
229
  class Watcher {
8
230
  get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
@@ -185,7 +407,7 @@ class LayoutBlockData {
185
407
  }
186
408
 
187
409
  const { updateAllMatrix, updateAllChange } = LeafHelper;
188
- const debug$1 = Debug.get('Layouter');
410
+ const debug$2 = Debug.get('Layouter');
189
411
  class Layouter {
190
412
  constructor(target, userConfig) {
191
413
  this.totalTimes = 0;
@@ -220,7 +442,7 @@ class Layouter {
220
442
  target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
221
443
  }
222
444
  catch (e) {
223
- debug$1.error(e);
445
+ debug$2.error(e);
224
446
  }
225
447
  this.layoutedBlocks = null;
226
448
  }
@@ -234,9 +456,9 @@ class Layouter {
234
456
  }
235
457
  layoutOnce() {
236
458
  if (this.layouting)
237
- return debug$1.warn('layouting');
459
+ return debug$2.warn('layouting');
238
460
  if (this.times > 3)
239
- return debug$1.warn('layout max times');
461
+ return debug$2.warn('layout max times');
240
462
  this.times++;
241
463
  this.totalTimes++;
242
464
  this.layouting = true;
@@ -302,9 +524,11 @@ class Layouter {
302
524
  updateAllChange(target);
303
525
  }
304
526
  addExtra(leaf) {
305
- const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
306
- block.updatedList.add(leaf);
307
- block.beforeBounds.add(leaf.__world);
527
+ if (!this.__updatedList.has(leaf)) {
528
+ const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
529
+ updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
530
+ updatedList.add(leaf);
531
+ }
308
532
  }
309
533
  createBlock(data) {
310
534
  return new LayoutBlockData(data);
@@ -338,7 +562,7 @@ class Layouter {
338
562
  }
339
563
  }
340
564
 
341
- const debug = Debug.get('Renderer');
565
+ const debug$1 = Debug.get('Renderer');
342
566
  class Renderer {
343
567
  get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
344
568
  constructor(target, canvas, userConfig) {
@@ -376,7 +600,7 @@ class Renderer {
376
600
  const { target } = this;
377
601
  this.times = 0;
378
602
  this.totalBounds = new Bounds();
379
- debug.log(target.innerName, '--->');
603
+ debug$1.log(target.innerName, '--->');
380
604
  try {
381
605
  this.emitRender(RenderEvent.START);
382
606
  this.renderOnce(callback);
@@ -385,9 +609,9 @@ class Renderer {
385
609
  }
386
610
  catch (e) {
387
611
  this.rendering = false;
388
- debug.error(e);
612
+ debug$1.error(e);
389
613
  }
390
- debug.log('-------------|');
614
+ debug$1.log('-------------|');
391
615
  }
392
616
  renderAgain() {
393
617
  if (this.rendering) {
@@ -399,9 +623,9 @@ class Renderer {
399
623
  }
400
624
  renderOnce(callback) {
401
625
  if (this.rendering)
402
- return debug.warn('rendering');
626
+ return debug$1.warn('rendering');
403
627
  if (this.times > 3)
404
- return debug.warn('render max times');
628
+ return debug$1.warn('render max times');
405
629
  this.times++;
406
630
  this.totalTimes++;
407
631
  this.rendering = true;
@@ -414,6 +638,10 @@ class Renderer {
414
638
  }
415
639
  else {
416
640
  this.requestLayout();
641
+ if (this.ignore) {
642
+ this.ignore = this.rendering = false;
643
+ return;
644
+ }
417
645
  this.emitRender(RenderEvent.BEFORE);
418
646
  if (this.config.usePartRender && this.totalTimes > 1) {
419
647
  this.partRender();
@@ -434,7 +662,7 @@ class Renderer {
434
662
  partRender() {
435
663
  const { canvas, updateBlocks: list } = this;
436
664
  if (!list)
437
- return debug.warn('PartRender: need update attr');
665
+ return debug$1.warn('PartRender: need update attr');
438
666
  this.mergeBlocks();
439
667
  list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
440
668
  this.clipRender(block); });
@@ -450,7 +678,7 @@ class Renderer {
450
678
  canvas.clear();
451
679
  }
452
680
  else {
453
- bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil();
681
+ bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
454
682
  canvas.clearWorld(bounds, true);
455
683
  canvas.clipWorld(bounds, true);
456
684
  }
@@ -474,14 +702,14 @@ class Renderer {
474
702
  if (Debug.showRepaint)
475
703
  this.canvas.strokeWorld(bounds, 'red');
476
704
  this.target.__render(this.canvas, options);
477
- this.renderBounds = realBounds || bounds;
705
+ this.renderBounds = realBounds = realBounds || bounds;
478
706
  this.renderOptions = options;
479
- this.totalBounds.isEmpty() ? this.totalBounds = this.renderBounds : this.totalBounds.add(this.renderBounds);
707
+ this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
480
708
  if (Debug.showHitView)
481
709
  this.renderHitView(options);
482
710
  if (Debug.showBoundsView)
483
711
  this.renderBoundsView(options);
484
- this.canvas.updateRender();
712
+ this.canvas.updateRender(realBounds);
485
713
  }
486
714
  renderHitView(_options) { }
487
715
  renderBoundsView(_options) { }
@@ -503,12 +731,12 @@ class Renderer {
503
731
  const startTime = Date.now();
504
732
  Platform.requestRender(() => {
505
733
  this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
506
- if (this.changed) {
507
- if (this.running && this.canvas.view)
734
+ if (this.running) {
735
+ this.target.emit(AnimateEvent.FRAME);
736
+ if (this.changed && this.canvas.view)
508
737
  this.render();
738
+ this.target.emit(RenderEvent.NEXT);
509
739
  }
510
- if (this.running)
511
- this.target.emit(AnimateEvent.FRAME);
512
740
  if (this.target)
513
741
  this.__requestRender();
514
742
  });
@@ -521,9 +749,12 @@ class Renderer {
521
749
  const bounds = new Bounds(0, 0, width, height);
522
750
  if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
523
751
  this.addBlock(this.canvas.bounds);
524
- this.target.forceUpdate('blendMode');
752
+ this.target.forceUpdate('surface');
753
+ return;
525
754
  }
526
755
  }
756
+ this.addBlock(new Bounds(0, 0, 1, 1));
757
+ this.changed = true;
527
758
  }
528
759
  __onLayoutEnd(event) {
529
760
  if (event.data)
@@ -534,7 +765,7 @@ class Renderer {
534
765
  empty = (!leaf.__world.width || !leaf.__world.height);
535
766
  if (empty) {
536
767
  if (!leaf.isLeafer)
537
- debug.tip(leaf.innerName, ': empty');
768
+ debug$1.tip(leaf.innerName, ': empty');
538
769
  empty = (!leaf.isBranch || leaf.isBranchLeaf);
539
770
  }
540
771
  return empty;
@@ -561,23 +792,13 @@ class Renderer {
561
792
  if (this.target) {
562
793
  this.stop();
563
794
  this.__removeListenEvents();
564
- this.target = null;
565
- this.canvas = null;
566
- this.config = null;
795
+ this.target = this.canvas = this.config = null;
567
796
  }
568
797
  }
569
798
  }
570
799
 
571
- var AnswerType;
572
- (function (AnswerType) {
573
- AnswerType[AnswerType["No"] = 0] = "No";
574
- AnswerType[AnswerType["Yes"] = 1] = "Yes";
575
- AnswerType[AnswerType["NoAndSkip"] = 2] = "NoAndSkip";
576
- AnswerType[AnswerType["YesAndSkip"] = 3] = "YesAndSkip";
577
- })(AnswerType || (AnswerType = {}));
578
-
579
800
  const { hitRadiusPoint } = BoundsHelper;
580
- class Pather {
801
+ class Picker {
581
802
  constructor(target, selector) {
582
803
  this.target = target;
583
804
  this.selector = selector;
@@ -589,33 +810,41 @@ class Pather {
589
810
  options = {};
590
811
  const through = options.through || false;
591
812
  const ignoreHittable = options.ignoreHittable || false;
813
+ const target = options.target || this.target;
592
814
  this.exclude = options.exclude || null;
593
815
  this.point = { x: hitPoint.x, y: hitPoint.y, radiusX: hitRadius, radiusY: hitRadius };
594
- this.findList = [];
595
- this.eachFind(this.target.children, this.target.__onlyHitMask);
596
- const list = this.findList;
597
- const leaf = this.getBestMatchLeaf();
816
+ this.findList = new LeafList(options.findList);
817
+ if (!options.findList)
818
+ this.hitBranch(target);
819
+ const { list } = this.findList;
820
+ const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
598
821
  const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
599
822
  this.clear();
600
- return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
823
+ return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
601
824
  }
602
- getBestMatchLeaf() {
603
- const { findList: targets } = this;
604
- if (targets.length > 1) {
825
+ getBestMatchLeaf(list, bottomList, ignoreHittable) {
826
+ if (list.length) {
605
827
  let find;
606
- this.findList = [];
828
+ this.findList = new LeafList();
607
829
  const { x, y } = this.point;
608
830
  const point = { x, y, radiusX: 0, radiusY: 0 };
609
- for (let i = 0, len = targets.length; i < len; i++) {
610
- find = targets[i];
611
- if (LeafHelper.worldHittable(find)) {
831
+ for (let i = 0, len = list.length; i < len; i++) {
832
+ find = list[i];
833
+ if (ignoreHittable || LeafHelper.worldHittable(find)) {
612
834
  this.hitChild(find, point);
613
835
  if (this.findList.length)
614
- return this.findList[0];
836
+ return this.findList.list[0];
615
837
  }
616
838
  }
617
839
  }
618
- return targets[0];
840
+ if (bottomList) {
841
+ for (let i = 0, len = bottomList.length; i < len; i++) {
842
+ this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
843
+ if (this.findList.length)
844
+ return this.findList.list[0];
845
+ }
846
+ }
847
+ return list[0];
619
848
  }
620
849
  getPath(leaf) {
621
850
  const path = new LeafList();
@@ -627,7 +856,7 @@ class Pather {
627
856
  return path;
628
857
  }
629
858
  getHitablePath(leaf) {
630
- const path = this.getPath(leaf);
859
+ const path = this.getPath(leaf && leaf.hittable ? leaf : null);
631
860
  let item, hittablePath = new LeafList();
632
861
  for (let i = path.list.length - 1; i > -1; i--) {
633
862
  item = path.list[i];
@@ -657,12 +886,15 @@ class Pather {
657
886
  }
658
887
  return throughPath;
659
888
  }
889
+ hitBranch(branch) {
890
+ this.eachFind(branch.children, branch.__onlyHitMask);
891
+ }
660
892
  eachFind(children, hitMask) {
661
893
  let child, hit;
662
894
  const { point } = this, len = children.length;
663
895
  for (let i = len - 1; i > -1; i--) {
664
896
  child = children[i];
665
- if (!child.__.visible || (hitMask && !child.__.isMask))
897
+ if (!child.__.visible || (hitMask && !child.__.mask))
666
898
  continue;
667
899
  hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
668
900
  if (child.isBranch) {
@@ -678,11 +910,15 @@ class Pather {
678
910
  }
679
911
  }
680
912
  }
681
- hitChild(child, point) {
913
+ hitChild(child, point, proxy) {
682
914
  if (this.exclude && this.exclude.has(child))
683
915
  return;
684
- if (child.__hitWorld(point))
685
- this.findList.push(child);
916
+ if (child.__hitWorld(point)) {
917
+ const { parent } = child;
918
+ if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
919
+ return;
920
+ this.findList.add(proxy || child);
921
+ }
686
922
  }
687
923
  clear() {
688
924
  this.point = null;
@@ -694,7 +930,8 @@ class Pather {
694
930
  }
695
931
  }
696
932
 
697
- const { Yes, NoAndSkip, YesAndSkip } = AnswerType;
933
+ const { Yes, NoAndSkip, YesAndSkip } = Answer;
934
+ const idCondition = {}, classNameCondition = {}, tagCondition = {};
698
935
  class Selector {
699
936
  constructor(target, userConfig) {
700
937
  this.config = {};
@@ -704,12 +941,13 @@ class Selector {
704
941
  id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
705
942
  innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
706
943
  className: (leaf, name) => leaf.className === name ? 1 : 0,
707
- tag: (leaf, name) => leaf.__tag === name ? 1 : 0
944
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
945
+ tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
708
946
  };
709
947
  this.target = target;
710
948
  if (userConfig)
711
949
  this.config = DataHelper.default(userConfig, this.config);
712
- this.pather = new Pather(target, this);
950
+ this.picker = new Picker(target, this);
713
951
  this.__listenEvents();
714
952
  }
715
953
  getBy(condition, branch, one, options) {
@@ -720,12 +958,25 @@ class Selector {
720
958
  case 'string':
721
959
  switch (condition[0]) {
722
960
  case '#':
723
- const leaf = this.getById(condition.substring(1), branch);
724
- return one ? leaf : (leaf ? [leaf] : []);
961
+ idCondition.id = condition.substring(1), condition = idCondition;
962
+ break;
725
963
  case '.':
726
- return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
964
+ classNameCondition.className = condition.substring(1), condition = classNameCondition;
965
+ break;
727
966
  default:
728
- return this.getByMethod(this.methods.tag, branch, one, condition);
967
+ tagCondition.tag = condition, condition = tagCondition;
968
+ }
969
+ case 'object':
970
+ if (condition.id !== undefined) {
971
+ const leaf = this.getById(condition.id, branch);
972
+ return one ? leaf : (leaf ? [leaf] : []);
973
+ }
974
+ else if (condition.tag) {
975
+ const { tag } = condition, isArray = tag instanceof Array;
976
+ return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
977
+ }
978
+ else {
979
+ return this.getByMethod(this.methods.className, branch, one, condition.className);
729
980
  }
730
981
  case 'function':
731
982
  return this.getByMethod(condition, branch, one, options);
@@ -734,7 +985,7 @@ class Selector {
734
985
  getByPoint(hitPoint, hitRadius, options) {
735
986
  if (Platform.name === 'node')
736
987
  this.target.emit(LayoutEvent.CHECK_UPDATE);
737
- return this.pather.getByPoint(hitPoint, hitRadius, options);
988
+ return this.picker.getByPoint(hitPoint, hitRadius, options);
738
989
  }
739
990
  getByInnerId(innerId, branch) {
740
991
  const cache = this.innerIdMap[innerId];
@@ -810,7 +1061,7 @@ class Selector {
810
1061
  destroy() {
811
1062
  if (this.__eventIds.length) {
812
1063
  this.__removeListenEvents();
813
- this.pather.destroy();
1064
+ this.picker.destroy();
814
1065
  this.findLeaf = null;
815
1066
  this.innerIdMap = {};
816
1067
  this.idMap = {};
@@ -826,104 +1077,14 @@ Object.assign(Creator, {
826
1077
  });
827
1078
  Platform.layout = Layouter.fullLayout;
828
1079
 
829
- class LeaferCanvas extends LeaferCanvasBase {
830
- get allowBackgroundColor() { return false; }
831
- init() {
832
- let { view } = this.config;
833
- if (view) {
834
- if (typeof view === 'string') {
835
- if (view[0] !== '#')
836
- view = '#' + view;
837
- this.viewSelect = Platform.miniapp.select(view);
838
- }
839
- else if (view.fields) {
840
- this.viewSelect = view;
841
- }
842
- else {
843
- this.initView(view);
844
- }
845
- if (this.viewSelect)
846
- Platform.miniapp.getSizeView(this.viewSelect).then(sizeView => {
847
- this.initView(sizeView);
848
- });
849
- }
850
- else {
851
- this.initView();
852
- }
853
- }
854
- initView(view) {
855
- if (!view) {
856
- view = {};
857
- this.__createView();
858
- }
859
- else {
860
- this.view = view.view || view;
861
- }
862
- this.__createContext();
863
- const { width, height, pixelRatio } = this.config;
864
- const size = { width: width || view.width, height: height || view.height, pixelRatio };
865
- this.resize(size);
866
- if (this.context.roundRect) {
867
- this.roundRect = function (x, y, width, height, radius) {
868
- this.context.roundRect(x, y, width, height, typeof radius === 'number' ? [radius] : radius);
869
- };
870
- }
871
- canvasPatch(this.context.__proto__);
872
- }
873
- __createView() {
874
- this.view = Platform.origin.createCanvas(1, 1);
875
- }
876
- updateViewSize() {
877
- const { width, height, pixelRatio } = this;
878
- this.view.width = width * pixelRatio;
879
- this.view.height = height * pixelRatio;
880
- }
881
- updateClientBounds(callback) {
882
- if (this.viewSelect)
883
- Platform.miniapp.getBounds(this.viewSelect).then(bounds => {
884
- this.clientBounds = bounds;
885
- if (callback)
886
- callback();
887
- });
888
- }
889
- startAutoLayout(_autoBounds, listener) {
890
- this.resizeListener = listener;
891
- this.checkSize = this.checkSize.bind(this);
892
- Platform.miniapp.onWindowResize(this.checkSize);
893
- }
894
- checkSize() {
895
- if (this.viewSelect) {
896
- setTimeout(() => {
897
- this.updateClientBounds(() => {
898
- const { width, height } = this.clientBounds;
899
- const { pixelRatio } = this;
900
- const size = { width, height, pixelRatio };
901
- if (!this.isSameSize(size)) {
902
- const oldSize = {};
903
- DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
904
- this.resize(size);
905
- if (this.width !== undefined)
906
- this.resizeListener(new ResizeEvent(size, oldSize));
907
- }
908
- });
909
- }, 500);
910
- }
911
- }
912
- stopAutoLayout() {
913
- this.autoLayout = false;
914
- this.resizeListener = null;
915
- Platform.miniapp.offWindowResize(this.checkSize);
916
- }
917
- }
918
-
919
- const PointerEventHelper = {
920
- convertTouch(e, local) {
921
- const touch = PointerEventHelper.getTouch(e);
922
- const base = InteractionHelper.getBase(e);
923
- return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'touch', pressure: touch.force || 1 });
924
- },
925
- getTouch(e) {
926
- return e.touches[0] || e.changedTouches[0];
1080
+ const PointerEventHelper = {
1081
+ convertTouch(e, local) {
1082
+ const touch = PointerEventHelper.getTouch(e);
1083
+ const base = InteractionHelper.getBase(e);
1084
+ return Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: 1, height: 1, pointerType: 'touch', multiTouch: e.touches.length > 1, pressure: touch.force || 1 });
1085
+ },
1086
+ getTouch(e) {
1087
+ return e.touches[0] || e.changedTouches[0];
927
1088
  }
928
1089
  };
929
1090
 
@@ -948,15 +1109,12 @@ class Interaction extends InteractionBase {
948
1109
  this.onTouchCancel();
949
1110
  }
950
1111
  }
951
- getLocal(p, updateClient) {
952
- if (updateClient)
953
- this.canvas.updateClientBounds();
954
- if (p.x !== undefined) {
955
- return { x: p.x, y: p.y };
1112
+ getLocal(clientPoint, updateClient) {
1113
+ if (clientPoint.x !== undefined) {
1114
+ return { x: clientPoint.x, y: clientPoint.y };
956
1115
  }
957
1116
  else {
958
- const { clientBounds } = this.canvas;
959
- return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
1117
+ return super.getLocal(clientPoint, updateClient);
960
1118
  }
961
1119
  }
962
1120
  getTouches(touches) {
@@ -983,7 +1141,7 @@ class Interaction extends InteractionBase {
983
1141
  this.pointerCancel();
984
1142
  }
985
1143
  multiTouchStart(e) {
986
- this.useMultiTouch = (e.touches.length >= 2);
1144
+ this.useMultiTouch = (e.touches.length > 1);
987
1145
  this.touches = this.useMultiTouch ? this.getTouches(e.touches) : undefined;
988
1146
  if (this.useMultiTouch)
989
1147
  this.pointerCancel();
@@ -1024,195 +1182,381 @@ class Interaction extends InteractionBase {
1024
1182
  }
1025
1183
  }
1026
1184
 
1027
- const { mineType, fileType } = FileHelper;
1028
- Object.assign(Creator, {
1029
- canvas: (options, manager) => new LeaferCanvas(options, manager),
1030
- image: (options) => new LeaferImage(options),
1031
- hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
1032
- interaction: (target, canvas, selector, options) => { return new Interaction(target, canvas, selector, options); }
1033
- });
1034
- function useCanvas(_canvasType, app) {
1035
- if (!Platform.origin) {
1036
- Platform.origin = {
1037
- createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
1038
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
1039
- canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
1040
- canvasSaveAs: (canvas, filePath, quality) => {
1041
- return new Promise((resolve, reject) => {
1042
- let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
1043
- data = data.substring(data.indexOf('64,') + 3);
1044
- let toAlbum;
1045
- if (!filePath.includes('/')) {
1046
- filePath = `${app.env.USER_DATA_PATH}/` + filePath;
1047
- toAlbum = true;
1048
- }
1049
- const fs = app.getFileSystemManager();
1050
- fs.writeFile({
1051
- filePath,
1052
- data,
1053
- encoding: 'base64',
1054
- success() {
1055
- if (toAlbum) {
1056
- Platform.miniapp.saveToAlbum(filePath).then(() => {
1057
- fs.unlink({ filePath });
1058
- });
1059
- }
1060
- resolve();
1061
- },
1062
- fail(error) {
1063
- reject(error);
1064
- }
1065
- });
1066
- });
1067
- },
1068
- loadImage(url) {
1069
- return new Promise((resolve, reject) => {
1070
- const img = Platform.canvas.view.createImage();
1071
- img.onload = () => { resolve(img); };
1072
- img.onerror = (error) => { reject(error); };
1073
- img.src = url;
1074
- });
1075
- },
1076
- noRepeat: 'repeat-x'
1077
- };
1078
- Platform.miniapp = {
1079
- select(name) {
1080
- return app.createSelectorQuery().select(name);
1081
- },
1082
- getBounds(select) {
1083
- return new Promise((resolve) => {
1084
- select.boundingClientRect().exec((res) => {
1085
- const rect = res[1];
1086
- resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
1087
- });
1088
- });
1089
- },
1090
- getSizeView(select) {
1091
- return new Promise((resolve) => {
1092
- select.fields({ node: true, size: true }).exec((res) => {
1093
- const data = res[0];
1094
- resolve({ view: data.node, width: data.width, height: data.height });
1095
- });
1096
- });
1097
- },
1098
- saveToAlbum(path) {
1099
- return new Promise((resolve) => {
1100
- app.getSetting({
1101
- success: (res) => {
1102
- if (res.authSetting['scope.writePhotosAlbum']) {
1103
- app.saveImageToPhotosAlbum({
1104
- filePath: path,
1105
- success() { resolve(true); }
1106
- });
1107
- }
1108
- else {
1109
- app.authorize({
1110
- scope: 'scope.writePhotosAlbum',
1111
- success: () => {
1112
- app.saveImageToPhotosAlbum({
1113
- filePath: path,
1114
- success() { resolve(true); }
1115
- });
1116
- },
1117
- fail: () => { }
1118
- });
1119
- }
1120
- }
1121
- });
1122
- });
1123
- },
1124
- onWindowResize(fun) {
1125
- app.onWindowResize(fun);
1126
- },
1127
- offWindowResize(fun) {
1128
- app.offWindowResize(fun);
1185
+ function fillText(ui, canvas) {
1186
+ let row;
1187
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1188
+ for (let i = 0, len = rows.length; i < len; i++) {
1189
+ row = rows[i];
1190
+ if (row.text) {
1191
+ canvas.fillText(row.text, row.x, row.y);
1192
+ }
1193
+ else if (row.data) {
1194
+ row.data.forEach(charData => {
1195
+ canvas.fillText(charData.char, charData.x, row.y);
1196
+ });
1197
+ }
1198
+ if (decorationY)
1199
+ canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1200
+ }
1201
+ }
1202
+
1203
+ function fill(fill, ui, canvas) {
1204
+ canvas.fillStyle = fill;
1205
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1206
+ }
1207
+ function fills(fills, ui, canvas) {
1208
+ let item;
1209
+ const { windingRule, __font } = ui.__;
1210
+ for (let i = 0, len = fills.length; i < len; i++) {
1211
+ item = fills[i];
1212
+ if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
1213
+ continue;
1214
+ if (item.style) {
1215
+ canvas.fillStyle = item.style;
1216
+ if (item.transform) {
1217
+ canvas.save();
1218
+ canvas.transform(item.transform);
1219
+ if (item.blendMode)
1220
+ canvas.blendMode = item.blendMode;
1221
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1222
+ canvas.restore();
1129
1223
  }
1130
- };
1131
- Platform.event = {
1132
- stopDefault(_origin) { },
1133
- stopNow(_origin) { },
1134
- stop(_origin) { }
1135
- };
1136
- Platform.canvas = Creator.canvas();
1137
- Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
1224
+ else {
1225
+ if (item.blendMode) {
1226
+ canvas.saveBlendMode(item.blendMode);
1227
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1228
+ canvas.restoreBlendMode();
1229
+ }
1230
+ else {
1231
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1232
+ }
1233
+ }
1234
+ }
1138
1235
  }
1139
1236
  }
1140
- Platform.name = 'miniapp';
1141
- Platform.requestRender = function (render) { Platform.canvas.view.requestAnimationFrame(render); };
1142
- Platform.devicePixelRatio = wx.getSystemInfoSync().pixelRatio;
1237
+
1238
+ function strokeText(stroke, ui, canvas) {
1239
+ const { strokeAlign } = ui.__;
1240
+ const isStrokes = typeof stroke !== 'string';
1241
+ switch (strokeAlign) {
1242
+ case 'center':
1243
+ canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1244
+ isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1245
+ break;
1246
+ case 'inside':
1247
+ drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
1248
+ break;
1249
+ case 'outside':
1250
+ drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
1251
+ break;
1252
+ }
1253
+ }
1254
+ function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
1255
+ const { __strokeWidth, __font } = ui.__;
1256
+ const out = canvas.getSameCanvas(true, true);
1257
+ out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
1258
+ out.font = __font;
1259
+ isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1260
+ out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1261
+ fillText(ui, out);
1262
+ out.blendMode = 'normal';
1263
+ if (ui.__worldFlipped) {
1264
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1265
+ }
1266
+ else {
1267
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1268
+ }
1269
+ out.recycle(ui.__nowWorld);
1270
+ }
1271
+ function drawTextStroke(ui, canvas) {
1272
+ let row;
1273
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1274
+ for (let i = 0, len = rows.length; i < len; i++) {
1275
+ row = rows[i];
1276
+ if (row.text) {
1277
+ canvas.strokeText(row.text, row.x, row.y);
1278
+ }
1279
+ else if (row.data) {
1280
+ row.data.forEach(charData => {
1281
+ canvas.strokeText(charData.char, charData.x, row.y);
1282
+ });
1283
+ }
1284
+ if (decorationY)
1285
+ canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1286
+ }
1287
+ }
1288
+ function drawStrokesStyle(strokes, isText, ui, canvas) {
1289
+ let item;
1290
+ for (let i = 0, len = strokes.length; i < len; i++) {
1291
+ item = strokes[i];
1292
+ if (item.image && PaintImage.checkImage(ui, canvas, item, false))
1293
+ continue;
1294
+ if (item.style) {
1295
+ canvas.strokeStyle = item.style;
1296
+ if (item.blendMode) {
1297
+ canvas.saveBlendMode(item.blendMode);
1298
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1299
+ canvas.restoreBlendMode();
1300
+ }
1301
+ else {
1302
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1303
+ }
1304
+ }
1305
+ }
1306
+ }
1307
+
1308
+ function stroke(stroke, ui, canvas) {
1309
+ const options = ui.__;
1310
+ const { __strokeWidth, strokeAlign, __font } = options;
1311
+ if (!__strokeWidth)
1312
+ return;
1313
+ if (__font) {
1314
+ strokeText(stroke, ui, canvas);
1315
+ }
1316
+ else {
1317
+ switch (strokeAlign) {
1318
+ case 'center':
1319
+ canvas.setStroke(stroke, __strokeWidth, options);
1320
+ canvas.stroke();
1321
+ break;
1322
+ case 'inside':
1323
+ canvas.save();
1324
+ canvas.setStroke(stroke, __strokeWidth * 2, options);
1325
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1326
+ canvas.stroke();
1327
+ canvas.restore();
1328
+ break;
1329
+ case 'outside':
1330
+ const out = canvas.getSameCanvas(true, true);
1331
+ out.setStroke(stroke, __strokeWidth * 2, options);
1332
+ ui.__drawRenderPath(out);
1333
+ out.stroke();
1334
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1335
+ out.clearWorld(ui.__layout.renderBounds);
1336
+ if (ui.__worldFlipped) {
1337
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1338
+ }
1339
+ else {
1340
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1341
+ }
1342
+ out.recycle(ui.__nowWorld);
1343
+ break;
1344
+ }
1345
+ }
1346
+ }
1347
+ function strokes(strokes, ui, canvas) {
1348
+ const options = ui.__;
1349
+ const { __strokeWidth, strokeAlign, __font } = options;
1350
+ if (!__strokeWidth)
1351
+ return;
1352
+ if (__font) {
1353
+ strokeText(strokes, ui, canvas);
1354
+ }
1355
+ else {
1356
+ switch (strokeAlign) {
1357
+ case 'center':
1358
+ canvas.setStroke(undefined, __strokeWidth, options);
1359
+ drawStrokesStyle(strokes, false, ui, canvas);
1360
+ break;
1361
+ case 'inside':
1362
+ canvas.save();
1363
+ canvas.setStroke(undefined, __strokeWidth * 2, options);
1364
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1365
+ drawStrokesStyle(strokes, false, ui, canvas);
1366
+ canvas.restore();
1367
+ break;
1368
+ case 'outside':
1369
+ const { renderBounds } = ui.__layout;
1370
+ const out = canvas.getSameCanvas(true, true);
1371
+ ui.__drawRenderPath(out);
1372
+ out.setStroke(undefined, __strokeWidth * 2, options);
1373
+ drawStrokesStyle(strokes, false, ui, out);
1374
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1375
+ out.clearWorld(renderBounds);
1376
+ if (ui.__worldFlipped) {
1377
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1378
+ }
1379
+ else {
1380
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1381
+ }
1382
+ out.recycle(ui.__nowWorld);
1383
+ break;
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1389
+ function shape(ui, current, options) {
1390
+ const canvas = current.getSameCanvas();
1391
+ const nowWorld = ui.__nowWorld;
1392
+ let bounds, fitMatrix, shapeBounds, worldCanvas;
1393
+ let { scaleX, scaleY } = nowWorld;
1394
+ if (scaleX < 0)
1395
+ scaleX = -scaleX;
1396
+ if (scaleY < 0)
1397
+ scaleY = -scaleY;
1398
+ if (current.bounds.includes(nowWorld)) {
1399
+ worldCanvas = canvas;
1400
+ bounds = shapeBounds = nowWorld;
1401
+ }
1402
+ else {
1403
+ const { renderShapeSpread: spread } = ui.__layout;
1404
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
1405
+ fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
1406
+ let { a: fitScaleX, d: fitScaleY } = fitMatrix;
1407
+ if (fitMatrix.a < 1) {
1408
+ worldCanvas = current.getSameCanvas();
1409
+ ui.__renderShape(worldCanvas, options);
1410
+ scaleX *= fitScaleX;
1411
+ scaleY *= fitScaleY;
1412
+ }
1413
+ shapeBounds = getOuterOf(nowWorld, fitMatrix);
1414
+ bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1415
+ if (options.matrix) {
1416
+ const { matrix } = options;
1417
+ fitMatrix.multiply(matrix);
1418
+ fitScaleX *= matrix.scaleX;
1419
+ fitScaleY *= matrix.scaleY;
1420
+ }
1421
+ options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
1422
+ }
1423
+ ui.__renderShape(canvas, options);
1424
+ return {
1425
+ canvas, matrix: fitMatrix, bounds,
1426
+ worldCanvas, shapeBounds, scaleX, scaleY
1427
+ };
1428
+ }
1429
+
1430
+ let recycleMap;
1431
+ function compute(attrName, ui) {
1432
+ const data = ui.__, leafPaints = [];
1433
+ let paints = data.__input[attrName], hasOpacityPixel;
1434
+ if (!(paints instanceof Array))
1435
+ paints = [paints];
1436
+ recycleMap = PaintImage.recycleImage(attrName, data);
1437
+ for (let i = 0, len = paints.length, item; i < len; i++) {
1438
+ item = getLeafPaint(attrName, paints[i], ui);
1439
+ if (item)
1440
+ leafPaints.push(item);
1441
+ }
1442
+ data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1443
+ if (leafPaints.length && leafPaints[0].image)
1444
+ hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1445
+ if (attrName === 'fill') {
1446
+ data.__pixelFill = hasOpacityPixel;
1447
+ }
1448
+ else {
1449
+ data.__pixelStroke = hasOpacityPixel;
1450
+ }
1451
+ }
1452
+ function getLeafPaint(attrName, paint, ui) {
1453
+ if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1454
+ return undefined;
1455
+ const { boxBounds } = ui.__layout;
1456
+ switch (paint.type) {
1457
+ case 'solid':
1458
+ let { type, blendMode, color, opacity } = paint;
1459
+ return { type, blendMode, style: ColorConvert.string(color, opacity) };
1460
+ case 'image':
1461
+ return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1462
+ case 'linear':
1463
+ return PaintGradient.linearGradient(paint, boxBounds);
1464
+ case 'radial':
1465
+ return PaintGradient.radialGradient(paint, boxBounds);
1466
+ case 'angular':
1467
+ return PaintGradient.conicGradient(paint, boxBounds);
1468
+ default:
1469
+ return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1470
+ }
1471
+ }
1472
+
1473
+ const PaintModule = {
1474
+ compute,
1475
+ fill,
1476
+ fills,
1477
+ fillText,
1478
+ stroke,
1479
+ strokes,
1480
+ strokeText,
1481
+ drawTextStroke,
1482
+ shape
1483
+ };
1143
1484
 
1144
1485
  let origin = {};
1145
- const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1146
- function fillOrFitMode(data, mode, box, width, height, rotation) {
1147
- const transform = get$4();
1148
- const swap = rotation && rotation !== 180;
1149
- const sw = box.width / (swap ? height : width);
1150
- const sh = box.height / (swap ? width : height);
1151
- const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1152
- const x = box.x + (box.width - width * scale) / 2;
1153
- const y = box.y + (box.height - height * scale) / 2;
1154
- translate$1(transform, x, y);
1155
- scaleHelper(transform, scale);
1486
+ const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
1487
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1488
+ const transform = get$3();
1489
+ translate$1(transform, box.x + x, box.y + y);
1490
+ scaleHelper(transform, scaleX, scaleY);
1156
1491
  if (rotation)
1157
- rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1158
- data.scaleX = data.scaleY = scale;
1492
+ rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1159
1493
  data.transform = transform;
1160
1494
  }
1161
1495
  function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
1162
- const transform = get$4();
1163
- translate$1(transform, box.x, box.y);
1164
- if (x || y)
1165
- translate$1(transform, x, y);
1166
- if (scaleX) {
1496
+ const transform = get$3();
1497
+ translate$1(transform, box.x + x, box.y + y);
1498
+ if (scaleX)
1167
1499
  scaleHelper(transform, scaleX, scaleY);
1168
- data.scaleX = transform.a;
1169
- data.scaleY = transform.d;
1170
- }
1171
1500
  if (rotation)
1172
1501
  rotate(transform, rotation);
1173
1502
  data.transform = transform;
1174
1503
  }
1175
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
1176
- const transform = get$4();
1504
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
1505
+ const transform = get$3();
1177
1506
  if (rotation) {
1178
- rotate(transform, rotation);
1179
- switch (rotation) {
1180
- case 90:
1181
- translate$1(transform, height, 0);
1182
- break;
1183
- case 180:
1184
- translate$1(transform, width, height);
1185
- break;
1186
- case 270:
1187
- translate$1(transform, 0, width);
1188
- break;
1507
+ if (align === 'center') {
1508
+ rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
1509
+ }
1510
+ else {
1511
+ rotate(transform, rotation);
1512
+ switch (rotation) {
1513
+ case 90:
1514
+ translate$1(transform, height, 0);
1515
+ break;
1516
+ case 180:
1517
+ translate$1(transform, width, height);
1518
+ break;
1519
+ case 270:
1520
+ translate$1(transform, 0, width);
1521
+ break;
1522
+ }
1189
1523
  }
1190
1524
  }
1191
- origin.x = box.x;
1192
- origin.y = box.y;
1193
- if (x || y)
1194
- origin.x += x, origin.y += y;
1525
+ origin.x = box.x + x;
1526
+ origin.y = box.y + y;
1195
1527
  translate$1(transform, origin.x, origin.y);
1196
- if (scaleX) {
1197
- scaleOfOuter$2(transform, origin, scaleX, scaleY);
1198
- data.scaleX = scaleX;
1199
- data.scaleY = scaleY;
1200
- }
1528
+ if (scaleX)
1529
+ scaleOfOuter$1(transform, origin, scaleX, scaleY);
1201
1530
  data.transform = transform;
1202
1531
  }
1203
1532
 
1204
- const { get: get$3, translate } = MatrixHelper;
1533
+ const { get: get$2, translate } = MatrixHelper;
1534
+ const tempBox = new Bounds();
1535
+ const tempPoint = {};
1205
1536
  function createData(leafPaint, image, paint, box) {
1206
- let { width, height } = image;
1207
- const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
1208
- const sameBox = box.width === width && box.height === height;
1537
+ const { blendMode } = paint;
1209
1538
  if (blendMode)
1210
1539
  leafPaint.blendMode = blendMode;
1211
- const data = leafPaint.data = { mode };
1212
- let x, y, scaleX, scaleY;
1213
- if (offset)
1214
- x = offset.x, y = offset.y;
1215
- if (size) {
1540
+ leafPaint.data = getPatternData(paint, box, image);
1541
+ }
1542
+ function getPatternData(paint, box, image) {
1543
+ let { width, height } = image;
1544
+ if (paint.padding)
1545
+ box = tempBox.set(box).shrink(paint.padding);
1546
+ const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
1547
+ const sameBox = box.width === width && box.height === height;
1548
+ const data = { mode };
1549
+ const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1550
+ const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1551
+ let x = 0, y = 0, scaleX, scaleY;
1552
+ if (!mode || mode === 'cover' || mode === 'fit') {
1553
+ if (!sameBox || rotation) {
1554
+ const sw = box.width / swapWidth, sh = box.height / swapHeight;
1555
+ scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1556
+ x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1557
+ }
1558
+ }
1559
+ else if (size) {
1216
1560
  scaleX = (typeof size === 'number' ? size : size.width) / width;
1217
1561
  scaleY = (typeof size === 'number' ? size : size.height) / height;
1218
1562
  }
@@ -1220,30 +1564,46 @@ function createData(leafPaint, image, paint, box) {
1220
1564
  scaleX = typeof scale === 'number' ? scale : scale.x;
1221
1565
  scaleY = typeof scale === 'number' ? scale : scale.y;
1222
1566
  }
1567
+ if (align) {
1568
+ const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1569
+ if (scaleX)
1570
+ imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1571
+ AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1572
+ x += tempPoint.x, y += tempPoint.y;
1573
+ }
1574
+ if (offset)
1575
+ x += offset.x, y += offset.y;
1223
1576
  switch (mode) {
1224
1577
  case 'strench':
1225
1578
  if (!sameBox)
1226
1579
  width = box.width, height = box.height;
1227
- if (box.x || box.y) {
1228
- data.transform = get$3();
1229
- translate(data.transform, box.x, box.y);
1230
- }
1231
1580
  break;
1581
+ case 'normal':
1232
1582
  case 'clip':
1233
- if (offset || scaleX || rotation)
1583
+ if (x || y || scaleX || rotation)
1234
1584
  clipMode(data, box, x, y, scaleX, scaleY, rotation);
1235
1585
  break;
1236
1586
  case 'repeat':
1237
1587
  if (!sameBox || scaleX || rotation)
1238
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
1588
+ repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1239
1589
  if (!repeat)
1240
1590
  data.repeat = 'repeat';
1241
1591
  break;
1242
1592
  case 'fit':
1243
1593
  case 'cover':
1244
1594
  default:
1245
- if (!sameBox || rotation)
1246
- fillOrFitMode(data, mode, box, width, height, rotation);
1595
+ if (scaleX)
1596
+ fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1597
+ }
1598
+ if (!data.transform) {
1599
+ if (box.x || box.y) {
1600
+ data.transform = get$2();
1601
+ translate(data.transform, box.x, box.y);
1602
+ }
1603
+ }
1604
+ if (scaleX && mode !== 'strench') {
1605
+ data.scaleX = scaleX;
1606
+ data.scaleY = scaleY;
1247
1607
  }
1248
1608
  data.width = width;
1249
1609
  data.height = height;
@@ -1251,112 +1611,108 @@ function createData(leafPaint, image, paint, box) {
1251
1611
  data.opacity = opacity;
1252
1612
  if (repeat)
1253
1613
  data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1614
+ return data;
1254
1615
  }
1255
1616
 
1256
- function image(ui, attrName, attrValue, box, firstUse) {
1257
- const leafPaint = { type: attrValue.type };
1258
- const image = leafPaint.image = ImageManager.get(attrValue);
1259
- const event = (firstUse || image.loading) && { target: ui, image, attrName, attrValue };
1617
+ let cache, box = new Bounds();
1618
+ const { isSame } = BoundsHelper;
1619
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1620
+ let leafPaint, event;
1621
+ const image = ImageManager.get(paint);
1622
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1623
+ leafPaint = cache.leafPaint;
1624
+ }
1625
+ else {
1626
+ leafPaint = { type: paint.type, image };
1627
+ cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1628
+ }
1629
+ if (firstUse || image.loading)
1630
+ event = { image, attrName, attrValue: paint };
1260
1631
  if (image.ready) {
1261
- if (hasNaturalSize(ui, attrName, image))
1262
- createData(leafPaint, image, attrValue, box);
1632
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1263
1633
  if (firstUse) {
1264
- emit(ImageEvent.LOAD, event);
1265
- emit(ImageEvent.LOADED, event);
1634
+ onLoad(ui, event);
1635
+ onLoadSuccess(ui, event);
1266
1636
  }
1267
1637
  }
1268
1638
  else if (image.error) {
1269
- if (firstUse) {
1270
- ui.forceUpdate('surface');
1271
- event.error = image.error;
1272
- emit(ImageEvent.ERROR, event);
1273
- }
1639
+ if (firstUse)
1640
+ onLoadError(ui, event, image.error);
1274
1641
  }
1275
1642
  else {
1643
+ ignoreRender(ui, true);
1276
1644
  if (firstUse)
1277
- emit(ImageEvent.LOAD, event);
1645
+ onLoad(ui, event);
1278
1646
  leafPaint.loadId = image.load(() => {
1647
+ ignoreRender(ui, false);
1279
1648
  if (!ui.destroyed) {
1280
- if (hasNaturalSize(ui, attrName, image)) {
1281
- createData(leafPaint, image, attrValue, box);
1649
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1650
+ if (image.hasOpacityPixel)
1651
+ ui.__layout.hitCanvasChanged = true;
1282
1652
  ui.forceUpdate('surface');
1283
1653
  }
1284
- emit(ImageEvent.LOADED, event);
1654
+ onLoadSuccess(ui, event);
1285
1655
  }
1656
+ leafPaint.loadId = null;
1286
1657
  }, (error) => {
1287
- ui.forceUpdate('surface');
1288
- event.error = error;
1289
- emit(ImageEvent.ERROR, event);
1658
+ ignoreRender(ui, false);
1659
+ onLoadError(ui, event, error);
1660
+ leafPaint.loadId = null;
1290
1661
  });
1291
1662
  }
1292
1663
  return leafPaint;
1293
1664
  }
1294
- function hasNaturalSize(ui, attrName, image) {
1665
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1295
1666
  if (attrName === 'fill' && !ui.__.__naturalWidth) {
1296
- const { __: d } = ui;
1297
- d.__naturalWidth = image.width;
1298
- d.__naturalHeight = image.height;
1299
- if (!d.__getInput('width') || !d.__getInput('height')) {
1667
+ const data = ui.__;
1668
+ data.__naturalWidth = image.width / data.pixelRatio;
1669
+ data.__naturalHeight = image.height / data.pixelRatio;
1670
+ if (data.__autoSide) {
1300
1671
  ui.forceUpdate('width');
1301
1672
  if (ui.__proxyData) {
1302
- ui.setProxyAttr('width', ui.__.width);
1303
- ui.setProxyAttr('height', ui.__.height);
1673
+ ui.setProxyAttr('width', data.width);
1674
+ ui.setProxyAttr('height', data.height);
1304
1675
  }
1305
1676
  return false;
1306
1677
  }
1307
1678
  }
1679
+ if (!leafPaint.data)
1680
+ createData(leafPaint, image, paint, boxBounds);
1308
1681
  return true;
1309
1682
  }
1310
- function emit(type, data) {
1311
- if (data.target.hasEvent(type))
1312
- data.target.emitEvent(new ImageEvent(type, data));
1683
+ function onLoad(ui, event) {
1684
+ emit(ui, ImageEvent.LOAD, event);
1685
+ }
1686
+ function onLoadSuccess(ui, event) {
1687
+ emit(ui, ImageEvent.LOADED, event);
1688
+ }
1689
+ function onLoadError(ui, event, error) {
1690
+ event.error = error;
1691
+ ui.forceUpdate('surface');
1692
+ emit(ui, ImageEvent.ERROR, event);
1693
+ }
1694
+ function emit(ui, type, data) {
1695
+ if (ui.hasEvent(type))
1696
+ ui.emitEvent(new ImageEvent(type, data));
1697
+ }
1698
+ function ignoreRender(ui, value) {
1699
+ const { leafer } = ui;
1700
+ if (leafer && leafer.viewReady)
1701
+ leafer.renderer.ignore = value;
1313
1702
  }
1314
1703
 
1315
- /******************************************************************************
1316
- Copyright (c) Microsoft Corporation.
1317
-
1318
- Permission to use, copy, modify, and/or distribute this software for any
1319
- purpose with or without fee is hereby granted.
1320
-
1321
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1322
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1323
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1324
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1325
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1326
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1327
- PERFORMANCE OF THIS SOFTWARE.
1328
- ***************************************************************************** */
1329
- /* global Reflect, Promise, SuppressedError, Symbol */
1330
-
1331
-
1332
- function __awaiter(thisArg, _arguments, P, generator) {
1333
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1334
- return new (P || (P = Promise))(function (resolve, reject) {
1335
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1336
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1337
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1338
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1339
- });
1340
- }
1341
-
1342
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1343
- var e = new Error(message);
1344
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1345
- };
1346
-
1347
- const Export$1 = {};
1348
-
1349
- const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
1704
+ const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
1705
+ const { ceil, abs: abs$1 } = Math;
1350
1706
  function createPattern(ui, paint, pixelRatio) {
1351
- let { scaleX, scaleY } = ui.__world;
1707
+ let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1352
1708
  const id = scaleX + '-' + scaleY;
1353
1709
  if (paint.patternId !== id && !ui.destroyed) {
1354
- scaleX = Math.abs(scaleX);
1355
- scaleY = Math.abs(scaleY);
1710
+ scaleX = abs$1(scaleX);
1711
+ scaleY = abs$1(scaleY);
1356
1712
  const { image, data } = paint;
1357
1713
  let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1358
1714
  if (sx) {
1359
- imageMatrix = get$2();
1715
+ imageMatrix = get$1();
1360
1716
  copy$1(imageMatrix, transform);
1361
1717
  scale(imageMatrix, 1 / sx, 1 / sy);
1362
1718
  scaleX *= sx;
@@ -1391,22 +1747,14 @@ function createPattern(ui, paint, pixelRatio) {
1391
1747
  }
1392
1748
  if (transform || scaleX !== 1 || scaleY !== 1) {
1393
1749
  if (!imageMatrix) {
1394
- imageMatrix = get$2();
1750
+ imageMatrix = get$1();
1395
1751
  if (transform)
1396
1752
  copy$1(imageMatrix, transform);
1397
1753
  }
1398
1754
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1399
1755
  }
1400
- const pattern = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), repeat || (Platform.origin.noRepeat || 'no-repeat'));
1401
- try {
1402
- if (paint.transform)
1403
- paint.transform = null;
1404
- if (imageMatrix)
1405
- pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
1406
- }
1407
- catch (_a) {
1408
- paint.transform = imageMatrix;
1409
- }
1756
+ const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
1757
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1410
1758
  paint.style = pattern;
1411
1759
  paint.patternId = id;
1412
1760
  return true;
@@ -1416,10 +1764,42 @@ function createPattern(ui, paint, pixelRatio) {
1416
1764
  }
1417
1765
  }
1418
1766
 
1767
+ /******************************************************************************
1768
+ Copyright (c) Microsoft Corporation.
1769
+
1770
+ Permission to use, copy, modify, and/or distribute this software for any
1771
+ purpose with or without fee is hereby granted.
1772
+
1773
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1774
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1775
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1776
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1777
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1778
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1779
+ PERFORMANCE OF THIS SOFTWARE.
1780
+ ***************************************************************************** */
1781
+ /* global Reflect, Promise, SuppressedError, Symbol */
1782
+
1783
+
1784
+ function __awaiter(thisArg, _arguments, P, generator) {
1785
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1786
+ return new (P || (P = Promise))(function (resolve, reject) {
1787
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1788
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1789
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1790
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
1791
+ });
1792
+ }
1793
+
1794
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1795
+ var e = new Error(message);
1796
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1797
+ };
1798
+
1419
1799
  const { abs } = Math;
1420
1800
  function checkImage(ui, canvas, paint, allowPaint) {
1421
- const { scaleX, scaleY } = ui.__world;
1422
- if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1801
+ const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1802
+ if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
1423
1803
  return false;
1424
1804
  }
1425
1805
  else {
@@ -1433,7 +1813,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1433
1813
  width *= data.scaleX;
1434
1814
  height *= data.scaleY;
1435
1815
  }
1436
- allowPaint = width * height > Platform.image.maxCacheSize;
1816
+ allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
1437
1817
  }
1438
1818
  else {
1439
1819
  allowPaint = false;
@@ -1450,309 +1830,74 @@ function checkImage(ui, canvas, paint, allowPaint) {
1450
1830
  canvas.transform(data.transform);
1451
1831
  canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
1452
1832
  canvas.restore();
1453
- return true;
1454
- }
1455
- else {
1456
- if (!paint.style || Export$1.running) {
1457
- createPattern(ui, paint, canvas.pixelRatio);
1458
- }
1459
- else {
1460
- if (!paint.patternTask) {
1461
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1462
- paint.patternTask = null;
1463
- if (canvas.bounds.hit(ui.__world))
1464
- createPattern(ui, paint, canvas.pixelRatio);
1465
- ui.forceUpdate('surface');
1466
- }), 300);
1467
- }
1468
- }
1469
- return false;
1470
- }
1471
- }
1472
- }
1473
-
1474
- function recycleImage(attrName, data) {
1475
- const paints = data['_' + attrName];
1476
- if (paints instanceof Array) {
1477
- let image, recycleMap, input, url;
1478
- for (let i = 0, len = paints.length; i < len; i++) {
1479
- image = paints[i].image;
1480
- url = image && image.url;
1481
- if (url) {
1482
- if (!recycleMap)
1483
- recycleMap = {};
1484
- recycleMap[url] = true;
1485
- ImageManager.recycle(image);
1486
- if (image.loading) {
1487
- if (!input) {
1488
- input = (data.__input && data.__input[attrName]) || [];
1489
- if (!(input instanceof Array))
1490
- input = [input];
1491
- }
1492
- image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1493
- }
1494
- }
1495
- }
1496
- return recycleMap;
1497
- }
1498
- return null;
1499
- }
1500
-
1501
- function fillText(ui, canvas) {
1502
- let row;
1503
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1504
- for (let i = 0, len = rows.length; i < len; i++) {
1505
- row = rows[i];
1506
- if (row.text) {
1507
- canvas.fillText(row.text, row.x, row.y);
1508
- }
1509
- else if (row.data) {
1510
- row.data.forEach(charData => {
1511
- canvas.fillText(charData.char, charData.x, row.y);
1512
- });
1513
- }
1514
- if (decorationY)
1515
- canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1516
- }
1517
- }
1518
-
1519
- function fill(fill, ui, canvas) {
1520
- canvas.fillStyle = fill;
1521
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1522
- }
1523
- function fills(fills, ui, canvas) {
1524
- let item;
1525
- const { windingRule, __font } = ui.__;
1526
- for (let i = 0, len = fills.length; i < len; i++) {
1527
- item = fills[i];
1528
- if (item.image && checkImage(ui, canvas, item, !__font))
1529
- continue;
1530
- if (item.style) {
1531
- canvas.fillStyle = item.style;
1532
- if (item.transform) {
1533
- canvas.save();
1534
- canvas.transform(item.transform);
1535
- if (item.blendMode)
1536
- canvas.blendMode = item.blendMode;
1537
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1538
- canvas.restore();
1539
- }
1540
- else {
1541
- if (item.blendMode) {
1542
- canvas.saveBlendMode(item.blendMode);
1543
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1544
- canvas.restoreBlendMode();
1545
- }
1546
- else {
1547
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1548
- }
1549
- }
1550
- }
1551
- }
1552
- }
1553
-
1554
- function strokeText(stroke, ui, canvas, renderOptions) {
1555
- const { strokeAlign } = ui.__;
1556
- const isStrokes = typeof stroke !== 'string';
1557
- switch (strokeAlign) {
1558
- case 'center':
1559
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1560
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1561
- break;
1562
- case 'inside':
1563
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
1564
- break;
1565
- case 'outside':
1566
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
1567
- break;
1568
- }
1569
- }
1570
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
1571
- const { strokeWidth, __font } = ui.__;
1572
- const out = canvas.getSameCanvas(true);
1573
- out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
1574
- out.font = __font;
1575
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1576
- out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1577
- fillText(ui, out);
1578
- out.blendMode = 'normal';
1579
- if (ui.__worldFlipped || renderOptions.matrix) {
1580
- canvas.copyWorldByReset(out);
1581
- }
1582
- else {
1583
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1584
- }
1585
- out.recycle();
1586
- }
1587
- function drawTextStroke(ui, canvas) {
1588
- let row;
1589
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1590
- for (let i = 0, len = rows.length; i < len; i++) {
1591
- row = rows[i];
1592
- if (row.text) {
1593
- canvas.strokeText(row.text, row.x, row.y);
1594
- }
1595
- else if (row.data) {
1596
- row.data.forEach(charData => {
1597
- canvas.strokeText(charData.char, charData.x, row.y);
1598
- });
1599
- }
1600
- if (decorationY)
1601
- canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1602
- }
1603
- }
1604
- function drawStrokesStyle(strokes, isText, ui, canvas) {
1605
- let item;
1606
- for (let i = 0, len = strokes.length; i < len; i++) {
1607
- item = strokes[i];
1608
- if (item.image && checkImage(ui, canvas, item, false))
1609
- continue;
1610
- if (item.style) {
1611
- canvas.strokeStyle = item.style;
1612
- if (item.blendMode) {
1613
- canvas.saveBlendMode(item.blendMode);
1614
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1615
- canvas.restoreBlendMode();
1833
+ return true;
1834
+ }
1835
+ else {
1836
+ if (!paint.style || Export.running) {
1837
+ createPattern(ui, paint, canvas.pixelRatio);
1616
1838
  }
1617
1839
  else {
1618
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1840
+ if (!paint.patternTask) {
1841
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1842
+ paint.patternTask = null;
1843
+ if (canvas.bounds.hit(ui.__nowWorld))
1844
+ createPattern(ui, paint, canvas.pixelRatio);
1845
+ ui.forceUpdate('surface');
1846
+ }), 300);
1847
+ }
1619
1848
  }
1849
+ return false;
1620
1850
  }
1621
1851
  }
1622
1852
  }
1623
1853
 
1624
- function stroke(stroke, ui, canvas, renderOptions) {
1625
- const options = ui.__;
1626
- const { strokeWidth, strokeAlign, __font } = options;
1627
- if (!strokeWidth)
1628
- return;
1629
- if (__font) {
1630
- strokeText(stroke, ui, canvas, renderOptions);
1631
- }
1632
- else {
1633
- switch (strokeAlign) {
1634
- case 'center':
1635
- canvas.setStroke(stroke, strokeWidth, options);
1636
- canvas.stroke();
1637
- break;
1638
- case 'inside':
1639
- canvas.save();
1640
- canvas.setStroke(stroke, strokeWidth * 2, options);
1641
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1642
- canvas.stroke();
1643
- canvas.restore();
1644
- break;
1645
- case 'outside':
1646
- const out = canvas.getSameCanvas(true);
1647
- out.setStroke(stroke, strokeWidth * 2, ui.__);
1648
- ui.__drawRenderPath(out);
1649
- out.stroke();
1650
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1651
- out.clearWorld(ui.__layout.renderBounds);
1652
- if (ui.__worldFlipped || renderOptions.matrix) {
1653
- canvas.copyWorldByReset(out);
1654
- }
1655
- else {
1656
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1657
- }
1658
- out.recycle();
1659
- break;
1660
- }
1661
- }
1662
- }
1663
- function strokes(strokes, ui, canvas, renderOptions) {
1664
- const options = ui.__;
1665
- const { strokeWidth, strokeAlign, __font } = options;
1666
- if (!strokeWidth)
1667
- return;
1668
- if (__font) {
1669
- strokeText(strokes, ui, canvas, renderOptions);
1670
- }
1671
- else {
1672
- switch (strokeAlign) {
1673
- case 'center':
1674
- canvas.setStroke(undefined, strokeWidth, options);
1675
- drawStrokesStyle(strokes, false, ui, canvas);
1676
- break;
1677
- case 'inside':
1678
- canvas.save();
1679
- canvas.setStroke(undefined, strokeWidth * 2, options);
1680
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1681
- drawStrokesStyle(strokes, false, ui, canvas);
1682
- canvas.restore();
1683
- break;
1684
- case 'outside':
1685
- const { renderBounds } = ui.__layout;
1686
- const out = canvas.getSameCanvas(true);
1687
- ui.__drawRenderPath(out);
1688
- out.setStroke(undefined, strokeWidth * 2, ui.__);
1689
- drawStrokesStyle(strokes, false, ui, out);
1690
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1691
- out.clearWorld(renderBounds);
1692
- if (ui.__worldFlipped || renderOptions.matrix) {
1693
- canvas.copyWorldByReset(out);
1694
- }
1695
- else {
1696
- canvas.copyWorldToInner(out, ui.__world, renderBounds);
1854
+ function recycleImage(attrName, data) {
1855
+ const paints = data['_' + attrName];
1856
+ if (paints instanceof Array) {
1857
+ let image, recycleMap, input, url;
1858
+ for (let i = 0, len = paints.length; i < len; i++) {
1859
+ image = paints[i].image;
1860
+ url = image && image.url;
1861
+ if (url) {
1862
+ if (!recycleMap)
1863
+ recycleMap = {};
1864
+ recycleMap[url] = true;
1865
+ ImageManager.recycle(image);
1866
+ if (image.loading) {
1867
+ if (!input) {
1868
+ input = (data.__input && data.__input[attrName]) || [];
1869
+ if (!(input instanceof Array))
1870
+ input = [input];
1871
+ }
1872
+ image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1697
1873
  }
1698
- out.recycle();
1699
- break;
1874
+ }
1700
1875
  }
1876
+ return recycleMap;
1701
1877
  }
1878
+ return null;
1702
1879
  }
1703
1880
 
1704
- const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1705
- function shape(ui, current, options) {
1706
- const canvas = current.getSameCanvas();
1707
- let bounds, matrix, shapeBounds;
1708
- let worldCanvas;
1709
- const { __world } = ui;
1710
- let { scaleX, scaleY } = __world;
1711
- if (scaleX < 0)
1712
- scaleX = -scaleX;
1713
- if (scaleY < 0)
1714
- scaleY = -scaleY;
1715
- if (!current.bounds.includes(__world, options.matrix)) {
1716
- const { renderShapeSpread: spread } = ui.__layout;
1717
- const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
1718
- matrix = current.bounds.getFitMatrix(worldClipBounds);
1719
- if (matrix.a < 1) {
1720
- worldCanvas = current.getSameCanvas();
1721
- ui.__renderShape(worldCanvas, options);
1722
- scaleX *= matrix.a;
1723
- scaleY *= matrix.d;
1724
- }
1725
- shapeBounds = getOuterOf(__world, matrix);
1726
- bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
1727
- if (options.matrix)
1728
- matrix.multiply(options.matrix);
1729
- options = Object.assign(Object.assign({}, options), { matrix });
1730
- }
1731
- else {
1732
- if (options.matrix) {
1733
- scaleX *= options.matrix.a;
1734
- scaleY *= options.matrix.d;
1735
- bounds = shapeBounds = getOuterOf(__world, options.matrix);
1736
- }
1737
- else {
1738
- bounds = shapeBounds = __world;
1739
- }
1740
- worldCanvas = canvas;
1741
- }
1742
- ui.__renderShape(canvas, options);
1743
- return {
1744
- canvas, matrix, bounds,
1745
- worldCanvas, shapeBounds, scaleX, scaleY
1746
- };
1747
- }
1881
+ const PaintImageModule = {
1882
+ image,
1883
+ checkImage,
1884
+ createPattern,
1885
+ recycleImage,
1886
+ createData,
1887
+ getPatternData,
1888
+ fillOrFitMode,
1889
+ clipMode,
1890
+ repeatMode
1891
+ };
1748
1892
 
1749
- const defaultFrom$2 = { x: 0.5, y: 0 };
1750
- const defaultTo$2 = { x: 0.5, y: 1 };
1893
+ const { toPoint: toPoint$2 } = AroundHelper;
1894
+ const realFrom$2 = {};
1895
+ const realTo$2 = {};
1751
1896
  function linearGradient(paint, box) {
1752
1897
  let { from, to, type, blendMode, opacity } = paint;
1753
- from || (from = defaultFrom$2);
1754
- to || (to = defaultTo$2);
1755
- const style = Platform.canvas.createLinearGradient(box.x + from.x * box.width, box.y + from.y * box.height, box.x + to.x * box.width, box.y + to.y * box.height);
1898
+ toPoint$2(from || 'top', box, realFrom$2);
1899
+ toPoint$2(to || 'bottom', box, realTo$2);
1900
+ const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1756
1901
  applyStops(style, paint.stops, opacity);
1757
1902
  const data = { type, style };
1758
1903
  if (blendMode)
@@ -1763,137 +1908,84 @@ function applyStops(gradient, stops, opacity) {
1763
1908
  let stop;
1764
1909
  for (let i = 0, len = stops.length; i < len; i++) {
1765
1910
  stop = stops[i];
1766
- gradient.addColorStop(stop.offset, ColorConvert$1.string(stop.color, opacity));
1911
+ if (typeof stop === 'string') {
1912
+ gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1913
+ }
1914
+ else {
1915
+ gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1916
+ }
1767
1917
  }
1768
1918
  }
1769
1919
 
1770
- const { set: set$1, getAngle: getAngle$1, getDistance: getDistance$1 } = PointHelper;
1771
- const { get: get$1, rotateOfOuter: rotateOfOuter$1, scaleOfOuter: scaleOfOuter$1 } = MatrixHelper;
1772
- const defaultFrom$1 = { x: 0.5, y: 0.5 };
1773
- const defaultTo$1 = { x: 0.5, y: 1 };
1920
+ const { getAngle, getDistance: getDistance$1 } = PointHelper;
1921
+ const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
1922
+ const { toPoint: toPoint$1 } = AroundHelper;
1774
1923
  const realFrom$1 = {};
1775
1924
  const realTo$1 = {};
1776
1925
  function radialGradient(paint, box) {
1777
1926
  let { from, to, type, opacity, blendMode, stretch } = paint;
1778
- from || (from = defaultFrom$1);
1779
- to || (to = defaultTo$1);
1780
- const { x, y, width, height } = box;
1781
- set$1(realFrom$1, x + from.x * width, y + from.y * height);
1782
- set$1(realTo$1, x + to.x * width, y + to.y * height);
1783
- let transform;
1784
- if (width !== height || stretch) {
1785
- transform = get$1();
1786
- scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
1787
- rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
1788
- }
1927
+ toPoint$1(from || 'center', box, realFrom$1);
1928
+ toPoint$1(to || 'bottom', box, realTo$1);
1789
1929
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
1790
1930
  applyStops(style, paint.stops, opacity);
1791
- const data = { type, style, transform };
1931
+ const data = { type, style };
1932
+ const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
1933
+ if (transform)
1934
+ data.transform = transform;
1792
1935
  if (blendMode)
1793
1936
  data.blendMode = blendMode;
1794
1937
  return data;
1795
1938
  }
1939
+ function getTransform(box, from, to, stretch, rotate90) {
1940
+ let transform;
1941
+ const { width, height } = box;
1942
+ if (width !== height || stretch) {
1943
+ const angle = getAngle(from, to);
1944
+ transform = get();
1945
+ if (rotate90) {
1946
+ scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
1947
+ rotateOfOuter(transform, from, angle + 90);
1948
+ }
1949
+ else {
1950
+ scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
1951
+ rotateOfOuter(transform, from, angle);
1952
+ }
1953
+ }
1954
+ return transform;
1955
+ }
1796
1956
 
1797
- const { set, getAngle, getDistance } = PointHelper;
1798
- const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
1799
- const defaultFrom = { x: 0.5, y: 0.5 };
1800
- const defaultTo = { x: 0.5, y: 1 };
1957
+ const { getDistance } = PointHelper;
1958
+ const { toPoint } = AroundHelper;
1801
1959
  const realFrom = {};
1802
1960
  const realTo = {};
1803
1961
  function conicGradient(paint, box) {
1804
1962
  let { from, to, type, opacity, blendMode, stretch } = paint;
1805
- from || (from = defaultFrom);
1806
- to || (to = defaultTo);
1807
- const { x, y, width, height } = box;
1808
- set(realFrom, x + from.x * width, y + from.y * height);
1809
- set(realTo, x + to.x * width, y + to.y * height);
1810
- const transform = get();
1811
- const angle = getAngle(realFrom, realTo);
1812
- if (Platform.conicGradientRotate90) {
1813
- scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
1814
- rotateOfOuter(transform, realFrom, angle + 90);
1815
- }
1816
- else {
1817
- scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
1818
- rotateOfOuter(transform, realFrom, angle);
1819
- }
1963
+ toPoint(from || 'center', box, realFrom);
1964
+ toPoint(to || 'bottom', box, realTo);
1820
1965
  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));
1821
1966
  applyStops(style, paint.stops, opacity);
1822
- const data = { type, style, transform };
1967
+ const data = { type, style };
1968
+ const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
1969
+ if (transform)
1970
+ data.transform = transform;
1823
1971
  if (blendMode)
1824
1972
  data.blendMode = blendMode;
1825
1973
  return data;
1826
1974
  }
1827
1975
 
1828
- let recycleMap;
1829
- function compute(attrName, ui) {
1830
- const value = [];
1831
- const data = ui.__;
1832
- let item;
1833
- let paints = data.__input[attrName];
1834
- if (!(paints instanceof Array))
1835
- paints = [paints];
1836
- recycleMap = recycleImage(attrName, data);
1837
- for (let i = 0, len = paints.length; i < len; i++) {
1838
- item = getLeafPaint(attrName, paints[i], ui);
1839
- if (item)
1840
- value.push(item);
1841
- }
1842
- data['_' + attrName] = value.length ? value : undefined;
1843
- let isPixel;
1844
- if (paints.length === 1) {
1845
- const paint = paints[0];
1846
- if (paint.type === 'image')
1847
- isPixel = ImageManager$1.isPixel(paint);
1848
- }
1849
- if (attrName === 'fill') {
1850
- data.__pixelFill = isPixel;
1851
- }
1852
- else {
1853
- data.__pixelStroke = isPixel;
1854
- }
1855
- }
1856
- function getLeafPaint(attrName, paint, ui) {
1857
- if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1858
- return undefined;
1859
- const { boxBounds } = ui.__layout;
1860
- switch (paint.type) {
1861
- case 'solid':
1862
- let { type, blendMode, color, opacity } = paint;
1863
- return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
1864
- case 'image':
1865
- return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1866
- case 'linear':
1867
- return linearGradient(paint, boxBounds);
1868
- case 'radial':
1869
- return radialGradient(paint, boxBounds);
1870
- case 'angular':
1871
- return conicGradient(paint, boxBounds);
1872
- default:
1873
- return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
1874
- }
1875
- }
1876
-
1877
- var UIPaint = /*#__PURE__*/Object.freeze({
1878
- __proto__: null,
1879
- compute: compute,
1880
- drawTextStroke: drawTextStroke,
1881
- fill: fill,
1882
- fillText: fillText,
1883
- fills: fills,
1884
- recycleImage: recycleImage,
1885
- shape: shape,
1886
- stroke: stroke,
1887
- strokeText: strokeText,
1888
- strokes: strokes
1889
- });
1976
+ const PaintGradientModule = {
1977
+ linearGradient,
1978
+ radialGradient,
1979
+ conicGradient,
1980
+ getTransform
1981
+ };
1890
1982
 
1891
1983
  const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
1892
1984
  const tempBounds = {};
1893
1985
  const offsetOutBounds$1 = {};
1894
- function shadow(ui, current, shape, renderOptions) {
1986
+ function shadow(ui, current, shape) {
1895
1987
  let copyBounds, spreadScale;
1896
- const { __world, __layout } = ui;
1988
+ const { __nowWorld: nowWorld, __layout } = ui;
1897
1989
  const { shadow } = ui.__;
1898
1990
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1899
1991
  const other = current.getSameCanvas();
@@ -1908,21 +2000,21 @@ function shadow(ui, current, shape, renderOptions) {
1908
2000
  other.restore();
1909
2001
  other.save();
1910
2002
  if (worldCanvas) {
1911
- other.copyWorld(other, bounds, __world, 'copy');
1912
- copyBounds = __world;
2003
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2004
+ copyBounds = nowWorld;
1913
2005
  }
1914
- worldCanvas ? other.copyWorld(worldCanvas, __world, __world, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
2006
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
1915
2007
  }
1916
- if (ui.__worldFlipped || renderOptions.matrix) {
1917
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2008
+ if (ui.__worldFlipped) {
2009
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
1918
2010
  }
1919
2011
  else {
1920
2012
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
1921
2013
  }
1922
2014
  if (end && index < end)
1923
- other.clear();
2015
+ other.clearWorld(copyBounds, true);
1924
2016
  });
1925
- other.recycle();
2017
+ other.recycle(copyBounds);
1926
2018
  }
1927
2019
  function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1928
2020
  const { bounds, shapeBounds } = shape;
@@ -1953,9 +2045,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
1953
2045
 
1954
2046
  const { toOffsetOutBounds } = BoundsHelper;
1955
2047
  const offsetOutBounds = {};
1956
- function innerShadow(ui, current, shape, renderOptions) {
2048
+ function innerShadow(ui, current, shape) {
1957
2049
  let copyBounds, spreadScale;
1958
- const { __world, __layout: __layout } = ui;
2050
+ const { __nowWorld: nowWorld, __layout: __layout } = ui;
1959
2051
  const { innerShadow } = ui.__;
1960
2052
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
1961
2053
  const other = current.getSameCanvas();
@@ -1968,40 +2060,115 @@ function innerShadow(ui, current, shape, renderOptions) {
1968
2060
  drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
1969
2061
  other.restore();
1970
2062
  if (worldCanvas) {
1971
- other.copyWorld(other, bounds, __world, 'copy');
1972
- other.copyWorld(worldCanvas, __world, __world, 'source-out');
1973
- copyBounds = __world;
2063
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2064
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
2065
+ copyBounds = nowWorld;
1974
2066
  }
1975
2067
  else {
1976
2068
  other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
1977
2069
  copyBounds = bounds;
1978
2070
  }
1979
2071
  other.fillWorld(copyBounds, item.color, 'source-in');
1980
- if (ui.__worldFlipped || renderOptions.matrix) {
1981
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2072
+ if (ui.__worldFlipped) {
2073
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
1982
2074
  }
1983
2075
  else {
1984
2076
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
1985
2077
  }
1986
2078
  if (end && index < end)
1987
- other.clear();
2079
+ other.clearWorld(copyBounds, true);
1988
2080
  });
1989
- other.recycle();
2081
+ other.recycle(copyBounds);
1990
2082
  }
1991
2083
 
1992
2084
  function blur(ui, current, origin) {
1993
2085
  const { blur } = ui.__;
1994
- origin.setWorldBlur(blur * ui.__world.a);
1995
- origin.copyWorldToInner(current, ui.__world, ui.__layout.renderBounds);
2086
+ origin.setWorldBlur(blur * ui.__nowWorld.a);
2087
+ origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
1996
2088
  origin.filter = 'none';
1997
2089
  }
1998
2090
 
1999
- var UIEffect = /*#__PURE__*/Object.freeze({
2000
- __proto__: null,
2001
- blur: blur,
2002
- innerShadow: innerShadow,
2003
- shadow: shadow
2004
- });
2091
+ function backgroundBlur(_ui, _current, _shape) {
2092
+ }
2093
+
2094
+ const EffectModule = {
2095
+ shadow,
2096
+ innerShadow,
2097
+ blur,
2098
+ backgroundBlur
2099
+ };
2100
+
2101
+ const { excludeRenderBounds } = LeafBoundsHelper;
2102
+ Group.prototype.__renderMask = function (canvas, options) {
2103
+ let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
2104
+ const { children } = this;
2105
+ for (let i = 0, len = children.length; i < len; i++) {
2106
+ child = children[i];
2107
+ if (child.__.mask) {
2108
+ if (currentMask) {
2109
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2110
+ maskCanvas = contentCanvas = null;
2111
+ }
2112
+ if (child.__.mask === 'path') {
2113
+ if (child.opacity < 1) {
2114
+ currentMask = 'opacity-path';
2115
+ maskOpacity = child.opacity;
2116
+ if (!contentCanvas)
2117
+ contentCanvas = getCanvas(canvas);
2118
+ }
2119
+ else {
2120
+ currentMask = 'path';
2121
+ canvas.save();
2122
+ }
2123
+ child.__clip(contentCanvas || canvas, options);
2124
+ }
2125
+ else {
2126
+ currentMask = 'alpha';
2127
+ if (!maskCanvas)
2128
+ maskCanvas = getCanvas(canvas);
2129
+ if (!contentCanvas)
2130
+ contentCanvas = getCanvas(canvas);
2131
+ child.__render(maskCanvas, options);
2132
+ }
2133
+ if (child.__.mask !== 'clipping')
2134
+ continue;
2135
+ }
2136
+ if (excludeRenderBounds(child, options))
2137
+ continue;
2138
+ child.__render(contentCanvas || canvas, options);
2139
+ }
2140
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2141
+ };
2142
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
2143
+ switch (maskMode) {
2144
+ case 'alpha':
2145
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
2146
+ break;
2147
+ case 'opacity-path':
2148
+ copyContent(leaf, canvas, contentCanvas, maskOpacity);
2149
+ break;
2150
+ case 'path':
2151
+ canvas.restore();
2152
+ }
2153
+ }
2154
+ function getCanvas(canvas) {
2155
+ return canvas.getSameCanvas(false, true);
2156
+ }
2157
+ function usePixelMask(leaf, canvas, content, mask) {
2158
+ const realBounds = leaf.__nowWorld;
2159
+ content.resetTransform();
2160
+ content.opacity = 1;
2161
+ content.useMask(mask, realBounds);
2162
+ mask.recycle(realBounds);
2163
+ copyContent(leaf, canvas, content, 1);
2164
+ }
2165
+ function copyContent(leaf, canvas, content, maskOpacity) {
2166
+ const realBounds = leaf.__nowWorld;
2167
+ canvas.resetTransform();
2168
+ canvas.opacity = maskOpacity;
2169
+ canvas.copyWorld(content, realBounds);
2170
+ content.recycle(realBounds);
2171
+ }
2005
2172
 
2006
2173
  const money = '¥¥$€££¢¢';
2007
2174
  const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
@@ -2158,7 +2325,8 @@ function createRows(drawData, content, style) {
2158
2325
  if (breakAll) {
2159
2326
  if (wordWidth)
2160
2327
  addWord();
2161
- addRow();
2328
+ if (rowWidth)
2329
+ addRow();
2162
2330
  }
2163
2331
  else {
2164
2332
  if (!afterBreak)
@@ -2166,10 +2334,12 @@ function createRows(drawData, content, style) {
2166
2334
  if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2167
2335
  if (wordWidth)
2168
2336
  addWord();
2169
- addRow();
2337
+ if (rowWidth)
2338
+ addRow();
2170
2339
  }
2171
2340
  else {
2172
- addRow();
2341
+ if (rowWidth)
2342
+ addRow();
2173
2343
  }
2174
2344
  }
2175
2345
  }
@@ -2264,11 +2434,11 @@ function layoutChar(drawData, style, width, _height) {
2264
2434
  if (mode === WordMode) {
2265
2435
  wordChar = { char: '', x: charX };
2266
2436
  charX = toWordChar(word.data, charX, wordChar);
2267
- if (wordChar.char !== ' ')
2437
+ if (row.isOverflow || wordChar.char !== ' ')
2268
2438
  row.data.push(wordChar);
2269
2439
  }
2270
2440
  else {
2271
- charX = toChar(word.data, charX, row.data);
2441
+ charX = toChar(word.data, charX, row.data, row.isOverflow);
2272
2442
  }
2273
2443
  if (!row.paraEnd && addWordWidth) {
2274
2444
  charX += addWordWidth;
@@ -2295,9 +2465,9 @@ function toWordChar(data, charX, wordChar) {
2295
2465
  });
2296
2466
  return charX;
2297
2467
  }
2298
- function toChar(data, charX, rowData) {
2468
+ function toChar(data, charX, rowData, isOverflow) {
2299
2469
  data.forEach(char => {
2300
- if (char.char !== ' ') {
2470
+ if (isOverflow || char.char !== ' ') {
2301
2471
  char.x = charX;
2302
2472
  rowData.push(char);
2303
2473
  }
@@ -2329,12 +2499,14 @@ function layoutText(drawData, style) {
2329
2499
  for (let i = 0, len = rows.length; i < len; i++) {
2330
2500
  row = rows[i];
2331
2501
  row.x = x;
2332
- switch (textAlign) {
2333
- case 'center':
2334
- row.x += (width - row.width) / 2;
2335
- break;
2336
- case 'right':
2337
- row.x += width - row.width;
2502
+ if (row.width < width || (row.width > width && !__clipText)) {
2503
+ switch (textAlign) {
2504
+ case 'center':
2505
+ row.x += (width - row.width) / 2;
2506
+ break;
2507
+ case 'right':
2508
+ row.x += width - row.width;
2509
+ }
2338
2510
  }
2339
2511
  if (row.paraStart && paraSpacing && i > 0)
2340
2512
  starY += paraSpacing;
@@ -2370,16 +2542,20 @@ function layoutText(drawData, style) {
2370
2542
  bounds.height = realHeight;
2371
2543
  }
2372
2544
 
2373
- function clipText(drawData, style) {
2545
+ function clipText(drawData, style, x, width) {
2546
+ if (!width)
2547
+ return;
2374
2548
  const { rows, overflow } = drawData;
2375
2549
  let { textOverflow } = style;
2376
2550
  rows.splice(overflow);
2377
- if (textOverflow !== 'hide') {
2378
- if (textOverflow === 'ellipsis')
2551
+ if (textOverflow && textOverflow !== 'show') {
2552
+ if (textOverflow === 'hide')
2553
+ textOverflow = '';
2554
+ else if (textOverflow === 'ellipsis')
2379
2555
  textOverflow = '...';
2380
2556
  let char, charRight;
2381
- const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2382
- const right = style.x + style.width - ellipsisWidth;
2557
+ const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
2558
+ const right = x + width - ellipsisWidth;
2383
2559
  const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2384
2560
  list.forEach(row => {
2385
2561
  if (row.isOverflow && row.data) {
@@ -2426,42 +2602,40 @@ function decorationText(drawData, style) {
2426
2602
  }
2427
2603
 
2428
2604
  const { top, right, bottom, left } = Direction4;
2429
- const TextConvert = {
2430
- getDrawData(content, style) {
2431
- if (typeof content !== 'string')
2432
- content = String(content);
2433
- let x = 0, y = 0;
2434
- let width = style.__getInput('width') || 0;
2435
- let height = style.__getInput('height') || 0;
2436
- const { textDecoration, __font, __padding: padding } = style;
2437
- if (padding) {
2438
- if (width) {
2439
- x = padding[left];
2440
- width -= (padding[right] + padding[left]);
2441
- }
2442
- if (height) {
2443
- y = padding[top];
2444
- height -= (padding[top] + padding[bottom]);
2445
- }
2446
- }
2447
- const drawData = {
2448
- bounds: { x, y, width, height },
2449
- rows: [],
2450
- paraNumber: 0,
2451
- font: Platform.canvas.font = __font
2452
- };
2453
- createRows(drawData, content, style);
2454
- if (padding)
2455
- padAutoText(padding, drawData, style, width, height);
2456
- layoutText(drawData, style);
2457
- layoutChar(drawData, style, width);
2458
- if (drawData.overflow)
2459
- clipText(drawData, style);
2460
- if (textDecoration !== 'none')
2461
- decorationText(drawData, style);
2462
- return drawData;
2463
- }
2464
- };
2605
+ function getDrawData(content, style) {
2606
+ if (typeof content !== 'string')
2607
+ content = String(content);
2608
+ let x = 0, y = 0;
2609
+ let width = style.__getInput('width') || 0;
2610
+ let height = style.__getInput('height') || 0;
2611
+ const { textDecoration, __font, __padding: padding } = style;
2612
+ if (padding) {
2613
+ if (width) {
2614
+ x = padding[left];
2615
+ width -= (padding[right] + padding[left]);
2616
+ }
2617
+ if (height) {
2618
+ y = padding[top];
2619
+ height -= (padding[top] + padding[bottom]);
2620
+ }
2621
+ }
2622
+ const drawData = {
2623
+ bounds: { x, y, width, height },
2624
+ rows: [],
2625
+ paraNumber: 0,
2626
+ font: Platform.canvas.font = __font
2627
+ };
2628
+ createRows(drawData, content, style);
2629
+ if (padding)
2630
+ padAutoText(padding, drawData, style, width, height);
2631
+ layoutText(drawData, style);
2632
+ layoutChar(drawData, style, width);
2633
+ if (drawData.overflow)
2634
+ clipText(drawData, style, x, width);
2635
+ if (textDecoration !== 'none')
2636
+ decorationText(drawData, style);
2637
+ return drawData;
2638
+ }
2465
2639
  function padAutoText(padding, drawData, style, width, height) {
2466
2640
  if (!width) {
2467
2641
  switch (style.textAlign) {
@@ -2489,67 +2663,157 @@ function offsetText(drawData, attrName, value) {
2489
2663
  rows[i][attrName] += value;
2490
2664
  }
2491
2665
 
2492
- const ColorConvert = {
2493
- string(color, opacity) {
2494
- if (typeof color === 'string')
2495
- return color;
2496
- let a = color.a === undefined ? 1 : color.a;
2497
- if (opacity)
2498
- a *= opacity;
2499
- const rgb = color.r + ',' + color.g + ',' + color.b;
2500
- return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2501
- }
2666
+ const TextConvertModule = {
2667
+ getDrawData
2668
+ };
2669
+
2670
+ function string(color, opacity) {
2671
+ if (typeof color === 'string')
2672
+ return color;
2673
+ let a = color.a === undefined ? 1 : color.a;
2674
+ if (opacity)
2675
+ a *= opacity;
2676
+ const rgb = color.r + ',' + color.g + ',' + color.b;
2677
+ return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2678
+ }
2679
+
2680
+ const ColorConvertModule = {
2681
+ string
2502
2682
  };
2503
2683
 
2504
- const Export = {
2684
+ const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
2685
+ function getTrimBounds(canvas) {
2686
+ const { width, height } = canvas.view;
2687
+ const { data } = canvas.context.getImageData(0, 0, width, height);
2688
+ let x, y, pointBounds, index = 0;
2689
+ for (let i = 0; i < data.length; i += 4) {
2690
+ if (data[i + 3] !== 0) {
2691
+ x = index % width;
2692
+ y = (index - x) / width;
2693
+ pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
2694
+ }
2695
+ index++;
2696
+ }
2697
+ const bounds = new Bounds();
2698
+ toBounds(pointBounds, bounds);
2699
+ return bounds.scale(1 / canvas.pixelRatio).ceil();
2700
+ }
2701
+
2702
+ const ExportModule = {
2505
2703
  export(leaf, filename, options) {
2506
- Export.running = true;
2704
+ this.running = true;
2705
+ const fileType = FileHelper.fileType(filename);
2706
+ options = FileHelper.getExportOptions(options);
2507
2707
  return addTask((success) => new Promise((resolve) => {
2708
+ const over = (result) => {
2709
+ success(result);
2710
+ resolve();
2711
+ this.running = false;
2712
+ };
2713
+ const { toURL } = Platform;
2714
+ const { download } = Platform.origin;
2715
+ if (filename === 'json') {
2716
+ return over({ data: leaf.toJSON(options.json) });
2717
+ }
2718
+ else if (fileType === 'json') {
2719
+ download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2720
+ return over({ data: true });
2721
+ }
2722
+ if (filename === 'svg') {
2723
+ return over({ data: leaf.toSVG() });
2724
+ }
2725
+ else if (fileType === 'svg') {
2726
+ download(toURL(leaf.toSVG(), 'svg'), filename);
2727
+ return over({ data: true });
2728
+ }
2508
2729
  const { leafer } = leaf;
2509
2730
  if (leafer) {
2731
+ checkLazy(leaf);
2510
2732
  leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2511
- let quality, blob;
2512
- let { canvas } = leafer;
2513
- let { unreal } = canvas;
2514
- if (unreal) {
2515
- canvas = canvas.getSameCanvas();
2516
- canvas.backgroundColor = leafer.config.fill;
2517
- leafer.__render(canvas, {});
2733
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2734
+ const { worldTransform, isLeafer, isFrame } = leaf;
2735
+ const { slice, trim, onCanvas } = options;
2736
+ let scale = options.scale || 1;
2737
+ let pixelRatio = options.pixelRatio || 1;
2738
+ const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
2739
+ const contextSettings = options.contextSettings || leafer.config.contextSettings;
2740
+ if (leaf.isApp) {
2741
+ scale *= pixelRatio;
2742
+ pixelRatio = leaf.app.pixelRatio;
2743
+ }
2744
+ const screenshot = options.screenshot || leaf.isApp;
2745
+ const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2746
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
2747
+ if (screenshot) {
2748
+ renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2518
2749
  }
2519
- switch (typeof options) {
2520
- case 'object':
2521
- if (options.quality)
2522
- quality = options.quality;
2523
- if (options.blob)
2524
- blob = true;
2525
- break;
2526
- case 'number':
2527
- quality = options;
2528
- break;
2529
- case 'boolean':
2530
- blob = options;
2750
+ else {
2751
+ let relative = options.relative || (isLeafer ? 'inner' : 'local');
2752
+ scaleX = worldTransform.scaleX;
2753
+ scaleY = worldTransform.scaleY;
2754
+ switch (relative) {
2755
+ case 'inner':
2756
+ matrix.set(worldTransform);
2757
+ break;
2758
+ case 'local':
2759
+ matrix.set(worldTransform).divide(leaf.localTransform);
2760
+ scaleX /= leaf.scaleX;
2761
+ scaleY /= leaf.scaleY;
2762
+ break;
2763
+ case 'world':
2764
+ scaleX = 1;
2765
+ scaleY = 1;
2766
+ break;
2767
+ case 'page':
2768
+ relative = leaf.leafer;
2769
+ default:
2770
+ matrix.set(worldTransform).divide(leaf.getTransform(relative));
2771
+ const l = relative.worldTransform;
2772
+ scaleX /= scaleX / l.scaleX;
2773
+ scaleY /= scaleY / l.scaleY;
2774
+ }
2775
+ renderBounds = leaf.getBounds('render', relative);
2531
2776
  }
2532
- let data;
2533
- if (filename.includes('.')) {
2534
- data = yield canvas.saveAs(filename, quality);
2777
+ const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
2778
+ let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
2779
+ const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
2780
+ let sliceLeaf;
2781
+ if (slice) {
2782
+ sliceLeaf = leaf;
2783
+ sliceLeaf.__worldOpacity = 0;
2784
+ leaf = leafer;
2785
+ renderOptions.bounds = canvas.bounds;
2535
2786
  }
2536
- else if (blob) {
2537
- data = yield canvas.toBlob(filename, quality);
2787
+ canvas.save();
2788
+ if (isFrame && fill !== undefined) {
2789
+ const oldFill = leaf.get('fill');
2790
+ leaf.fill = '';
2791
+ leaf.__render(canvas, renderOptions);
2792
+ leaf.fill = oldFill;
2538
2793
  }
2539
2794
  else {
2540
- data = yield canvas.toDataURL(filename, quality);
2795
+ leaf.__render(canvas, renderOptions);
2541
2796
  }
2542
- success({ data });
2543
- resolve();
2544
- Export.running = false;
2545
- if (unreal)
2546
- canvas.recycle();
2797
+ canvas.restore();
2798
+ if (sliceLeaf)
2799
+ sliceLeaf.__updateWorldOpacity();
2800
+ if (trim) {
2801
+ trimBounds = getTrimBounds(canvas);
2802
+ const old = canvas, { width, height } = trimBounds;
2803
+ const config = { x: 0, y: 0, width, height, pixelRatio };
2804
+ canvas = Creator.canvas(config);
2805
+ canvas.copyWorld(old, trimBounds, config);
2806
+ }
2807
+ if (needFill)
2808
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
2809
+ if (onCanvas)
2810
+ onCanvas(canvas);
2811
+ const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
2812
+ over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
2547
2813
  }));
2548
2814
  }
2549
2815
  else {
2550
- success({ data: false });
2551
- resolve();
2552
- Export.running = false;
2816
+ over({ data: false });
2553
2817
  }
2554
2818
  }));
2555
2819
  }
@@ -2562,46 +2826,91 @@ function addTask(task) {
2562
2826
  tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
2563
2827
  });
2564
2828
  }
2829
+ function checkLazy(leaf) {
2830
+ if (leaf.__.__needComputePaint)
2831
+ leaf.__.__computePaint();
2832
+ if (leaf.isBranch)
2833
+ leaf.children.forEach(child => checkLazy(child));
2834
+ }
2835
+
2836
+ const canvas = LeaferCanvasBase.prototype;
2837
+ const debug = Debug.get('@leafer-ui/export');
2838
+ canvas.export = function (filename, options) {
2839
+ const { quality, blob } = FileHelper.getExportOptions(options);
2840
+ if (filename.includes('.')) {
2841
+ return this.saveAs(filename, quality);
2842
+ }
2843
+ else if (blob) {
2844
+ return this.toBlob(filename, quality);
2845
+ }
2846
+ else {
2847
+ return this.toDataURL(filename, quality);
2848
+ }
2849
+ };
2850
+ canvas.toBlob = function (type, quality) {
2851
+ return new Promise((resolve) => {
2852
+ Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
2853
+ resolve(blob);
2854
+ }).catch((e) => {
2855
+ debug.error(e);
2856
+ resolve(null);
2857
+ });
2858
+ });
2859
+ };
2860
+ canvas.toDataURL = function (type, quality) {
2861
+ return Platform.origin.canvasToDataURL(this.view, type, quality);
2862
+ };
2863
+ canvas.saveAs = function (filename, quality) {
2864
+ return new Promise((resolve) => {
2865
+ Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
2866
+ resolve(true);
2867
+ }).catch((e) => {
2868
+ debug.error(e);
2869
+ resolve(false);
2870
+ });
2871
+ });
2872
+ };
2565
2873
 
2566
- Object.assign(Paint, UIPaint);
2567
- Object.assign(Effect, UIEffect);
2568
- Object.assign(TextConvert$1, TextConvert);
2569
- Object.assign(ColorConvert$1, ColorConvert);
2570
- Object.assign(Export$2, Export);
2874
+ Object.assign(TextConvert, TextConvertModule);
2875
+ Object.assign(ColorConvert, ColorConvertModule);
2876
+ Object.assign(Paint, PaintModule);
2877
+ Object.assign(PaintImage, PaintImageModule);
2878
+ Object.assign(PaintGradient, PaintGradientModule);
2879
+ Object.assign(Effect, EffectModule);
2880
+ Object.assign(Export, ExportModule);
2571
2881
 
2882
+ Object.assign(Creator, {
2883
+ interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
2884
+ hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
2885
+ hitCanvasManager: () => new HitCanvasManager()
2886
+ });
2572
2887
  try {
2573
2888
  useCanvas('wx', wx);
2574
2889
  }
2575
2890
  catch (_a) { }
2576
2891
 
2577
- LeaferCanvas.prototype.__createContext = function () {
2578
- if (this.viewSelect) {
2579
- const offscreenView = Platform$1.origin.createCanvas(1, 1);
2580
- const context = this.view.getContext('2d');
2581
- this.testView = this.view;
2582
- this.testContext = context;
2583
- this.view = offscreenView;
2584
- }
2585
- this.context = this.view.getContext('2d');
2586
- this.__bindContext();
2587
- };
2588
- LeaferCanvas.prototype.updateRender = function () {
2589
- if (this.testView) {
2590
- let pattern = this.context.createPattern(this.view, Platform$1.origin.noRepeat);
2591
- this.testContext.clearRect(0, 0, this.view.width, this.view.height);
2592
- this.testContext.fillStyle = pattern;
2593
- this.testContext.fillRect(0, 0, this.view.width, this.view.height);
2594
- this.testContext.fillStyle = pattern = null;
2595
- }
2596
- };
2597
- LeaferCanvas.prototype.updateViewSize = function () {
2598
- const { width, height, pixelRatio, view, testView } = this;
2599
- view.width = width * pixelRatio;
2600
- view.height = height * pixelRatio;
2601
- if (testView) {
2602
- testView.width = view.width;
2603
- testView.height = view.height;
2604
- }
2605
- };
2892
+ const systemInfo = wx.getSystemInfoSync();
2893
+ const platform = systemInfo.platform;
2894
+ if (platform === 'ios') {
2895
+ LeaferImage.prototype.getPattern = function (canvas, repeat, transform, paint) {
2896
+ const pattern = Platform$1.canvas.createPattern(this.view, repeat);
2897
+ const { width, height } = canvas;
2898
+ if (this.width !== width || this.height !== height) {
2899
+ if (!transform)
2900
+ transform = MatrixHelper$1.get();
2901
+ MatrixHelper$1.scale(transform, width / this.width, height / this.height);
2902
+ }
2903
+ try {
2904
+ if (transform && pattern.setTransform) {
2905
+ pattern.setTransform(transform);
2906
+ transform = null;
2907
+ }
2908
+ }
2909
+ catch (_a) { }
2910
+ if (paint)
2911
+ paint.transform = transform;
2912
+ return pattern;
2913
+ };
2914
+ }
2606
2915
 
2607
2916
  export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };