leafer-ui 1.0.3 → 1.0.5

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/README.md CHANGED
@@ -1,20 +1,26 @@
1
- # Leafer UI
1
+ # leafer-ui
2
2
 
3
3
  [![LeaferJS](./leaferjs.jpg)](https://www.leaferjs.com)
4
4
 
5
- Leafer UI 是基于 [Leafer](https://github.com/leaferjs/leafer) 开发的一套绚丽多彩的 UI 绘图、交互框架,作为 [LeaferJS](https://www.leaferjs.com) 的表现层,可结合 AI 绘图、生成界面,表现力丰富、性能强劲。
5
+ [**leafer-ui**](https://leaferjs.com/ui/guide/install/ui/start.html) 是基于核心库 [leafer](https://github.com/leaferjs/leafer) 开发的一套绚丽多彩的 UI 绘图、交互框架。作为[LeaferJS](https://www.leaferjs.com) 的表现层,可结合 AI 绘图、生成界面,表现力丰富、性能强劲,可媲美当前主流设计软件。
6
6
 
7
7
  提供了丰富的 UI 绘图元素,和开箱即用的功能,如自动布局、图形编辑、SVG 导出,方便与 Figma、Sketch 等产品进行数据交换。并为跨平台开发提供了统一的交互事件,如拖拽、旋转、缩放手势等。
8
8
 
9
- 可用于高效绘图、组态、开发图形图像编辑软件。随着生态的不断发展,未来将支撑可视化开发网页、应用、游戏、动画。
9
+ 可用于高效绘图 、UI 交互(小游戏、互动应用、组态)、图形编辑。随着生态的不断发展,未来将支撑可视化开发网页、应用、游戏、动画。
10
10
 
11
11
  v1.0 正式版已发布 🎉🎉🎉
12
12
 
13
- 📗[图文并茂、由浅入深的了解 LeaferJS](https://leaferjs.com/ui/blog/2024-07-09.html)
13
+ 📗 [图文并茂、由浅入深的了解 LeaferJS](https://leaferjs.com/ui/blog/2024-07-09.html)
14
+
15
+ 📙 [全新动画、状态、过渡、游戏功能](https://leaferjs.com/ui/blog/2024-09-20.html)
16
+
17
+ 📘 [绝境中盛开,LeaferJS 的创业故事](https://leaferjs.com/ui/blog/2024-04-08.html)
18
+
19
+ 如果你觉得不错,请帮我们点个 [Star](https://github.com/leaferjs/leafer-ui) 🌟 ,让这个库被更多的人看见 - [GitHub](https://github.com/leaferjs/leafer-ui) / [Gitee](https://gitee.com/leaferjs/ui) ✨ ✨ ✨
14
20
 
15
21
  ## 快速安装
16
22
 
17
- 🚀 想马上使用,请安装 [ leafer-ui](https://leaferjs.com/ui/guide/install/ui/start.html),开始你的探索之旅。
23
+ 🚀 想马上使用,请安装 [leafer-ui](https://leaferjs.com/ui/guide/install/ui/start.html),开始你的探索之旅。
18
24
 
19
25
  ## 场景版
20
26
 
@@ -22,17 +28,29 @@ v1.0 正式版已发布 🎉🎉🎉
22
28
 
23
29
  单纯绘图的场景,推荐安装更轻量的 [leafer-draw](https://leaferjs.com/ui/guide/type/draw/start.html) (49KB min+gzip)。
24
30
 
31
+ ## 入门场景
32
+
33
+ **高效绘图:** 长图、产品海报、印刷品等
34
+
35
+ Flex 自动布局、中心绘制,后端批量生成,渐变、内外阴影、裁剪、遮罩、擦除...
36
+
37
+ **UI 交互:** 小游戏、互动应用、组态等
38
+
39
+ 跨平台交互事件、手势,CSS 交互状态、光标,动画、状态、过渡、精灵,箭头、连线...
40
+
41
+ **图形编辑:** 头像裁剪、图片、DIY 编辑器等
42
+
43
+ 丰富的图形编辑功能、高可定制,标尺、视窗控制、滚动条...
44
+
25
45
  ## 互动交流
26
46
 
27
- 有问题、建议可以 [提交 issue](https://github.com/leaferjs/ui/issues),留下你的贡献足迹。
47
+ 有问题、建议可以 [提交 issue](https://github.com/leaferjs/leafer-ui/issues),留下你的贡献足迹。
28
48
 
29
49
  欢迎加入 [技术交流群](https://leaferjs.com/#contact) ,与小伙伴们建立联系,共同学习进步,偶尔会有特殊福利。
30
50
 
31
- 🌟 记得前往 [GitHub](https://github.com/leaferjs/ui) / [Gitee](https://gitee.com/leaferjs/ui) 点亮你的 [小星星](https://github.com/leaferjs/ui) ✨ ✨ ✨
32
-
33
51
  ## 使命与愿景
34
52
 
35
- Leafer UI 致力于实现一套简洁、开放、现代化的 UI 绘图语言标准,表现力丰富,便于 AI 理解,人类可视化使用,并为数字化产品开发提供跨平台、轻量化、高性能的运行时。
53
+ leafer-ui 致力于实现一套简洁、开放、现代化的 UI 绘图语言标准,表现力丰富,便于 AI 理解,人类可视化使用,并为数字化产品开发提供跨平台、轻量化、高性能的运行时。
36
54
 
37
55
  让不同的软件之间能够沟通、协作、共享绘图数据,让数字化产品开发可以更快、更简单。
38
56
 
@@ -50,10 +68,10 @@ Leafer UI 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
50
68
 
51
69
  [LeaferJS 主仓库](https://github.com/leaferjs/LeaferJS)
52
70
 
53
- [Leafer 仓库](https://github.com/leaferjs/leafer)
71
+ [leafer 仓库](https://github.com/leaferjs/leafer)
54
72
 
55
- [LeaferIN 官方插件仓库](https://github.com/leaferjs/in)
73
+ [leafer-in 官方插件仓库](https://github.com/leaferjs/leafer-in)
56
74
 
57
75
  ### License
58
76
 
59
- Leafer UI 是采用 MIT 许可的开源项目,可以永久免费使用。
77
+ leafer-ui 是采用 MIT 许可的开源项目,可以永久免费使用。
package/dist/web.cjs CHANGED
@@ -644,6 +644,7 @@ class Renderer {
644
644
  this.totalBounds = new core.Bounds();
645
645
  debug$1.log(target.innerName, '--->');
646
646
  try {
647
+ target.app.emit(core.RenderEvent.CHILD_START, target);
647
648
  this.emitRender(core.RenderEvent.START);
648
649
  this.renderOnce(callback);
649
650
  this.emitRender(core.RenderEvent.END, this.totalBounds);
@@ -941,7 +942,7 @@ class Picker {
941
942
  if (child.isBranch) {
942
943
  if (hit || child.__ignoreHitWorld) {
943
944
  this.eachFind(child.children, child.__onlyHitMask);
944
- if (child.isBranchLeaf && !this.findList.length)
945
+ if (child.isBranchLeaf)
945
946
  this.hitChild(child, point);
946
947
  }
947
948
  }
@@ -1930,9 +1931,10 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1930
1931
  onLoadError(ui, event, image.error);
1931
1932
  }
1932
1933
  else {
1933
- ignoreRender(ui, true);
1934
- if (firstUse)
1934
+ if (firstUse) {
1935
+ ignoreRender(ui, true);
1935
1936
  onLoad(ui, event);
1937
+ }
1936
1938
  leafPaint.loadId = image.load(() => {
1937
1939
  ignoreRender(ui, false);
1938
1940
  if (!ui.destroyed) {
@@ -2576,11 +2578,12 @@ const { trimRight } = TextRowHelper;
2576
2578
  const { Letter, Single, Before, After, Symbol, Break } = CharType;
2577
2579
  let word, row, wordWidth, rowWidth, realWidth;
2578
2580
  let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
2579
- let textDrawData, rows = [], bounds;
2581
+ let textDrawData, rows = [], bounds, findMaxWidth;
2580
2582
  function createRows(drawData, content, style) {
2581
2583
  textDrawData = drawData;
2582
2584
  rows = drawData.rows;
2583
2585
  bounds = drawData.bounds;
2586
+ findMaxWidth = !bounds.width && !style.autoSizeAlign;
2584
2587
  const { __letterSpacing, paraIndent, textCase } = style;
2585
2588
  const { canvas } = core.Platform;
2586
2589
  const { width, height } = bounds;
@@ -2665,7 +2668,10 @@ function createRows(drawData, content, style) {
2665
2668
  else {
2666
2669
  content.split('\n').forEach(content => {
2667
2670
  textDrawData.paraNumber++;
2668
- rows.push({ x: paraIndent || 0, text: content, width: canvas.measureText(content).width, paraStart: true });
2671
+ rowWidth = canvas.measureText(content).width;
2672
+ rows.push({ x: paraIndent || 0, text: content, width: rowWidth, paraStart: true });
2673
+ if (findMaxWidth)
2674
+ setMaxWidth();
2669
2675
  });
2670
2676
  }
2671
2677
  }
@@ -2696,10 +2702,16 @@ function addRow() {
2696
2702
  row.width = rowWidth;
2697
2703
  if (bounds.width)
2698
2704
  trimRight(row);
2705
+ else if (findMaxWidth)
2706
+ setMaxWidth();
2699
2707
  rows.push(row);
2700
2708
  row = { words: [] };
2701
2709
  rowWidth = 0;
2702
2710
  }
2711
+ function setMaxWidth() {
2712
+ if (rowWidth > (textDrawData.maxWidth || 0))
2713
+ textDrawData.maxWidth = rowWidth;
2714
+ }
2703
2715
 
2704
2716
  const CharMode = 0;
2705
2717
  const WordMode = 1;
@@ -2771,34 +2783,32 @@ function toChar(data, charX, rowData, isOverflow) {
2771
2783
 
2772
2784
  function layoutText(drawData, style) {
2773
2785
  const { rows, bounds } = drawData;
2774
- const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2786
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
2775
2787
  let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2776
2788
  let starY = __baseLine;
2777
2789
  if (__clipText && realHeight > height) {
2778
2790
  realHeight = Math.max(height, __lineHeight);
2779
2791
  drawData.overflow = rows.length;
2780
2792
  }
2781
- else {
2793
+ else if (height || autoSizeAlign) {
2782
2794
  switch (verticalAlign) {
2783
2795
  case 'middle':
2784
2796
  y += (height - realHeight) / 2;
2785
2797
  break;
2786
- case 'bottom':
2787
- y += (height - realHeight);
2798
+ case 'bottom': y += (height - realHeight);
2788
2799
  }
2789
2800
  }
2790
2801
  starY += y;
2791
- let row, rowX, rowWidth;
2802
+ let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
2792
2803
  for (let i = 0, len = rows.length; i < len; i++) {
2793
2804
  row = rows[i];
2794
2805
  row.x = x;
2795
2806
  if (row.width < width || (row.width > width && !__clipText)) {
2796
2807
  switch (textAlign) {
2797
2808
  case 'center':
2798
- row.x += (width - row.width) / 2;
2809
+ row.x += (layoutWidth - row.width) / 2;
2799
2810
  break;
2800
- case 'right':
2801
- row.x += width - row.width;
2811
+ case 'right': row.x += layoutWidth - row.width;
2802
2812
  }
2803
2813
  }
2804
2814
  if (row.paraStart && paraSpacing && i > 0)
@@ -2903,14 +2913,14 @@ function getDrawData(content, style) {
2903
2913
  let height = style.__getInput('height') || 0;
2904
2914
  const { textDecoration, __font, __padding: padding } = style;
2905
2915
  if (padding) {
2906
- if (width) {
2916
+ if (width)
2917
+ x = padding[left], width -= (padding[right] + padding[left]);
2918
+ else if (!style.autoSizeAlign)
2907
2919
  x = padding[left];
2908
- width -= (padding[right] + padding[left]);
2909
- }
2910
- if (height) {
2920
+ if (height)
2921
+ y = padding[top], height -= (padding[top] + padding[bottom]);
2922
+ else if (!style.autoSizeAlign)
2911
2923
  y = padding[top];
2912
- height -= (padding[top] + padding[bottom]);
2913
- }
2914
2924
  }
2915
2925
  const drawData = {
2916
2926
  bounds: { x, y, width, height },
@@ -2930,22 +2940,20 @@ function getDrawData(content, style) {
2930
2940
  return drawData;
2931
2941
  }
2932
2942
  function padAutoText(padding, drawData, style, width, height) {
2933
- if (!width) {
2943
+ if (!width && style.autoSizeAlign) {
2934
2944
  switch (style.textAlign) {
2935
2945
  case 'left':
2936
2946
  offsetText(drawData, 'x', padding[left]);
2937
2947
  break;
2938
- case 'right':
2939
- offsetText(drawData, 'x', -padding[right]);
2948
+ case 'right': offsetText(drawData, 'x', -padding[right]);
2940
2949
  }
2941
2950
  }
2942
- if (!height) {
2951
+ if (!height && style.autoSizeAlign) {
2943
2952
  switch (style.verticalAlign) {
2944
2953
  case 'top':
2945
2954
  offsetText(drawData, 'y', padding[top]);
2946
2955
  break;
2947
- case 'bottom':
2948
- offsetText(drawData, 'y', -padding[bottom]);
2956
+ case 'bottom': offsetText(drawData, 'y', -padding[bottom]);
2949
2957
  }
2950
2958
  }
2951
2959
  }
package/dist/web.esm.js CHANGED
@@ -645,6 +645,7 @@ class Renderer {
645
645
  this.totalBounds = new Bounds();
646
646
  debug$1.log(target.innerName, '--->');
647
647
  try {
648
+ target.app.emit(RenderEvent.CHILD_START, target);
648
649
  this.emitRender(RenderEvent.START);
649
650
  this.renderOnce(callback);
650
651
  this.emitRender(RenderEvent.END, this.totalBounds);
@@ -942,7 +943,7 @@ class Picker {
942
943
  if (child.isBranch) {
943
944
  if (hit || child.__ignoreHitWorld) {
944
945
  this.eachFind(child.children, child.__onlyHitMask);
945
- if (child.isBranchLeaf && !this.findList.length)
946
+ if (child.isBranchLeaf)
946
947
  this.hitChild(child, point);
947
948
  }
948
949
  }
@@ -1931,9 +1932,10 @@ function image(ui, attrName, paint, boxBounds, firstUse) {
1931
1932
  onLoadError(ui, event, image.error);
1932
1933
  }
1933
1934
  else {
1934
- ignoreRender(ui, true);
1935
- if (firstUse)
1935
+ if (firstUse) {
1936
+ ignoreRender(ui, true);
1936
1937
  onLoad(ui, event);
1938
+ }
1937
1939
  leafPaint.loadId = image.load(() => {
1938
1940
  ignoreRender(ui, false);
1939
1941
  if (!ui.destroyed) {
@@ -2577,11 +2579,12 @@ const { trimRight } = TextRowHelper;
2577
2579
  const { Letter, Single, Before, After, Symbol, Break } = CharType;
2578
2580
  let word, row, wordWidth, rowWidth, realWidth;
2579
2581
  let char, charWidth, startCharSize, charSize, charType, lastCharType, langBreak, afterBreak, paraStart;
2580
- let textDrawData, rows = [], bounds;
2582
+ let textDrawData, rows = [], bounds, findMaxWidth;
2581
2583
  function createRows(drawData, content, style) {
2582
2584
  textDrawData = drawData;
2583
2585
  rows = drawData.rows;
2584
2586
  bounds = drawData.bounds;
2587
+ findMaxWidth = !bounds.width && !style.autoSizeAlign;
2585
2588
  const { __letterSpacing, paraIndent, textCase } = style;
2586
2589
  const { canvas } = Platform;
2587
2590
  const { width, height } = bounds;
@@ -2666,7 +2669,10 @@ function createRows(drawData, content, style) {
2666
2669
  else {
2667
2670
  content.split('\n').forEach(content => {
2668
2671
  textDrawData.paraNumber++;
2669
- rows.push({ x: paraIndent || 0, text: content, width: canvas.measureText(content).width, paraStart: true });
2672
+ rowWidth = canvas.measureText(content).width;
2673
+ rows.push({ x: paraIndent || 0, text: content, width: rowWidth, paraStart: true });
2674
+ if (findMaxWidth)
2675
+ setMaxWidth();
2670
2676
  });
2671
2677
  }
2672
2678
  }
@@ -2697,10 +2703,16 @@ function addRow() {
2697
2703
  row.width = rowWidth;
2698
2704
  if (bounds.width)
2699
2705
  trimRight(row);
2706
+ else if (findMaxWidth)
2707
+ setMaxWidth();
2700
2708
  rows.push(row);
2701
2709
  row = { words: [] };
2702
2710
  rowWidth = 0;
2703
2711
  }
2712
+ function setMaxWidth() {
2713
+ if (rowWidth > (textDrawData.maxWidth || 0))
2714
+ textDrawData.maxWidth = rowWidth;
2715
+ }
2704
2716
 
2705
2717
  const CharMode = 0;
2706
2718
  const WordMode = 1;
@@ -2772,34 +2784,32 @@ function toChar(data, charX, rowData, isOverflow) {
2772
2784
 
2773
2785
  function layoutText(drawData, style) {
2774
2786
  const { rows, bounds } = drawData;
2775
- const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing } = style;
2787
+ const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
2776
2788
  let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2777
2789
  let starY = __baseLine;
2778
2790
  if (__clipText && realHeight > height) {
2779
2791
  realHeight = Math.max(height, __lineHeight);
2780
2792
  drawData.overflow = rows.length;
2781
2793
  }
2782
- else {
2794
+ else if (height || autoSizeAlign) {
2783
2795
  switch (verticalAlign) {
2784
2796
  case 'middle':
2785
2797
  y += (height - realHeight) / 2;
2786
2798
  break;
2787
- case 'bottom':
2788
- y += (height - realHeight);
2799
+ case 'bottom': y += (height - realHeight);
2789
2800
  }
2790
2801
  }
2791
2802
  starY += y;
2792
- let row, rowX, rowWidth;
2803
+ let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
2793
2804
  for (let i = 0, len = rows.length; i < len; i++) {
2794
2805
  row = rows[i];
2795
2806
  row.x = x;
2796
2807
  if (row.width < width || (row.width > width && !__clipText)) {
2797
2808
  switch (textAlign) {
2798
2809
  case 'center':
2799
- row.x += (width - row.width) / 2;
2810
+ row.x += (layoutWidth - row.width) / 2;
2800
2811
  break;
2801
- case 'right':
2802
- row.x += width - row.width;
2812
+ case 'right': row.x += layoutWidth - row.width;
2803
2813
  }
2804
2814
  }
2805
2815
  if (row.paraStart && paraSpacing && i > 0)
@@ -2904,14 +2914,14 @@ function getDrawData(content, style) {
2904
2914
  let height = style.__getInput('height') || 0;
2905
2915
  const { textDecoration, __font, __padding: padding } = style;
2906
2916
  if (padding) {
2907
- if (width) {
2917
+ if (width)
2918
+ x = padding[left], width -= (padding[right] + padding[left]);
2919
+ else if (!style.autoSizeAlign)
2908
2920
  x = padding[left];
2909
- width -= (padding[right] + padding[left]);
2910
- }
2911
- if (height) {
2921
+ if (height)
2922
+ y = padding[top], height -= (padding[top] + padding[bottom]);
2923
+ else if (!style.autoSizeAlign)
2912
2924
  y = padding[top];
2913
- height -= (padding[top] + padding[bottom]);
2914
- }
2915
2925
  }
2916
2926
  const drawData = {
2917
2927
  bounds: { x, y, width, height },
@@ -2931,22 +2941,20 @@ function getDrawData(content, style) {
2931
2941
  return drawData;
2932
2942
  }
2933
2943
  function padAutoText(padding, drawData, style, width, height) {
2934
- if (!width) {
2944
+ if (!width && style.autoSizeAlign) {
2935
2945
  switch (style.textAlign) {
2936
2946
  case 'left':
2937
2947
  offsetText(drawData, 'x', padding[left]);
2938
2948
  break;
2939
- case 'right':
2940
- offsetText(drawData, 'x', -padding[right]);
2949
+ case 'right': offsetText(drawData, 'x', -padding[right]);
2941
2950
  }
2942
2951
  }
2943
- if (!height) {
2952
+ if (!height && style.autoSizeAlign) {
2944
2953
  switch (style.verticalAlign) {
2945
2954
  case 'top':
2946
2955
  offsetText(drawData, 'y', padding[top]);
2947
2956
  break;
2948
- case 'bottom':
2949
- offsetText(drawData, 'y', -padding[bottom]);
2957
+ case 'bottom': offsetText(drawData, 'y', -padding[bottom]);
2950
2958
  }
2951
2959
  }
2952
2960
  }