leafer-ui 1.5.2 → 1.6.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/README.md +1 -57
- package/dist/web.cjs +68 -71
- package/dist/web.cjs.map +1 -1
- package/dist/web.esm.js +68 -71
- package/dist/web.esm.js.map +1 -1
- package/dist/web.esm.min.js +1 -1
- package/dist/web.esm.min.js.map +1 -1
- package/dist/web.js +303 -192
- package/dist/web.js.map +1 -1
- package/dist/web.min.cjs +1 -1
- package/dist/web.min.cjs.map +1 -1
- package/dist/web.min.js +1 -1
- package/dist/web.min.js.map +1 -1
- package/dist/web.module.js +303 -192
- package/dist/web.module.js.map +1 -1
- package/dist/web.module.min.js +1 -1
- package/dist/web.module.min.js.map +1 -1
- package/package.json +11 -12
package/README.md
CHANGED
|
@@ -63,62 +63,6 @@
|
|
|
63
63
|
|
|
64
64
|
[docs](https://github.com/leaferjs/docs) 在线文档仓库。
|
|
65
65
|
|
|
66
|
-
## 社区提问指南
|
|
67
|
-
|
|
68
|
-
### ⏰ 每周 4 天工作制
|
|
69
|
-
|
|
70
|
-
LeaferJS 试行 [4 天工作制](https://www.leaferjs.com/ui/blog/2025-02-06.html)(周一、二、四、五),寻求支持请留意时间,感谢你的支持与理解。
|
|
71
|
-
|
|
72
|
-
### 一. 反馈 Bug 与建议
|
|
73
|
-
|
|
74
|
-
发现 Bug 或有改进建议?欢迎在 GitHub 上 [提交 issue](https://github.com/leaferjs/leafer-ui/issues),你的贡献能让 LeaferJS 变得更强大!
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
提交模版
|
|
78
|
-
|
|
79
|
-
【Bug/建议】xxxxxxxxxxx 标题 xxxxxxxxxxxxxx
|
|
80
|
-
|
|
81
|
-
环境:电脑 + window 11 + chrome 131 + leaferjs 1.5.2
|
|
82
|
-
|
|
83
|
-
复现步骤:请提供详细的复现逻辑及可直接运行的代码,以便更快解决问题。
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### 二. 求助使用问题?
|
|
87
|
-
|
|
88
|
-
使用过程中遇到不懂的问题或缺失功能?我们提供了多种求助渠道,同时也招募社区管理员参与。
|
|
89
|
-
|
|
90
|
-
#### 1. 社区支持(推荐)
|
|
91
|
-
|
|
92
|
-
为让更多的人可以参与解答,同时让搜索引擎收录问题(避免重复劳动),请公开求助你的问题。
|
|
93
|
-
|
|
94
|
-
[前往知乎](https://www.zhihu.com/topic/736459154/unanswered) 创建一个问题并绑定话题 [#LeaferJS](https://www.zhihu.com/topic/736459154/unanswered):
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
提交模版
|
|
98
|
-
|
|
99
|
-
【leaferjs】xxxxxxxxxxx 标题 xxxxxxxxxxxxxx
|
|
100
|
-
|
|
101
|
-
环境:电脑 + window 11 + chrome 131 + leaferjs 1.5.2
|
|
102
|
-
|
|
103
|
-
#LeaferJS (点击知乎提问框底部的 # 号,可绑定话题)
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
我和社区管理员们会安排固定的时间查看、回复大家的问题,也可将链接转发到 [LeaferJS 技术交流群](https://leaferjs.com/#contact) 里。多次有效回答问题即视为有意愿成为 LeaferJS 社区管理员,可 [联系我们](https://leaferjs.com/#contact) 进管理群。
|
|
107
|
-
|
|
108
|
-
#### 2. 官方支持
|
|
109
|
-
|
|
110
|
-
由于资源有限,我们优先为 [金牌以上赞助用户](https://www.leaferjs.com/ui/sponsor/#%E5%BC%80%E5%8F%91%E8%B5%9E%E5%8A%A9) 和社区管理员提供支持(如优先修复 Bug、补充缺失功能)。随着资源增加,我们将招募更多专业人员,并开发系统化的 LeaferJS 场景教程。
|
|
111
|
-
|
|
112
|
-
#### 3. 询问 AI (即将上线)
|
|
113
|
-
|
|
114
|
-
我们计划训练、对接外部 AI 助手,预计 **未来几个月内** 上线,可自动解答 LeaferJS 相关问题。
|
|
115
|
-
|
|
116
|
-
### 三、技术交流
|
|
117
|
-
|
|
118
|
-
欢迎加入 [LeaferJS 技术交流群](https://leaferjs.com/#contact),与社区开发者交流、分享经验、改进产品。
|
|
119
|
-
|
|
120
|
-
偶尔还有 **福利活动**,不容错过!
|
|
121
|
-
|
|
122
66
|
## 使命与愿景
|
|
123
67
|
|
|
124
68
|
LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标准,表现力丰富,便于 AI 理解,人类可视化使用,并为数字化产品开发提供跨平台、轻量化、高性能的运行时。
|
|
@@ -352,7 +296,7 @@ LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
|
|
|
352
296
|
</p>
|
|
353
297
|
<p><h3 align="center">铜牌赞助</h3></p>
|
|
354
298
|
<p style="display: flex;flex-wrap: wrap;justify-content: center;gap: 15px;">
|
|
355
|
-
|
|
299
|
+
Lauginwing 江万江 在路上 张余🌈 Jerry 李狗嗨。💢 李维亮 朝夕 SaltedFish zhk 格子 等等 goosen 建伟F4nniu 梁福斌 江万江 杨超 ToB Dev 前端之虎陈随易 A☀️云☀️A ʚ LMT ɞ 爱发电用户_c9c82 轻简历 爱发电用户_0fac0 wangyesheji.cn 风间 爱发电用户_Tqsm 爱发电用户_6KpE dongdong zwm 爱发电用户_3725c Noth1ng 纳西妲の√ 爱发电用户_Ahb9 爱发电用户_7617d 冷漠 爱发电用户_9RXB 今日值得读 爱发电用户_49sT 爱发电用户_NFCS 爱发电用户_43ad8 爱发电用户_30455 xiaozhang 砖吐筷筷 爱发电用户_b47b3 longbow1998 爱发电用户_5d755 爱发电用户_b76b8 爱发电用户_e70c2 爱发电用户_039dc 花祁 爱发电用户_99f39 坤坤 爱发电用户_X6hp 爱发电用户_s5u9 曹吉美爸爸 啸沧海 Ronny Biu 王志强 PD.新城คิดถึง 糖颂缘冥倾 ALBERT. 爱发电用户_UXEV SaltedFish 爱发电用户_76f9d Leafer 爱发电用户_Pbm7 </p>
|
|
356
300
|
|
|
357
301
|
## License
|
|
358
302
|
|
package/dist/web.cjs
CHANGED
|
@@ -423,7 +423,6 @@ function updateChange(updateList) {
|
|
|
423
423
|
}
|
|
424
424
|
|
|
425
425
|
const { worldBounds } = core.LeafBoundsHelper;
|
|
426
|
-
const bigBounds = { x: 0, y: 0, width: 100000, height: 100000 };
|
|
427
426
|
class LayoutBlockData {
|
|
428
427
|
constructor(list) {
|
|
429
428
|
this.updatedBounds = new core.Bounds();
|
|
@@ -437,13 +436,7 @@ class LayoutBlockData {
|
|
|
437
436
|
this.beforeBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
438
437
|
}
|
|
439
438
|
setAfter() {
|
|
440
|
-
|
|
441
|
-
if (list.some(leaf => leaf.noBounds)) {
|
|
442
|
-
this.afterBounds.set(bigBounds);
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
this.afterBounds.setListWithFn(list, worldBounds);
|
|
446
|
-
}
|
|
439
|
+
this.afterBounds.setListWithFn(this.updatedList.list, worldBounds);
|
|
447
440
|
this.updatedBounds.setList([this.beforeBounds, this.afterBounds]);
|
|
448
441
|
}
|
|
449
442
|
merge(data) {
|
|
@@ -645,6 +638,13 @@ class Renderer {
|
|
|
645
638
|
requestLayout() {
|
|
646
639
|
this.target.emit(core.LayoutEvent.REQUEST);
|
|
647
640
|
}
|
|
641
|
+
checkRender() {
|
|
642
|
+
if (this.running) {
|
|
643
|
+
if (this.changed && this.canvas.view)
|
|
644
|
+
this.render();
|
|
645
|
+
this.target.emit(core.RenderEvent.NEXT);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
648
|
render(callback) {
|
|
649
649
|
if (!(this.running && this.canvas.view))
|
|
650
650
|
return this.update();
|
|
@@ -653,8 +653,6 @@ class Renderer {
|
|
|
653
653
|
this.totalBounds = new core.Bounds();
|
|
654
654
|
debug.log(target.innerName, '--->');
|
|
655
655
|
try {
|
|
656
|
-
if (!target.isApp)
|
|
657
|
-
target.app.emit(core.RenderEvent.CHILD_START, target);
|
|
658
656
|
this.emitRender(core.RenderEvent.START);
|
|
659
657
|
this.renderOnce(callback);
|
|
660
658
|
this.emitRender(core.RenderEvent.END, this.totalBounds);
|
|
@@ -722,20 +720,12 @@ class Renderer {
|
|
|
722
720
|
}
|
|
723
721
|
clipRender(block) {
|
|
724
722
|
const t = core.Run.start('PartRender');
|
|
725
|
-
const { canvas } = this;
|
|
726
|
-
const bounds = block.getIntersect(canvas.bounds);
|
|
727
|
-
const includes = block.includes(this.target.__world);
|
|
728
|
-
const realBounds = new core.Bounds(bounds);
|
|
723
|
+
const { canvas } = this, bounds = block.getIntersect(canvas.bounds), realBounds = new core.Bounds(bounds);
|
|
729
724
|
canvas.save();
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
bounds.spread(10 + 1 / this.canvas.pixelRatio).ceil();
|
|
735
|
-
canvas.clearWorld(bounds, true);
|
|
736
|
-
canvas.clipWorld(bounds, true);
|
|
737
|
-
}
|
|
738
|
-
this.__render(bounds, includes, realBounds);
|
|
725
|
+
bounds.spread(Renderer.clipSpread).ceil();
|
|
726
|
+
canvas.clearWorld(bounds, true);
|
|
727
|
+
canvas.clipWorld(bounds, true);
|
|
728
|
+
this.__render(bounds, block.includes(this.target.__world), realBounds);
|
|
739
729
|
canvas.restore();
|
|
740
730
|
core.Run.end(t);
|
|
741
731
|
}
|
|
@@ -749,23 +739,17 @@ class Renderer {
|
|
|
749
739
|
core.Run.end(t);
|
|
750
740
|
}
|
|
751
741
|
__render(bounds, includes, realBounds) {
|
|
752
|
-
const options =
|
|
742
|
+
const { canvas } = this, options = includes ? { includes } : { bounds, includes };
|
|
753
743
|
if (this.needFill)
|
|
754
|
-
|
|
744
|
+
canvas.fillWorld(bounds, this.config.fill);
|
|
755
745
|
if (core.Debug.showRepaint)
|
|
756
|
-
|
|
757
|
-
this.target.__render(
|
|
746
|
+
core.Debug.drawRepaint(canvas, bounds);
|
|
747
|
+
this.target.__render(canvas, options);
|
|
758
748
|
this.renderBounds = realBounds = realBounds || bounds;
|
|
759
749
|
this.renderOptions = options;
|
|
760
750
|
this.totalBounds.isEmpty() ? this.totalBounds = realBounds : this.totalBounds.add(realBounds);
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
if (core.Debug.showBoundsView)
|
|
764
|
-
this.renderBoundsView(options);
|
|
765
|
-
this.canvas.updateRender(realBounds);
|
|
766
|
-
}
|
|
767
|
-
renderHitView(_options) { }
|
|
768
|
-
renderBoundsView(_options) { }
|
|
751
|
+
canvas.updateRender(realBounds);
|
|
752
|
+
}
|
|
769
753
|
addBlock(block) {
|
|
770
754
|
if (!this.updateBlocks)
|
|
771
755
|
this.updateBlocks = [];
|
|
@@ -781,17 +765,24 @@ class Renderer {
|
|
|
781
765
|
}
|
|
782
766
|
}
|
|
783
767
|
__requestRender() {
|
|
768
|
+
const target = this.target;
|
|
769
|
+
if (target.parentApp)
|
|
770
|
+
return target.parentApp.renderer.update(false);
|
|
784
771
|
if (this.requestTime)
|
|
785
772
|
return;
|
|
786
773
|
const requestTime = this.requestTime = Date.now();
|
|
787
774
|
core.Platform.requestRender(() => {
|
|
788
775
|
this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - requestTime)));
|
|
789
776
|
this.requestTime = 0;
|
|
790
|
-
if (
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
777
|
+
if (target.isApp) {
|
|
778
|
+
target.emit(core.RenderEvent.CHILD_START, target);
|
|
779
|
+
target.children.forEach(leafer => {
|
|
780
|
+
leafer.renderer.FPS = this.FPS;
|
|
781
|
+
leafer.renderer.checkRender();
|
|
782
|
+
});
|
|
783
|
+
target.emit(core.RenderEvent.CHILD_END, target);
|
|
794
784
|
}
|
|
785
|
+
this.checkRender();
|
|
795
786
|
});
|
|
796
787
|
}
|
|
797
788
|
__onResize(e) {
|
|
@@ -849,6 +840,7 @@ class Renderer {
|
|
|
849
840
|
}
|
|
850
841
|
}
|
|
851
842
|
}
|
|
843
|
+
Renderer.clipSpread = 10;
|
|
852
844
|
|
|
853
845
|
const { hitRadiusPoint } = core.BoundsHelper;
|
|
854
846
|
class Picker {
|
|
@@ -1677,9 +1669,11 @@ const tempBox = new core.Bounds();
|
|
|
1677
1669
|
const tempPoint = {};
|
|
1678
1670
|
const tempScaleData = {};
|
|
1679
1671
|
function createData(leafPaint, image, paint, box) {
|
|
1680
|
-
const { blendMode, sync } = paint;
|
|
1672
|
+
const { blendMode, changeful, sync } = paint;
|
|
1681
1673
|
if (blendMode)
|
|
1682
1674
|
leafPaint.blendMode = blendMode;
|
|
1675
|
+
if (changeful)
|
|
1676
|
+
leafPaint.changeful = changeful;
|
|
1683
1677
|
if (sync)
|
|
1684
1678
|
leafPaint.sync = sync;
|
|
1685
1679
|
leafPaint.data = getPatternData(paint, box, image);
|
|
@@ -1944,40 +1938,32 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
1944
1938
|
};
|
|
1945
1939
|
|
|
1946
1940
|
const { abs } = Math;
|
|
1947
|
-
function checkImage(ui, canvas, paint,
|
|
1941
|
+
function checkImage(ui, canvas, paint, allowDraw) {
|
|
1948
1942
|
const { scaleX, scaleY } = core.ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
|
|
1949
|
-
const { pixelRatio } = canvas;
|
|
1950
|
-
if (!
|
|
1943
|
+
const { pixelRatio } = canvas, { data } = paint;
|
|
1944
|
+
if (!data || (paint.patternId === scaleX + '-' + scaleY + '-' + pixelRatio && !draw.Export.running)) {
|
|
1951
1945
|
return false;
|
|
1952
1946
|
}
|
|
1953
1947
|
else {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
let { width, height } = data;
|
|
1958
|
-
width *= abs(scaleX) * pixelRatio;
|
|
1959
|
-
height *= abs(scaleY) * pixelRatio;
|
|
1960
|
-
if (data.scaleX) {
|
|
1961
|
-
width *= data.scaleX;
|
|
1962
|
-
height *= data.scaleY;
|
|
1963
|
-
}
|
|
1964
|
-
allowPaint = (width * height > core.Platform.image.maxCacheSize) || draw.Export.running;
|
|
1948
|
+
if (allowDraw) {
|
|
1949
|
+
if (data.repeat) {
|
|
1950
|
+
allowDraw = false;
|
|
1965
1951
|
}
|
|
1966
1952
|
else {
|
|
1967
|
-
|
|
1953
|
+
if (!(paint.changeful || core.ResizeEvent.isResizing(ui) || draw.Export.running)) {
|
|
1954
|
+
let { width, height } = data;
|
|
1955
|
+
width *= abs(scaleX) * pixelRatio;
|
|
1956
|
+
height *= abs(scaleY) * pixelRatio;
|
|
1957
|
+
if (data.scaleX) {
|
|
1958
|
+
width *= data.scaleX;
|
|
1959
|
+
height *= data.scaleY;
|
|
1960
|
+
}
|
|
1961
|
+
allowDraw = (width * height > core.Platform.image.maxCacheSize);
|
|
1962
|
+
}
|
|
1968
1963
|
}
|
|
1969
1964
|
}
|
|
1970
|
-
if (
|
|
1971
|
-
canvas
|
|
1972
|
-
ui.windingRule ? canvas.clip(ui.windingRule) : canvas.clip();
|
|
1973
|
-
if (paint.blendMode)
|
|
1974
|
-
canvas.blendMode = paint.blendMode;
|
|
1975
|
-
if (data.opacity)
|
|
1976
|
-
canvas.opacity *= data.opacity;
|
|
1977
|
-
if (data.transform)
|
|
1978
|
-
canvas.transform(data.transform);
|
|
1979
|
-
canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
|
|
1980
|
-
canvas.restore();
|
|
1965
|
+
if (allowDraw) {
|
|
1966
|
+
drawImage(ui, canvas, paint, data);
|
|
1981
1967
|
return true;
|
|
1982
1968
|
}
|
|
1983
1969
|
else {
|
|
@@ -1998,13 +1984,26 @@ function checkImage(ui, canvas, paint, allowPaint) {
|
|
|
1998
1984
|
}
|
|
1999
1985
|
}
|
|
2000
1986
|
}
|
|
1987
|
+
function drawImage(ui, canvas, paint, data) {
|
|
1988
|
+
canvas.save();
|
|
1989
|
+
ui.windingRule ? canvas.clip(ui.windingRule) : canvas.clip();
|
|
1990
|
+
if (paint.blendMode)
|
|
1991
|
+
canvas.blendMode = paint.blendMode;
|
|
1992
|
+
if (data.opacity)
|
|
1993
|
+
canvas.opacity *= data.opacity;
|
|
1994
|
+
if (data.transform)
|
|
1995
|
+
canvas.transform(data.transform);
|
|
1996
|
+
canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
|
|
1997
|
+
canvas.restore();
|
|
1998
|
+
}
|
|
2001
1999
|
|
|
2002
2000
|
function recycleImage(attrName, data) {
|
|
2003
2001
|
const paints = data['_' + attrName];
|
|
2004
2002
|
if (paints instanceof Array) {
|
|
2005
|
-
let image, recycleMap, input, url;
|
|
2003
|
+
let paint, image, recycleMap, input, url;
|
|
2006
2004
|
for (let i = 0, len = paints.length; i < len; i++) {
|
|
2007
|
-
|
|
2005
|
+
paint = paints[i];
|
|
2006
|
+
image = paint.image;
|
|
2008
2007
|
url = image && image.url;
|
|
2009
2008
|
if (url) {
|
|
2010
2009
|
if (!recycleMap)
|
|
@@ -2019,8 +2018,6 @@ function recycleImage(attrName, data) {
|
|
|
2019
2018
|
}
|
|
2020
2019
|
image.unload(paints[i].loadId, !input.some((item) => item.url === url));
|
|
2021
2020
|
}
|
|
2022
|
-
else
|
|
2023
|
-
paints[i].style = null;
|
|
2024
2021
|
}
|
|
2025
2022
|
}
|
|
2026
2023
|
return recycleMap;
|
|
@@ -2199,7 +2196,7 @@ const { toOffsetOutBounds } = core.BoundsHelper;
|
|
|
2199
2196
|
const offsetOutBounds = {};
|
|
2200
2197
|
function innerShadow(ui, current, shape) {
|
|
2201
2198
|
let copyBounds, spreadScale;
|
|
2202
|
-
const { __nowWorld: nowWorld, __layout
|
|
2199
|
+
const { __nowWorld: nowWorld, __layout } = ui;
|
|
2203
2200
|
const { innerShadow } = ui.__;
|
|
2204
2201
|
const { worldCanvas, bounds, shapeBounds, scaleX, scaleY } = shape;
|
|
2205
2202
|
const other = current.getSameCanvas();
|