leafer-ui 1.2.1 → 1.3.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,11 +1,11 @@
1
- import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Answer, MathHelper, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
1
+ import { Debug, LeaferCanvasBase, Platform, DataHelper, canvasSizeAttrs, ResizeEvent, canvasPatch, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, Plugin, MathHelper, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4 } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
4
  import { InteractionHelper, InteractionBase, Cursor, HitCanvasManager } from '@leafer-ui/core';
5
5
  export * from '@leafer-ui/core';
6
6
  import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
7
7
 
8
- const debug$3 = Debug.get('LeaferCanvas');
8
+ const debug$2 = Debug.get('LeaferCanvas');
9
9
  class LeaferCanvas extends LeaferCanvasBase {
10
10
  set zIndex(zIndex) {
11
11
  const { style } = this.view;
@@ -77,7 +77,7 @@ class LeaferCanvas extends LeaferCanvasBase {
77
77
  }
78
78
  }
79
79
  else {
80
- debug$3.error(`no id: ${inputView}`);
80
+ debug$2.error(`no id: ${inputView}`);
81
81
  this.__createView();
82
82
  }
83
83
  }
@@ -95,7 +95,8 @@ class LeaferCanvas extends LeaferCanvasBase {
95
95
  this.view.height = Math.ceil(height * pixelRatio);
96
96
  }
97
97
  updateClientBounds() {
98
- this.clientBounds = this.view.getBoundingClientRect();
98
+ if (this.view.parentElement)
99
+ this.clientBounds = this.view.getBoundingClientRect();
99
100
  }
100
101
  startAutoLayout(autoBounds, listener) {
101
102
  this.resizeListener = listener;
@@ -114,7 +115,7 @@ class LeaferCanvas extends LeaferCanvasBase {
114
115
  }
115
116
  else {
116
117
  this.checkAutoBounds(this.view);
117
- debug$3.warn('no parent');
118
+ debug$2.warn('no parent');
118
119
  }
119
120
  }
120
121
  catch (_a) {
@@ -450,7 +451,7 @@ class LayoutBlockData {
450
451
  }
451
452
 
452
453
  const { updateAllMatrix, updateAllChange } = LeafHelper;
453
- const debug$2 = Debug.get('Layouter');
454
+ const debug$1 = Debug.get('Layouter');
454
455
  class Layouter {
455
456
  constructor(target, userConfig) {
456
457
  this.totalTimes = 0;
@@ -485,7 +486,7 @@ class Layouter {
485
486
  target.emitEvent(new LayoutEvent(LayoutEvent.END, this.layoutedBlocks, this.times));
486
487
  }
487
488
  catch (e) {
488
- debug$2.error(e);
489
+ debug$1.error(e);
489
490
  }
490
491
  this.layoutedBlocks = null;
491
492
  }
@@ -499,9 +500,9 @@ class Layouter {
499
500
  }
500
501
  layoutOnce() {
501
502
  if (this.layouting)
502
- return debug$2.warn('layouting');
503
+ return debug$1.warn('layouting');
503
504
  if (this.times > 3)
504
- return debug$2.warn('layout max times');
505
+ return debug$1.warn('layout max times');
505
506
  this.times++;
506
507
  this.totalTimes++;
507
508
  this.layouting = true;
@@ -605,7 +606,7 @@ class Layouter {
605
606
  }
606
607
  }
607
608
 
608
- const debug$1 = Debug.get('Renderer');
609
+ const debug = Debug.get('Renderer');
609
610
  class Renderer {
610
611
  get needFill() { return !!(!this.canvas.allowBackgroundColor && this.config.fill); }
611
612
  constructor(target, canvas, userConfig) {
@@ -643,7 +644,7 @@ class Renderer {
643
644
  const { target } = this;
644
645
  this.times = 0;
645
646
  this.totalBounds = new Bounds();
646
- debug$1.log(target.innerName, '--->');
647
+ debug.log(target.innerName, '--->');
647
648
  try {
648
649
  if (!target.isApp)
649
650
  target.app.emit(RenderEvent.CHILD_START, target);
@@ -654,9 +655,9 @@ class Renderer {
654
655
  }
655
656
  catch (e) {
656
657
  this.rendering = false;
657
- debug$1.error(e);
658
+ debug.error(e);
658
659
  }
659
- debug$1.log('-------------|');
660
+ debug.log('-------------|');
660
661
  }
661
662
  renderAgain() {
662
663
  if (this.rendering) {
@@ -668,9 +669,9 @@ class Renderer {
668
669
  }
669
670
  renderOnce(callback) {
670
671
  if (this.rendering)
671
- return debug$1.warn('rendering');
672
+ return debug.warn('rendering');
672
673
  if (this.times > 3)
673
- return debug$1.warn('render max times');
674
+ return debug.warn('render max times');
674
675
  this.times++;
675
676
  this.totalTimes++;
676
677
  this.rendering = true;
@@ -707,7 +708,7 @@ class Renderer {
707
708
  partRender() {
708
709
  const { canvas, updateBlocks: list } = this;
709
710
  if (!list)
710
- return debug$1.warn('PartRender: need update attr');
711
+ return debug.warn('PartRender: need update attr');
711
712
  this.mergeBlocks();
712
713
  list.forEach(block => { if (canvas.bounds.hit(block) && !block.isEmpty())
713
714
  this.clipRender(block); });
@@ -810,7 +811,7 @@ class Renderer {
810
811
  empty = (!leaf.__world.width || !leaf.__world.height);
811
812
  if (empty) {
812
813
  if (!leaf.isLeafer)
813
- debug$1.tip(leaf.innerName, ': empty');
814
+ debug.tip(leaf.innerName, ': empty');
814
815
  empty = (!leaf.isBranch || leaf.isBranchLeaf);
815
816
  }
816
817
  return empty;
@@ -976,143 +977,26 @@ class Picker {
976
977
  }
977
978
  }
978
979
 
979
- const { Yes, NoAndSkip, YesAndSkip } = Answer;
980
- const idCondition = {}, classNameCondition = {}, tagCondition = {};
981
980
  class Selector {
982
981
  constructor(target, userConfig) {
983
982
  this.config = {};
984
- this.innerIdMap = {};
985
- this.idMap = {};
986
- this.methods = {
987
- id: (leaf, name) => leaf.id === name ? (this.target && (this.idMap[name] = leaf), 1) : 0,
988
- innerId: (leaf, innerId) => leaf.innerId === innerId ? (this.target && (this.innerIdMap[innerId] = leaf), 1) : 0,
989
- className: (leaf, name) => leaf.className === name ? 1 : 0,
990
- tag: (leaf, name) => leaf.__tag === name ? 1 : 0,
991
- tags: (leaf, nameMap) => nameMap[leaf.__tag] ? 1 : 0
992
- };
993
- this.target = target;
994
983
  if (userConfig)
995
984
  this.config = DataHelper.default(userConfig, this.config);
996
- this.picker = new Picker(target, this);
997
- if (target)
998
- this.__listenEvents();
999
- }
1000
- getBy(condition, branch, one, options) {
1001
- switch (typeof condition) {
1002
- case 'number':
1003
- const leaf = this.getByInnerId(condition, branch);
1004
- return one ? leaf : (leaf ? [leaf] : []);
1005
- case 'string':
1006
- switch (condition[0]) {
1007
- case '#':
1008
- idCondition.id = condition.substring(1), condition = idCondition;
1009
- break;
1010
- case '.':
1011
- classNameCondition.className = condition.substring(1), condition = classNameCondition;
1012
- break;
1013
- default:
1014
- tagCondition.tag = condition, condition = tagCondition;
1015
- }
1016
- case 'object':
1017
- if (condition.id !== undefined) {
1018
- const leaf = this.getById(condition.id, branch);
1019
- return one ? leaf : (leaf ? [leaf] : []);
1020
- }
1021
- else if (condition.tag) {
1022
- const { tag } = condition, isArray = tag instanceof Array;
1023
- return this.getByMethod(isArray ? this.methods.tags : this.methods.tag, branch, one, isArray ? DataHelper.toMap(tag) : tag);
1024
- }
1025
- else {
1026
- return this.getByMethod(this.methods.className, branch, one, condition.className);
1027
- }
1028
- case 'function':
1029
- return this.getByMethod(condition, branch, one, options);
1030
- }
985
+ this.picker = new Picker(this.target = target, this);
986
+ this.finder = Creator.finder && Creator.finder();
1031
987
  }
1032
988
  getByPoint(hitPoint, hitRadius, options) {
1033
- if (Platform.name === 'node' && this.target)
1034
- this.target.emit(LayoutEvent.CHECK_UPDATE);
989
+ if (Platform.backgrounder && this.target)
990
+ this.target.updateLayout();
1035
991
  return this.picker.getByPoint(hitPoint, hitRadius, options);
1036
992
  }
1037
- getByInnerId(innerId, branch) {
1038
- const cache = this.innerIdMap[innerId];
1039
- if (cache)
1040
- return cache;
1041
- this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId);
1042
- return this.findLeaf;
1043
- }
1044
- getById(id, branch) {
1045
- const cache = this.idMap[id];
1046
- if (cache && LeafHelper.hasParent(cache, branch || this.target))
1047
- return cache;
1048
- this.eachFind(this.toChildren(branch), this.methods.id, null, id);
1049
- return this.findLeaf;
1050
- }
1051
- getByClassName(className, branch) {
1052
- return this.getByMethod(this.methods.className, branch, false, className);
1053
- }
1054
- getByTag(tag, branch) {
1055
- return this.getByMethod(this.methods.tag, branch, false, tag);
1056
- }
1057
- getByMethod(method, branch, one, options) {
1058
- const list = one ? null : [];
1059
- this.eachFind(this.toChildren(branch), method, list, options);
1060
- return list || this.findLeaf;
1061
- }
1062
- eachFind(children, method, list, options) {
1063
- let child, result;
1064
- for (let i = 0, len = children.length; i < len; i++) {
1065
- child = children[i];
1066
- result = method(child, options);
1067
- if (result === Yes || result === YesAndSkip) {
1068
- if (list) {
1069
- list.push(child);
1070
- }
1071
- else {
1072
- this.findLeaf = child;
1073
- return;
1074
- }
1075
- }
1076
- if (child.isBranch && result < NoAndSkip)
1077
- this.eachFind(child.children, method, list, options);
1078
- }
1079
- }
1080
- toChildren(branch) {
1081
- this.findLeaf = null;
1082
- return [branch || this.target];
1083
- }
1084
- __onRemoveChild(event) {
1085
- const { id, innerId } = event.child;
1086
- if (this.idMap[id])
1087
- delete this.idMap[id];
1088
- if (this.innerIdMap[innerId])
1089
- delete this.innerIdMap[innerId];
1090
- }
1091
- __checkIdChange(event) {
1092
- if (event.attrName === 'id') {
1093
- const id = event.oldValue;
1094
- if (this.idMap[id])
1095
- delete this.idMap[id];
1096
- }
1097
- }
1098
- __listenEvents() {
1099
- this.__eventIds = [
1100
- this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
1101
- this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
1102
- ];
1103
- }
1104
- __removeListenEvents() {
1105
- this.target.off_(this.__eventIds);
1106
- this.__eventIds.length = 0;
993
+ getBy(condition, branch, one, options) {
994
+ return this.finder ? this.finder.getBy(condition, branch, one, options) : Plugin.need('find');
1107
995
  }
1108
996
  destroy() {
1109
- if (this.__eventIds.length) {
1110
- this.__removeListenEvents();
1111
- this.picker.destroy();
1112
- this.findLeaf = null;
1113
- this.innerIdMap = {};
1114
- this.idMap = {};
1115
- }
997
+ this.picker.destroy();
998
+ if (this.finder)
999
+ this.finder.destroy();
1116
1000
  }
1117
1001
  }
1118
1002
 
@@ -2939,197 +2823,12 @@ const ColorConvertModule = {
2939
2823
  string
2940
2824
  };
2941
2825
 
2942
- const { setPoint, addPoint, toBounds } = TwoPointBoundsHelper;
2943
- function getTrimBounds(canvas) {
2944
- const { width, height } = canvas.view;
2945
- const { data } = canvas.context.getImageData(0, 0, width, height);
2946
- let x, y, pointBounds, index = 0;
2947
- for (let i = 0; i < data.length; i += 4) {
2948
- if (data[i + 3] !== 0) {
2949
- x = index % width;
2950
- y = (index - x) / width;
2951
- pointBounds ? addPoint(pointBounds, x, y) : setPoint(pointBounds = {}, x, y);
2952
- }
2953
- index++;
2954
- }
2955
- const bounds = new Bounds();
2956
- toBounds(pointBounds, bounds);
2957
- return bounds.scale(1 / canvas.pixelRatio).ceil();
2958
- }
2959
-
2960
- const ExportModule = {
2961
- export(leaf, filename, options) {
2962
- this.running = true;
2963
- const fileType = FileHelper.fileType(filename);
2964
- const isDownload = filename.includes('.');
2965
- options = FileHelper.getExportOptions(options);
2966
- return addTask((success) => new Promise((resolve) => {
2967
- const over = (result) => {
2968
- success(result);
2969
- resolve();
2970
- this.running = false;
2971
- };
2972
- const { toURL } = Platform;
2973
- const { download } = Platform.origin;
2974
- if (fileType === 'json') {
2975
- isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2976
- return over({ data: isDownload ? true : leaf.toJSON(options.json) });
2977
- }
2978
- if (fileType === 'svg') {
2979
- isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
2980
- return over({ data: isDownload ? true : leaf.toSVG() });
2981
- }
2982
- const { leafer } = leaf;
2983
- if (leafer) {
2984
- checkLazy(leaf);
2985
- leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2986
- let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2987
- const { worldTransform, isLeafer, isFrame } = leaf;
2988
- const { slice, trim, onCanvas } = options;
2989
- const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
2990
- const contextSettings = options.contextSettings || leafer.config.contextSettings;
2991
- const screenshot = options.screenshot || leaf.isApp;
2992
- const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2993
- const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
2994
- if (screenshot) {
2995
- renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2996
- }
2997
- else {
2998
- let relative = options.relative || (isLeafer ? 'inner' : 'local');
2999
- scaleX = worldTransform.scaleX;
3000
- scaleY = worldTransform.scaleY;
3001
- switch (relative) {
3002
- case 'inner':
3003
- matrix.set(worldTransform);
3004
- break;
3005
- case 'local':
3006
- matrix.set(worldTransform).divide(leaf.localTransform);
3007
- scaleX /= leaf.scaleX;
3008
- scaleY /= leaf.scaleY;
3009
- break;
3010
- case 'world':
3011
- scaleX = 1;
3012
- scaleY = 1;
3013
- break;
3014
- case 'page':
3015
- relative = leaf.leafer;
3016
- default:
3017
- matrix.set(worldTransform).divide(leaf.getTransform(relative));
3018
- const l = relative.worldTransform;
3019
- scaleX /= scaleX / l.scaleX;
3020
- scaleY /= scaleY / l.scaleY;
3021
- }
3022
- renderBounds = leaf.getBounds('render', relative);
3023
- }
3024
- const scaleData = { scaleX: 1, scaleY: 1 };
3025
- MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData);
3026
- let pixelRatio = options.pixelRatio || 1;
3027
- if (leaf.isApp) {
3028
- scaleData.scaleX *= pixelRatio;
3029
- scaleData.scaleY *= pixelRatio;
3030
- pixelRatio = leaf.app.pixelRatio;
3031
- }
3032
- const { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
3033
- const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
3034
- let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
3035
- let sliceLeaf;
3036
- if (slice) {
3037
- sliceLeaf = leaf;
3038
- sliceLeaf.__worldOpacity = 0;
3039
- leaf = leafer;
3040
- renderOptions.bounds = canvas.bounds;
3041
- }
3042
- canvas.save();
3043
- if (isFrame && fill !== undefined) {
3044
- const oldFill = leaf.get('fill');
3045
- leaf.fill = '';
3046
- leaf.__render(canvas, renderOptions);
3047
- leaf.fill = oldFill;
3048
- }
3049
- else {
3050
- leaf.__render(canvas, renderOptions);
3051
- }
3052
- canvas.restore();
3053
- if (sliceLeaf)
3054
- sliceLeaf.__updateWorldOpacity();
3055
- if (trim) {
3056
- trimBounds = getTrimBounds(canvas);
3057
- const old = canvas, { width, height } = trimBounds;
3058
- const config = { x: 0, y: 0, width, height, pixelRatio };
3059
- canvas = Creator.canvas(config);
3060
- canvas.copyWorld(old, trimBounds, config);
3061
- }
3062
- if (needFill)
3063
- canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
3064
- if (onCanvas)
3065
- onCanvas(canvas);
3066
- const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
3067
- over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
3068
- }));
3069
- }
3070
- else {
3071
- over({ data: false });
3072
- }
3073
- }));
3074
- }
3075
- };
3076
- let tasker;
3077
- function addTask(task) {
3078
- if (!tasker)
3079
- tasker = new TaskProcessor();
3080
- return new Promise((resolve) => {
3081
- tasker.add(() => __awaiter(this, void 0, void 0, function* () { return yield task(resolve); }), { parallel: false });
3082
- });
3083
- }
3084
- function checkLazy(leaf) {
3085
- if (leaf.__.__needComputePaint)
3086
- leaf.__.__computePaint();
3087
- if (leaf.isBranch)
3088
- leaf.children.forEach(child => checkLazy(child));
3089
- }
3090
-
3091
- const canvas = LeaferCanvasBase.prototype;
3092
- const debug = Debug.get('@leafer-ui/export');
3093
- canvas.export = function (filename, options) {
3094
- const { quality, blob } = FileHelper.getExportOptions(options);
3095
- if (filename.includes('.'))
3096
- return this.saveAs(filename, quality);
3097
- else if (blob)
3098
- return this.toBlob(filename, quality);
3099
- else
3100
- return this.toDataURL(filename, quality);
3101
- };
3102
- canvas.toBlob = function (type, quality) {
3103
- return new Promise((resolve) => {
3104
- Platform.origin.canvasToBolb(this.view, type, quality).then((blob) => {
3105
- resolve(blob);
3106
- }).catch((e) => {
3107
- debug.error(e);
3108
- resolve(null);
3109
- });
3110
- });
3111
- };
3112
- canvas.toDataURL = function (type, quality) {
3113
- return Platform.origin.canvasToDataURL(this.view, type, quality);
3114
- };
3115
- canvas.saveAs = function (filename, quality) {
3116
- return new Promise((resolve) => {
3117
- Platform.origin.canvasSaveAs(this.view, filename, quality).then(() => {
3118
- resolve(true);
3119
- }).catch((e) => {
3120
- debug.error(e);
3121
- resolve(false);
3122
- });
3123
- });
3124
- };
3125
-
3126
2826
  Object.assign(TextConvert, TextConvertModule);
3127
2827
  Object.assign(ColorConvert, ColorConvertModule);
3128
2828
  Object.assign(Paint, PaintModule);
3129
2829
  Object.assign(PaintImage, PaintImageModule);
3130
2830
  Object.assign(PaintGradient, PaintGradientModule);
3131
2831
  Object.assign(Effect, EffectModule);
3132
- Object.assign(Export, ExportModule);
3133
2832
 
3134
2833
  Object.assign(Creator, {
3135
2834
  interaction: (target, canvas, selector, options) => new Interaction(target, canvas, selector, options),
@@ -3138,4 +2837,4 @@ Object.assign(Creator, {
3138
2837
  });
3139
2838
  useCanvas();
3140
2839
 
3141
- export { Interaction, Layouter, LeaferCanvas, Renderer, Selector, Watcher, useCanvas };
2840
+ export { Interaction, Layouter, LeaferCanvas, Picker, Renderer, Selector, Watcher, useCanvas };