leafer-ui 1.0.0-rc.5 → 1.0.0-rc.7

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,7 +1,7 @@
1
- import { LeafList, DataHelper, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, BoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, Platform, AnimateEvent, ResizeEvent, Creator, LeaferCanvasBase, Cursor, canvasSizeAttrs, canvasPatch, InteractionHelper, MathHelper, InteractionBase, LeaferImage, FileHelper, MatrixHelper, ImageEvent, PointHelper, TaskProcessor } from '@leafer/core';
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, TaskProcessor } 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$1 } from '@leafer-ui/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';
5
5
  export * from '@leafer-ui/core';
6
6
 
7
7
  class Watcher {
@@ -10,7 +10,7 @@ class Watcher {
10
10
  if (this.hasRemove) {
11
11
  const updatedList = new LeafList();
12
12
  this.__updatedList.list.forEach(item => { if (item.leafer)
13
- updatedList.push(item); });
13
+ updatedList.add(item); });
14
14
  return updatedList;
15
15
  }
16
16
  else {
@@ -45,7 +45,7 @@ class Watcher {
45
45
  this.target.emit(RenderEvent.REQUEST);
46
46
  }
47
47
  __onAttrChange(event) {
48
- this.__updatedList.push(event.target);
48
+ this.__updatedList.add(event.target);
49
49
  this.update();
50
50
  }
51
51
  __onChildEvent(event) {
@@ -55,12 +55,12 @@ class Watcher {
55
55
  }
56
56
  else {
57
57
  this.hasRemove = true;
58
- this.__updatedList.push(event.parent);
58
+ this.__updatedList.add(event.parent);
59
59
  }
60
60
  this.update();
61
61
  }
62
62
  __pushChild(child) {
63
- this.__updatedList.push(child);
63
+ this.__updatedList.add(child);
64
64
  if (child.isBranch)
65
65
  this.__loopChildren(child);
66
66
  }
@@ -99,7 +99,7 @@ class Watcher {
99
99
  }
100
100
  }
101
101
 
102
- const { updateAllWorldMatrix: updateAllWorldMatrix$1, updateAllWorldOpacity } = LeafHelper;
102
+ const { updateAllMatrix: updateAllMatrix$1, updateBounds: updateOneBounds, updateAllWorldOpacity } = LeafHelper;
103
103
  const { pushAllChildBranch, pushAllParent } = BranchHelper;
104
104
  function updateMatrix(updateList, levelList) {
105
105
  let layout;
@@ -107,14 +107,14 @@ function updateMatrix(updateList, levelList) {
107
107
  layout = leaf.__layout;
108
108
  if (levelList.without(leaf) && !layout.proxyZoom) {
109
109
  if (layout.matrixChanged) {
110
- updateAllWorldMatrix$1(leaf);
111
- levelList.push(leaf);
110
+ updateAllMatrix$1(leaf, true);
111
+ levelList.add(leaf);
112
112
  if (leaf.isBranch)
113
113
  pushAllChildBranch(leaf, levelList);
114
114
  pushAllParent(leaf, levelList);
115
115
  }
116
116
  else if (layout.boundsChanged) {
117
- levelList.push(leaf);
117
+ levelList.add(leaf);
118
118
  if (leaf.isBranch)
119
119
  leaf.__tempNumber = 0;
120
120
  pushAllParent(leaf, levelList);
@@ -123,20 +123,21 @@ function updateMatrix(updateList, levelList) {
123
123
  });
124
124
  }
125
125
  function updateBounds(boundsList) {
126
- let itemList, branch;
126
+ let list, branch, children;
127
127
  boundsList.sort(true);
128
128
  boundsList.levels.forEach(level => {
129
- itemList = boundsList.levelMap[level];
130
- for (let i = 0, len = itemList.length; i < len; i++) {
131
- branch = itemList[i];
129
+ list = boundsList.levelMap[level];
130
+ for (let i = 0, len = list.length; i < len; i++) {
131
+ branch = list[i];
132
132
  if (branch.isBranch && branch.__tempNumber) {
133
- for (let j = 0, jLen = branch.children.length; j < jLen; j++) {
134
- if (!branch.children[j].isBranch) {
135
- branch.children[j].__updateWorldBounds();
133
+ children = branch.children;
134
+ for (let j = 0, jLen = children.length; j < jLen; j++) {
135
+ if (!children[j].isBranch) {
136
+ updateOneBounds(children[j]);
136
137
  }
137
138
  }
138
139
  }
139
- branch.__updateWorldBounds();
140
+ updateOneBounds(branch);
140
141
  }
141
142
  });
142
143
  }
@@ -149,7 +150,7 @@ function updateChange(updateList) {
149
150
  }
150
151
 
151
152
  const { worldBounds } = LeafBoundsHelper;
152
- const { setByListWithHandle } = BoundsHelper;
153
+ const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
153
154
  class LayoutBlockData {
154
155
  constructor(list) {
155
156
  this.updatedBounds = new Bounds();
@@ -160,14 +161,20 @@ class LayoutBlockData {
160
161
  this.updatedList = list;
161
162
  }
162
163
  setBefore() {
163
- setByListWithHandle(this.beforeBounds, this.updatedList.list, worldBounds);
164
+ this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
164
165
  }
165
166
  setAfter() {
166
- setByListWithHandle(this.afterBounds, this.updatedList.list, worldBounds);
167
- this.updatedBounds.setByList([this.beforeBounds, this.afterBounds]);
167
+ const { list } = this.updatedList;
168
+ if (list.some(leaf => leaf.noBounds)) {
169
+ this.afterBounds.set(bigBounds);
170
+ }
171
+ else {
172
+ this.afterBounds.setListWithFn(list, worldBounds);
173
+ }
174
+ this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
168
175
  }
169
176
  merge(data) {
170
- this.updatedList.pushList(data.updatedList.list);
177
+ this.updatedList.addList(data.updatedList.list);
171
178
  this.beforeBounds.add(data.beforeBounds);
172
179
  this.afterBounds.add(data.afterBounds);
173
180
  this.updatedBounds.add(data.updatedBounds);
@@ -177,8 +184,7 @@ class LayoutBlockData {
177
184
  }
178
185
  }
179
186
 
180
- const { updateAllWorldMatrix, updateAllChange } = LeafHelper;
181
- const { pushAllBranchStack, updateWorldBoundsByBranchStack } = BranchHelper;
187
+ const { updateAllMatrix, updateAllChange } = LeafHelper;
182
188
  const debug$2 = Debug.get('Layouter');
183
189
  class Layouter {
184
190
  constructor(target, userConfig) {
@@ -255,12 +261,15 @@ class Layouter {
255
261
  const { target, __updatedList: updateList } = this;
256
262
  const { BEFORE, LAYOUT, AFTER } = LayoutEvent;
257
263
  const blocks = this.getBlocks(updateList);
258
- blocks.forEach(item => { item.setBefore(); });
264
+ blocks.forEach(item => item.setBefore());
259
265
  target.emitEvent(new LayoutEvent(BEFORE, blocks, this.times));
266
+ this.extraBlock = null;
260
267
  updateList.sort();
261
268
  updateMatrix(updateList, this.__levelList);
262
269
  updateBounds(this.__levelList);
263
270
  updateChange(updateList);
271
+ if (this.extraBlock)
272
+ blocks.push(this.extraBlock);
264
273
  blocks.forEach(item => item.setAfter());
265
274
  target.emitEvent(new LayoutEvent(LAYOUT, blocks, this.times));
266
275
  target.emitEvent(new LayoutEvent(AFTER, blocks, this.times));
@@ -283,17 +292,20 @@ class Layouter {
283
292
  Run.end(t);
284
293
  }
285
294
  static fullLayout(target) {
286
- updateAllWorldMatrix(target);
295
+ updateAllMatrix(target, true);
287
296
  if (target.isBranch) {
288
- const branchStack = [target];
289
- pushAllBranchStack(target, branchStack);
290
- updateWorldBoundsByBranchStack(branchStack);
297
+ BranchHelper.updateBounds(target);
291
298
  }
292
299
  else {
293
- target.__updateWorldBounds();
300
+ LeafHelper.updateBounds(target);
294
301
  }
295
302
  updateAllChange(target);
296
303
  }
304
+ addExtra(leaf) {
305
+ const block = this.extraBlock || (this.extraBlock = new LayoutBlockData([]));
306
+ block.updatedList.add(leaf);
307
+ block.beforeBounds.add(leaf.__world);
308
+ }
297
309
  createBlock(data) {
298
310
  return new LayoutBlockData(data);
299
311
  }
@@ -321,8 +333,7 @@ class Layouter {
321
333
  if (this.target) {
322
334
  this.stop();
323
335
  this.__removeListenEvents();
324
- this.target = null;
325
- this.config = null;
336
+ this.target = this.config = null;
326
337
  }
327
338
  }
328
339
  }
@@ -433,7 +444,7 @@ class Renderer {
433
444
  const { canvas } = this;
434
445
  const bounds = block.getIntersect(canvas.bounds);
435
446
  const includes = block.includes(this.target.__world);
436
- const realBounds = new Bounds().copy(bounds);
447
+ const realBounds = new Bounds(bounds);
437
448
  canvas.save();
438
449
  if (includes && !Debug.showRepaint) {
439
450
  canvas.clear();
@@ -483,7 +494,7 @@ class Renderer {
483
494
  const { updateBlocks: list } = this;
484
495
  if (list) {
485
496
  const bounds = new Bounds();
486
- bounds.setByList(list);
497
+ bounds.setList(list);
487
498
  list.length = 0;
488
499
  list.push(bounds);
489
500
  }
@@ -523,7 +534,7 @@ class Renderer {
523
534
  empty = (!leaf.__world.width || !leaf.__world.height);
524
535
  if (empty) {
525
536
  if (!leaf.isLeafer)
526
- debug$1.warn(leaf.innerName, ': empty');
537
+ debug$1.tip(leaf.innerName, ': empty');
527
538
  empty = (!leaf.isBranch || leaf.isBranchLeaf);
528
539
  }
529
540
  return empty;
@@ -557,8 +568,16 @@ class Renderer {
557
568
  }
558
569
  }
559
570
 
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
+
560
579
  const { hitRadiusPoint } = BoundsHelper;
561
- class FindPath {
580
+ class Pather {
562
581
  constructor(target, selector) {
563
582
  this.target = target;
564
583
  this.selector = selector;
@@ -601,10 +620,10 @@ class FindPath {
601
620
  getPath(leaf) {
602
621
  const path = new LeafList();
603
622
  while (leaf) {
604
- path.push(leaf);
623
+ path.add(leaf);
605
624
  leaf = leaf.parent;
606
625
  }
607
- path.push(this.target);
626
+ path.add(this.target);
608
627
  return path;
609
628
  }
610
629
  getHitablePath(leaf) {
@@ -614,7 +633,7 @@ class FindPath {
614
633
  item = path.list[i];
615
634
  if (!item.__.hittable)
616
635
  break;
617
- hittablePath.unshift(item);
636
+ hittablePath.addAt(item, 0);
618
637
  if (!item.__.hitChildren)
619
638
  break;
620
639
  }
@@ -633,7 +652,7 @@ class FindPath {
633
652
  leaf = path.list[j];
634
653
  if (nextPath && nextPath.has(leaf))
635
654
  break;
636
- throughPath.push(leaf);
655
+ throughPath.add(leaf);
637
656
  }
638
657
  }
639
658
  return throughPath;
@@ -675,120 +694,113 @@ class FindPath {
675
694
  }
676
695
  }
677
696
 
697
+ const { Yes, NoAndSkip, YesAndSkip } = AnswerType;
678
698
  class Selector {
679
699
  constructor(target, userConfig) {
680
700
  this.config = {};
681
- this.innerIdList = {};
682
- this.idList = {};
683
- this.classNameList = {};
684
- this.tagNameList = {};
701
+ this.innerIdMap = {};
702
+ this.idMap = {};
703
+ this.methods = {
704
+ id: (leaf, name) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
705
+ innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
706
+ className: (leaf, name) => leaf.className === name ? 1 : 0,
707
+ tag: (leaf, name) => leaf.__tag === name ? 1 : 0
708
+ };
685
709
  this.target = target;
686
710
  if (userConfig)
687
711
  this.config = DataHelper.default(userConfig, this.config);
688
- this.findPath = new FindPath(target, this);
712
+ this.pather = new Pather(target, this);
689
713
  this.__listenEvents();
690
714
  }
715
+ getBy(condition, branch, one, options) {
716
+ switch (typeof condition) {
717
+ case 'number':
718
+ const leaf = this.getByInnerId(condition, branch);
719
+ return one ? leaf : (leaf ? [leaf] : []);
720
+ case 'string':
721
+ switch (condition[0]) {
722
+ case '#':
723
+ const leaf = this.getById(condition.substring(1), branch);
724
+ return one ? leaf : (leaf ? [leaf] : []);
725
+ case '.':
726
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1));
727
+ default:
728
+ return this.getByMethod(this.methods.tag, branch, one, condition);
729
+ }
730
+ case 'function':
731
+ return this.getByMethod(condition, branch, one, options);
732
+ }
733
+ }
691
734
  getByPoint(hitPoint, hitRadius, options) {
692
735
  if (Platform.name === 'node')
693
736
  this.target.emit(LayoutEvent.CHECK_UPDATE);
694
- return this.findPath.getByPoint(hitPoint, hitRadius, options);
737
+ return this.pather.getByPoint(hitPoint, hitRadius, options);
695
738
  }
696
- find(name, branch) {
697
- if (typeof name === 'number') {
698
- return this.getByInnerId(name, branch);
699
- }
700
- else if (name.startsWith('#')) {
701
- return this.getById(name.substring(1), branch);
702
- }
703
- else if (name.startsWith('.')) {
704
- return this.getByClassName(name.substring(1), branch);
705
- }
706
- else {
707
- return this.getByTagName(name, branch);
708
- }
709
- }
710
- getByInnerId(name, branch) {
711
- let cache = this.innerIdList[name];
739
+ getByInnerId(innerId, branch) {
740
+ const cache = this.innerIdMap[innerId];
712
741
  if (cache)
713
742
  return cache;
714
- if (!branch)
715
- branch = this.target;
716
- let find;
717
- this.loopFind(branch, (leaf) => {
718
- if (leaf.innerId === name) {
719
- find = leaf;
720
- this.innerIdList[name] = find;
721
- return true;
722
- }
723
- else {
724
- return false;
725
- }
726
- });
727
- return find;
743
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
744
+ return this.findLeaf;
728
745
  }
729
- getById(name, branch) {
730
- let cache = this.idList[name];
731
- if (cache)
746
+ getById(id, branch) {
747
+ const cache = this.idMap[id];
748
+ if (cache && LeafHelper.hasParent(cache, branch || this.target))
732
749
  return cache;
733
- if (!branch)
734
- branch = this.target;
735
- let find;
736
- this.loopFind(branch, (leaf) => {
737
- if (leaf.id === name) {
738
- find = leaf;
739
- this.idList[name] = find;
740
- return true;
741
- }
742
- else {
743
- return false;
744
- }
745
- });
746
- return find;
747
- }
748
- getByClassName(name, branch) {
749
- if (!branch)
750
- branch = this.target;
751
- let find = [];
752
- this.loopFind(branch, (leaf) => {
753
- if (leaf.className === name)
754
- find.push(leaf);
755
- return false;
756
- });
757
- return find;
758
- }
759
- getByTagName(name, branch) {
760
- if (!branch)
761
- branch = this.target;
762
- let find = [];
763
- this.loopFind(branch, (leaf) => {
764
- if (leaf.__tag === name)
765
- find.push(leaf);
766
- return false;
767
- });
768
- return find;
750
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id);
751
+ return this.findLeaf;
769
752
  }
770
- loopFind(branch, find) {
771
- if (find(branch))
772
- return;
773
- const { children } = branch;
753
+ getByClassName(className, branch) {
754
+ return this.getByMethod(this.methods.className, branch, false, className);
755
+ }
756
+ getByTag(tag, branch) {
757
+ return this.getByMethod(this.methods.tag, branch, false, tag);
758
+ }
759
+ getByMethod(method, branch, one, options) {
760
+ const list = one ? null : [];
761
+ this.eachFind(this.toChildren(branch), method, list, options);
762
+ return list || this.findLeaf;
763
+ }
764
+ eachFind(children, method, list, options) {
765
+ let child, result;
774
766
  for (let i = 0, len = children.length; i < len; i++) {
775
- branch = children[i];
776
- if (find(branch))
777
- return;
778
- if (branch.isBranch)
779
- this.loopFind(branch, find);
767
+ child = children[i];
768
+ result = method(child, options);
769
+ if (result === Yes || result === YesAndSkip) {
770
+ if (list) {
771
+ list.push(child);
772
+ }
773
+ else {
774
+ this.findLeaf = child;
775
+ return;
776
+ }
777
+ }
778
+ if (child.isBranch && result < NoAndSkip)
779
+ this.eachFind(child.children, method, list, options);
780
780
  }
781
781
  }
782
+ toChildren(branch) {
783
+ this.findLeaf = null;
784
+ return [branch || this.target];
785
+ }
782
786
  __onRemoveChild(event) {
783
- const target = event.target;
784
- if (this.idList[target.id])
785
- this.idList[target.id] = null;
786
- if (this.innerIdList[target.id])
787
- this.innerIdList[target.innerId] = null;
787
+ const { id, innerId } = event.child;
788
+ if (this.idMap[id])
789
+ delete this.idMap[id];
790
+ if (this.innerIdMap[innerId])
791
+ delete this.innerIdMap[innerId];
792
+ }
793
+ __checkIdChange(event) {
794
+ if (event.attrName === 'id') {
795
+ const id = event.oldValue;
796
+ if (this.idMap[id])
797
+ delete this.idMap[id];
798
+ }
788
799
  }
789
800
  __listenEvents() {
790
801
  this.__eventIds = [
791
- this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this)
802
+ this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
803
+ this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
792
804
  ];
793
805
  }
794
806
  __removeListenEvents() {
@@ -798,11 +810,10 @@ class Selector {
798
810
  destroy() {
799
811
  if (this.__eventIds.length) {
800
812
  this.__removeListenEvents();
801
- this.findPath.destroy();
802
- this.innerIdList = {};
803
- this.idList = {};
804
- this.classNameList = {};
805
- this.tagNameList = {};
813
+ this.pather.destroy();
814
+ this.findLeaf = null;
815
+ this.innerIdMap = {};
816
+ this.idMap = {};
806
817
  }
807
818
  }
808
819
  }
@@ -1024,7 +1035,7 @@ const WheelEventHelper = {
1024
1035
  let { zoomMode, zoomSpeed } = config;
1025
1036
  const delta = e.deltaY || e.deltaX;
1026
1037
  if (zoomMode) {
1027
- zoom = !e.deltaX && (Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta);
1038
+ zoom = (zoomMode === 'mouse') ? true : (!e.deltaX && (Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta));
1028
1039
  if (e.shiftKey || e.metaKey || e.ctrlKey)
1029
1040
  zoom = true;
1030
1041
  }
@@ -1335,8 +1346,8 @@ function useCanvas(_canvasType, _power) {
1335
1346
  img.crossOrigin = 'anonymous';
1336
1347
  img.onload = () => { resolve(img); };
1337
1348
  img.onerror = (e) => { reject(e); };
1338
- if (!src.startsWith('data:') && Platform.imageSuffix)
1339
- src += (src.includes("?") ? "&" : "?") + Platform.imageSuffix;
1349
+ if (!src.startsWith('data:') && Platform.image.suffix)
1350
+ src += (src.includes("?") ? "&" : "?") + Platform.image.suffix;
1340
1351
  img.src = src;
1341
1352
  });
1342
1353
  }
@@ -1352,8 +1363,7 @@ function useCanvas(_canvasType, _power) {
1352
1363
  Platform.name = 'web';
1353
1364
  Platform.isMobile = 'ontouchstart' in window;
1354
1365
  Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
1355
- Platform.devicePixelRatio = devicePixelRatio;
1356
- Platform.realtimeLayout = true;
1366
+ Platform.devicePixelRatio = Math.max(1, devicePixelRatio);
1357
1367
  const { userAgent } = navigator;
1358
1368
  if (userAgent.indexOf("Firefox") > -1) {
1359
1369
  Platform.conicGradientRotate90 = true;
@@ -1374,7 +1384,7 @@ else if (userAgent.indexOf('Linux') > -1) {
1374
1384
  Platform.os = 'Linux';
1375
1385
  }
1376
1386
 
1377
- const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper$1, rotate } = MatrixHelper;
1387
+ const { get: get$4, rotateOfOuter: rotateOfOuter$2, translate: translate$1, scaleOfOuter: scaleOfOuter$2, scale: scaleHelper, rotate } = MatrixHelper;
1378
1388
  function fillOrFitMode(data, mode, box, width, height, rotation) {
1379
1389
  const transform = get$4();
1380
1390
  const swap = rotation && rotation !== 180;
@@ -1384,7 +1394,7 @@ function fillOrFitMode(data, mode, box, width, height, rotation) {
1384
1394
  const x = box.x + (box.width - width * scale) / 2;
1385
1395
  const y = box.y + (box.height - height * scale) / 2;
1386
1396
  translate$1(transform, x, y);
1387
- scaleHelper$1(transform, scale);
1397
+ scaleHelper(transform, scale);
1388
1398
  if (rotation)
1389
1399
  rotateOfOuter$2(transform, { x: box.x + box.width / 2, y: box.y + box.height / 2 }, rotation);
1390
1400
  data.scaleX = data.scaleY = scale;
@@ -1396,7 +1406,7 @@ function clipMode(data, box, offset, scale, rotation) {
1396
1406
  if (offset)
1397
1407
  translate$1(transform, offset.x, offset.y);
1398
1408
  if (scale) {
1399
- typeof scale === 'number' ? scaleHelper$1(transform, scale) : scaleHelper$1(transform, scale.x, scale.y);
1409
+ typeof scale === 'number' ? scaleHelper(transform, scale) : scaleHelper(transform, scale.x, scale.y);
1400
1410
  data.scaleX = transform.a;
1401
1411
  data.scaleY = transform.d;
1402
1412
  }
@@ -1509,6 +1519,10 @@ function hasNaturalSize(ui, attrName, image) {
1509
1519
  d.__naturalWidth = image.width;
1510
1520
  d.__naturalHeight = image.height;
1511
1521
  if (!d.__getInput('width') || !d.__getInput('height')) {
1522
+ if (ui.__proxyData) {
1523
+ ui.setProxyAttr('width', ui.__.width);
1524
+ ui.setProxyAttr('height', ui.__.height);
1525
+ }
1512
1526
  ui.forceUpdate('width');
1513
1527
  return false;
1514
1528
  }
@@ -1552,22 +1566,21 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
1552
1566
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1553
1567
  };
1554
1568
 
1555
- const { get: get$2, scale: scaleHelper, copy: copy$1 } = MatrixHelper;
1569
+ const Export$1 = {};
1570
+
1571
+ const { get: get$2, scale, copy: copy$1 } = MatrixHelper;
1556
1572
  function createPattern(ui, paint, pixelRatio) {
1557
1573
  let { scaleX, scaleY } = ui.__world;
1558
1574
  const id = scaleX + '-' + scaleY;
1559
1575
  if (paint.patternId !== id && !ui.destroyed) {
1560
- paint.patternId = id;
1561
1576
  scaleX = Math.abs(scaleX);
1562
1577
  scaleY = Math.abs(scaleY);
1563
1578
  const { image, data } = paint;
1564
- const maxWidth = image.isSVG ? 4096 : Math.min(image.width, 4096);
1565
- const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096);
1566
- let scale, matrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data;
1579
+ let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data;
1567
1580
  if (sx) {
1568
- matrix = get$2();
1569
- copy$1(matrix, transform);
1570
- scaleHelper(matrix, 1 / sx, 1 / sy);
1581
+ imageMatrix = get$2();
1582
+ copy$1(imageMatrix, transform);
1583
+ scale(imageMatrix, 1 / sx, 1 / sy);
1571
1584
  scaleX *= sx;
1572
1585
  scaleY *= sy;
1573
1586
  }
@@ -1575,38 +1588,49 @@ function createPattern(ui, paint, pixelRatio) {
1575
1588
  scaleY *= pixelRatio;
1576
1589
  width *= scaleX;
1577
1590
  height *= scaleY;
1578
- if (width > maxWidth || height > maxHeight) {
1579
- scale = Math.max(width / maxWidth, height / maxHeight);
1591
+ const size = width * height;
1592
+ if (paint.data.mode !== 'repeat') {
1593
+ if (size > Platform.image.maxCacheSize)
1594
+ return false;
1595
+ }
1596
+ let maxSize = Platform.image.maxPatternSize;
1597
+ if (!image.isSVG) {
1598
+ const imageSize = image.width * image.height;
1599
+ if (maxSize > imageSize)
1600
+ maxSize = imageSize;
1580
1601
  }
1581
- if (scale) {
1582
- scaleX /= scale;
1583
- scaleY /= scale;
1584
- width /= scale;
1585
- height /= scale;
1602
+ if (size > maxSize)
1603
+ imageScale = Math.sqrt(size / maxSize);
1604
+ if (imageScale) {
1605
+ scaleX /= imageScale;
1606
+ scaleY /= imageScale;
1607
+ width /= imageScale;
1608
+ height /= imageScale;
1586
1609
  }
1587
1610
  if (sx) {
1588
1611
  scaleX /= sx;
1589
1612
  scaleY /= sy;
1590
1613
  }
1591
1614
  if (transform || scaleX !== 1 || scaleY !== 1) {
1592
- if (!matrix) {
1593
- matrix = get$2();
1615
+ if (!imageMatrix) {
1616
+ imageMatrix = get$2();
1594
1617
  if (transform)
1595
- copy$1(matrix, transform);
1618
+ copy$1(imageMatrix, transform);
1596
1619
  }
1597
- scaleHelper(matrix, 1 / scaleX, 1 / scaleY);
1620
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1598
1621
  }
1599
- const style = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'));
1622
+ const pattern = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity), mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'));
1600
1623
  try {
1601
1624
  if (paint.transform)
1602
1625
  paint.transform = null;
1603
- if (matrix)
1604
- style.setTransform ? style.setTransform(matrix) : paint.transform = matrix;
1626
+ if (imageMatrix)
1627
+ pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix;
1605
1628
  }
1606
1629
  catch (_a) {
1607
- paint.transform = matrix;
1630
+ paint.transform = imageMatrix;
1608
1631
  }
1609
- paint.style = style;
1632
+ paint.style = pattern;
1633
+ paint.patternId = id;
1610
1634
  return true;
1611
1635
  }
1612
1636
  else {
@@ -1614,18 +1638,24 @@ function createPattern(ui, paint, pixelRatio) {
1614
1638
  }
1615
1639
  }
1616
1640
 
1641
+ const { abs } = Math;
1617
1642
  function checkImage(ui, canvas, paint, allowPaint) {
1618
1643
  const { scaleX, scaleY } = ui.__world;
1619
1644
  if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
1620
1645
  return false;
1621
1646
  }
1622
1647
  else {
1648
+ const { data } = paint;
1623
1649
  if (allowPaint) {
1624
- if (paint.image.isSVG && paint.data.mode !== 'repeat') {
1625
- let { width, height } = paint.data;
1626
- width *= scaleX * canvas.pixelRatio;
1627
- height *= scaleY * canvas.pixelRatio;
1628
- allowPaint = width > 4096 || height > 4096;
1650
+ if (data.mode !== 'repeat') {
1651
+ let { width, height } = data;
1652
+ width *= abs(scaleX) * canvas.pixelRatio;
1653
+ height *= abs(scaleY) * canvas.pixelRatio;
1654
+ if (data.scaleX) {
1655
+ width *= data.scaleX;
1656
+ height *= data.scaleY;
1657
+ }
1658
+ allowPaint = width * height > Platform.image.maxCacheSize;
1629
1659
  }
1630
1660
  else {
1631
1661
  allowPaint = false;
@@ -1634,7 +1664,6 @@ function checkImage(ui, canvas, paint, allowPaint) {
1634
1664
  if (allowPaint) {
1635
1665
  canvas.save();
1636
1666
  canvas.clip();
1637
- const { data } = paint;
1638
1667
  if (paint.blendMode)
1639
1668
  canvas.blendMode = paint.blendMode;
1640
1669
  if (data.opacity)
@@ -1646,15 +1675,16 @@ function checkImage(ui, canvas, paint, allowPaint) {
1646
1675
  return true;
1647
1676
  }
1648
1677
  else {
1649
- if (!paint.style) {
1678
+ if (!paint.style || Export$1.running) {
1650
1679
  createPattern(ui, paint, canvas.pixelRatio);
1651
1680
  }
1652
1681
  else {
1653
1682
  if (!paint.patternTask) {
1654
1683
  paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1655
1684
  paint.patternTask = null;
1656
- if (canvas.bounds.hit(ui.__world) && createPattern(ui, paint, canvas.pixelRatio))
1657
- ui.forceUpdate('surface');
1685
+ if (canvas.bounds.hit(ui.__world))
1686
+ createPattern(ui, paint, canvas.pixelRatio);
1687
+ ui.forceUpdate('surface');
1658
1688
  }), 300);
1659
1689
  }
1660
1690
  }
@@ -1664,7 +1694,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1664
1694
  }
1665
1695
 
1666
1696
  function recycleImage(attrName, data) {
1667
- const paints = (attrName === 'fill' ? data._fill : data._stroke);
1697
+ const paints = data['_' + attrName];
1668
1698
  if (paints instanceof Array) {
1669
1699
  let image, recycleMap, input, url;
1670
1700
  for (let i = 0, len = paints.length; i < len; i++) {
@@ -1768,7 +1798,7 @@ function drawAlignStroke(align, stroke, isStrokes, ui, canvas, renderOptions) {
1768
1798
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in';
1769
1799
  fillText(ui, out);
1770
1800
  out.blendMode = 'normal';
1771
- if (ui.__hasMirror || renderOptions.matrix) {
1801
+ if (ui.__worldFlipped || renderOptions.matrix) {
1772
1802
  canvas.copyWorldByReset(out);
1773
1803
  }
1774
1804
  else {
@@ -1841,7 +1871,7 @@ function stroke(stroke, ui, canvas, renderOptions) {
1841
1871
  out.stroke();
1842
1872
  options.windingRule ? out.clip(options.windingRule) : out.clip();
1843
1873
  out.clearWorld(ui.__layout.renderBounds);
1844
- if (ui.__hasMirror || renderOptions.matrix) {
1874
+ if (ui.__worldFlipped || renderOptions.matrix) {
1845
1875
  canvas.copyWorldByReset(out);
1846
1876
  }
1847
1877
  else {
@@ -1881,7 +1911,7 @@ function strokes(strokes, ui, canvas, renderOptions) {
1881
1911
  drawStrokesStyle(strokes, false, ui, out);
1882
1912
  options.windingRule ? out.clip(options.windingRule) : out.clip();
1883
1913
  out.clearWorld(renderBounds);
1884
- if (ui.__hasMirror || renderOptions.matrix) {
1914
+ if (ui.__worldFlipped || renderOptions.matrix) {
1885
1915
  canvas.copyWorldByReset(out);
1886
1916
  }
1887
1917
  else {
@@ -2105,7 +2135,7 @@ function shadow(ui, current, shape, renderOptions) {
2105
2135
  }
2106
2136
  worldCanvas ? other.copyWorld(worldCanvas, __world, __world, 'destination-out') : other.copyWorld(shape.canvas, shapeBounds, bounds, 'destination-out');
2107
2137
  }
2108
- if (ui.__hasMirror || renderOptions.matrix) {
2138
+ if (ui.__worldFlipped || renderOptions.matrix) {
2109
2139
  current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2110
2140
  }
2111
2141
  else {
@@ -2169,7 +2199,7 @@ function innerShadow(ui, current, shape, renderOptions) {
2169
2199
  copyBounds = bounds;
2170
2200
  }
2171
2201
  other.fillWorld(copyBounds, item.color, 'source-in');
2172
- if (ui.__hasMirror || renderOptions.matrix) {
2202
+ if (ui.__worldFlipped || renderOptions.matrix) {
2173
2203
  current.copyWorldByReset(other, copyBounds, __world, item.blendMode);
2174
2204
  }
2175
2205
  else {
@@ -2318,6 +2348,8 @@ function createRows(drawData, content, style) {
2318
2348
  const { width, height } = bounds;
2319
2349
  const charMode = width || height || __letterSpacing || (textCase !== 'none');
2320
2350
  if (charMode) {
2351
+ const wrap = style.textWrap !== 'none';
2352
+ const breakAll = style.textWrap === 'break';
2321
2353
  paraStart = true;
2322
2354
  lastCharType = null;
2323
2355
  startCharSize = charWidth = charSize = wordWidth = rowWidth = 0;
@@ -2344,16 +2376,23 @@ function createRows(drawData, content, style) {
2344
2376
  langBreak = (charType === Single && (lastCharType === Single || lastCharType === Letter)) || (lastCharType === Single && charType !== After);
2345
2377
  afterBreak = ((charType === Before || charType === Single) && (lastCharType === Symbol || lastCharType === After));
2346
2378
  realWidth = paraStart && paraIndent ? width - paraIndent : width;
2347
- if (width && rowWidth + wordWidth + charWidth > realWidth) {
2348
- if (!afterBreak)
2349
- afterBreak = charType === Letter && lastCharType == After;
2350
- if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2379
+ if (wrap && (width && rowWidth + wordWidth + charWidth > realWidth)) {
2380
+ if (breakAll) {
2351
2381
  if (wordWidth)
2352
2382
  addWord();
2353
2383
  addRow();
2354
2384
  }
2355
2385
  else {
2356
- addRow();
2386
+ if (!afterBreak)
2387
+ afterBreak = charType === Letter && lastCharType == After;
2388
+ if (langBreak || afterBreak || charType === Break || charType === Before || charType === Single || (wordWidth + charWidth > realWidth)) {
2389
+ if (wordWidth)
2390
+ addWord();
2391
+ addRow();
2392
+ }
2393
+ else {
2394
+ addRow();
2395
+ }
2357
2396
  }
2358
2397
  }
2359
2398
  if (char === ' ' && paraStart !== true && (rowWidth + wordWidth) === 0) ;
@@ -2423,7 +2462,7 @@ function addRow() {
2423
2462
 
2424
2463
  const CharMode = 0;
2425
2464
  const WordMode = 1;
2426
- const RowMode = 2;
2465
+ const TextMode = 2;
2427
2466
  function layoutChar(drawData, style, width, _height) {
2428
2467
  const { rows } = drawData;
2429
2468
  const { textAlign, paraIndent, letterSpacing } = style;
@@ -2432,15 +2471,12 @@ function layoutChar(drawData, style, width, _height) {
2432
2471
  if (row.words) {
2433
2472
  indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
2434
2473
  addWordWidth = (width && textAlign === 'justify' && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
2435
- mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : RowMode);
2436
- if (mode === RowMode) {
2437
- row.text = '';
2474
+ mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
2475
+ if (row.isOverflow && !letterSpacing)
2476
+ row.textMode = true;
2477
+ if (mode === TextMode) {
2438
2478
  row.x += indentWidth;
2439
- row.words.forEach(word => {
2440
- word.data.forEach(char => {
2441
- row.text += char.char;
2442
- });
2443
- });
2479
+ toTextChar$1(row);
2444
2480
  }
2445
2481
  else {
2446
2482
  row.x += indentWidth;
@@ -2466,6 +2502,14 @@ function layoutChar(drawData, style, width, _height) {
2466
2502
  }
2467
2503
  });
2468
2504
  }
2505
+ function toTextChar$1(row) {
2506
+ row.text = '';
2507
+ row.words.forEach(word => {
2508
+ word.data.forEach(char => {
2509
+ row.text += char.char;
2510
+ });
2511
+ });
2512
+ }
2469
2513
  function toWordChar(data, charX, wordChar) {
2470
2514
  data.forEach(char => {
2471
2515
  wordChar.char += char.char;
@@ -2486,10 +2530,10 @@ function toChar(data, charX, rowData) {
2486
2530
 
2487
2531
  function layoutText(drawData, style) {
2488
2532
  const { rows, bounds } = drawData;
2489
- const { __lineHeight, __baseLine, __letterSpacing, textAlign, verticalAlign, paraSpacing, textOverflow } = style;
2533
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2490
2534
  let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2491
2535
  let starY = __baseLine;
2492
- if (textOverflow !== 'show' && realHeight > height) {
2536
+ if (__clipText && realHeight > height) {
2493
2537
  realHeight = Math.max(height, __lineHeight);
2494
2538
  drawData.overflow = rows.length;
2495
2539
  }
@@ -2538,39 +2582,58 @@ function layoutText(drawData, style) {
2538
2582
  bounds.x = rowX;
2539
2583
  if (rowWidth > bounds.width)
2540
2584
  bounds.width = rowWidth;
2585
+ if (__clipText && width && width < rowWidth) {
2586
+ row.isOverflow = true;
2587
+ if (!drawData.overflow)
2588
+ drawData.overflow = rows.length;
2589
+ }
2541
2590
  }
2542
2591
  bounds.y = y;
2543
2592
  bounds.height = realHeight;
2544
2593
  }
2545
2594
 
2546
- function clipText(drawData, textOverflow) {
2595
+ function clipText(drawData, style) {
2547
2596
  const { rows, overflow } = drawData;
2597
+ let { textOverflow } = style;
2548
2598
  rows.splice(overflow);
2549
2599
  if (textOverflow !== 'hide') {
2550
2600
  if (textOverflow === 'ellipsis')
2551
2601
  textOverflow = '...';
2602
+ let char, charRight;
2552
2603
  const ellipsisWidth = Platform.canvas.measureText(textOverflow).width;
2553
- const row = rows[overflow - 1];
2554
- let char, end = row.data.length - 1, charRight;
2555
- const { x, width } = drawData.bounds;
2556
- const right = x + width - ellipsisWidth;
2557
- for (let i = end; i > -1; i--) {
2558
- char = row.data[i];
2559
- charRight = char.x + char.width;
2560
- if (i === end && charRight < right) {
2561
- break;
2562
- }
2563
- else if (charRight < right && char.char !== ' ') {
2564
- row.data.splice(i + 1);
2565
- row.width -= char.width;
2566
- break;
2604
+ const right = style.x + style.width - ellipsisWidth;
2605
+ const list = style.textWrap === 'none' ? rows : [rows[overflow - 1]];
2606
+ list.forEach(row => {
2607
+ if (row.isOverflow && row.data) {
2608
+ let end = row.data.length - 1;
2609
+ for (let i = end; i > -1; i--) {
2610
+ char = row.data[i];
2611
+ charRight = char.x + char.width;
2612
+ if (i === end && charRight < right) {
2613
+ break;
2614
+ }
2615
+ else if (charRight < right && char.char !== ' ') {
2616
+ row.data.splice(i + 1);
2617
+ row.width -= char.width;
2618
+ break;
2619
+ }
2620
+ row.width -= char.width;
2621
+ }
2622
+ row.width += ellipsisWidth;
2623
+ row.data.push({ char: textOverflow, x: charRight });
2624
+ if (row.textMode)
2625
+ toTextChar(row);
2567
2626
  }
2568
- row.width -= char.width;
2569
- }
2570
- row.width += ellipsisWidth;
2571
- row.data.push({ char: textOverflow, x: charRight });
2627
+ });
2572
2628
  }
2573
2629
  }
2630
+ function toTextChar(row) {
2631
+ row.text = '';
2632
+ row.data.forEach(char => {
2633
+ row.text += char.char;
2634
+ });
2635
+ row.data = null;
2636
+ }
2574
2637
 
2575
2638
  function decorationText(drawData, style) {
2576
2639
  const { fontSize } = style;
@@ -2591,7 +2654,7 @@ const TextConvert = {
2591
2654
  let x = 0, y = 0;
2592
2655
  let width = style.__getInput('width') || 0;
2593
2656
  let height = style.__getInput('height') || 0;
2594
- const { textDecoration, textOverflow, __font, padding } = style;
2657
+ const { textDecoration, __font, padding } = style;
2595
2658
  if (padding) {
2596
2659
  const [top, right, bottom, left] = MathHelper.fourNumber(padding);
2597
2660
  if (width) {
@@ -2613,7 +2676,7 @@ const TextConvert = {
2613
2676
  layoutText(drawData, style);
2614
2677
  layoutChar(drawData, style, width);
2615
2678
  if (drawData.overflow)
2616
- clipText(drawData, textOverflow);
2679
+ clipText(drawData, style);
2617
2680
  if (textDecoration !== 'none')
2618
2681
  decorationText(drawData, style);
2619
2682
  return drawData;
@@ -2634,6 +2697,7 @@ const ColorConvert = {
2634
2697
 
2635
2698
  const Export = {
2636
2699
  export(leaf, filename, options) {
2700
+ Export.running = true;
2637
2701
  return addTask((success) => new Promise((resolve) => {
2638
2702
  const { leafer } = leaf;
2639
2703
  if (leafer) {
@@ -2671,6 +2735,7 @@ const Export = {
2671
2735
  }
2672
2736
  success({ data });
2673
2737
  resolve();
2738
+ Export.running = false;
2674
2739
  if (unreal)
2675
2740
  canvas.recycle();
2676
2741
  }));
@@ -2678,6 +2743,7 @@ const Export = {
2678
2743
  else {
2679
2744
  success({ data: false });
2680
2745
  resolve();
2746
+ Export.running = false;
2681
2747
  }
2682
2748
  }));
2683
2749
  }
@@ -2695,7 +2761,7 @@ Object.assign(Paint, UIPaint);
2695
2761
  Object.assign(Effect, UIEffect);
2696
2762
  Object.assign(TextConvert$1, TextConvert);
2697
2763
  Object.assign(ColorConvert$1, ColorConvert);
2698
- Object.assign(Export$1, Export);
2764
+ Object.assign(Export$2, Export);
2699
2765
 
2700
2766
  useCanvas();
2701
2767