leafer-ui 1.0.0-rc.9 → 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,180 +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
- this.parentView = this.view.parentElement;
837
- if (this.parentView)
838
- this.parentView.style.userSelect = 'none';
839
- if (Platform.syncDomFont && !this.parentView) {
840
- this.view.style.display = 'none';
841
- document.body.appendChild(this.view);
842
- }
843
- this.__createContext();
844
- if (!this.autoLayout)
845
- this.resize(this.config);
846
- }
847
- set backgroundColor(color) { this.view.style.backgroundColor = color; }
848
- get backgroundColor() { return this.view.style.backgroundColor; }
849
- set hittable(hittable) { this.view.style.pointerEvents = hittable ? 'auto' : 'none'; }
850
- get hittable() { return this.view.style.pointerEvents !== 'none'; }
851
- __createView() {
852
- this.view = document.createElement('canvas');
853
- }
854
- setCursor(cursor) {
855
- const list = [];
856
- this.eachCursor(cursor, list);
857
- if (typeof list[list.length - 1] === 'object')
858
- list.push('default');
859
- this.view.style.cursor = list.map(item => (typeof item === 'object') ? `url(${item.url}) ${item.x || 0} ${item.y || 0}` : item).join(',');
860
- }
861
- eachCursor(cursor, list, level = 0) {
862
- level++;
863
- if (cursor instanceof Array) {
864
- cursor.forEach(item => this.eachCursor(item, list, level));
865
- }
866
- else {
867
- const custom = typeof cursor === 'string' && Cursor.get(cursor);
868
- if (custom && level < 2) {
869
- this.eachCursor(custom, list, level);
870
- }
871
- else {
872
- list.push(cursor);
873
- }
874
- }
875
- }
876
- __createViewFrom(inputView) {
877
- let find = (typeof inputView === 'string') ? document.getElementById(inputView) : inputView;
878
- if (find) {
879
- if (find instanceof HTMLCanvasElement) {
880
- this.view = find;
881
- }
882
- else {
883
- let parent = find;
884
- if (find === window || find === document) {
885
- const div = document.createElement('div');
886
- const { style } = div;
887
- style.position = 'absolute';
888
- style.top = style.bottom = style.left = style.right = '0px';
889
- document.body.appendChild(div);
890
- parent = div;
891
- }
892
- this.__createView();
893
- const view = this.view;
894
- if (parent.hasChildNodes()) {
895
- const { style } = view;
896
- style.position = 'absolute';
897
- style.top = style.left = '0px';
898
- parent.style.position || (parent.style.position = 'relative');
899
- }
900
- parent.appendChild(view);
901
- }
902
- }
903
- else {
904
- debug.error(`no id: ${inputView}`);
905
- this.__createView();
906
- }
907
- }
908
- updateViewSize() {
909
- const { width, height, pixelRatio } = this;
910
- const { style } = this.view;
911
- style.width = width + 'px';
912
- style.height = height + 'px';
913
- this.view.width = width * pixelRatio;
914
- this.view.height = height * pixelRatio;
915
- }
916
- updateClientBounds() {
917
- this.clientBounds = this.view.getBoundingClientRect();
918
- }
919
- startAutoLayout(autoBounds, listener) {
920
- this.autoBounds = autoBounds;
921
- this.resizeListener = listener;
922
- try {
923
- this.resizeObserver = new ResizeObserver((entries) => {
924
- this.updateClientBounds();
925
- for (const entry of entries)
926
- this.checkAutoBounds(entry.contentRect);
927
- });
928
- const parent = this.parentView;
929
- if (parent) {
930
- this.resizeObserver.observe(parent);
931
- this.checkAutoBounds(parent.getBoundingClientRect());
932
- }
933
- }
934
- catch (_a) {
935
- this.imitateResizeObserver();
936
- }
937
- }
938
- imitateResizeObserver() {
939
- if (this.autoLayout) {
940
- if (this.parentView)
941
- this.checkAutoBounds(this.parentView.getBoundingClientRect());
942
- Platform.requestRender(this.imitateResizeObserver.bind(this));
943
- }
944
- }
945
- checkAutoBounds(parentSize) {
946
- const view = this.view;
947
- const { x, y, width, height } = this.autoBounds.getBoundsFrom(parentSize);
948
- if (width !== this.width || height !== this.height) {
949
- const { style } = view;
950
- const { pixelRatio } = this;
951
- style.marginLeft = x + 'px';
952
- style.marginTop = y + 'px';
953
- const size = { width, height, pixelRatio };
954
- const oldSize = {};
955
- DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs);
956
- this.resize(size);
957
- if (this.width !== undefined)
958
- this.resizeListener(new ResizeEvent(size, oldSize));
959
- }
960
- }
961
- stopAutoLayout() {
962
- this.autoLayout = false;
963
- this.resizeListener = null;
964
- if (this.resizeObserver) {
965
- this.resizeObserver.disconnect();
966
- this.resizeObserver = null;
967
- }
968
- }
969
- unrealCanvas() {
970
- if (!this.unreal && this.parentView) {
971
- const view = this.view;
972
- if (view)
973
- view.remove();
974
- this.view = this.parentView;
975
- this.unreal = true;
976
- }
977
- }
978
- destroy() {
979
- if (this.view) {
980
- this.stopAutoLayout();
981
- if (!this.unreal) {
982
- const view = this.view;
983
- if (view.parentElement)
984
- view.remove();
985
- }
986
- super.destroy();
987
- }
988
- }
989
- }
990
-
991
- canvasPatch(CanvasRenderingContext2D.prototype);
992
- canvasPatch(Path2D.prototype);
993
-
994
- const PointerEventHelper = {
995
- convert(e, local) {
996
- const base = InteractionHelper.getBase(e);
997
- 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 });
998
- if (data.pointerType === 'pen') {
999
- data.tangentialPressure = e.tangentialPressure;
1000
- data.tiltX = e.tiltX;
1001
- data.tiltY = e.tiltY;
1002
- 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;
1003
1114
  }
1004
1115
  return data;
1005
1116
  },
@@ -1047,7 +1158,7 @@ const WheelEventHelper = {
1047
1158
  if (zoom) {
1048
1159
  zoomSpeed = MathHelper.within(zoomSpeed, 0, 1);
1049
1160
  const min = e.deltaY ? config.delta.y : config.delta.x;
1050
- scale = 1 - delta / (min * 25 * (1 - zoomSpeed) + 10);
1161
+ scale = 1 - delta / (min * 4) * zoomSpeed;
1051
1162
  if (scale < 0.5)
1052
1163
  scale = 0.5;
1053
1164
  if (scale >= 1.5)
@@ -1115,12 +1226,6 @@ class Interaction extends InteractionBase {
1115
1226
  this.windowEvents = {};
1116
1227
  }
1117
1228
  }
1118
- getLocal(p, updateClient) {
1119
- if (updateClient)
1120
- this.canvas.updateClientBounds();
1121
- const { clientBounds } = this.canvas;
1122
- return { x: p.clientX - clientBounds.x, y: p.clientY - clientBounds.y };
1123
- }
1124
1229
  getTouches(touches) {
1125
1230
  const list = [];
1126
1231
  for (let i = 0, len = touches.length; i < len; i++) {
@@ -1148,6 +1253,8 @@ class Interaction extends InteractionBase {
1148
1253
  this.keyUp(KeyEventHelper.convert(e));
1149
1254
  }
1150
1255
  onContextMenu(e) {
1256
+ if (this.config.pointer.preventDefaultMenu)
1257
+ e.preventDefault();
1151
1258
  this.menu(PointerEventHelper.convert(e, this.getLocal(e)));
1152
1259
  }
1153
1260
  onScroll() {
@@ -1277,17 +1384,23 @@ class Interaction extends InteractionBase {
1277
1384
  onWheel(e) {
1278
1385
  this.preventDefaultWheel(e);
1279
1386
  const { wheel } = this.config;
1387
+ if (wheel.disabled)
1388
+ return;
1280
1389
  const scale = wheel.getScale ? wheel.getScale(e, wheel) : WheelEventHelper.getScale(e, wheel);
1281
1390
  const local = this.getLocal(e);
1282
1391
  const eventBase = InteractionHelper.getBase(e);
1283
1392
  scale !== 1 ? this.zoom(getZoomEventData(local, scale, eventBase)) : this.move(getMoveEventData(local, wheel.getMove ? wheel.getMove(e, wheel) : WheelEventHelper.getMove(e, wheel), eventBase));
1284
1393
  }
1285
1394
  onGesturestart(e) {
1395
+ if (this.useMultiTouch)
1396
+ return;
1286
1397
  this.preventDefaultWheel(e);
1287
1398
  this.lastGestureScale = 1;
1288
1399
  this.lastGestureRotation = 0;
1289
1400
  }
1290
1401
  onGesturechange(e) {
1402
+ if (this.useMultiTouch)
1403
+ return;
1291
1404
  this.preventDefaultWheel(e);
1292
1405
  const local = this.getLocal(e);
1293
1406
  const eventBase = InteractionHelper.getBase(e);
@@ -1301,9 +1414,34 @@ class Interaction extends InteractionBase {
1301
1414
  this.lastGestureRotation = e.rotation;
1302
1415
  }
1303
1416
  onGestureend(e) {
1417
+ if (this.useMultiTouch)
1418
+ return;
1304
1419
  this.preventDefaultWheel(e);
1305
1420
  this.transformEnd();
1306
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
+ }
1307
1445
  destroy() {
1308
1446
  if (this.view) {
1309
1447
  super.destroy();
@@ -1313,151 +1451,381 @@ class Interaction extends InteractionBase {
1313
1451
  }
1314
1452
  }
1315
1453
 
1316
- const { mineType, fileType } = FileHelper;
1317
- Object.assign(Creator, {
1318
- canvas: (options, manager) => new LeaferCanvas(options, manager),
1319
- image: (options) => new LeaferImage(options),
1320
- hitCanvas: (options, manager) => new LeaferCanvas(options, manager),
1321
- interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
1322
- });
1323
- function useCanvas(_canvasType, _power) {
1324
- Platform.origin = {
1325
- createCanvas(width, height) {
1326
- const canvas = document.createElement('canvas');
1327
- canvas.width = width;
1328
- canvas.height = height;
1329
- return canvas;
1330
- },
1331
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
1332
- canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
1333
- canvasSaveAs: (canvas, filename, quality) => {
1334
- return new Promise((resolve) => {
1335
- let el = document.createElement('a');
1336
- el.href = canvas.toDataURL(mineType(fileType(filename)), quality);
1337
- el.download = filename;
1338
- document.body.appendChild(el);
1339
- el.click();
1340
- document.body.removeChild(el);
1341
- resolve();
1342
- });
1343
- },
1344
- loadImage(src) {
1345
- return new Promise((resolve, reject) => {
1346
- const img = new Image();
1347
- img.setAttribute('crossOrigin', 'anonymous');
1348
- img.crossOrigin = 'anonymous';
1349
- img.onload = () => { resolve(img); };
1350
- img.onerror = (e) => { reject(e); };
1351
- if (!src.startsWith('data:') && Platform.image.suffix)
1352
- src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
1353
- 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);
1354
1465
  });
1355
1466
  }
1356
- };
1357
- Platform.event = {
1358
- stopDefault(origin) { origin.preventDefault(); },
1359
- stopNow(origin) { origin.stopImmediatePropagation(); },
1360
- stop(origin) { origin.stopPropagation(); }
1361
- };
1362
- Platform.canvas = Creator.canvas();
1363
- Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
1364
- }
1365
- Platform.name = 'web';
1366
- Platform.isMobile = 'ontouchstart' in window;
1367
- Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
1368
- Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
1369
- const { userAgent } = navigator;
1370
- if (userAgent.indexOf("Firefox") > -1) {
1371
- Platform.conicGradientRotate90 = true;
1372
- Platform.intWheelDeltaY = true;
1373
- Platform.syncDomFont = true;
1374
- }
1375
- else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
1376
- Platform.fullImageShadow = true;
1377
- }
1378
- if (userAgent.indexOf('Windows') > -1) {
1379
- Platform.os = 'Windows';
1380
- Platform.intWheelDeltaY = true;
1381
- }
1382
- else if (userAgent.indexOf('Mac') > -1) {
1383
- Platform.os = 'Mac';
1384
- }
1385
- else if (userAgent.indexOf('Linux') > -1) {
1386
- Platform.os = 'Linux';
1467
+ if (decorationY)
1468
+ canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1469
+ }
1387
1470
  }
1388
1471
 
1389
- let origin = {};
1390
- const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1391
- function fillOrFitMode(data, mode, box, width, height, rotation) {
1392
- const transform = get$4();
1393
- const swap = rotation && rotation !== 180;
1394
- const sw = box.width / (swap ? height : width);
1395
- const sh = box.height / (swap ? width : height);
1396
- const scale = mode === 'fit' ? Math.min(sw, sh) : Math.max(sw, sh);
1397
- const x = box.x + (box.width - width * scale) / 2;
1398
- const y = box.y + (box.height - height * scale) / 2;
1399
- translate$1(transform, x, y);
1400
- scaleHelper(transform, scale);
1401
- if (rotation)
1402
- rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1403
- data.scaleX = data.scaleY = scale;
1404
- 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());
1405
1475
  }
1406
- function clipMode(data, box, x, y, scaleX, scaleY, rotation) {
1407
- const transform = get$4();
1408
- translate$1(transform, box.x, box.y);
1409
- if (x || y)
1410
- translate$1(transform, x, y);
1411
- if (scaleX) {
1412
- scaleHelper(transform, scaleX, scaleY);
1413
- data.scaleX = transform.a;
1414
- data.scaleY = transform.d;
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
+ }
1505
+ }
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);
1612
+ break;
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);
1629
+ break;
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);
1652
+ break;
1653
+ }
1654
+ }
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;
1415
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);
1416
1769
  if (rotation)
1417
1770
  rotate(transform, rotation);
1418
1771
  data.transform = transform;
1419
1772
  }
1420
- function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation) {
1421
- const transform = get$4();
1773
+ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align) {
1774
+ const transform = get$3();
1422
1775
  if (rotation) {
1423
- rotate(transform, rotation);
1424
- switch (rotation) {
1425
- case 90:
1426
- translate$1(transform, height, 0);
1427
- break;
1428
- case 180:
1429
- translate$1(transform, width, height);
1430
- break;
1431
- case 270:
1432
- translate$1(transform, 0, width);
1433
- break;
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
+ }
1434
1792
  }
1435
1793
  }
1436
- origin.x = box.x;
1437
- origin.y = box.y;
1438
- if (x || y)
1439
- origin.x += x, origin.y += y;
1794
+ origin.x = box.x + x;
1795
+ origin.y = box.y + y;
1440
1796
  translate$1(transform, origin.x, origin.y);
1441
- if (scaleX) {
1442
- scaleOfOuter$2(transform, origin, scaleX, scaleY);
1443
- data.scaleX = scaleX;
1444
- data.scaleY = scaleY;
1445
- }
1797
+ if (scaleX)
1798
+ scaleOfOuter$1(transform, origin, scaleX, scaleY);
1446
1799
  data.transform = transform;
1447
1800
  }
1448
1801
 
1449
- const { get: get$3, translate } = MatrixHelper;
1802
+ const { get: get$2, translate } = MatrixHelper;
1803
+ const tempBox = new Bounds();
1804
+ const tempPoint = {};
1450
1805
  function createData(leafPaint, image, paint, box) {
1451
- let { width, height } = image;
1452
- const { opacity, mode, offset, scale, size, rotation, blendMode, repeat } = paint;
1453
- const sameBox = box.width === width && box.height === height;
1806
+ const { blendMode } = paint;
1454
1807
  if (blendMode)
1455
1808
  leafPaint.blendMode = blendMode;
1456
- const data = leafPaint.data = { mode };
1457
- let x, y, scaleX, scaleY;
1458
- if (offset)
1459
- x = offset.x, y = offset.y;
1460
- if (size) {
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) {
1461
1829
  scaleX = (typeof size === 'number' ? size : size.width) / width;
1462
1830
  scaleY = (typeof size === 'number' ? size : size.height) / height;
1463
1831
  }
@@ -1465,30 +1833,46 @@ function createData(leafPaint, image, paint, box) {
1465
1833
  scaleX = typeof scale === 'number' ? scale : scale.x;
1466
1834
  scaleY = typeof scale === 'number' ? scale : scale.y;
1467
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;
1468
1845
  switch (mode) {
1469
1846
  case 'strench':
1470
1847
  if (!sameBox)
1471
1848
  width = box.width, height = box.height;
1472
- if (box.x || box.y) {
1473
- data.transform = get$3();
1474
- translate(data.transform, box.x, box.y);
1475
- }
1476
1849
  break;
1850
+ case 'normal':
1477
1851
  case 'clip':
1478
- if (offset || scaleX || rotation)
1852
+ if (x || y || scaleX || rotation)
1479
1853
  clipMode(data, box, x, y, scaleX, scaleY, rotation);
1480
1854
  break;
1481
1855
  case 'repeat':
1482
1856
  if (!sameBox || scaleX || rotation)
1483
- repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation);
1857
+ repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, align);
1484
1858
  if (!repeat)
1485
1859
  data.repeat = 'repeat';
1486
1860
  break;
1487
1861
  case 'fit':
1488
1862
  case 'cover':
1489
1863
  default:
1490
- if (!sameBox || rotation)
1491
- 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;
1492
1876
  }
1493
1877
  data.width = width;
1494
1878
  data.height = height;
@@ -1496,112 +1880,108 @@ function createData(leafPaint, image, paint, box) {
1496
1880
  data.opacity = opacity;
1497
1881
  if (repeat)
1498
1882
  data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1883
+ return data;
1499
1884
  }
1500
1885
 
1501
- function image(ui, attrName, attrValue, box, firstUse) {
1502
- const leafPaint = { type: attrValue.type };
1503
- const image = leafPaint.image = ImageManager.get(attrValue);
1504
- 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 };
1505
1900
  if (image.ready) {
1506
- if (hasNaturalSize(ui, attrName, image))
1507
- createData(leafPaint, image, attrValue, box);
1901
+ checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds);
1508
1902
  if (firstUse) {
1509
- emit(ImageEvent.LOAD, event);
1510
- emit(ImageEvent.LOADED, event);
1903
+ onLoad(ui, event);
1904
+ onLoadSuccess(ui, event);
1511
1905
  }
1512
1906
  }
1513
1907
  else if (image.error) {
1514
- if (firstUse) {
1515
- ui.forceUpdate('surface');
1516
- event.error = image.error;
1517
- emit(ImageEvent.ERROR, event);
1518
- }
1908
+ if (firstUse)
1909
+ onLoadError(ui, event, image.error);
1519
1910
  }
1520
1911
  else {
1912
+ ignoreRender(ui, true);
1521
1913
  if (firstUse)
1522
- emit(ImageEvent.LOAD, event);
1914
+ onLoad(ui, event);
1523
1915
  leafPaint.loadId = image.load(() => {
1916
+ ignoreRender(ui, false);
1524
1917
  if (!ui.destroyed) {
1525
- if (hasNaturalSize(ui, attrName, image)) {
1526
- createData(leafPaint, image, attrValue, box);
1918
+ if (checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds)) {
1919
+ if (image.hasOpacityPixel)
1920
+ ui.__layout.hitCanvasChanged = true;
1527
1921
  ui.forceUpdate('surface');
1528
1922
  }
1529
- emit(ImageEvent.LOADED, event);
1923
+ onLoadSuccess(ui, event);
1530
1924
  }
1925
+ leafPaint.loadId = null;
1531
1926
  }, (error) => {
1532
- ui.forceUpdate('surface');
1533
- event.error = error;
1534
- emit(ImageEvent.ERROR, event);
1927
+ ignoreRender(ui, false);
1928
+ onLoadError(ui, event, error);
1929
+ leafPaint.loadId = null;
1535
1930
  });
1536
1931
  }
1537
1932
  return leafPaint;
1538
1933
  }
1539
- function hasNaturalSize(ui, attrName, image) {
1934
+ function checkSizeAndCreateData(ui, attrName, paint, image, leafPaint, boxBounds) {
1540
1935
  if (attrName === 'fill' && !ui.__.__naturalWidth) {
1541
- const { __: d } = ui;
1542
- d.__naturalWidth = image.width;
1543
- d.__naturalHeight = image.height;
1544
- 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) {
1545
1940
  ui.forceUpdate('width');
1546
1941
  if (ui.__proxyData) {
1547
- ui.setProxyAttr('width', ui.__.width);
1548
- ui.setProxyAttr('height', ui.__.height);
1942
+ ui.setProxyAttr('width', data.width);
1943
+ ui.setProxyAttr('height', data.height);
1549
1944
  }
1550
1945
  return false;
1551
1946
  }
1552
1947
  }
1948
+ if (!leafPaint.data)
1949
+ createData(leafPaint, image, paint, boxBounds);
1553
1950
  return true;
1554
1951
  }
1555
- function emit(type, data) {
1556
- if (data.target.hasEvent(type))
1557
- 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;
1558
1971
  }
1559
1972
 
1560
- /******************************************************************************
1561
- Copyright (c) Microsoft Corporation.
1562
-
1563
- Permission to use, copy, modify, and/or distribute this software for any
1564
- purpose with or without fee is hereby granted.
1565
-
1566
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
1567
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
1568
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
1569
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
1570
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
1571
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
1572
- PERFORMANCE OF THIS SOFTWARE.
1573
- ***************************************************************************** */
1574
- /* global Reflect, Promise, SuppressedError, Symbol */
1575
-
1576
-
1577
- function __awaiter(thisArg, _arguments, P, generator) {
1578
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
1579
- return new (P || (P = Promise))(function (resolve, reject) {
1580
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
1581
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
1582
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
1583
- step((generator = generator.apply(thisArg, _arguments || [])).next());
1584
- });
1585
- }
1586
-
1587
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
1588
- var e = new Error(message);
1589
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1590
- };
1591
-
1592
- const Export$1 = {};
1593
-
1594
- 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;
1595
1975
  function createPattern(ui, paint, pixelRatio) {
1596
- let { scaleX, scaleY } = ui.__world;
1976
+ let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1597
1977
  const id = scaleX + '-' + scaleY;
1598
1978
  if (paint.patternId !== id && !ui.destroyed) {
1599
- scaleX = Math.abs(scaleX);
1600
- scaleY = Math.abs(scaleY);
1979
+ scaleX = abs$1(scaleX);
1980
+ scaleY = abs$1(scaleY);
1601
1981
  const { image, data } = paint;
1602
1982
  let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1603
1983
  if (sx) {
1604
- imageMatrix = get$2();
1984
+ imageMatrix = get$1();
1605
1985
  copy$1(imageMatrix, transform);
1606
1986
  scale(imageMatrix, 1 / sx, 1 / sy);
1607
1987
  scaleX *= sx;
@@ -1636,22 +2016,14 @@ function createPattern(ui, paint, pixelRatio) {
1636
2016
  }
1637
2017
  if (transform || scaleX !== 1 || scaleY !== 1) {
1638
2018
  if (!imageMatrix) {
1639
- imageMatrix = get$2();
2019
+ imageMatrix = get$1();
1640
2020
  if (transform)
1641
2021
  copy$1(imageMatrix, transform);
1642
2022
  }
1643
2023
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1644
2024
  }
1645
- const pattern = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), repeat || (Platform.origin.noRepeat || 'no-repeat'));
1646
- try {
1647
- if (paint.transform)
1648
- paint.transform = null;
1649
- if (imageMatrix)
1650
- pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
1651
- }
1652
- catch (_a) {
1653
- paint.transform = imageMatrix;
1654
- }
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);
1655
2027
  paint.style = pattern;
1656
2028
  paint.patternId = id;
1657
2029
  return true;
@@ -1661,9 +2033,41 @@ function createPattern(ui, paint, pixelRatio) {
1661
2033
  }
1662
2034
  }
1663
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
+
1664
2068
  const { abs } = Math;
1665
2069
  function checkImage(ui, canvas, paint, allowPaint) {
1666
- const { scaleX, scaleY } = ui.__world;
2070
+ const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1667
2071
  if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1668
2072
  return false;
1669
2073
  }
@@ -1678,7 +2082,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1678
2082
  width *= data.scaleX;
1679
2083
  height *= data.scaleY;
1680
2084
  }
1681
- allowPaint = width * height > Platform.image.maxCacheSize;
2085
+ allowPaint = (width * height > Platform.image.maxCacheSize) || Export.running;
1682
2086
  }
1683
2087
  else {
1684
2088
  allowPaint = false;
@@ -1697,307 +2101,72 @@ function checkImage(ui, canvas, paint, allowPaint) {
1697
2101
  canvas.restore();
1698
2102
  return true;
1699
2103
  }
1700
- else {
1701
- if (!paint.style || Export$1.running) {
1702
- createPattern(ui, paint, canvas.pixelRatio);
1703
- }
1704
- else {
1705
- if (!paint.patternTask) {
1706
- paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1707
- paint.patternTask = null;
1708
- if (canvas.bounds.hit(ui.__world))
1709
- createPattern(ui, paint, canvas.pixelRatio);
1710
- ui.forceUpdate('surface');
1711
- }), 300);
1712
- }
1713
- }
1714
- return false;
1715
- }
1716
- }
1717
- }
1718
-
1719
- function recycleImage(attrName, data) {
1720
- const paints = data['_' + attrName];
1721
- if (paints instanceof Array) {
1722
- let image, recycleMap, input, url;
1723
- for (let i = 0, len = paints.length; i < len; i++) {
1724
- image = paints[i].image;
1725
- url = image && image.url;
1726
- if (url) {
1727
- if (!recycleMap)
1728
- recycleMap = {};
1729
- recycleMap[url] = true;
1730
- ImageManager.recycle(image);
1731
- if (image.loading) {
1732
- if (!input) {
1733
- input = (data.__input && data.__input[attrName]) || [];
1734
- if (!(input instanceof Array))
1735
- input = [input];
1736
- }
1737
- image.unload(paints[i].loadId, !input.some((item) => item.url === url));
1738
- }
1739
- }
1740
- }
1741
- return recycleMap;
1742
- }
1743
- return null;
1744
- }
1745
-
1746
- function fillText(ui, canvas) {
1747
- let row;
1748
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1749
- for (let i = 0, len = rows.length; i < len; i++) {
1750
- row = rows[i];
1751
- if (row.text) {
1752
- canvas.fillText(row.text, row.x, row.y);
1753
- }
1754
- else if (row.data) {
1755
- row.data.forEach(charData => {
1756
- canvas.fillText(charData.char, charData.x, row.y);
1757
- });
1758
- }
1759
- if (decorationY)
1760
- canvas.fillRect(row.x, row.y + decorationY, row.width, decorationHeight);
1761
- }
1762
- }
1763
-
1764
- function fill(fill, ui, canvas) {
1765
- canvas.fillStyle = fill;
1766
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill());
1767
- }
1768
- function fills(fills, ui, canvas) {
1769
- let item;
1770
- const { windingRule, __font } = ui.__;
1771
- for (let i = 0, len = fills.length; i < len; i++) {
1772
- item = fills[i];
1773
- if (item.image && checkImage(ui, canvas, item, !__font))
1774
- continue;
1775
- if (item.style) {
1776
- canvas.fillStyle = item.style;
1777
- if (item.transform) {
1778
- canvas.save();
1779
- canvas.transform(item.transform);
1780
- if (item.blendMode)
1781
- canvas.blendMode = item.blendMode;
1782
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1783
- canvas.restore();
1784
- }
1785
- else {
1786
- if (item.blendMode) {
1787
- canvas.saveBlendMode(item.blendMode);
1788
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1789
- canvas.restoreBlendMode();
1790
- }
1791
- else {
1792
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill());
1793
- }
1794
- }
1795
- }
1796
- }
1797
- }
1798
-
1799
- function strokeText(stroke, ui, canvas, renderOptions) {
1800
- const { strokeAlign } = ui.__;
1801
- const isStrokes = typeof stroke !== 'string';
1802
- switch (strokeAlign) {
1803
- case 'center':
1804
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__);
1805
- isStrokes ? drawStrokesStyle(stroke, true, ui, canvas) : drawTextStroke(ui, canvas);
1806
- break;
1807
- case 'inside':
1808
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas, renderOptions);
1809
- break;
1810
- case 'outside':
1811
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas, renderOptions);
1812
- break;
1813
- }
1814
- }
1815
- function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
1816
- const { strokeWidth, __font } = ui.__;
1817
- const out = canvas.getSameCanvas(true);
1818
- out.setStroke(isStrokes ? undefined : stroke, strokeWidth * 2, ui.__);
1819
- out.font = __font;
1820
- isStrokes ? drawStrokesStyle(stroke, true, ui, out) : drawTextStroke(ui, out);
1821
- out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1822
- fillText(ui, out);
1823
- out.blendMode = 'normal';
1824
- if (ui.__worldFlipped || renderOptions.matrix) {
1825
- canvas.copyWorldByReset(out);
1826
- }
1827
- else {
1828
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1829
- }
1830
- out.recycle();
1831
- }
1832
- function drawTextStroke(ui, canvas) {
1833
- let row;
1834
- const { rows, decorationY, decorationHeight } = ui.__.__textDrawData;
1835
- for (let i = 0, len = rows.length; i < len; i++) {
1836
- row = rows[i];
1837
- if (row.text) {
1838
- canvas.strokeText(row.text, row.x, row.y);
1839
- }
1840
- else if (row.data) {
1841
- row.data.forEach(charData => {
1842
- canvas.strokeText(charData.char, charData.x, row.y);
1843
- });
1844
- }
1845
- if (decorationY)
1846
- canvas.strokeRect(row.x, row.y + decorationY, row.width, decorationHeight);
1847
- }
1848
- }
1849
- function drawStrokesStyle(strokes, isText, ui, canvas) {
1850
- let item;
1851
- for (let i = 0, len = strokes.length; i < len; i++) {
1852
- item = strokes[i];
1853
- if (item.image && checkImage(ui, canvas, item, false))
1854
- continue;
1855
- if (item.style) {
1856
- canvas.strokeStyle = item.style;
1857
- if (item.blendMode) {
1858
- canvas.saveBlendMode(item.blendMode);
1859
- isText ? drawTextStroke(ui, canvas) : canvas.stroke();
1860
- canvas.restoreBlendMode();
2104
+ else {
2105
+ if (!paint.style || Export.running) {
2106
+ createPattern(ui, paint, canvas.pixelRatio);
1861
2107
  }
1862
2108
  else {
1863
- 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
+ }
1864
2117
  }
2118
+ return false;
1865
2119
  }
1866
2120
  }
1867
2121
  }
1868
2122
 
1869
- function stroke(stroke, ui, canvas, renderOptions) {
1870
- const options = ui.__;
1871
- const { strokeWidth, strokeAlign, __font } = options;
1872
- if (!strokeWidth)
1873
- return;
1874
- if (__font) {
1875
- strokeText(stroke, ui, canvas, renderOptions);
1876
- }
1877
- else {
1878
- switch (strokeAlign) {
1879
- case 'center':
1880
- canvas.setStroke(stroke, strokeWidth, options);
1881
- canvas.stroke();
1882
- break;
1883
- case 'inside':
1884
- canvas.save();
1885
- canvas.setStroke(stroke, strokeWidth * 2, options);
1886
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1887
- canvas.stroke();
1888
- canvas.restore();
1889
- break;
1890
- case 'outside':
1891
- const out = canvas.getSameCanvas(true);
1892
- out.setStroke(stroke, strokeWidth * 2, ui.__);
1893
- ui.__drawRenderPath(out);
1894
- out.stroke();
1895
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1896
- out.clearWorld(ui.__layout.renderBounds);
1897
- if (ui.__worldFlipped || renderOptions.matrix) {
1898
- canvas.copyWorldByReset(out);
1899
- }
1900
- else {
1901
- canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds);
1902
- }
1903
- out.recycle();
1904
- break;
1905
- }
1906
- }
1907
- }
1908
- function strokes(strokes, ui, canvas, renderOptions) {
1909
- const options = ui.__;
1910
- const { strokeWidth, strokeAlign, __font } = options;
1911
- if (!strokeWidth)
1912
- return;
1913
- if (__font) {
1914
- strokeText(strokes, ui, canvas, renderOptions);
1915
- }
1916
- else {
1917
- switch (strokeAlign) {
1918
- case 'center':
1919
- canvas.setStroke(undefined, strokeWidth, options);
1920
- drawStrokesStyle(strokes, false, ui, canvas);
1921
- break;
1922
- case 'inside':
1923
- canvas.save();
1924
- canvas.setStroke(undefined, strokeWidth * 2, options);
1925
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip();
1926
- drawStrokesStyle(strokes, false, ui, canvas);
1927
- canvas.restore();
1928
- break;
1929
- case 'outside':
1930
- const { renderBounds } = ui.__layout;
1931
- const out = canvas.getSameCanvas(true);
1932
- ui.__drawRenderPath(out);
1933
- out.setStroke(undefined, strokeWidth * 2, ui.__);
1934
- drawStrokesStyle(strokes, false, ui, out);
1935
- options.windingRule ? out.clip(options.windingRule) : out.clip();
1936
- out.clearWorld(renderBounds);
1937
- if (ui.__worldFlipped || renderOptions.matrix) {
1938
- canvas.copyWorldByReset(out);
1939
- }
1940
- else {
1941
- 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));
1942
2142
  }
1943
- out.recycle();
1944
- break;
2143
+ }
1945
2144
  }
2145
+ return recycleMap;
1946
2146
  }
2147
+ return null;
1947
2148
  }
1948
2149
 
1949
- const { getSpread, getOuterOf, getByMove, getIntersectData } = BoundsHelper;
1950
- function shape(ui, current, options) {
1951
- const canvas = current.getSameCanvas();
1952
- let bounds, matrix, shapeBounds;
1953
- let worldCanvas;
1954
- const { __world } = ui;
1955
- let { scaleX, scaleY } = __world;
1956
- if (scaleX < 0)
1957
- scaleX = -scaleX;
1958
- if (scaleY < 0)
1959
- scaleY = -scaleY;
1960
- if (!current.bounds.includes(__world, options.matrix)) {
1961
- const { renderShapeSpread: spread } = ui.__layout;
1962
- const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix);
1963
- matrix = current.bounds.getFitMatrix(worldClipBounds);
1964
- if (matrix.a < 1) {
1965
- worldCanvas = current.getSameCanvas();
1966
- ui.__renderShape(worldCanvas, options);
1967
- scaleX *= matrix.a;
1968
- scaleY *= matrix.d;
1969
- }
1970
- shapeBounds = getOuterOf(__world, matrix);
1971
- bounds = getByMove(shapeBounds, -matrix.e, -matrix.f);
1972
- if (options.matrix)
1973
- matrix.multiply(options.matrix);
1974
- options = Object.assign(Object.assign({}, options), { matrix });
1975
- }
1976
- else {
1977
- if (options.matrix) {
1978
- scaleX *= options.matrix.a;
1979
- scaleY *= options.matrix.d;
1980
- bounds = shapeBounds = getOuterOf(__world, options.matrix);
1981
- }
1982
- else {
1983
- bounds = shapeBounds = __world;
1984
- }
1985
- worldCanvas = canvas;
1986
- }
1987
- ui.__renderShape(canvas, options);
1988
- return {
1989
- canvas, matrix, bounds,
1990
- worldCanvas, shapeBounds, scaleX, scaleY
1991
- };
1992
- }
2150
+ const PaintImageModule = {
2151
+ image,
2152
+ checkImage,
2153
+ createPattern,
2154
+ recycleImage,
2155
+ createData,
2156
+ getPatternData,
2157
+ fillOrFitMode,
2158
+ clipMode,
2159
+ repeatMode
2160
+ };
1993
2161
 
1994
- const defaultFrom$2 = { x: 0.5, y: 0 };
1995
- const defaultTo$2 = { x: 0.5, y: 1 };
2162
+ const { toPoint: toPoint$2 } = AroundHelper;
2163
+ const realFrom$2 = {};
2164
+ const realTo$2 = {};
1996
2165
  function linearGradient(paint, box) {
1997
2166
  let { from, to, type, blendMode, opacity } = paint;
1998
- from || (from = defaultFrom$2);
1999
- to || (to = defaultTo$2);
2000
- 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);
2001
2170
  applyStops(style, paint.stops, opacity);
2002
2171
  const data = { type, style };
2003
2172
  if (blendMode)
@@ -2008,137 +2177,84 @@ function applyStops(gradient, stops, opacity) {
2008
2177
  let stop;
2009
2178
  for (let i = 0, len = stops.length; i < len; i++) {
2010
2179
  stop = stops[i];
2011
- 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
+ }
2012
2186
  }
2013
2187
  }
2014
2188
 
2015
- const { set: set$1, getAngle: getAngle$1, getDistance: getDistance$1 } = PointHelper;
2016
- const { get: get$1, rotateOfOuter: rotateOfOuter$1, scaleOfOuter: scaleOfOuter$1 } = MatrixHelper;
2017
- const defaultFrom$1 = { x: 0.5, y: 0.5 };
2018
- 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;
2019
2192
  const realFrom$1 = {};
2020
2193
  const realTo$1 = {};
2021
2194
  function radialGradient(paint, box) {
2022
2195
  let { from, to, type, opacity, blendMode, stretch } = paint;
2023
- from || (from = defaultFrom$1);
2024
- to || (to = defaultTo$1);
2025
- const { x, y, width, height } = box;
2026
- set$1(realFrom$1, x + from.x * width, y + from.y * height);
2027
- set$1(realTo$1, x + to.x * width, y + to.y * height);
2028
- let transform;
2029
- if (width !== height || stretch) {
2030
- transform = get$1();
2031
- scaleOfOuter$1(transform, realFrom$1, width / height * (stretch || 1), 1);
2032
- rotateOfOuter$1(transform, realFrom$1, getAngle$1(realFrom$1, realTo$1) + 90);
2033
- }
2196
+ toPoint$1(from || 'center', box, realFrom$1);
2197
+ toPoint$1(to || 'bottom', box, realTo$1);
2034
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));
2035
2199
  applyStops(style, paint.stops, opacity);
2036
- 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;
2037
2204
  if (blendMode)
2038
2205
  data.blendMode = blendMode;
2039
2206
  return data;
2040
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
+ }
2041
2225
 
2042
- const { set, getAngle, getDistance } = PointHelper;
2043
- const { get, rotateOfOuter, scaleOfOuter } = MatrixHelper;
2044
- const defaultFrom = { x: 0.5, y: 0.5 };
2045
- const defaultTo = { x: 0.5, y: 1 };
2226
+ const { getDistance } = PointHelper;
2227
+ const { toPoint } = AroundHelper;
2046
2228
  const realFrom = {};
2047
2229
  const realTo = {};
2048
2230
  function conicGradient(paint, box) {
2049
2231
  let { from, to, type, opacity, blendMode, stretch } = paint;
2050
- from || (from = defaultFrom);
2051
- to || (to = defaultTo);
2052
- const { x, y, width, height } = box;
2053
- set(realFrom, x + from.x * width, y + from.y * height);
2054
- set(realTo, x + to.x * width, y + to.y * height);
2055
- const transform = get();
2056
- const angle = getAngle(realFrom, realTo);
2057
- if (Platform.conicGradientRotate90) {
2058
- scaleOfOuter(transform, realFrom, width / height * (stretch || 1), 1);
2059
- rotateOfOuter(transform, realFrom, angle + 90);
2060
- }
2061
- else {
2062
- scaleOfOuter(transform, realFrom, 1, width / height * (stretch || 1));
2063
- rotateOfOuter(transform, realFrom, angle);
2064
- }
2232
+ toPoint(from || 'center', box, realFrom);
2233
+ toPoint(to || 'bottom', box, realTo);
2065
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));
2066
2235
  applyStops(style, paint.stops, opacity);
2067
- 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;
2068
2240
  if (blendMode)
2069
2241
  data.blendMode = blendMode;
2070
2242
  return data;
2071
2243
  }
2072
2244
 
2073
- let recycleMap;
2074
- function compute(attrName, ui) {
2075
- const value = [];
2076
- const data = ui.__;
2077
- let item;
2078
- let paints = data.__input[attrName];
2079
- if (!(paints instanceof Array))
2080
- paints = [paints];
2081
- recycleMap = recycleImage(attrName, data);
2082
- for (let i = 0, len = paints.length; i < len; i++) {
2083
- item = getLeafPaint(attrName, paints[i], ui);
2084
- if (item)
2085
- value.push(item);
2086
- }
2087
- data['_' + attrName] = value.length ? value : undefined;
2088
- let isPixel;
2089
- if (paints.length === 1) {
2090
- const paint = paints[0];
2091
- if (paint.type === 'image')
2092
- isPixel = ImageManager$1.isPixel(paint);
2093
- }
2094
- if (attrName === 'fill') {
2095
- data.__pixelFill = isPixel;
2096
- }
2097
- else {
2098
- data.__pixelStroke = isPixel;
2099
- }
2100
- }
2101
- function getLeafPaint(attrName, paint, ui) {
2102
- if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0)
2103
- return undefined;
2104
- const { boxBounds } = ui.__layout;
2105
- switch (paint.type) {
2106
- case 'solid':
2107
- let { type, blendMode, color, opacity } = paint;
2108
- return { type, blendMode, style: ColorConvert$1.string(color, opacity) };
2109
- case 'image':
2110
- return image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url]);
2111
- case 'linear':
2112
- return linearGradient(paint, boxBounds);
2113
- case 'radial':
2114
- return radialGradient(paint, boxBounds);
2115
- case 'angular':
2116
- return conicGradient(paint, boxBounds);
2117
- default:
2118
- return paint.r ? { type: 'solid', style: ColorConvert$1.string(paint) } : undefined;
2119
- }
2120
- }
2121
-
2122
- var UIPaint = /*#__PURE__*/Object.freeze({
2123
- __proto__: null,
2124
- compute: compute,
2125
- drawTextStroke: drawTextStroke,
2126
- fill: fill,
2127
- fillText: fillText,
2128
- fills: fills,
2129
- recycleImage: recycleImage,
2130
- shape: shape,
2131
- stroke: stroke,
2132
- strokeText: strokeText,
2133
- strokes: strokes
2134
- });
2245
+ const PaintGradientModule = {
2246
+ linearGradient,
2247
+ radialGradient,
2248
+ conicGradient,
2249
+ getTransform
2250
+ };
2135
2251
 
2136
2252
  const { copy, toOffsetOutBounds: toOffsetOutBounds$1 } = BoundsHelper;
2137
2253
  const tempBounds = {};
2138
2254
  const offsetOutBounds$1 = {};
2139
- function shadow(ui, current, shape, renderOptions) {
2255
+ function shadow(ui, current, shape) {
2140
2256
  let copyBounds, spreadScale;
2141
- const { __world, __layout } = ui;
2257
+ const { __nowWorld: nowWorld, __layout } = ui;
2142
2258
  const { shadow } = ui.__;
2143
2259
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2144
2260
  const other = current.getSameCanvas();
@@ -2153,21 +2269,21 @@ function shadow(ui, current, shape, renderOptions) {
2153
2269
  other.restore();
2154
2270
  other.save();
2155
2271
  if (worldCanvas) {
2156
- other.copyWorld(other, bounds, __world, 'copy');
2157
- copyBounds = __world;
2272
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2273
+ copyBounds = nowWorld;
2158
2274
  }
2159
- 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');
2160
2276
  }
2161
- if (ui.__worldFlipped || renderOptions.matrix) {
2162
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2277
+ if (ui.__worldFlipped) {
2278
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2163
2279
  }
2164
2280
  else {
2165
2281
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2166
2282
  }
2167
2283
  if (end && index < end)
2168
- other.clear();
2284
+ other.clearWorld(copyBounds, true);
2169
2285
  });
2170
- other.recycle();
2286
+ other.recycle(copyBounds);
2171
2287
  }
2172
2288
  function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2173
2289
  const { bounds, shapeBounds } = shape;
@@ -2198,9 +2314,9 @@ function drawWorldShadow(canvas, outBounds, spreadScale, shape) {
2198
2314
 
2199
2315
  const { toOffsetOutBounds } = BoundsHelper;
2200
2316
  const offsetOutBounds = {};
2201
- function innerShadow(ui, current, shape, renderOptions) {
2317
+ function innerShadow(ui, current, shape) {
2202
2318
  let copyBounds, spreadScale;
2203
- const { __world, __layout: __layout } = ui;
2319
+ const { __nowWorld: nowWorld, __layout: __layout } = ui;
2204
2320
  const { innerShadow } = ui.__;
2205
2321
  const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
2206
2322
  const other = current.getSameCanvas();
@@ -2213,40 +2329,115 @@ function innerShadow(ui, current, shape, renderOptions) {
2213
2329
  drawWorldShadow(other, offsetOutBounds, spreadScale, shape);
2214
2330
  other.restore();
2215
2331
  if (worldCanvas) {
2216
- other.copyWorld(other, bounds, __world, 'copy');
2217
- other.copyWorld(worldCanvas, __world, __world, 'source-out');
2218
- copyBounds = __world;
2332
+ other.copyWorld(other, bounds, nowWorld, 'copy');
2333
+ other.copyWorld(worldCanvas, nowWorld, nowWorld, 'source-out');
2334
+ copyBounds = nowWorld;
2219
2335
  }
2220
2336
  else {
2221
2337
  other.copyWorld(shape.canvas, shapeBounds, bounds, 'source-out');
2222
2338
  copyBounds = bounds;
2223
2339
  }
2224
2340
  other.fillWorld(copyBounds, item.color, 'source-in');
2225
- if (ui.__worldFlipped || renderOptions.matrix) {
2226
- current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2341
+ if (ui.__worldFlipped) {
2342
+ current.copyWorldByReset(other, copyBounds, nowWorld, item.blendMode);
2227
2343
  }
2228
2344
  else {
2229
2345
  current.copyWorldToInner(other, copyBounds, __layout.renderBounds, item.blendMode);
2230
2346
  }
2231
2347
  if (end && index < end)
2232
- other.clear();
2348
+ other.clearWorld(copyBounds, true);
2233
2349
  });
2234
- other.recycle();
2350
+ other.recycle(copyBounds);
2235
2351
  }
2236
2352
 
2237
2353
  function blur(ui, current, origin) {
2238
2354
  const { blur } = ui.__;
2239
- origin.setWorldBlur(blur * ui.__world.a);
2240
- origin.copyWorldToInner(current, ui.__world, ui.__layout.renderBounds);
2355
+ origin.setWorldBlur(blur * ui.__nowWorld.a);
2356
+ origin.copyWorldToInner(current, ui.__nowWorld, ui.__layout.renderBounds);
2241
2357
  origin.filter = 'none';
2242
2358
  }
2243
2359
 
2244
- var UIEffect = /*#__PURE__*/Object.freeze({
2245
- __proto__: null,
2246
- blur: blur,
2247
- innerShadow: innerShadow,
2248
- shadow: shadow
2249
- });
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
+ }
2250
2441
 
2251
2442
  const money = '¥¥$€££¢¢';
2252
2443
  const letter = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
@@ -2403,7 +2594,8 @@ function createRows(drawData, content, style) {
2403
2594
  if (breakAll) {
2404
2595
  if (wordWidth)
2405
2596
  addWord();
2406
- addRow();
2597
+ if (rowWidth)
2598
+ addRow();
2407
2599
  }
2408
2600
  else {
2409
2601
  if (!afterBreak)
@@ -2411,10 +2603,12 @@ function createRows(drawData, content, style) {
2411
2603
  if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2412
2604
  if (wordWidth)
2413
2605
  addWord();
2414
- addRow();
2606
+ if (rowWidth)
2607
+ addRow();
2415
2608
  }
2416
2609
  else {
2417
- addRow();
2610
+ if (rowWidth)
2611
+ addRow();
2418
2612
  }
2419
2613
  }
2420
2614
  }
@@ -2509,11 +2703,11 @@ function layoutChar(drawData, style, width, _height) {
2509
2703
  if (mode === WordMode) {
2510
2704
  wordChar = { char: '', x: charX };
2511
2705
  charX = toWordChar(word.data, charX, wordChar);
2512
- if (wordChar.char !== ' ')
2706
+ if (row.isOverflow || wordChar.char !== ' ')
2513
2707
  row.data.push(wordChar);
2514
2708
  }
2515
2709
  else {
2516
- charX = toChar(word.data, charX, row.data);
2710
+ charX = toChar(word.data, charX, row.data, row.isOverflow);
2517
2711
  }
2518
2712
  if (!row.paraEnd && addWordWidth) {
2519
2713
  charX += addWordWidth;
@@ -2540,9 +2734,9 @@ function toWordChar(data, charX, wordChar) {
2540
2734
  });
2541
2735
  return charX;
2542
2736
  }
2543
- function toChar(data, charX, rowData) {
2737
+ function toChar(data, charX, rowData, isOverflow) {
2544
2738
  data.forEach(char => {
2545
- if (char.char !== ' ') {
2739
+ if (isOverflow || char.char !== ' ') {
2546
2740
  char.x = charX;
2547
2741
  rowData.push(char);
2548
2742
  }
@@ -2574,12 +2768,14 @@ function layoutText(drawData, style) {
2574
2768
  for (let i = 0, len = rows.length; i < len; i++) {
2575
2769
  row = rows[i];
2576
2770
  row.x = x;
2577
- switch (textAlign) {
2578
- case 'center':
2579
- row.x += (width - row.width) / 2;
2580
- break;
2581
- case 'right':
2582
- 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
+ }
2583
2779
  }
2584
2780
  if (row.paraStart && paraSpacing && i > 0)
2585
2781
  starY += paraSpacing;
@@ -2615,16 +2811,20 @@ function layoutText(drawData, style) {
2615
2811
  bounds.height = realHeight;
2616
2812
  }
2617
2813
 
2618
- function clipText(drawData, style) {
2814
+ function clipText(drawData, style, x, width) {
2815
+ if (!width)
2816
+ return;
2619
2817
  const { rows, overflow } = drawData;
2620
2818
  let { textOverflow } = style;
2621
2819
  rows.splice(overflow);
2622
- if (textOverflow !== 'hide') {
2623
- if (textOverflow === 'ellipsis')
2820
+ if (textOverflow && textOverflow !== 'show') {
2821
+ if (textOverflow === 'hide')
2822
+ textOverflow = '';
2823
+ else if (textOverflow === 'ellipsis')
2624
2824
  textOverflow = '...';
2625
2825
  let char, charRight;
2626
- const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2627
- const right = style.x + style.width - ellipsisWidth;
2826
+ const ellipsisWidth = textOverflow ? Platform.canvas.measureText(textOverflow).width : 0;
2827
+ const right = x + width - ellipsisWidth;
2628
2828
  const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2629
2829
  list.forEach(row => {
2630
2830
  if (row.isOverflow && row.data) {
@@ -2671,42 +2871,40 @@ function decorationText(drawData, style) {
2671
2871
  }
2672
2872
 
2673
2873
  const { top, right, bottom, left } = Direction4;
2674
- const TextConvert = {
2675
- getDrawData(content, style) {
2676
- if (typeof content !== 'string')
2677
- content = String(content);
2678
- let x = 0, y = 0;
2679
- let width = style.__getInput('width') || 0;
2680
- let height = style.__getInput('height') || 0;
2681
- const { textDecoration, __font, __padding: padding } = style;
2682
- if (padding) {
2683
- if (width) {
2684
- x = padding[left];
2685
- width -= (padding[right] + padding[left]);
2686
- }
2687
- if (height) {
2688
- y = padding[top];
2689
- height -= (padding[top] + padding[bottom]);
2690
- }
2691
- }
2692
- const drawData = {
2693
- bounds: { x, y, width, height },
2694
- rows: [],
2695
- paraNumber: 0,
2696
- font: Platform.canvas.font = __font
2697
- };
2698
- createRows(drawData, content, style);
2699
- if (padding)
2700
- padAutoText(padding, drawData, style, width, height);
2701
- layoutText(drawData, style);
2702
- layoutChar(drawData, style, width);
2703
- if (drawData.overflow)
2704
- clipText(drawData, style);
2705
- if (textDecoration !== 'none')
2706
- decorationText(drawData, style);
2707
- return drawData;
2708
- }
2709
- };
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
+ }
2710
2908
  function padAutoText(padding, drawData, style, width, height) {
2711
2909
  if (!width) {
2712
2910
  switch (style.textAlign) {
@@ -2734,67 +2932,152 @@ function offsetText(drawData, attrName, value) {
2734
2932
  rows[i][attrName] += value;
2735
2933
  }
2736
2934
 
2737
- const ColorConvert = {
2738
- string(color, opacity) {
2739
- if (typeof color === 'string')
2740
- return color;
2741
- let a = color.a === undefined ? 1 : color.a;
2742
- if (opacity)
2743
- a *= opacity;
2744
- const rgb = color.r + ',' + color.g + ',' + color.b;
2745
- return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
2746
- }
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
2747
2951
  };
2748
2952
 
2749
- 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 = {
2750
2972
  export(leaf, filename, options) {
2751
- Export.running = true;
2973
+ this.running = true;
2974
+ const fileType = FileHelper.fileType(filename);
2975
+ options = FileHelper.getExportOptions(options);
2752
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
+ }
2753
2998
  const { leafer } = leaf;
2754
2999
  if (leafer) {
3000
+ checkLazy(leaf);
2755
3001
  leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2756
- let quality, blob;
2757
- let { canvas } = leafer;
2758
- let { unreal } = canvas;
2759
- if (unreal) {
2760
- canvas = canvas.getSameCanvas();
2761
- canvas.backgroundColor = leafer.config.fill;
2762
- 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;
2763
3018
  }
2764
- switch (typeof options) {
2765
- case 'object':
2766
- if (options.quality)
2767
- quality = options.quality;
2768
- if (options.blob)
2769
- blob = true;
2770
- break;
2771
- case 'number':
2772
- quality = options;
2773
- break;
2774
- case 'boolean':
2775
- 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);
2776
3045
  }
2777
- let data;
2778
- if (filename.includes('.')) {
2779
- 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;
2780
3052
  }
2781
- else if (blob) {
2782
- 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;
2783
3059
  }
2784
3060
  else {
2785
- data = yield canvas.toDataURL(filename, quality);
3061
+ leaf.__render(canvas, renderOptions);
2786
3062
  }
2787
- success({ data });
2788
- resolve();
2789
- Export.running = false;
2790
- if (unreal)
2791
- 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 });
2792
3077
  }));
2793
3078
  }
2794
3079
  else {
2795
- success({ data: false });
2796
- resolve();
2797
- Export.running = false;
3080
+ over({ data: false });
2798
3081
  }
2799
3082
  }));
2800
3083
  }
@@ -2807,13 +3090,64 @@ function addTask(task) {
2807
3090
  tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
2808
3091
  });
2809
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
+ };
2810
3137
 
2811
- Object.assign(Paint, UIPaint);
2812
- Object.assign(Effect, UIEffect);
2813
- Object.assign(TextConvert$1, TextConvert);
2814
- Object.assign(ColorConvert$1, ColorConvert);
2815
- 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);
2816
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
+ });
2817
3151
  useCanvas();
2818
3152
 
2819
3153
  export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };