leafer-ui 1.0.0-rc.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/web.esm.js CHANGED
@@ -1,8 +1,255 @@
1
- import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, Platform, AnimateEvent, ResizeEvent, BoundsHelper, Creator, LeaferCanvasBase, Cursor, canvasSizeAttrs, canvasPatch, InteractionHelper, MathHelper, InteractionBase, LeaferImage, FileHelper, MatrixHelper, ImageEvent, PointHelper, Direction4, TaskProcessor } from '@leafer/core';
1
+ import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, Answer, MathHelper, 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 } from '@leafer-ui/core';
4
+ import { InteractionHelper, InteractionBase, Cursor, HitCanvasManager } 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
+ const debug$3 = Debug.get('LeaferCanvas');
9
+ class LeaferCanvas extends LeaferCanvasBase {
10
+ set zIndex(zIndex) {
11
+ const { style } = this.view;
12
+ style.zIndex = zIndex;
13
+ this.setAbsolute(this.view);
14
+ }
15
+ set childIndex(index) {
16
+ const { view, parentView } = this;
17
+ if (view && parentView) {
18
+ const beforeNode = parentView.children[index];
19
+ if (beforeNode) {
20
+ this.setAbsolute(beforeNode);
21
+ parentView.insertBefore(view, beforeNode);
22
+ }
23
+ else {
24
+ parentView.appendChild(beforeNode);
25
+ }
26
+ }
27
+ }
28
+ init() {
29
+ const { view } = this.config;
30
+ view ? this.__createViewFrom(view) : this.__createView();
31
+ const { style } = this.view;
32
+ style.display || (style.display = 'block');
33
+ this.parentView = this.view.parentElement;
34
+ if (this.parentView) {
35
+ const pStyle = this.parentView.style;
36
+ pStyle.webkitUserSelect = pStyle.userSelect = 'none';
37
+ }
38
+ if (Platform.syncDomFont && !this.parentView) {
39
+ style.display = 'none';
40
+ document.body.appendChild(this.view);
41
+ }
42
+ this.__createContext();
43
+ if (!this.autoLayout)
44
+ this.resize(this.config);
45
+ }
46
+ set backgroundColor(color) { this.view.style.backgroundColor = color; }
47
+ get backgroundColor() { return this.view.style.backgroundColor; }
48
+ set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
49
+ get hittable() { return this.view.style.pointerEvents !== 'none'; }
50
+ __createView() {
51
+ this.view = document.createElement('canvas');
52
+ }
53
+ __createViewFrom(inputView) {
54
+ let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
55
+ if (find) {
56
+ if (find instanceof HTMLCanvasElement) {
57
+ this.view = find;
58
+ }
59
+ else {
60
+ let parent = find;
61
+ if (find === window || find === document) {
62
+ const div = document.createElement('div');
63
+ const { style } = div;
64
+ style.position = 'absolute';
65
+ style.top = style.bottom = style.left = style.right = '0px';
66
+ document.body.appendChild(div);
67
+ parent = div;
68
+ }
69
+ this.__createView();
70
+ const view = this.view;
71
+ if (parent.hasChildNodes()) {
72
+ this.setAbsolute(view);
73
+ parent.style.position || (parent.style.position = 'relative');
74
+ }
75
+ parent.appendChild(view);
76
+ }
77
+ }
78
+ else {
79
+ debug$3.error(`no id: ${inputView}`);
80
+ this.__createView();
81
+ }
82
+ }
83
+ setAbsolute(view) {
84
+ const { style } = view;
85
+ style.position = 'absolute';
86
+ style.top = style.left = '0px';
87
+ }
88
+ updateViewSize() {
89
+ const { width, height, pixelRatio } = this;
90
+ const { style } = this.view;
91
+ style.width = width + 'px';
92
+ style.height = height + 'px';
93
+ this.view.width = Math.ceil(width * pixelRatio);
94
+ this.view.height = Math.ceil(height * pixelRatio);
95
+ }
96
+ updateClientBounds() {
97
+ this.clientBounds = this.view.getBoundingClientRect();
98
+ }
99
+ startAutoLayout(autoBounds, listener) {
100
+ this.autoBounds = autoBounds;
101
+ this.resizeListener = listener;
102
+ try {
103
+ this.resizeObserver = new ResizeObserver((entries) => {
104
+ this.updateClientBounds();
105
+ for (const entry of entries)
106
+ this.checkAutoBounds(entry.contentRect);
107
+ });
108
+ const parent = this.parentView;
109
+ if (parent) {
110
+ this.resizeObserver.observe(parent);
111
+ this.checkAutoBounds(parent.getBoundingClientRect());
112
+ }
113
+ else {
114
+ this.checkAutoBounds(this.view);
115
+ debug$3.warn('no parent');
116
+ }
117
+ }
118
+ catch (_a) {
119
+ this.imitateResizeObserver();
120
+ }
121
+ }
122
+ imitateResizeObserver() {
123
+ if (this.autoLayout) {
124
+ if (this.parentView)
125
+ this.checkAutoBounds(this.parentView.getBoundingClientRect());
126
+ Platform.requestRender(this.imitateResizeObserver.bind(this));
127
+ }
128
+ }
129
+ checkAutoBounds(parentSize) {
130
+ const view = this.view;
131
+ const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
132
+ if (width !== this.width || height !== this.height) {
133
+ const { style } = view;
134
+ const { pixelRatio } = this;
135
+ style.marginLeft = x + 'px';
136
+ style.marginTop = y + 'px';
137
+ const size = { width, height, pixelRatio };
138
+ const oldSize = {};
139
+ DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
140
+ this.resize(size);
141
+ if (this.width !== undefined)
142
+ this.resizeListener(new ResizeEvent(size, oldSize));
143
+ }
144
+ }
145
+ stopAutoLayout() {
146
+ this.autoLayout = false;
147
+ this.resizeListener = null;
148
+ if (this.resizeObserver) {
149
+ this.resizeObserver.disconnect();
150
+ this.resizeObserver = null;
151
+ }
152
+ }
153
+ unrealCanvas() {
154
+ if (!this.unreal && this.parentView) {
155
+ const view = this.view;
156
+ if (view)
157
+ view.remove();
158
+ this.view = this.parentView;
159
+ this.unreal = true;
160
+ }
161
+ }
162
+ destroy() {
163
+ if (this.view) {
164
+ this.stopAutoLayout();
165
+ if (!this.unreal) {
166
+ const view = this.view;
167
+ if (view.parentElement)
168
+ view.remove();
169
+ }
170
+ super.destroy();
171
+ }
172
+ }
173
+ }
174
+
175
+ canvasPatch(CanvasRenderingContext2D.prototype);
176
+ canvasPatch(Path2D.prototype);
177
+
178
+ const { mineType, fileType } = FileHelper;
179
+ Object.assign(Creator, {
180
+ canvas: (options, manager) => new LeaferCanvas(options, manager),
181
+ image: (options) => new LeaferImage(options)
182
+ });
183
+ function useCanvas(_canvasType, _power) {
184
+ Platform.origin = {
185
+ createCanvas(width, height) {
186
+ const canvas = document.createElement('canvas');
187
+ canvas.width = width;
188
+ canvas.height = height;
189
+ return canvas;
190
+ },
191
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
192
+ canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
193
+ canvasSaveAs: (canvas, filename, quality) => {
194
+ const url = canvas.toDataURL(mineType(fileType(filename)), quality);
195
+ return Platform.origin.download(url, filename);
196
+ },
197
+ download(url, filename) {
198
+ return new Promise((resolve) => {
199
+ let el = document.createElement('a');
200
+ el.href = url;
201
+ el.download = filename;
202
+ document.body.appendChild(el);
203
+ el.click();
204
+ document.body.removeChild(el);
205
+ resolve();
206
+ });
207
+ },
208
+ loadImage(src) {
209
+ return new Promise((resolve, reject) => {
210
+ const img = new Image();
211
+ const { crossOrigin } = Platform.image;
212
+ if (crossOrigin) {
213
+ img.setAttribute('crossOrigin', crossOrigin);
214
+ img.crossOrigin = crossOrigin;
215
+ }
216
+ img.onload = () => { resolve(img); };
217
+ img.onerror = (e) => { reject(e); };
218
+ img.src = Platform.image.getRealURL(src);
219
+ });
220
+ }
221
+ };
222
+ Platform.event = {
223
+ stopDefault(origin) { origin.preventDefault(); },
224
+ stopNow(origin) { origin.stopImmediatePropagation(); },
225
+ stop(origin) { origin.stopPropagation(); }
226
+ };
227
+ Platform.canvas = Creator.canvas();
228
+ Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
229
+ }
230
+ Platform.name = 'web';
231
+ Platform.isMobile = 'ontouchstart' in window;
232
+ Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
233
+ Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
234
+ const { userAgent } = navigator;
235
+ if (userAgent.indexOf("Firefox") > -1) {
236
+ Platform.conicGradientRotate90 = true;
237
+ Platform.intWheelDeltaY = true;
238
+ Platform.syncDomFont = true;
239
+ }
240
+ else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
241
+ Platform.fullImageShadow = true;
242
+ }
243
+ if (userAgent.indexOf('Windows') > -1) {
244
+ Platform.os = 'Windows';
245
+ Platform.intWheelDeltaY = true;
246
+ }
247
+ else if (userAgent.indexOf('Mac') > -1) {
248
+ Platform.os = 'Mac';
249
+ }
250
+ else if (userAgent.indexOf('Linux') > -1) {
251
+ Platform.os = 'Linux';
252
+ }
6
253
 
7
254
  class Watcher {
8
255
  get childrenChanged() { return this.hasAdd || this.hasRemove || this.hasVisible; }
@@ -302,9 +549,11 @@ class Layouter {
302
549
  updateAllChange(target);
303
550
  }
304
551
  addExtra(leaf) {
305
- const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
306
- block.updatedList.add(leaf);
307
- block.beforeBounds.add(leaf.__world);
552
+ if (!this.__updatedList.has(leaf)) {
553
+ const { updatedList, beforeBounds } = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
554
+ updatedList.length ? beforeBounds.add(leaf.__world) : beforeBounds.set(leaf.__world);
555
+ updatedList.add(leaf);
556
+ }
308
557
  }
309
558
  createBlock(data) {
310
559
  return new LayoutBlockData(data);
@@ -414,6 +663,10 @@ class Renderer {
414
663
  }
415
664
  else {
416
665
  this.requestLayout();
666
+ if (this.ignore) {
667
+ this.ignore = this.rendering = false;
668
+ return;
669
+ }
417
670
  this.emitRender(RenderEvent.BEFORE);
418
671
  if (this.config.usePartRender && this.totalTimes > 1) {
419
672
  this.partRender();
@@ -450,7 +703,7 @@ class Renderer {
450
703
  canvas.clear();
451
704
  }
452
705
  else {
453
- bounds.spread(1 + 1 / this.canvas.pixelRatio).ceil();
706
+ bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
454
707
  canvas.clearWorld(bounds, true);
455
708
  canvas.clipWorld(bounds, true);
456
709
  }
@@ -503,12 +756,12 @@ class Renderer {
503
756
  const startTime = Date.now();
504
757
  Platform.requestRender(() => {
505
758
  this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
506
- if (this.changed) {
507
- if (this.running && this.canvas.view)
759
+ if (this.running) {
760
+ this.target.emit(AnimateEvent.FRAME);
761
+ if (this.changed && this.canvas.view)
508
762
  this.render();
763
+ this.target.emit(RenderEvent.NEXT);
509
764
  }
510
- if (this.running)
511
- this.target.emit(AnimateEvent.FRAME);
512
765
  if (this.target)
513
766
  this.__requestRender();
514
767
  });
@@ -521,9 +774,12 @@ class Renderer {
521
774
  const bounds = new Bounds(0, 0, width, height);
522
775
  if (!bounds.includes(this.target.__world) || this.needFill || !e.samePixelRatio) {
523
776
  this.addBlock(this.canvas.bounds);
524
- this.target.forceUpdate('blendMode');
777
+ this.target.forceUpdate('surface');
778
+ return;
525
779
  }
526
780
  }
781
+ this.addBlock(new Bounds(0, 0, 1, 1));
782
+ this.changed = true;
527
783
  }
528
784
  __onLayoutEnd(event) {
529
785
  if (event.data)
@@ -561,23 +817,13 @@ class Renderer {
561
817
  if (this.target) {
562
818
  this.stop();
563
819
  this.__removeListenEvents();
564
- this.target = null;
565
- this.canvas = null;
566
- this.config = null;
820
+ this.target = this.canvas = this.config = null;
567
821
  }
568
822
  }
569
823
  }
570
824
 
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
825
  const { hitRadiusPoint } = BoundsHelper;
580
- class Pather {
826
+ class Picker {
581
827
  constructor(target, selector) {
582
828
  this.target = target;
583
829
  this.selector = selector;
@@ -589,33 +835,41 @@ class Pather {
589
835
  options = {};
590
836
  const through = options.through || false;
591
837
  const ignoreHittable = options.ignoreHittable || false;
838
+ const target = options.target || this.target;
592
839
  this.exclude = options.exclude || null;
593
840
  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();
841
+ this.findList = new LeafList(options.findList);
842
+ if (!options.findList)
843
+ this.hitBranch(target);
844
+ const { list } = this.findList;
845
+ const leaf = this.getBestMatchLeaf(list, options.bottomList, ignoreHittable);
598
846
  const path = ignoreHittable ? this.getPath(leaf) : this.getHitablePath(leaf);
599
847
  this.clear();
600
- return through ? { path, leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, leaf };
848
+ return through ? { path, target: leaf, throughPath: list.length ? this.getThroughPath(list) : path } : { path, target: leaf };
601
849
  }
602
- getBestMatchLeaf() {
603
- const { findList: targets } = this;
604
- if (targets.length > 1) {
850
+ getBestMatchLeaf(list, bottomList, ignoreHittable) {
851
+ if (list.length) {
605
852
  let find;
606
- this.findList = [];
853
+ this.findList = new LeafList();
607
854
  const { x, y } = this.point;
608
855
  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)) {
856
+ for (let i = 0, len = list.length; i < len; i++) {
857
+ find = list[i];
858
+ if (ignoreHittable || LeafHelper.worldHittable(find)) {
612
859
  this.hitChild(find, point);
613
860
  if (this.findList.length)
614
- return this.findList[0];
861
+ return this.findList.list[0];
615
862
  }
616
863
  }
617
864
  }
618
- return targets[0];
865
+ if (bottomList) {
866
+ for (let i = 0, len = bottomList.length; i < len; i++) {
867
+ this.hitChild(bottomList[i].target, this.point, bottomList[i].proxy);
868
+ if (this.findList.length)
869
+ return this.findList.list[0];
870
+ }
871
+ }
872
+ return list[0];
619
873
  }
620
874
  getPath(leaf) {
621
875
  const path = new LeafList();
@@ -627,7 +881,7 @@ class Pather {
627
881
  return path;
628
882
  }
629
883
  getHitablePath(leaf) {
630
- const path = this.getPath(leaf);
884
+ const path = this.getPath(leaf && leaf.hittable ? leaf : null);
631
885
  let item, hittablePath = new LeafList();
632
886
  for (let i = path.list.length - 1; i > -1; i--) {
633
887
  item = path.list[i];
@@ -657,12 +911,15 @@ class Pather {
657
911
  }
658
912
  return throughPath;
659
913
  }
914
+ hitBranch(branch) {
915
+ this.eachFind(branch.children, branch.__onlyHitMask);
916
+ }
660
917
  eachFind(children, hitMask) {
661
918
  let child, hit;
662
919
  const { point } = this, len = children.length;
663
920
  for (let i = len - 1; i > -1; i--) {
664
921
  child = children[i];
665
- if (!child.__.visible || (hitMask && !child.__.isMask))
922
+ if (!child.__.visible || (hitMask && !child.__.mask))
666
923
  continue;
667
924
  hit = child.__.hitRadius ? true : hitRadiusPoint(child.__world, point);
668
925
  if (child.isBranch) {
@@ -678,11 +935,15 @@ class Pather {
678
935
  }
679
936
  }
680
937
  }
681
- hitChild(child, point) {
938
+ hitChild(child, point, proxy) {
682
939
  if (this.exclude && this.exclude.has(child))
683
940
  return;
684
- if (child.__hitWorld(point))
685
- this.findList.push(child);
941
+ if (child.__hitWorld(point)) {
942
+ const { parent } = child;
943
+ if (parent && parent.__hasMask && !child.__.mask && !parent.children.some(item => item.__.mask && item.__hitWorld(point)))
944
+ return;
945
+ this.findList.add(proxy || child);
946
+ }
686
947
  }
687
948
  clear() {
688
949
  this.point = null;
@@ -694,7 +955,8 @@ class Pather {
694
955
  }
695
956
  }
696
957
 
697
- const { Yes, NoAndSkip, YesAndSkip } = AnswerType;
958
+ const { Yes, NoAndSkip, YesAndSkip } = Answer;
959
+ const idCondition = {}, classNameCondition = {}, tagCondition = {};
698
960
  class Selector {
699
961
  constructor(target, userConfig) {
700
962
  this.config = {};
@@ -704,12 +966,13 @@ class Selector {
704
966
  id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
705
967
  innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
706
968
  className: (leaf, name) => leaf.className === name ? 1 : 0,
707
- tag: (leaf, name) => leaf.__tag === name ? 1 : 0
969
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
970
+ tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
708
971
  };
709
972
  this.target = target;
710
973
  if (userConfig)
711
974
  this.config = DataHelper.default(userConfig, this.config);
712
- this.pather = new Pather(target, this);
975
+ this.picker = new Picker(target, this);
713
976
  this.__listenEvents();
714
977
  }
715
978
  getBy(condition, branch, one, options) {
@@ -720,12 +983,25 @@ class Selector {
720
983
  case 'string':
721
984
  switch (condition[0]) {
722
985
  case '#':
723
- const leaf = this.getById(condition.substring(1), branch);
724
- return one ? leaf : (leaf ? [leaf] : []);
986
+ idCondition.id = condition.substring(1), condition = idCondition;
987
+ break;
725
988
  case '.':
726
- return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
989
+ classNameCondition.className = condition.substring(1), condition = classNameCondition;
990
+ break;
727
991
  default:
728
- return this.getByMethod(this.methods.tag, branch, one, condition);
992
+ tagCondition.tag = condition, condition = tagCondition;
993
+ }
994
+ case 'object':
995
+ if (condition.id !== undefined) {
996
+ const leaf = this.getById(condition.id, branch);
997
+ return one ? leaf : (leaf ? [leaf] : []);
998
+ }
999
+ else if (condition.tag) {
1000
+ const { tag } = condition, isArray = tag instanceof Array;
1001
+ return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
1002
+ }
1003
+ else {
1004
+ return this.getByMethod(this.methods.className, branch, one, condition.className);
729
1005
  }
730
1006
  case 'function':
731
1007
  return this.getByMethod(condition, branch, one, options);
@@ -734,7 +1010,7 @@ class Selector {
734
1010
  getByPoint(hitPoint, hitRadius, options) {
735
1011
  if (Platform.name === 'node')
736
1012
  this.target.emit(LayoutEvent.CHECK_UPDATE);
737
- return this.pather.getByPoint(hitPoint, hitRadius, options);
1013
+ return this.picker.getByPoint(hitPoint, hitRadius, options);
738
1014
  }
739
1015
  getByInnerId(innerId, branch) {
740
1016
  const cache = this.innerIdMap[innerId];
@@ -810,7 +1086,7 @@ class Selector {
810
1086
  destroy() {
811
1087
  if (this.__eventIds.length) {
812
1088
  this.__removeListenEvents();
813
- this.pather.destroy();
1089
+ this.picker.destroy();
814
1090
  this.findLeaf = null;
815
1091
  this.innerIdMap = {};
816
1092
  this.idMap = {};
@@ -826,179 +1102,15 @@ Object.assign(Creator, {
826
1102
  });
827
1103
  Platform.layout = Layouter.fullLayout;
828
1104
 
829
- const debug = Debug.get('LeaferCanvas');
830
- class LeaferCanvas extends LeaferCanvasBase {
831
- init() {
832
- const { view } = this.config;
833
- view ? this.__createViewFrom(view) : this.__createView();
834
- const { style } = this.view;
835
- style.display || (style.display = 'block');
836
- style.userSelect = 'none';
837
- this.parentView = this.view.parentElement;
838
- if (Platform.syncDomFont && !this.parentView) {
839
- this.view.style.display = 'none';
840
- document.body.appendChild(this.view);
841
- }
842
- this.__createContext();
843
- if (!this.autoLayout)
844
- this.resize(this.config);
845
- }
846
- set backgroundColor(color) { this.view.style.backgroundColor = color; }
847
- get backgroundColor() { return this.view.style.backgroundColor; }
848
- set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
849
- get hittable() { return this.view.style.pointerEvents !== 'none'; }
850
- __createView() {
851
- this.view = document.createElement('canvas');
852
- }
853
- setCursor(cursor) {
854
- const list = [];
855
- this.eachCursor(cursor, list);
856
- if (typeof list[list.length - 1] === 'object')
857
- list.push('default');
858
- this.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
859
- }
860
- eachCursor(cursor, list, level = 0) {
861
- level++;
862
- if (cursor instanceof Array) {
863
- cursor.forEach(item => this.eachCursor(item, list, level));
864
- }
865
- else {
866
- const custom = typeof cursor === 'string' && Cursor.get(cursor);
867
- if (custom && level < 2) {
868
- this.eachCursor(custom, list, level);
869
- }
870
- else {
871
- list.push(cursor);
872
- }
873
- }
874
- }
875
- __createViewFrom(inputView) {
876
- let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
877
- if (find) {
878
- if (find instanceof HTMLCanvasElement) {
879
- this.view = find;
880
- }
881
- else {
882
- let parent = find;
883
- if (find === window || find === document) {
884
- const div = document.createElement('div');
885
- const { style } = div;
886
- style.position = 'absolute';
887
- style.top = style.bottom = style.left = style.right = '0px';
888
- document.body.appendChild(div);
889
- parent = div;
890
- }
891
- this.__createView();
892
- const view = this.view;
893
- if (parent.hasChildNodes()) {
894
- const { style } = view;
895
- style.position = 'absolute';
896
- style.top = style.left = '0px';
897
- parent.style.position || (parent.style.position = 'relative');
898
- }
899
- parent.appendChild(view);
900
- }
901
- }
902
- else {
903
- debug.error(`no id: ${inputView}`);
904
- this.__createView();
905
- }
906
- }
907
- updateViewSize() {
908
- const { width, height, pixelRatio } = this;
909
- const { style } = this.view;
910
- style.width = width + 'px';
911
- style.height = height + 'px';
912
- this.view.width = width * pixelRatio;
913
- this.view.height = height * pixelRatio;
914
- }
915
- updateClientBounds() {
916
- this.clientBounds = this.view.getBoundingClientRect();
917
- }
918
- startAutoLayout(autoBounds, listener) {
919
- this.autoBounds = autoBounds;
920
- this.resizeListener = listener;
921
- try {
922
- this.resizeObserver = new ResizeObserver((entries) => {
923
- this.updateClientBounds();
924
- for (const entry of entries)
925
- this.checkAutoBounds(entry.contentRect);
926
- });
927
- const parent = this.parentView;
928
- if (parent) {
929
- this.resizeObserver.observe(parent);
930
- this.checkAutoBounds(parent.getBoundingClientRect());
931
- }
932
- }
933
- catch (_a) {
934
- this.imitateResizeObserver();
935
- }
936
- }
937
- imitateResizeObserver() {
938
- if (this.autoLayout) {
939
- if (this.parentView)
940
- this.checkAutoBounds(this.parentView.getBoundingClientRect());
941
- Platform.requestRender(this.imitateResizeObserver.bind(this));
942
- }
943
- }
944
- checkAutoBounds(parentSize) {
945
- const view = this.view;
946
- const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
947
- if (width !== this.width || height !== this.height) {
948
- const { style } = view;
949
- const { pixelRatio } = this;
950
- style.marginLeft = x + 'px';
951
- style.marginTop = y + 'px';
952
- const size = { width, height, pixelRatio };
953
- const oldSize = {};
954
- DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
955
- this.resize(size);
956
- if (this.width !== undefined)
957
- this.resizeListener(new ResizeEvent(size, oldSize));
958
- }
959
- }
960
- stopAutoLayout() {
961
- this.autoLayout = false;
962
- this.resizeListener = null;
963
- if (this.resizeObserver) {
964
- this.resizeObserver.disconnect();
965
- this.resizeObserver = null;
966
- }
967
- }
968
- unrealCanvas() {
969
- if (!this.unreal && this.parentView) {
970
- const view = this.view;
971
- if (view)
972
- view.remove();
973
- this.view = this.parentView;
974
- this.unreal = true;
975
- }
976
- }
977
- destroy() {
978
- if (this.view) {
979
- this.stopAutoLayout();
980
- if (!this.unreal) {
981
- const view = this.view;
982
- if (view.parentElement)
983
- view.remove();
984
- }
985
- super.destroy();
986
- }
987
- }
988
- }
989
-
990
- canvasPatch(CanvasRenderingContext2D.prototype);
991
- canvasPatch(Path2D.prototype);
992
-
993
- const PointerEventHelper = {
994
- convert(e, local) {
995
- const base = InteractionHelper.getBase(e);
996
- const data = Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: e.width, height: e.height, pointerType: e.pointerType, pressure: e.pressure });
997
- if (data.pointerType === 'pen') {
998
- data.tangentialPressure = e.tangentialPressure;
999
- data.tiltX = e.tiltX;
1000
- data.tiltY = e.tiltY;
1001
- data.twist = e.twist;
1105
+ const PointerEventHelper = {
1106
+ convert(e, local) {
1107
+ const base = InteractionHelper.getBase(e);
1108
+ const data = Object.assign(Object.assign({}, base), { x: local.x, y: local.y, width: e.width, height: e.height, pointerType: e.pointerType, pressure: e.pressure });
1109
+ if (data.pointerType === 'pen') {
1110
+ data.tangentialPressure = e.tangentialPressure;
1111
+ data.tiltX = e.tiltX;
1112
+ data.tiltY = e.tiltY;
1113
+ data.twist = e.twist;
1002
1114
  }
1003
1115
  return data;
1004
1116
  },
@@ -1046,7 +1158,7 @@ const WheelEventHelper = {
1046
1158
  if (zoom) {
1047
1159
  zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
1048
1160
  const min = e.deltaY ? config.delta.y : config.delta.x;
1049
- scale = 1 - delta / (min * 25 * (1 - zoomSpeed) + 10);
1161
+ scale = 1 - delta / (min * 4) * zoomSpeed;
1050
1162
  if (scale < 0.5)
1051
1163
  scale = 0.5;
1052
1164
  if (scale >= 1.5)
@@ -1114,12 +1226,6 @@ class Interaction extends InteractionBase {
1114
1226
  this.windowEvents = {};
1115
1227
  }
1116
1228
  }
1117
- getLocal(p, updateClient) {
1118
- if (updateClient)
1119
- this.canvas.updateClientBounds();
1120
- const { clientBounds } = this.canvas;
1121
- return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
1122
- }
1123
1229
  getTouches(touches) {
1124
1230
  const list = [];
1125
1231
  for (let i = 0, len = touches.length; i < len; i++) {
@@ -1147,6 +1253,8 @@ class Interaction extends InteractionBase {
1147
1253
  this.keyUp(KeyEventHelper.convert(e));
1148
1254
  }
1149
1255
  onContextMenu(e) {
1256
+ if (this.config.pointer.preventDefaultMenu)
1257
+ e.preventDefault();
1150
1258
  this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
1151
1259
  }
1152
1260
  onScroll() {
@@ -1276,17 +1384,23 @@ class Interaction extends InteractionBase {
1276
1384
  onWheel(e) {
1277
1385
  this.preventDefaultWheel(e);
1278
1386
  const { wheel } = this.config;
1387
+ if (wheel.disabled)
1388
+ return;
1279
1389
  const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
1280
1390
  const local = this.getLocal(e);
1281
1391
  const eventBase = InteractionHelper.getBase(e);
1282
1392
  scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
1283
1393
  }
1284
1394
  onGesturestart(e) {
1395
+ if (this.useMultiTouch)
1396
+ return;
1285
1397
  this.preventDefaultWheel(e);
1286
1398
  this.lastGestureScale = 1;
1287
1399
  this.lastGestureRotation = 0;
1288
1400
  }
1289
1401
  onGesturechange(e) {
1402
+ if (this.useMultiTouch)
1403
+ return;
1290
1404
  this.preventDefaultWheel(e);
1291
1405
  const local = this.getLocal(e);
1292
1406
  const eventBase = InteractionHelper.getBase(e);
@@ -1300,9 +1414,34 @@ class Interaction extends InteractionBase {
1300
1414
  this.lastGestureRotation = e.rotation;
1301
1415
  }
1302
1416
  onGestureend(e) {
1417
+ if (this.useMultiTouch)
1418
+ return;
1303
1419
  this.preventDefaultWheel(e);
1304
1420
  this.transformEnd();
1305
1421
  }
1422
+ setCursor(cursor) {
1423
+ super.setCursor(cursor);
1424
+ const list = [];
1425
+ this.eachCursor(cursor, list);
1426
+ if (typeof list[list.length - 1] === 'object')
1427
+ list.push('default');
1428
+ this.canvas.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
1429
+ }
1430
+ eachCursor(cursor, list, level = 0) {
1431
+ level++;
1432
+ if (cursor instanceof Array) {
1433
+ cursor.forEach(item => this.eachCursor(item, list, level));
1434
+ }
1435
+ else {
1436
+ const custom = typeof cursor === 'string' && Cursor.get(cursor);
1437
+ if (custom && level < 2) {
1438
+ this.eachCursor(custom, list, level);
1439
+ }
1440
+ else {
1441
+ list.push(cursor);
1442
+ }
1443
+ }
1444
+ }
1306
1445
  destroy() {
1307
1446
  if (this.view) {
1308
1447
  super.destroy();
@@ -1312,165 +1451,428 @@ class Interaction extends InteractionBase {
1312
1451
  }
1313
1452
  }
1314
1453
 
1315
- const { mineType, fileType } = FileHelper;
1316
- Object.assign(Creator, {
1317
- canvas: (options, manager) => new LeaferCanvas(options, manager),
1318
- image: (options) => new LeaferImage(options),
1319
- hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
1320
- interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
1321
- });
1322
- function useCanvas(_canvasType, _power) {
1323
- Platform.origin = {
1324
- createCanvas(width, height) {
1325
- const canvas = document.createElement('canvas');
1326
- canvas.width = width;
1327
- canvas.height = height;
1328
- return canvas;
1329
- },
1330
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
1331
- canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
1332
- canvasSaveAs: (canvas, filename, quality) => {
1333
- return new Promise((resolve) => {
1334
- let el = document.createElement('a');
1335
- el.href = canvas.toDataURL(mineType(fileType(filename)), quality);
1336
- el.download = filename;
1337
- document.body.appendChild(el);
1338
- el.click();
1339
- document.body.removeChild(el);
1340
- resolve();
1341
- });
1342
- },
1343
- loadImage(src) {
1344
- return new Promise((resolve, reject) => {
1345
- const img = new Image();
1346
- img.setAttribute('crossOrigin', 'anonymous');
1347
- img.crossOrigin = 'anonymous';
1348
- img.onload = () => { resolve(img); };
1349
- img.onerror = (e) => { reject(e); };
1350
- if (!src.startsWith('data:') && Platform.image.suffix)
1351
- src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
1352
- img.src = src;
1454
+ function fillText(ui, canvas) {
1455
+ let row;
1456
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1457
+ for (let i = 0, len = rows.length; i < len; i++) {
1458
+ row = rows[i];
1459
+ if (row.text) {
1460
+ canvas.fillText(row.text, row.x, row.y);
1461
+ }
1462
+ else if (row.data) {
1463
+ row.data.forEach(charData => {
1464
+ canvas.fillText(charData.char, charData.x, row.y);
1353
1465
  });
1354
1466
  }
1355
- };
1356
- Platform.event = {
1357
- stopDefault(origin) { origin.preventDefault(); },
1358
- stopNow(origin) { origin.stopImmediatePropagation(); },
1359
- stop(origin) { origin.stopPropagation(); }
1360
- };
1361
- Platform.canvas = Creator.canvas();
1362
- Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
1363
- }
1364
- Platform.name = 'web';
1365
- Platform.isMobile = 'ontouchstart' in window;
1366
- Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
1367
- Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
1368
- const { userAgent } = navigator;
1369
- if (userAgent.indexOf("Firefox") > -1) {
1370
- Platform.conicGradientRotate90 = true;
1371
- Platform.intWheelDeltaY = true;
1372
- Platform.syncDomFont = true;
1373
- }
1374
- else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
1375
- Platform.fullImageShadow = true;
1376
- }
1377
- if (userAgent.indexOf('Windows') > -1) {
1378
- Platform.os = 'Windows';
1379
- Platform.intWheelDeltaY = true;
1380
- }
1381
- else if (userAgent.indexOf('Mac') > -1) {
1382
- Platform.os = 'Mac';
1383
- }
1384
- else if (userAgent.indexOf('Linux') > -1) {
1385
- Platform.os = 'Linux';
1467
+ if (decorationY)
1468
+ canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1469
+ }
1386
1470
  }
1387
1471
 
1388
- const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1389
- function fillOrFitMode(data, mode, box, width, height, rotation) {
1390
- const transform = get$4();
1391
- const swap = rotation && rotation !== 180;
1392
- const sw = box.width / (swap ? height : width);
1393
- const sh = box.height / (swap ? width : height);
1394
- const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1395
- const x = box.x + (box.width - width * scale) / 2;
1396
- const y = box.y + (box.height - height * scale) / 2;
1397
- translate$1(transform, x, y);
1398
- scaleHelper(transform, scale);
1399
- if (rotation)
1400
- rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1401
- data.scaleX = data.scaleY = scale;
1402
- data.transform = transform;
1472
+ function fill(fill, ui, canvas) {
1473
+ canvas.fillStyle = fill;
1474
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1403
1475
  }
1404
- function clipMode(data, box, offset, scale, rotation) {
1405
- const transform = get$4();
1406
- translate$1(transform, box.x, box.y);
1407
- if (offset)
1408
- translate$1(transform, offset.x, offset.y);
1409
- if (scale) {
1410
- typeof scale === 'number' ? scaleHelper(transform, scale) : scaleHelper(transform, scale.x, scale.y);
1411
- data.scaleX = transform.a;
1412
- data.scaleY = transform.d;
1413
- }
1414
- if (rotation)
1415
- rotate(transform, rotation);
1416
- data.transform = transform;
1476
+ function fills(fills, ui, canvas) {
1477
+ let item;
1478
+ const { windingRule, __font } = ui.__;
1479
+ for (let i = 0, len = fills.length; i < len; i++) {
1480
+ item = fills[i];
1481
+ if (item.image && PaintImage.checkImage(ui, canvas, item, !__font))
1482
+ continue;
1483
+ if (item.style) {
1484
+ canvas.fillStyle = item.style;
1485
+ if (item.transform) {
1486
+ canvas.save();
1487
+ canvas.transform(item.transform);
1488
+ if (item.blendMode)
1489
+ canvas.blendMode = item.blendMode;
1490
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1491
+ canvas.restore();
1492
+ }
1493
+ else {
1494
+ if (item.blendMode) {
1495
+ canvas.saveBlendMode(item.blendMode);
1496
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1497
+ canvas.restoreBlendMode();
1498
+ }
1499
+ else {
1500
+ __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1501
+ }
1502
+ }
1503
+ }
1504
+ }
1417
1505
  }
1418
- function repeatMode(data, box, width, height, scale, rotation) {
1419
- const transform = get$4();
1420
- if (rotation) {
1421
- rotate(transform, rotation);
1422
- switch (rotation) {
1423
- case 90:
1424
- translate$1(transform, height, 0);
1506
+
1507
+ function strokeText(stroke, ui, canvas) {
1508
+ const { strokeAlign } = ui.__;
1509
+ const isStrokes = typeof stroke !== 'string';
1510
+ switch (strokeAlign) {
1511
+ case 'center':
1512
+ canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1513
+ isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1514
+ break;
1515
+ case 'inside':
1516
+ drawAlignStroke('inside', stroke, isStrokes, ui, canvas);
1517
+ break;
1518
+ case 'outside':
1519
+ drawAlignStroke('outside', stroke, isStrokes, ui, canvas);
1520
+ break;
1521
+ }
1522
+ }
1523
+ function drawAlignStroke(align, stroke, isStrokes, ui, canvas) {
1524
+ const { __strokeWidth, __font } = ui.__;
1525
+ const out = canvas.getSameCanvas(true, true);
1526
+ out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__);
1527
+ out.font = __font;
1528
+ isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1529
+ out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1530
+ fillText(ui, out);
1531
+ out.blendMode = 'normal';
1532
+ if (ui.__worldFlipped) {
1533
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1534
+ }
1535
+ else {
1536
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1537
+ }
1538
+ out.recycle(ui.__nowWorld);
1539
+ }
1540
+ function drawTextStroke(ui, canvas) {
1541
+ let row;
1542
+ const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1543
+ for (let i = 0, len = rows.length; i < len; i++) {
1544
+ row = rows[i];
1545
+ if (row.text) {
1546
+ canvas.strokeText(row.text, row.x, row.y);
1547
+ }
1548
+ else if (row.data) {
1549
+ row.data.forEach(charData => {
1550
+ canvas.strokeText(charData.char, charData.x, row.y);
1551
+ });
1552
+ }
1553
+ if (decorationY)
1554
+ canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1555
+ }
1556
+ }
1557
+ function drawStrokesStyle(strokes, isText, ui, canvas) {
1558
+ let item;
1559
+ for (let i = 0, len = strokes.length; i < len; i++) {
1560
+ item = strokes[i];
1561
+ if (item.image && PaintImage.checkImage(ui, canvas, item, false))
1562
+ continue;
1563
+ if (item.style) {
1564
+ canvas.strokeStyle = item.style;
1565
+ if (item.blendMode) {
1566
+ canvas.saveBlendMode(item.blendMode);
1567
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1568
+ canvas.restoreBlendMode();
1569
+ }
1570
+ else {
1571
+ isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1572
+ }
1573
+ }
1574
+ }
1575
+ }
1576
+
1577
+ function stroke(stroke, ui, canvas) {
1578
+ const options = ui.__;
1579
+ const { __strokeWidth, strokeAlign, __font } = options;
1580
+ if (!__strokeWidth)
1581
+ return;
1582
+ if (__font) {
1583
+ strokeText(stroke, ui, canvas);
1584
+ }
1585
+ else {
1586
+ switch (strokeAlign) {
1587
+ case 'center':
1588
+ canvas.setStroke(stroke, __strokeWidth, options);
1589
+ canvas.stroke();
1590
+ break;
1591
+ case 'inside':
1592
+ canvas.save();
1593
+ canvas.setStroke(stroke, __strokeWidth * 2, options);
1594
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1595
+ canvas.stroke();
1596
+ canvas.restore();
1597
+ break;
1598
+ case 'outside':
1599
+ const out = canvas.getSameCanvas(true, true);
1600
+ out.setStroke(stroke, __strokeWidth * 2, options);
1601
+ ui.__drawRenderPath(out);
1602
+ out.stroke();
1603
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1604
+ out.clearWorld(ui.__layout.renderBounds);
1605
+ if (ui.__worldFlipped) {
1606
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1607
+ }
1608
+ else {
1609
+ canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds);
1610
+ }
1611
+ out.recycle(ui.__nowWorld);
1425
1612
  break;
1426
- case 180:
1427
- translate$1(transform, width, height);
1613
+ }
1614
+ }
1615
+ }
1616
+ function strokes(strokes, ui, canvas) {
1617
+ const options = ui.__;
1618
+ const { __strokeWidth, strokeAlign, __font } = options;
1619
+ if (!__strokeWidth)
1620
+ return;
1621
+ if (__font) {
1622
+ strokeText(strokes, ui, canvas);
1623
+ }
1624
+ else {
1625
+ switch (strokeAlign) {
1626
+ case 'center':
1627
+ canvas.setStroke(undefined, __strokeWidth, options);
1628
+ drawStrokesStyle(strokes, false, ui, canvas);
1428
1629
  break;
1429
- case 270:
1430
- translate$1(transform, 0, width);
1630
+ case 'inside':
1631
+ canvas.save();
1632
+ canvas.setStroke(undefined, __strokeWidth * 2, options);
1633
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1634
+ drawStrokesStyle(strokes, false, ui, canvas);
1635
+ canvas.restore();
1636
+ break;
1637
+ case 'outside':
1638
+ const { renderBounds } = ui.__layout;
1639
+ const out = canvas.getSameCanvas(true, true);
1640
+ ui.__drawRenderPath(out);
1641
+ out.setStroke(undefined, __strokeWidth * 2, options);
1642
+ drawStrokesStyle(strokes, false, ui, out);
1643
+ options.windingRule ? out.clip(options.windingRule) : out.clip();
1644
+ out.clearWorld(renderBounds);
1645
+ if (ui.__worldFlipped) {
1646
+ canvas.copyWorldByReset(out, ui.__nowWorld);
1647
+ }
1648
+ else {
1649
+ canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds);
1650
+ }
1651
+ out.recycle(ui.__nowWorld);
1431
1652
  break;
1432
1653
  }
1433
1654
  }
1434
- translate$1(transform, box.x, box.y);
1435
- if (scale) {
1436
- scaleOfOuter$2(transform, box, scale);
1437
- data.scaleX = data.scaleY = scale;
1655
+ }
1656
+
1657
+ const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1658
+ function shape(ui, current, options) {
1659
+ const canvas = current.getSameCanvas();
1660
+ const nowWorld = ui.__nowWorld;
1661
+ let bounds, fitMatrix, shapeBounds, worldCanvas;
1662
+ let { scaleX, scaleY } = nowWorld;
1663
+ if (scaleX < 0)
1664
+ scaleX = -scaleX;
1665
+ if (scaleY < 0)
1666
+ scaleY = -scaleY;
1667
+ if (current.bounds.includes(nowWorld)) {
1668
+ worldCanvas = canvas;
1669
+ bounds = shapeBounds = nowWorld;
1670
+ }
1671
+ else {
1672
+ const { renderShapeSpread: spread } = ui.__layout;
1673
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, scaleX === scaleY ? spread * scaleX : [spread * scaleY, spread * scaleX]) : current.bounds, nowWorld);
1674
+ fitMatrix = current.bounds.getFitMatrix(worldClipBounds);
1675
+ let { a: fitScaleX, d: fitScaleY } = fitMatrix;
1676
+ if (fitMatrix.a < 1) {
1677
+ worldCanvas = current.getSameCanvas();
1678
+ ui.__renderShape(worldCanvas, options);
1679
+ scaleX *= fitScaleX;
1680
+ scaleY *= fitScaleY;
1681
+ }
1682
+ shapeBounds = getOuterOf(nowWorld, fitMatrix);
1683
+ bounds = getByMove(shapeBounds, -fitMatrix.e, -fitMatrix.f);
1684
+ if (options.matrix) {
1685
+ const { matrix } = options;
1686
+ fitMatrix.multiply(matrix);
1687
+ fitScaleX *= matrix.scaleX;
1688
+ fitScaleY *= matrix.scaleY;
1689
+ }
1690
+ options = Object.assign(Object.assign({}, options), { matrix: fitMatrix.withScale(fitScaleX, fitScaleY) });
1691
+ }
1692
+ ui.__renderShape(canvas, options);
1693
+ return {
1694
+ canvas, matrix: fitMatrix, bounds,
1695
+ worldCanvas, shapeBounds, scaleX, scaleY
1696
+ };
1697
+ }
1698
+
1699
+ let recycleMap;
1700
+ function compute(attrName, ui) {
1701
+ const data = ui.__, leafPaints = [];
1702
+ let paints = data.__input[attrName], hasOpacityPixel;
1703
+ if (!(paints instanceof Array))
1704
+ paints = [paints];
1705
+ recycleMap = PaintImage.recycleImage(attrName, data);
1706
+ for (let i = 0, len = paints.length, item; i < len; i++) {
1707
+ item = getLeafPaint(attrName, paints[i], ui);
1708
+ if (item)
1709
+ leafPaints.push(item);
1710
+ }
1711
+ data['_' + attrName] = leafPaints.length ? leafPaints : undefined;
1712
+ if (leafPaints.length && leafPaints[0].image)
1713
+ hasOpacityPixel = leafPaints[0].image.hasOpacityPixel;
1714
+ if (attrName === 'fill') {
1715
+ data.__pixelFill = hasOpacityPixel;
1716
+ }
1717
+ else {
1718
+ data.__pixelStroke = hasOpacityPixel;
1719
+ }
1720
+ }
1721
+ function getLeafPaint(attrName, paint, ui) {
1722
+ if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
1723
+ return undefined;
1724
+ const { boxBounds } = ui.__layout;
1725
+ switch (paint.type) {
1726
+ case 'solid':
1727
+ let { type, blendMode, color, opacity } = paint;
1728
+ return { type, blendMode, style: ColorConvert.string(color, opacity) };
1729
+ case 'image':
1730
+ return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
1731
+ case 'linear':
1732
+ return PaintGradient.linearGradient(paint, boxBounds);
1733
+ case 'radial':
1734
+ return PaintGradient.radialGradient(paint, boxBounds);
1735
+ case 'angular':
1736
+ return PaintGradient.conicGradient(paint, boxBounds);
1737
+ default:
1738
+ return paint.r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined;
1739
+ }
1740
+ }
1741
+
1742
+ const PaintModule = {
1743
+ compute,
1744
+ fill,
1745
+ fills,
1746
+ fillText,
1747
+ stroke,
1748
+ strokes,
1749
+ strokeText,
1750
+ drawTextStroke,
1751
+ shape
1752
+ };
1753
+
1754
+ let origin = {};
1755
+ const { get: get$3, rotateOfOuter: rotateOfOuter$1, translate: translate$1, scaleOfOuter: scaleOfOuter$1, scale: scaleHelper, rotate } = MatrixHelper;
1756
+ function fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation) {
1757
+ const transform = get$3();
1758
+ translate$1(transform, box.x + x, box.y + y);
1759
+ scaleHelper(transform, scaleX, scaleY);
1760
+ if (rotation)
1761
+ rotateOfOuter$1(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1762
+ data.transform = transform;
1763
+ }
1764
+ function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
1765
+ const transform = get$3();
1766
+ translate$1(transform, box.x + x, box.y + y);
1767
+ if (scaleX)
1768
+ scaleHelper(transform, scaleX, scaleY);
1769
+ if (rotation)
1770
+ rotate(transform, rotation);
1771
+ data.transform = transform;
1772
+ }
1773
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
1774
+ const transform = get$3();
1775
+ if (rotation) {
1776
+ if (align === 'center') {
1777
+ rotateOfOuter$1(transform, { x: width / 2, y: height / 2 }, rotation);
1778
+ }
1779
+ else {
1780
+ rotate(transform, rotation);
1781
+ switch (rotation) {
1782
+ case 90:
1783
+ translate$1(transform, height, 0);
1784
+ break;
1785
+ case 180:
1786
+ translate$1(transform, width, height);
1787
+ break;
1788
+ case 270:
1789
+ translate$1(transform, 0, width);
1790
+ break;
1791
+ }
1792
+ }
1438
1793
  }
1794
+ origin.x = box.x + x;
1795
+ origin.y = box.y + y;
1796
+ translate$1(transform, origin.x, origin.y);
1797
+ if (scaleX)
1798
+ scaleOfOuter$1(transform, origin, scaleX, scaleY);
1439
1799
  data.transform = transform;
1440
1800
  }
1441
1801
 
1442
- const { get: get$3, translate } = MatrixHelper;
1802
+ const { get: get$2, translate } = MatrixHelper;
1803
+ const tempBox = new Bounds();
1804
+ const tempPoint = {};
1443
1805
  function createData(leafPaint, image, paint, box) {
1444
- let { width, height } = image;
1445
- const { opacity, mode, offset, scale, rotation, blendMode, repeat } = paint;
1446
- const sameBox = box.width === width && box.height === height;
1806
+ const { blendMode } = paint;
1447
1807
  if (blendMode)
1448
1808
  leafPaint.blendMode = blendMode;
1449
- const data = leafPaint.data = { mode };
1809
+ leafPaint.data = getPatternData(paint, box, image);
1810
+ }
1811
+ function getPatternData(paint, box, image) {
1812
+ let { width, height } = image;
1813
+ if (paint.padding)
1814
+ box = tempBox.set(box).shrink(paint.padding);
1815
+ const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
1816
+ const sameBox = box.width === width && box.height === height;
1817
+ const data = { mode };
1818
+ const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
1819
+ const swapWidth = swapSize ? height : width, swapHeight = swapSize ? width : height;
1820
+ let x = 0, y = 0, scaleX, scaleY;
1821
+ if (!mode || mode === 'cover' || mode === 'fit') {
1822
+ if (!sameBox || rotation) {
1823
+ const sw = box.width / swapWidth, sh = box.height / swapHeight;
1824
+ scaleX = scaleY = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1825
+ x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1826
+ }
1827
+ }
1828
+ else if (size) {
1829
+ scaleX = (typeof size === 'number' ? size : size.width) / width;
1830
+ scaleY = (typeof size === 'number' ? size : size.height) / height;
1831
+ }
1832
+ else if (scale) {
1833
+ scaleX = typeof scale === 'number' ? scale : scale.x;
1834
+ scaleY = typeof scale === 'number' ? scale : scale.y;
1835
+ }
1836
+ if (align) {
1837
+ const imageBounds = { x, y, width: swapWidth, height: swapHeight };
1838
+ if (scaleX)
1839
+ imageBounds.width *= scaleX, imageBounds.height *= scaleY;
1840
+ AlignHelper.toPoint(align, imageBounds, box, tempPoint, true);
1841
+ x += tempPoint.x, y += tempPoint.y;
1842
+ }
1843
+ if (offset)
1844
+ x += offset.x, y += offset.y;
1450
1845
  switch (mode) {
1451
1846
  case 'strench':
1452
1847
  if (!sameBox)
1453
1848
  width = box.width, height = box.height;
1454
- if (box.x || box.y) {
1455
- data.transform = get$3();
1456
- translate(data.transform, box.x, box.y);
1457
- }
1458
1849
  break;
1850
+ case 'normal':
1459
1851
  case 'clip':
1460
- if (offset || scale || rotation)
1461
- clipMode(data, box, offset, scale, rotation);
1852
+ if (x || y || scaleX || rotation)
1853
+ clipMode(data, box, x, y, scaleX, scaleY, rotation);
1462
1854
  break;
1463
1855
  case 'repeat':
1464
- if (!sameBox || scale || rotation)
1465
- repeatMode(data, box, width, height, scale, rotation);
1856
+ if (!sameBox || scaleX || rotation)
1857
+ repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1466
1858
  if (!repeat)
1467
1859
  data.repeat = 'repeat';
1468
1860
  break;
1469
1861
  case 'fit':
1470
1862
  case 'cover':
1471
1863
  default:
1472
- if (!sameBox || rotation)
1473
- fillOrFitMode(data, mode, box, width, height, rotation);
1864
+ if (scaleX)
1865
+ fillOrFitMode(data, box, x, y, scaleX, scaleY, rotation);
1866
+ }
1867
+ if (!data.transform) {
1868
+ if (box.x || box.y) {
1869
+ data.transform = get$2();
1870
+ translate(data.transform, box.x, box.y);
1871
+ }
1872
+ }
1873
+ if (scaleX && mode !== 'strench') {
1874
+ data.scaleX = scaleX;
1875
+ data.scaleY = scaleY;
1474
1876
  }
1475
1877
  data.width = width;
1476
1878
  data.height = height;
@@ -1478,112 +1880,108 @@ function createData(leafPaint, image, paint, box) {
1478
1880
  data.opacity = opacity;
1479
1881
  if (repeat)
1480
1882
  data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1883
+ return data;
1481
1884
  }
1482
1885
 
1483
- function image(ui, attrName, attrValue, box, firstUse) {
1484
- const leafPaint = { type: attrValue.type };
1485
- const image = leafPaint.image = ImageManager.get(attrValue);
1486
- const event = (firstUse || image.loading) && { target: ui, image, attrName, attrValue };
1886
+ let cache, box = new Bounds();
1887
+ const { isSame } = BoundsHelper;
1888
+ function image(ui, attrName, paint, boxBounds, firstUse) {
1889
+ let leafPaint, event;
1890
+ const image = ImageManager.get(paint);
1891
+ if (cache && paint === cache.paint && isSame(boxBounds, cache.boxBounds)) {
1892
+ leafPaint = cache.leafPaint;
1893
+ }
1894
+ else {
1895
+ leafPaint = { type: paint.type, image };
1896
+ cache = image.use > 1 ? { leafPaint, paint, boxBounds: box.set(boxBounds) } : null;
1897
+ }
1898
+ if (firstUse || image.loading)
1899
+ event = { image, attrName, attrValue: paint };
1487
1900
  if (image.ready) {
1488
- if (hasNaturalSize(ui, attrName, image))
1489
- createData(leafPaint, image, attrValue, box);
1901
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1490
1902
  if (firstUse) {
1491
- emit(ImageEvent.LOAD, event);
1492
- emit(ImageEvent.LOADED, event);
1903
+ onLoad(ui, event);
1904
+ onLoadSuccess(ui, event);
1493
1905
  }
1494
1906
  }
1495
1907
  else if (image.error) {
1496
- if (firstUse) {
1497
- ui.forceUpdate('surface');
1498
- event.error = image.error;
1499
- emit(ImageEvent.ERROR, event);
1500
- }
1908
+ if (firstUse)
1909
+ onLoadError(ui, event, image.error);
1501
1910
  }
1502
1911
  else {
1912
+ ignoreRender(ui, true);
1503
1913
  if (firstUse)
1504
- emit(ImageEvent.LOAD, event);
1914
+ onLoad(ui, event);
1505
1915
  leafPaint.loadId = image.load(() => {
1916
+ ignoreRender(ui, false);
1506
1917
  if (!ui.destroyed) {
1507
- if (hasNaturalSize(ui, attrName, image)) {
1508
- createData(leafPaint, image, attrValue, box);
1918
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1919
+ if (image.hasOpacityPixel)
1920
+ ui.__layout.hitCanvasChanged = true;
1509
1921
  ui.forceUpdate('surface');
1510
1922
  }
1511
- emit(ImageEvent.LOADED, event);
1923
+ onLoadSuccess(ui, event);
1512
1924
  }
1925
+ leafPaint.loadId = null;
1513
1926
  }, (error) => {
1514
- ui.forceUpdate('surface');
1515
- event.error = error;
1516
- emit(ImageEvent.ERROR, event);
1927
+ ignoreRender(ui, false);
1928
+ onLoadError(ui, event, error);
1929
+ leafPaint.loadId = null;
1517
1930
  });
1518
1931
  }
1519
1932
  return leafPaint;
1520
1933
  }
1521
- function hasNaturalSize(ui, attrName, image) {
1934
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1522
1935
  if (attrName === 'fill' && !ui.__.__naturalWidth) {
1523
- const { __: d } = ui;
1524
- d.__naturalWidth = image.width;
1525
- d.__naturalHeight = image.height;
1526
- if (!d.__getInput('width') || !d.__getInput('height')) {
1936
+ const data = ui.__;
1937
+ data.__naturalWidth = image.width / data.pixelRatio;
1938
+ data.__naturalHeight = image.height / data.pixelRatio;
1939
+ if (data.__autoSide) {
1527
1940
  ui.forceUpdate('width');
1528
1941
  if (ui.__proxyData) {
1529
- ui.setProxyAttr('width', ui.__.width);
1530
- ui.setProxyAttr('height', ui.__.height);
1942
+ ui.setProxyAttr('width', data.width);
1943
+ ui.setProxyAttr('height', data.height);
1531
1944
  }
1532
1945
  return false;
1533
1946
  }
1534
1947
  }
1948
+ if (!leafPaint.data)
1949
+ createData(leafPaint, image, paint, boxBounds);
1535
1950
  return true;
1536
1951
  }
1537
- function emit(type, data) {
1538
- if (data.target.hasEvent(type))
1539
- data.target.emitEvent(new ImageEvent(type, data));
1952
+ function onLoad(ui, event) {
1953
+ emit(ui, ImageEvent.LOAD, event);
1954
+ }
1955
+ function onLoadSuccess(ui, event) {
1956
+ emit(ui, ImageEvent.LOADED, event);
1957
+ }
1958
+ function onLoadError(ui, event, error) {
1959
+ event.error = error;
1960
+ ui.forceUpdate('surface');
1961
+ emit(ui, ImageEvent.ERROR, event);
1962
+ }
1963
+ function emit(ui, type, data) {
1964
+ if (ui.hasEvent(type))
1965
+ ui.emitEvent(new ImageEvent(type, data));
1966
+ }
1967
+ function ignoreRender(ui, value) {
1968
+ const { leafer } = ui;
1969
+ if (leafer && leafer.viewReady)
1970
+ leafer.renderer.ignore = value;
1540
1971
  }
1541
1972
 
1542
- /******************************************************************************
1543
- Copyright (c) Microsoft Corporation.
1544
-
1545
- Permission to use, copy, modify, and/or distribute this software for any
1546
- purpose with or without fee is hereby granted.
1547
-
1548
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1549
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1550
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1551
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1552
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1553
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1554
- PERFORMANCE OF THIS SOFTWARE.
1555
- ***************************************************************************** */
1556
- /* global Reflect, Promise, SuppressedError, Symbol */
1557
-
1558
-
1559
- function __awaiter(thisArg, _arguments, P, generator) {
1560
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1561
- return new (P || (P = Promise))(function (resolve, reject) {
1562
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1563
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1564
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1565
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1566
- });
1567
- }
1568
-
1569
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1570
- var e = new Error(message);
1571
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1572
- };
1573
-
1574
- const Export$1 = {};
1575
-
1576
- const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
1973
+ const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
1974
+ const { ceil, abs: abs$1 } = Math;
1577
1975
  function createPattern(ui, paint, pixelRatio) {
1578
- let { scaleX, scaleY } = ui.__world;
1976
+ let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1579
1977
  const id = scaleX + '-' + scaleY;
1580
1978
  if (paint.patternId !== id && !ui.destroyed) {
1581
- scaleX = Math.abs(scaleX);
1582
- scaleY = Math.abs(scaleY);
1979
+ scaleX = abs$1(scaleX);
1980
+ scaleY = abs$1(scaleY);
1583
1981
  const { image, data } = paint;
1584
1982
  let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1585
1983
  if (sx) {
1586
- imageMatrix = get$2();
1984
+ imageMatrix = get$1();
1587
1985
  copy$1(imageMatrix, transform);
1588
1986
  scale(imageMatrix, 1 / sx, 1 / sy);
1589
1987
  scaleX *= sx;
@@ -1618,22 +2016,14 @@ function createPattern(ui, paint, pixelRatio) {
1618
2016
  }
1619
2017
  if (transform || scaleX !== 1 || scaleY !== 1) {
1620
2018
  if (!imageMatrix) {
1621
- imageMatrix = get$2();
2019
+ imageMatrix = get$1();
1622
2020
  if (transform)
1623
2021
  copy$1(imageMatrix, transform);
1624
2022
  }
1625
2023
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1626
2024
  }
1627
- const pattern = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), repeat || (Platform.origin.noRepeat || 'no-repeat'));
1628
- try {
1629
- if (paint.transform)
1630
- paint.transform = null;
1631
- if (imageMatrix)
1632
- pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
1633
- }
1634
- catch (_a) {
1635
- paint.transform = imageMatrix;
1636
- }
2025
+ const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
2026
+ const pattern = image.getPattern(canvas, repeat || (Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1637
2027
  paint.style = pattern;
1638
2028
  paint.patternId = id;
1639
2029
  return true;
@@ -1643,9 +2033,41 @@ function createPattern(ui, paint, pixelRatio) {
1643
2033
  }
1644
2034
  }
1645
2035
 
2036
+ /******************************************************************************
2037
+ Copyright (c) Microsoft Corporation.
2038
+
2039
+ Permission to use, copy, modify, and/or distribute this software for any
2040
+ purpose with or without fee is hereby granted.
2041
+
2042
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2043
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2044
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2045
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2046
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2047
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2048
+ PERFORMANCE OF THIS SOFTWARE.
2049
+ ***************************************************************************** */
2050
+ /* global Reflect, Promise, SuppressedError, Symbol */
2051
+
2052
+
2053
+ function __awaiter(thisArg, _arguments, P, generator) {
2054
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
2055
+ return new (P || (P = Promise))(function (resolve, reject) {
2056
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
2057
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
2058
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
2059
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
2060
+ });
2061
+ }
2062
+
2063
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
2064
+ var e = new Error(message);
2065
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
2066
+ };
2067
+
1646
2068
  const { abs } = Math;
1647
2069
  function checkImage(ui, canvas, paint, allowPaint) {
1648
- const { scaleX, scaleY } = ui.__world;
2070
+ const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1649
2071
  if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1650
2072
  return false;
1651
2073
  }
@@ -1660,7 +2082,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1660
2082
  width *= data.scaleX;
1661
2083
  height *= data.scaleY;
1662
2084
  }
1663
- allowPaint = width * height > Platform.image.maxCacheSize;
2085
+ allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
1664
2086
  }
1665
2087
  else {
1666
2088
  allowPaint = false;
@@ -1679,307 +2101,72 @@ function checkImage(ui, canvas, paint, allowPaint) {
1679
2101
  canvas.restore();
1680
2102
  return true;
1681
2103
  }
1682
- else {
1683
- if (!paint.style || Export$1.running) {
1684
- createPattern(ui, paint, canvas.pixelRatio);
1685
- }
1686
- else {
1687
- if (!paint.patternTask) {
1688
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1689
- paint.patternTask = null;
1690
- if (canvas.bounds.hit(ui.__world))
1691
- createPattern(ui, paint, canvas.pixelRatio);
1692
- ui.forceUpdate('surface');
1693
- }), 300);
1694
- }
1695
- }
1696
- return false;
1697
- }
1698
- }
1699
- }
1700
-
1701
- function recycleImage(attrName, data) {
1702
- const paints = data['_' + attrName];
1703
- if (paints instanceof Array) {
1704
- let image, recycleMap, input, url;
1705
- for (let i = 0, len = paints.length; i < len; i++) {
1706
- image = paints[i].image;
1707
- url = image && image.url;
1708
- if (url) {
1709
- if (!recycleMap)
1710
- recycleMap = {};
1711
- recycleMap[url] = true;
1712
- ImageManager.recycle(image);
1713
- if (image.loading) {
1714
- if (!input) {
1715
- input = (data.__input && data.__input[attrName]) || [];
1716
- if (!(input instanceof Array))
1717
- input = [input];
1718
- }
1719
- image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1720
- }
1721
- }
1722
- }
1723
- return recycleMap;
1724
- }
1725
- return null;
1726
- }
1727
-
1728
- function fillText(ui, canvas) {
1729
- let row;
1730
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1731
- for (let i = 0, len = rows.length; i < len; i++) {
1732
- row = rows[i];
1733
- if (row.text) {
1734
- canvas.fillText(row.text, row.x, row.y);
1735
- }
1736
- else if (row.data) {
1737
- row.data.forEach(charData => {
1738
- canvas.fillText(charData.char, charData.x, row.y);
1739
- });
1740
- }
1741
- if (decorationY)
1742
- canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1743
- }
1744
- }
1745
-
1746
- function fill(fill, ui, canvas) {
1747
- canvas.fillStyle = fill;
1748
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1749
- }
1750
- function fills(fills, ui, canvas) {
1751
- let item;
1752
- const { windingRule, __font } = ui.__;
1753
- for (let i = 0, len = fills.length; i < len; i++) {
1754
- item = fills[i];
1755
- if (item.image && checkImage(ui, canvas, item, !__font))
1756
- continue;
1757
- if (item.style) {
1758
- canvas.fillStyle = item.style;
1759
- if (item.transform) {
1760
- canvas.save();
1761
- canvas.transform(item.transform);
1762
- if (item.blendMode)
1763
- canvas.blendMode = item.blendMode;
1764
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1765
- canvas.restore();
1766
- }
1767
- else {
1768
- if (item.blendMode) {
1769
- canvas.saveBlendMode(item.blendMode);
1770
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1771
- canvas.restoreBlendMode();
1772
- }
1773
- else {
1774
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1775
- }
1776
- }
1777
- }
1778
- }
1779
- }
1780
-
1781
- function strokeText(stroke, ui, canvas, renderOptions) {
1782
- const { strokeAlign } = ui.__;
1783
- const isStrokes = typeof stroke !== 'string';
1784
- switch (strokeAlign) {
1785
- case 'center':
1786
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1787
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1788
- break;
1789
- case 'inside':
1790
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
1791
- break;
1792
- case 'outside':
1793
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
1794
- break;
1795
- }
1796
- }
1797
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
1798
- const { strokeWidth, __font } = ui.__;
1799
- const out = canvas.getSameCanvas(true);
1800
- out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
1801
- out.font = __font;
1802
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1803
- out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1804
- fillText(ui, out);
1805
- out.blendMode = 'normal';
1806
- if (ui.__worldFlipped || renderOptions.matrix) {
1807
- canvas.copyWorldByReset(out);
1808
- }
1809
- else {
1810
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1811
- }
1812
- out.recycle();
1813
- }
1814
- function drawTextStroke(ui, canvas) {
1815
- let row;
1816
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1817
- for (let i = 0, len = rows.length; i < len; i++) {
1818
- row = rows[i];
1819
- if (row.text) {
1820
- canvas.strokeText(row.text, row.x, row.y);
1821
- }
1822
- else if (row.data) {
1823
- row.data.forEach(charData => {
1824
- canvas.strokeText(charData.char, charData.x, row.y);
1825
- });
1826
- }
1827
- if (decorationY)
1828
- canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1829
- }
1830
- }
1831
- function drawStrokesStyle(strokes, isText, ui, canvas) {
1832
- let item;
1833
- for (let i = 0, len = strokes.length; i < len; i++) {
1834
- item = strokes[i];
1835
- if (item.image && checkImage(ui, canvas, item, false))
1836
- continue;
1837
- if (item.style) {
1838
- canvas.strokeStyle = item.style;
1839
- if (item.blendMode) {
1840
- canvas.saveBlendMode(item.blendMode);
1841
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1842
- canvas.restoreBlendMode();
2104
+ else {
2105
+ if (!paint.style || Export.running) {
2106
+ createPattern(ui, paint, canvas.pixelRatio);
1843
2107
  }
1844
2108
  else {
1845
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
2109
+ if (!paint.patternTask) {
2110
+ paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
2111
+ paint.patternTask = null;
2112
+ if (canvas.bounds.hit(ui.__nowWorld))
2113
+ createPattern(ui, paint, canvas.pixelRatio);
2114
+ ui.forceUpdate('surface');
2115
+ }), 300);
2116
+ }
1846
2117
  }
2118
+ return false;
1847
2119
  }
1848
2120
  }
1849
2121
  }
1850
2122
 
1851
- function stroke(stroke, ui, canvas, renderOptions) {
1852
- const options = ui.__;
1853
- const { strokeWidth, strokeAlign, __font } = options;
1854
- if (!strokeWidth)
1855
- return;
1856
- if (__font) {
1857
- strokeText(stroke, ui, canvas, renderOptions);
1858
- }
1859
- else {
1860
- switch (strokeAlign) {
1861
- case 'center':
1862
- canvas.setStroke(stroke, strokeWidth, options);
1863
- canvas.stroke();
1864
- break;
1865
- case 'inside':
1866
- canvas.save();
1867
- canvas.setStroke(stroke, strokeWidth * 2, options);
1868
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1869
- canvas.stroke();
1870
- canvas.restore();
1871
- break;
1872
- case 'outside':
1873
- const out = canvas.getSameCanvas(true);
1874
- out.setStroke(stroke, strokeWidth * 2, ui.__);
1875
- ui.__drawRenderPath(out);
1876
- out.stroke();
1877
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1878
- out.clearWorld(ui.__layout.renderBounds);
1879
- if (ui.__worldFlipped || renderOptions.matrix) {
1880
- canvas.copyWorldByReset(out);
1881
- }
1882
- else {
1883
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1884
- }
1885
- out.recycle();
1886
- break;
1887
- }
1888
- }
1889
- }
1890
- function strokes(strokes, ui, canvas, renderOptions) {
1891
- const options = ui.__;
1892
- const { strokeWidth, strokeAlign, __font } = options;
1893
- if (!strokeWidth)
1894
- return;
1895
- if (__font) {
1896
- strokeText(strokes, ui, canvas, renderOptions);
1897
- }
1898
- else {
1899
- switch (strokeAlign) {
1900
- case 'center':
1901
- canvas.setStroke(undefined, strokeWidth, options);
1902
- drawStrokesStyle(strokes, false, ui, canvas);
1903
- break;
1904
- case 'inside':
1905
- canvas.save();
1906
- canvas.setStroke(undefined, strokeWidth * 2, options);
1907
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1908
- drawStrokesStyle(strokes, false, ui, canvas);
1909
- canvas.restore();
1910
- break;
1911
- case 'outside':
1912
- const { renderBounds } = ui.__layout;
1913
- const out = canvas.getSameCanvas(true);
1914
- ui.__drawRenderPath(out);
1915
- out.setStroke(undefined, strokeWidth * 2, ui.__);
1916
- drawStrokesStyle(strokes, false, ui, out);
1917
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1918
- out.clearWorld(renderBounds);
1919
- if (ui.__worldFlipped || renderOptions.matrix) {
1920
- canvas.copyWorldByReset(out);
1921
- }
1922
- else {
1923
- canvas.copyWorldToInner(out, ui.__world, renderBounds);
2123
+ function recycleImage(attrName, data) {
2124
+ const paints = data['_' + attrName];
2125
+ if (paints instanceof Array) {
2126
+ let image, recycleMap, input, url;
2127
+ for (let i = 0, len = paints.length; i < len; i++) {
2128
+ image = paints[i].image;
2129
+ url = image && image.url;
2130
+ if (url) {
2131
+ if (!recycleMap)
2132
+ recycleMap = {};
2133
+ recycleMap[url] = true;
2134
+ ImageManager.recycle(image);
2135
+ if (image.loading) {
2136
+ if (!input) {
2137
+ input = (data.__input && data.__input[attrName]) || [];
2138
+ if (!(input instanceof Array))
2139
+ input = [input];
2140
+ }
2141
+ image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1924
2142
  }
1925
- out.recycle();
1926
- break;
2143
+ }
1927
2144
  }
2145
+ return recycleMap;
1928
2146
  }
2147
+ return null;
1929
2148
  }
1930
2149
 
1931
- const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1932
- function shape(ui, current, options) {
1933
- const canvas = current.getSameCanvas();
1934
- let bounds, matrix, shapeBounds;
1935
- let worldCanvas;
1936
- const { __world } = ui;
1937
- let { scaleX, scaleY } = __world;
1938
- if (scaleX < 0)
1939
- scaleX = -scaleX;
1940
- if (scaleY < 0)
1941
- scaleY = -scaleY;
1942
- if (!current.bounds.includes(__world, options.matrix)) {
1943
- const { renderShapeSpread: spread } = ui.__layout;
1944
- const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
1945
- matrix = current.bounds.getFitMatrix(worldClipBounds);
1946
- if (matrix.a < 1) {
1947
- worldCanvas = current.getSameCanvas();
1948
- ui.__renderShape(worldCanvas, options);
1949
- scaleX *= matrix.a;
1950
- scaleY *= matrix.d;
1951
- }
1952
- shapeBounds = getOuterOf(__world, matrix);
1953
- bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
1954
- if (options.matrix)
1955
- matrix.multiply(options.matrix);
1956
- options = Object.assign(Object.assign({}, options), { matrix });
1957
- }
1958
- else {
1959
- if (options.matrix) {
1960
- scaleX *= options.matrix.a;
1961
- scaleY *= options.matrix.d;
1962
- bounds = shapeBounds = getOuterOf(__world, options.matrix);
1963
- }
1964
- else {
1965
- bounds = shapeBounds = __world;
1966
- }
1967
- worldCanvas = canvas;
1968
- }
1969
- ui.__renderShape(canvas, options);
1970
- return {
1971
- canvas, matrix, bounds,
1972
- worldCanvas, shapeBounds, scaleX, scaleY
1973
- };
1974
- }
2150
+ const PaintImageModule = {
2151
+ image,
2152
+ checkImage,
2153
+ createPattern,
2154
+ recycleImage,
2155
+ createData,
2156
+ getPatternData,
2157
+ fillOrFitMode,
2158
+ clipMode,
2159
+ repeatMode
2160
+ };
1975
2161
 
1976
- const defaultFrom$2 = { x: 0.5, y: 0 };
1977
- const defaultTo$2 = { x: 0.5, y: 1 };
2162
+ const { toPoint: toPoint$2 } = AroundHelper;
2163
+ const realFrom$2 = {};
2164
+ const realTo$2 = {};
1978
2165
  function linearGradient(paint, box) {
1979
2166
  let { from, to, type, blendMode, opacity } = paint;
1980
- from || (from = defaultFrom$2);
1981
- to || (to = defaultTo$2);
1982
- 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);
2167
+ toPoint$2(from || 'top', box, realFrom$2);
2168
+ toPoint$2(to || 'bottom', box, realTo$2);
2169
+ const style = Platform.canvas.createLinearGradient(realFrom$2.x, realFrom$2.y, realTo$2.x, realTo$2.y);
1983
2170
  applyStops(style, paint.stops, opacity);
1984
2171
  const data = { type, style };
1985
2172
  if (blendMode)
@@ -1990,137 +2177,84 @@ function applyStops(gradient, stops, opacity) {
1990
2177
  let stop;
1991
2178
  for (let i = 0, len = stops.length; i < len; i++) {
1992
2179
  stop = stops[i];
1993
- gradient.addColorStop(stop.offset, ColorConvert$1.string(stop.color, opacity));
2180
+ if (typeof stop === 'string') {
2181
+ gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
2182
+ }
2183
+ else {
2184
+ gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
2185
+ }
1994
2186
  }
1995
2187
  }
1996
2188
 
1997
- const { set: set$1, getAngle: getAngle$1, getDistance: getDistance$1 } = PointHelper;
1998
- const { get: get$1, rotateOfOuter: rotateOfOuter$1, scaleOfOuter: scaleOfOuter$1 } = MatrixHelper;
1999
- const defaultFrom$1 = { x: 0.5, y: 0.5 };
2000
- const defaultTo$1 = { x: 0.5, y: 1 };
2189
+ const { getAngle, getDistance: getDistance$1 } = PointHelper;
2190
+ const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
2191
+ const { toPoint: toPoint$1 } = AroundHelper;
2001
2192
  const realFrom$1 = {};
2002
2193
  const realTo$1 = {};
2003
2194
  function radialGradient(paint, box) {
2004
2195
  let { from, to, type, opacity, blendMode, stretch } = paint;
2005
- from || (from = defaultFrom$1);
2006
- to || (to = defaultTo$1);
2007
- const { x, y, width, height } = box;
2008
- set$1(realFrom$1, x + from.x * width, y + from.y * height);
2009
- set$1(realTo$1, x + to.x * width, y + to.y * height);
2010
- let transform;
2011
- if (width !== height || stretch) {
2012
- transform = get$1();
2013
- scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
2014
- rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
2015
- }
2196
+ toPoint$1(from || 'center', box, realFrom$1);
2197
+ toPoint$1(to || 'bottom', box, realTo$1);
2016
2198
  const style = Platform.canvas.createRadialGradient(realFrom$1.x, realFrom$1.y, 0, realFrom$1.x, realFrom$1.y, getDistance$1(realFrom$1, realTo$1));
2017
2199
  applyStops(style, paint.stops, opacity);
2018
- const data = { type, style, transform };
2200
+ const data = { type, style };
2201
+ const transform = getTransform(box, realFrom$1, realTo$1, stretch, true);
2202
+ if (transform)
2203
+ data.transform = transform;
2019
2204
  if (blendMode)
2020
2205
  data.blendMode = blendMode;
2021
2206
  return data;
2022
2207
  }
2208
+ function getTransform(box, from, to, stretch, rotate90) {
2209
+ let transform;
2210
+ const { width, height } = box;
2211
+ if (width !== height || stretch) {
2212
+ const angle = getAngle(from, to);
2213
+ transform = get();
2214
+ if (rotate90) {
2215
+ scaleOfOuter(transform, from, width / height * (stretch || 1), 1);
2216
+ rotateOfOuter(transform, from, angle + 90);
2217
+ }
2218
+ else {
2219
+ scaleOfOuter(transform, from, 1, width / height * (stretch || 1));
2220
+ rotateOfOuter(transform, from, angle);
2221
+ }
2222
+ }
2223
+ return transform;
2224
+ }
2023
2225
 
2024
- const { set, getAngle, getDistance } = PointHelper;
2025
- const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
2026
- const defaultFrom = { x: 0.5, y: 0.5 };
2027
- const defaultTo = { x: 0.5, y: 1 };
2226
+ const { getDistance } = PointHelper;
2227
+ const { toPoint } = AroundHelper;
2028
2228
  const realFrom = {};
2029
2229
  const realTo = {};
2030
2230
  function conicGradient(paint, box) {
2031
2231
  let { from, to, type, opacity, blendMode, stretch } = paint;
2032
- from || (from = defaultFrom);
2033
- to || (to = defaultTo);
2034
- const { x, y, width, height } = box;
2035
- set(realFrom, x + from.x * width, y + from.y * height);
2036
- set(realTo, x + to.x * width, y + to.y * height);
2037
- const transform = get();
2038
- const angle = getAngle(realFrom, realTo);
2039
- if (Platform.conicGradientRotate90) {
2040
- scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
2041
- rotateOfOuter(transform, realFrom, angle + 90);
2042
- }
2043
- else {
2044
- scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
2045
- rotateOfOuter(transform, realFrom, angle);
2046
- }
2232
+ toPoint(from || 'center', box, realFrom);
2233
+ toPoint(to || 'bottom', box, realTo);
2047
2234
  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));
2048
2235
  applyStops(style, paint.stops, opacity);
2049
- const data = { type, style, transform };
2236
+ const data = { type, style };
2237
+ const transform = getTransform(box, realFrom, realTo, stretch || 1, Platform.conicGradientRotate90);
2238
+ if (transform)
2239
+ data.transform = transform;
2050
2240
  if (blendMode)
2051
2241
  data.blendMode = blendMode;
2052
2242
  return data;
2053
2243
  }
2054
2244
 
2055
- let recycleMap;
2056
- function compute(attrName, ui) {
2057
- const value = [];
2058
- const data = ui.__;
2059
- let item;
2060
- let paints = data.__input[attrName];
2061
- if (!(paints instanceof Array))
2062
- paints = [paints];
2063
- recycleMap = recycleImage(attrName, data);
2064
- for (let i = 0, len = paints.length; i < len; i++) {
2065
- item = getLeafPaint(attrName, paints[i], ui);
2066
- if (item)
2067
- value.push(item);
2068
- }
2069
- data['_' + attrName] = value.length ? value : undefined;
2070
- let isPixel;
2071
- if (paints.length === 1) {
2072
- const paint = paints[0];
2073
- if (paint.type === 'image')
2074
- isPixel = ImageManager$1.isPixel(paint);
2075
- }
2076
- if (attrName === 'fill') {
2077
- data.__pixelFill = isPixel;
2078
- }
2079
- else {
2080
- data.__pixelStroke = isPixel;
2081
- }
2082
- }
2083
- function getLeafPaint(attrName, paint, ui) {
2084
- if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
2085
- return undefined;
2086
- const { boxBounds } = ui.__layout;
2087
- switch (paint.type) {
2088
- case 'solid':
2089
- let { type, blendMode, color, opacity } = paint;
2090
- return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
2091
- case 'image':
2092
- return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
2093
- case 'linear':
2094
- return linearGradient(paint, boxBounds);
2095
- case 'radial':
2096
- return radialGradient(paint, boxBounds);
2097
- case 'angular':
2098
- return conicGradient(paint, boxBounds);
2099
- default:
2100
- return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
2101
- }
2102
- }
2103
-
2104
- var UIPaint = /*#__PURE__*/Object.freeze({
2105
- __proto__: null,
2106
- compute: compute,
2107
- drawTextStroke: drawTextStroke,
2108
- fill: fill,
2109
- fillText: fillText,
2110
- fills: fills,
2111
- recycleImage: recycleImage,
2112
- shape: shape,
2113
- stroke: stroke,
2114
- strokeText: strokeText,
2115
- strokes: strokes
2116
- });
2245
+ const PaintGradientModule = {
2246
+ linearGradient,
2247
+ radialGradient,
2248
+ conicGradient,
2249
+ getTransform
2250
+ };
2117
2251
 
2118
2252
  const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
2119
2253
  const tempBounds = {};
2120
2254
  const offsetOutBounds$1 = {};
2121
- function shadow(ui, current, shape, renderOptions) {
2255
+ function shadow(ui, current, shape) {
2122
2256
  let copyBounds, spreadScale;
2123
- const { __world, __layout } = ui;
2257
+ const { __nowWorld: nowWorld, __layout } = ui;
2124
2258
  const { shadow } = ui.__;
2125
2259
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2126
2260
  const other = current.getSameCanvas();
@@ -2135,21 +2269,21 @@ function shadow(ui, current, shape, renderOptions) {
2135
2269
  other.restore();
2136
2270
  other.save();
2137
2271
  if (worldCanvas) {
2138
- other.copyWorld(other, bounds, __world, 'copy');
2139
- copyBounds = __world;
2272
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2273
+ copyBounds = nowWorld;
2140
2274
  }
2141
- worldCanvas ? other.copyWorld(worldCanvas, __world, __world, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
2275
+ worldCanvas ? other.copyWorld(worldCanvas, nowWorld, nowWorld, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
2142
2276
  }
2143
- if (ui.__worldFlipped || renderOptions.matrix) {
2144
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2277
+ if (ui.__worldFlipped) {
2278
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2145
2279
  }
2146
2280
  else {
2147
2281
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2148
2282
  }
2149
2283
  if (end && index < end)
2150
- other.clear();
2284
+ other.clearWorld(copyBounds, true);
2151
2285
  });
2152
- other.recycle();
2286
+ other.recycle(copyBounds);
2153
2287
  }
2154
2288
  function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2155
2289
  const { bounds, shapeBounds } = shape;
@@ -2180,9 +2314,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2180
2314
 
2181
2315
  const { toOffsetOutBounds } = BoundsHelper;
2182
2316
  const offsetOutBounds = {};
2183
- function innerShadow(ui, current, shape, renderOptions) {
2317
+ function innerShadow(ui, current, shape) {
2184
2318
  let copyBounds, spreadScale;
2185
- const { __world, __layout: __layout } = ui;
2319
+ const { __nowWorld: nowWorld, __layout: __layout } = ui;
2186
2320
  const { innerShadow } = ui.__;
2187
2321
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2188
2322
  const other = current.getSameCanvas();
@@ -2195,40 +2329,115 @@ function innerShadow(ui, current, shape, renderOptions) {
2195
2329
  drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
2196
2330
  other.restore();
2197
2331
  if (worldCanvas) {
2198
- other.copyWorld(other, bounds, __world, 'copy');
2199
- other.copyWorld(worldCanvas, __world, __world, 'source-out');
2200
- copyBounds = __world;
2332
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2333
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
2334
+ copyBounds = nowWorld;
2201
2335
  }
2202
2336
  else {
2203
2337
  other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
2204
2338
  copyBounds = bounds;
2205
2339
  }
2206
2340
  other.fillWorld(copyBounds, item.color, 'source-in');
2207
- if (ui.__worldFlipped || renderOptions.matrix) {
2208
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2341
+ if (ui.__worldFlipped) {
2342
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2209
2343
  }
2210
2344
  else {
2211
2345
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2212
2346
  }
2213
2347
  if (end && index < end)
2214
- other.clear();
2348
+ other.clearWorld(copyBounds, true);
2215
2349
  });
2216
- other.recycle();
2350
+ other.recycle(copyBounds);
2217
2351
  }
2218
2352
 
2219
2353
  function blur(ui, current, origin) {
2220
2354
  const { blur } = ui.__;
2221
- origin.setWorldBlur(blur * ui.__world.a);
2222
- origin.copyWorldToInner(current, ui.__world, ui.__layout.renderBounds);
2355
+ origin.setWorldBlur(blur * ui.__nowWorld.a);
2356
+ origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
2223
2357
  origin.filter = 'none';
2224
2358
  }
2225
2359
 
2226
- var UIEffect = /*#__PURE__*/Object.freeze({
2227
- __proto__: null,
2228
- blur: blur,
2229
- innerShadow: innerShadow,
2230
- shadow: shadow
2231
- });
2360
+ function backgroundBlur(_ui, _current, _shape) {
2361
+ }
2362
+
2363
+ const EffectModule = {
2364
+ shadow,
2365
+ innerShadow,
2366
+ blur,
2367
+ backgroundBlur
2368
+ };
2369
+
2370
+ const { excludeRenderBounds } = LeafBoundsHelper;
2371
+ Group.prototype.__renderMask = function (canvas, options) {
2372
+ let child, maskCanvas, contentCanvas, maskOpacity, currentMask;
2373
+ const { children } = this;
2374
+ for (let i = 0, len = children.length; i < len; i++) {
2375
+ child = children[i];
2376
+ if (child.__.mask) {
2377
+ if (currentMask) {
2378
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2379
+ maskCanvas = contentCanvas = null;
2380
+ }
2381
+ if (child.__.mask === 'path') {
2382
+ if (child.opacity < 1) {
2383
+ currentMask = 'opacity-path';
2384
+ maskOpacity = child.opacity;
2385
+ if (!contentCanvas)
2386
+ contentCanvas = getCanvas(canvas);
2387
+ }
2388
+ else {
2389
+ currentMask = 'path';
2390
+ canvas.save();
2391
+ }
2392
+ child.__clip(contentCanvas || canvas, options);
2393
+ }
2394
+ else {
2395
+ currentMask = 'alpha';
2396
+ if (!maskCanvas)
2397
+ maskCanvas = getCanvas(canvas);
2398
+ if (!contentCanvas)
2399
+ contentCanvas = getCanvas(canvas);
2400
+ child.__render(maskCanvas, options);
2401
+ }
2402
+ if (child.__.mask !== 'clipping')
2403
+ continue;
2404
+ }
2405
+ if (excludeRenderBounds(child, options))
2406
+ continue;
2407
+ child.__render(contentCanvas || canvas, options);
2408
+ }
2409
+ maskEnd(this, currentMask, canvas, contentCanvas, maskCanvas, maskOpacity);
2410
+ };
2411
+ function maskEnd(leaf, maskMode, canvas, contentCanvas, maskCanvas, maskOpacity) {
2412
+ switch (maskMode) {
2413
+ case 'alpha':
2414
+ usePixelMask(leaf, canvas, contentCanvas, maskCanvas);
2415
+ break;
2416
+ case 'opacity-path':
2417
+ copyContent(leaf, canvas, contentCanvas, maskOpacity);
2418
+ break;
2419
+ case 'path':
2420
+ canvas.restore();
2421
+ }
2422
+ }
2423
+ function getCanvas(canvas) {
2424
+ return canvas.getSameCanvas(false, true);
2425
+ }
2426
+ function usePixelMask(leaf, canvas, content, mask) {
2427
+ const realBounds = leaf.__nowWorld;
2428
+ content.resetTransform();
2429
+ content.opacity = 1;
2430
+ content.useMask(mask, realBounds);
2431
+ mask.recycle(realBounds);
2432
+ copyContent(leaf, canvas, content, 1);
2433
+ }
2434
+ function copyContent(leaf, canvas, content, maskOpacity) {
2435
+ const realBounds = leaf.__nowWorld;
2436
+ canvas.resetTransform();
2437
+ canvas.opacity = maskOpacity;
2438
+ canvas.copyWorld(content, realBounds);
2439
+ content.recycle(realBounds);
2440
+ }
2232
2441
 
2233
2442
  const money = '¥¥$€££¢¢';
2234
2443
  const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
@@ -2385,7 +2594,8 @@ function createRows(drawData, content, style) {
2385
2594
  if (breakAll) {
2386
2595
  if (wordWidth)
2387
2596
  addWord();
2388
- addRow();
2597
+ if (rowWidth)
2598
+ addRow();
2389
2599
  }
2390
2600
  else {
2391
2601
  if (!afterBreak)
@@ -2393,10 +2603,12 @@ function createRows(drawData, content, style) {
2393
2603
  if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2394
2604
  if (wordWidth)
2395
2605
  addWord();
2396
- addRow();
2606
+ if (rowWidth)
2607
+ addRow();
2397
2608
  }
2398
2609
  else {
2399
- addRow();
2610
+ if (rowWidth)
2611
+ addRow();
2400
2612
  }
2401
2613
  }
2402
2614
  }
@@ -2491,11 +2703,11 @@ function layoutChar(drawData, style, width, _height) {
2491
2703
  if (mode === WordMode) {
2492
2704
  wordChar = { char: '', x: charX };
2493
2705
  charX = toWordChar(word.data, charX, wordChar);
2494
- if (wordChar.char !== ' ')
2706
+ if (row.isOverflow || wordChar.char !== ' ')
2495
2707
  row.data.push(wordChar);
2496
2708
  }
2497
2709
  else {
2498
- charX = toChar(word.data, charX, row.data);
2710
+ charX = toChar(word.data, charX, row.data, row.isOverflow);
2499
2711
  }
2500
2712
  if (!row.paraEnd && addWordWidth) {
2501
2713
  charX += addWordWidth;
@@ -2522,9 +2734,9 @@ function toWordChar(data, charX, wordChar) {
2522
2734
  });
2523
2735
  return charX;
2524
2736
  }
2525
- function toChar(data, charX, rowData) {
2737
+ function toChar(data, charX, rowData, isOverflow) {
2526
2738
  data.forEach(char => {
2527
- if (char.char !== ' ') {
2739
+ if (isOverflow || char.char !== ' ') {
2528
2740
  char.x = charX;
2529
2741
  rowData.push(char);
2530
2742
  }
@@ -2556,12 +2768,14 @@ function layoutText(drawData, style) {
2556
2768
  for (let i = 0, len = rows.length; i < len; i++) {
2557
2769
  row = rows[i];
2558
2770
  row.x = x;
2559
- switch (textAlign) {
2560
- case 'center':
2561
- row.x += (width - row.width) / 2;
2562
- break;
2563
- case 'right':
2564
- row.x += width - row.width;
2771
+ if (row.width < width || (row.width > width && !__clipText)) {
2772
+ switch (textAlign) {
2773
+ case 'center':
2774
+ row.x += (width - row.width) / 2;
2775
+ break;
2776
+ case 'right':
2777
+ row.x += width - row.width;
2778
+ }
2565
2779
  }
2566
2780
  if (row.paraStart && paraSpacing && i > 0)
2567
2781
  starY += paraSpacing;
@@ -2597,16 +2811,20 @@ function layoutText(drawData, style) {
2597
2811
  bounds.height = realHeight;
2598
2812
  }
2599
2813
 
2600
- function clipText(drawData, style) {
2814
+ function clipText(drawData, style, x, width) {
2815
+ if (!width)
2816
+ return;
2601
2817
  const { rows, overflow } = drawData;
2602
2818
  let { textOverflow } = style;
2603
2819
  rows.splice(overflow);
2604
- if (textOverflow !== 'hide') {
2605
- if (textOverflow === 'ellipsis')
2820
+ if (textOverflow && textOverflow !== 'show') {
2821
+ if (textOverflow === 'hide')
2822
+ textOverflow = '';
2823
+ else if (textOverflow === 'ellipsis')
2606
2824
  textOverflow = '...';
2607
2825
  let char, charRight;
2608
- const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2609
- const right = style.x + style.width - ellipsisWidth;
2826
+ const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
2827
+ const right = x + width - ellipsisWidth;
2610
2828
  const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2611
2829
  list.forEach(row => {
2612
2830
  if (row.isOverflow && row.data) {
@@ -2653,42 +2871,40 @@ function decorationText(drawData, style) {
2653
2871
  }
2654
2872
 
2655
2873
  const { top, right, bottom, left } = Direction4;
2656
- const TextConvert = {
2657
- getDrawData(content, style) {
2658
- if (typeof content !== 'string')
2659
- content = String(content);
2660
- let x = 0, y = 0;
2661
- let width = style.__getInput('width') || 0;
2662
- let height = style.__getInput('height') || 0;
2663
- const { textDecoration, __font, __padding: padding } = style;
2664
- if (padding) {
2665
- if (width) {
2666
- x = padding[left];
2667
- width -= (padding[right] + padding[left]);
2668
- }
2669
- if (height) {
2670
- y = padding[top];
2671
- height -= (padding[top] + padding[bottom]);
2672
- }
2673
- }
2674
- const drawData = {
2675
- bounds: { x, y, width, height },
2676
- rows: [],
2677
- paraNumber: 0,
2678
- font: Platform.canvas.font = __font
2679
- };
2680
- createRows(drawData, content, style);
2681
- if (padding)
2682
- padAutoText(padding, drawData, style, width, height);
2683
- layoutText(drawData, style);
2684
- layoutChar(drawData, style, width);
2685
- if (drawData.overflow)
2686
- clipText(drawData, style);
2687
- if (textDecoration !== 'none')
2688
- decorationText(drawData, style);
2689
- return drawData;
2690
- }
2691
- };
2874
+ function getDrawData(content, style) {
2875
+ if (typeof content !== 'string')
2876
+ content = String(content);
2877
+ let x = 0, y = 0;
2878
+ let width = style.__getInput('width') || 0;
2879
+ let height = style.__getInput('height') || 0;
2880
+ const { textDecoration, __font, __padding: padding } = style;
2881
+ if (padding) {
2882
+ if (width) {
2883
+ x = padding[left];
2884
+ width -= (padding[right] + padding[left]);
2885
+ }
2886
+ if (height) {
2887
+ y = padding[top];
2888
+ height -= (padding[top] + padding[bottom]);
2889
+ }
2890
+ }
2891
+ const drawData = {
2892
+ bounds: { x, y, width, height },
2893
+ rows: [],
2894
+ paraNumber: 0,
2895
+ font: Platform.canvas.font = __font
2896
+ };
2897
+ createRows(drawData, content, style);
2898
+ if (padding)
2899
+ padAutoText(padding, drawData, style, width, height);
2900
+ layoutText(drawData, style);
2901
+ layoutChar(drawData, style, width);
2902
+ if (drawData.overflow)
2903
+ clipText(drawData, style, x, width);
2904
+ if (textDecoration !== 'none')
2905
+ decorationText(drawData, style);
2906
+ return drawData;
2907
+ }
2692
2908
  function padAutoText(padding, drawData, style, width, height) {
2693
2909
  if (!width) {
2694
2910
  switch (style.textAlign) {
@@ -2716,67 +2932,152 @@ function offsetText(drawData, attrName, value) {
2716
2932
  rows[i][attrName] += value;
2717
2933
  }
2718
2934
 
2719
- const ColorConvert = {
2720
- string(color, opacity) {
2721
- if (typeof color === 'string')
2722
- return color;
2723
- let a = color.a === undefined ? 1 : color.a;
2724
- if (opacity)
2725
- a *= opacity;
2726
- const rgb = color.r + ',' + color.g + ',' + color.b;
2727
- return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2728
- }
2935
+ const TextConvertModule = {
2936
+ getDrawData
2937
+ };
2938
+
2939
+ function string(color, opacity) {
2940
+ if (typeof color === 'string')
2941
+ return color;
2942
+ let a = color.a === undefined ? 1 : color.a;
2943
+ if (opacity)
2944
+ a *= opacity;
2945
+ const rgb = color.r + ',' + color.g + ',' + color.b;
2946
+ return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2947
+ }
2948
+
2949
+ const ColorConvertModule = {
2950
+ string
2729
2951
  };
2730
2952
 
2731
- const Export = {
2953
+ const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
2954
+ function getTrimBounds(canvas) {
2955
+ const { width, height } = canvas.view;
2956
+ const { data } = canvas.context.getImageData(0, 0, width, height);
2957
+ let x, y, pointBounds, index = 0;
2958
+ for (let i = 0; i < data.length; i += 4) {
2959
+ if (data[i + 3] !== 0) {
2960
+ x = index % width;
2961
+ y = (index - x) / width;
2962
+ pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
2963
+ }
2964
+ index++;
2965
+ }
2966
+ const bounds = new Bounds();
2967
+ toBounds(pointBounds, bounds);
2968
+ return bounds.scale(1 / canvas.pixelRatio).ceil();
2969
+ }
2970
+
2971
+ const ExportModule = {
2732
2972
  export(leaf, filename, options) {
2733
- Export.running = true;
2973
+ this.running = true;
2974
+ const fileType = FileHelper.fileType(filename);
2975
+ options = FileHelper.getExportOptions(options);
2734
2976
  return addTask((success) => new Promise((resolve) => {
2977
+ const over = (result) => {
2978
+ success(result);
2979
+ resolve();
2980
+ this.running = false;
2981
+ };
2982
+ const { toURL } = Platform;
2983
+ const { download } = Platform.origin;
2984
+ if (filename === 'json') {
2985
+ return over({ data: leaf.toJSON(options.json) });
2986
+ }
2987
+ else if (fileType === 'json') {
2988
+ download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2989
+ return over({ data: true });
2990
+ }
2991
+ if (filename === 'svg') {
2992
+ return over({ data: leaf.toSVG() });
2993
+ }
2994
+ else if (fileType === 'svg') {
2995
+ download(toURL(leaf.toSVG(), 'svg'), filename);
2996
+ return over({ data: true });
2997
+ }
2735
2998
  const { leafer } = leaf;
2736
2999
  if (leafer) {
3000
+ checkLazy(leaf);
2737
3001
  leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2738
- let quality, blob;
2739
- let { canvas } = leafer;
2740
- let { unreal } = canvas;
2741
- if (unreal) {
2742
- canvas = canvas.getSameCanvas();
2743
- canvas.backgroundColor = leafer.config.fill;
2744
- leafer.__render(canvas, {});
3002
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
3003
+ const { worldTransform, isLeafer, isFrame } = leaf;
3004
+ const { slice, trim, onCanvas } = options;
3005
+ let scale = options.scale || 1;
3006
+ let pixelRatio = options.pixelRatio || 1;
3007
+ const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
3008
+ const contextSettings = options.contextSettings || leafer.config.contextSettings;
3009
+ if (leaf.isApp) {
3010
+ scale *= pixelRatio;
3011
+ pixelRatio = leaf.app.pixelRatio;
3012
+ }
3013
+ const screenshot = options.screenshot || leaf.isApp;
3014
+ const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
3015
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
3016
+ if (screenshot) {
3017
+ renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2745
3018
  }
2746
- switch (typeof options) {
2747
- case 'object':
2748
- if (options.quality)
2749
- quality = options.quality;
2750
- if (options.blob)
2751
- blob = true;
2752
- break;
2753
- case 'number':
2754
- quality = options;
2755
- break;
2756
- case 'boolean':
2757
- blob = options;
3019
+ else {
3020
+ let relative = options.relative || (isLeafer ? 'inner' : 'local');
3021
+ scaleX = worldTransform.scaleX;
3022
+ scaleY = worldTransform.scaleY;
3023
+ switch (relative) {
3024
+ case 'inner':
3025
+ matrix.set(worldTransform);
3026
+ break;
3027
+ case 'local':
3028
+ matrix.set(worldTransform).divide(leaf.localTransform);
3029
+ scaleX /= leaf.scaleX;
3030
+ scaleY /= leaf.scaleY;
3031
+ break;
3032
+ case 'world':
3033
+ scaleX = 1;
3034
+ scaleY = 1;
3035
+ break;
3036
+ case 'page':
3037
+ relative = leaf.leafer;
3038
+ default:
3039
+ matrix.set(worldTransform).divide(leaf.getTransform(relative));
3040
+ const l = relative.worldTransform;
3041
+ scaleX /= scaleX / l.scaleX;
3042
+ scaleY /= scaleY / l.scaleY;
3043
+ }
3044
+ renderBounds = leaf.getBounds('render', relative);
2758
3045
  }
2759
- let data;
2760
- if (filename.includes('.')) {
2761
- data = yield canvas.saveAs(filename, quality);
3046
+ const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
3047
+ let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
3048
+ const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
3049
+ if (slice) {
3050
+ leaf = leafer;
3051
+ renderOptions.bounds = canvas.bounds;
2762
3052
  }
2763
- else if (blob) {
2764
- data = yield canvas.toBlob(filename, quality);
3053
+ canvas.save();
3054
+ if (isFrame && fill !== undefined) {
3055
+ const oldFill = leaf.get('fill');
3056
+ leaf.fill = '';
3057
+ leaf.__render(canvas, renderOptions);
3058
+ leaf.fill = oldFill;
2765
3059
  }
2766
3060
  else {
2767
- data = yield canvas.toDataURL(filename, quality);
3061
+ leaf.__render(canvas, renderOptions);
2768
3062
  }
2769
- success({ data });
2770
- resolve();
2771
- Export.running = false;
2772
- if (unreal)
2773
- canvas.recycle();
3063
+ canvas.restore();
3064
+ if (trim) {
3065
+ trimBounds = getTrimBounds(canvas);
3066
+ const old = canvas, { width, height } = trimBounds;
3067
+ const config = { x: 0, y: 0, width, height, pixelRatio };
3068
+ canvas = Creator.canvas(config);
3069
+ canvas.copyWorld(old, trimBounds, config);
3070
+ }
3071
+ if (needFill)
3072
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
3073
+ if (onCanvas)
3074
+ onCanvas(canvas);
3075
+ const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
3076
+ over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
2774
3077
  }));
2775
3078
  }
2776
3079
  else {
2777
- success({ data: false });
2778
- resolve();
2779
- Export.running = false;
3080
+ over({ data: false });
2780
3081
  }
2781
3082
  }));
2782
3083
  }
@@ -2789,13 +3090,64 @@ function addTask(task) {
2789
3090
  tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
2790
3091
  });
2791
3092
  }
3093
+ function checkLazy(leaf) {
3094
+ if (leaf.__.__needComputePaint)
3095
+ leaf.__.__computePaint();
3096
+ if (leaf.isBranch)
3097
+ leaf.children.forEach(child => checkLazy(child));
3098
+ }
3099
+
3100
+ const canvas = LeaferCanvasBase.prototype;
3101
+ const debug = Debug.get('@leafer-ui/export');
3102
+ canvas.export = function (filename, options) {
3103
+ const { quality, blob } = FileHelper.getExportOptions(options);
3104
+ if (filename.includes('.')) {
3105
+ return this.saveAs(filename, quality);
3106
+ }
3107
+ else if (blob) {
3108
+ return this.toBlob(filename, quality);
3109
+ }
3110
+ else {
3111
+ return this.toDataURL(filename, quality);
3112
+ }
3113
+ };
3114
+ canvas.toBlob = function (type, quality) {
3115
+ return new Promise((resolve) => {
3116
+ Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
3117
+ resolve(blob);
3118
+ }).catch((e) => {
3119
+ debug.error(e);
3120
+ resolve(null);
3121
+ });
3122
+ });
3123
+ };
3124
+ canvas.toDataURL = function (type, quality) {
3125
+ return Platform.origin.canvasToDataURL(this.view, type, quality);
3126
+ };
3127
+ canvas.saveAs = function (filename, quality) {
3128
+ return new Promise((resolve) => {
3129
+ Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
3130
+ resolve(true);
3131
+ }).catch((e) => {
3132
+ debug.error(e);
3133
+ resolve(false);
3134
+ });
3135
+ });
3136
+ };
2792
3137
 
2793
- Object.assign(Paint, UIPaint);
2794
- Object.assign(Effect, UIEffect);
2795
- Object.assign(TextConvert$1, TextConvert);
2796
- Object.assign(ColorConvert$1, ColorConvert);
2797
- Object.assign(Export$2, Export);
3138
+ Object.assign(TextConvert, TextConvertModule);
3139
+ Object.assign(ColorConvert, ColorConvertModule);
3140
+ Object.assign(Paint, PaintModule);
3141
+ Object.assign(PaintImage, PaintImageModule);
3142
+ Object.assign(PaintGradient, PaintGradientModule);
3143
+ Object.assign(Effect, EffectModule);
3144
+ Object.assign(Export, ExportModule);
2798
3145
 
3146
+ Object.assign(Creator, {
3147
+ interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
3148
+ hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
3149
+ hitCanvasManager: () => new HitCanvasManager()
3150
+ });
2799
3151
  useCanvas();
2800
3152
 
2801
3153
  export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };