leafer-ui 1.3.3 → 1.4.1

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
@@ -12,7 +12,11 @@
12
12
 
13
13
  📘 [绝境中盛开,LeaferJS 的创业故事](https://leaferjs.com/ui/blog/2024-04-08.html)
14
14
 
15
- 如果你觉得不错,请帮我们点个 [Star](https://github.com/leaferjs/leafer-ui) 🌟 ,让这个库被更多的人看见 - [GitHub](https://github.com/leaferjs/leafer-ui) / [Gitee](https://gitee.com/leaferjs/ui) ✨ ✨ ✨
15
+ 如果你觉得不错,请帮我们点个 [Star](https://github.com/leaferjs/leafer-ui) 🌟 ,让这个库被更多的人看见 ✨ ✨ ✨
16
+
17
+ <a target="_blank" href="https://github.com/leaferjs/leafer-ui">
18
+ <img width="120" title="github" src="https://www.leaferjs.com/svg/github-stars.svg" />
19
+ </a>
16
20
 
17
21
  ## 快速入门
18
22
 
@@ -26,22 +30,15 @@
26
30
 
27
31
  ## 快速安装
28
32
 
29
- 🚀 想马上在产品中使用,请安装 [leafer-ui](https://leaferjs.com/ui/guide/install/ui/start.html),开始你的探索之旅。
33
+ 🚀 想马上在产品中使用,请安装 [leafer-ui](https://leaferjs.com/ui/guide/install/ui/start.html)(60KB min+gzip),开始你的探索之旅。
30
34
 
31
- ## 场景包
35
+ <!-- ### 场景包
32
36
 
33
37
  高效绘图场景,推荐直接安装更轻量的 [leafer-draw](https://leaferjs.com/ui/guide/install/draw/start.html) (50KB min+gzip)。
34
38
 
35
39
  游戏开发场景,推荐直接安装更省心的 [leafer-game](https://leaferjs.com/ui/guide/install/game/start.html),已集成了游戏相关插件。
36
40
 
37
- 图形编辑场景,推荐直接安装更省心的 [leafer-editor](https://leaferjs.com/ui/guide/install/editor/start.html),已集成了图形编辑器相关插件。
38
-
39
- ## 互动交流
40
-
41
- 有 Bug、建议可以 [提交 issue](https://github.com/leaferjs/leafer-ui/issues),留下你的贡献足迹,了解 [提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md#%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7)
42
-
43
-
44
- 欢迎加入 [技术交流群](https://leaferjs.com/#contact) ,与小伙伴们建立联系,共同学习进步,偶尔会有特殊福利。
41
+ 图形编辑场景,推荐直接安装更省心的 [leafer-editor](https://leaferjs.com/ui/guide/install/editor/start.html),已集成了图形编辑器相关插件。 -->
45
42
 
46
43
  ## 仓库组成
47
44
 
@@ -61,6 +58,62 @@
61
58
 
62
59
  [docs](https://github.com/leaferjs/docs) 在线文档仓库。
63
60
 
61
+ ## 社区提问指南
62
+
63
+ ### ⏰ 每周 4 天工作制
64
+
65
+ LeaferJS 试行 [4 天工作制](https://www.leaferjs.com/ui/blog/2025-02-06.html)(周一、二、四、五),寻求支持请留意时间,感谢你的支持与理解。
66
+
67
+ ### 一. 反馈 Bug 与建议
68
+
69
+ 发现 Bug 或有改进建议?欢迎在 GitHub 上 [提交 issue](https://github.com/leaferjs/leafer-ui/issues),你的贡献能让 LeaferJS 变得更强大!
70
+
71
+ ```
72
+ 提交模版
73
+
74
+ 【Bug/建议】xxxxxxxxxxx 标题 xxxxxxxxxxxxxx
75
+
76
+ 环境:电脑 + window 11 + chrome 131 + leaferjs 1.4.1
77
+
78
+ 复现步骤:请提供详细的复现逻辑及可直接运行的代码,以便更快解决问题。
79
+ ```
80
+
81
+ ### 二. 求助使用问题?
82
+
83
+ 使用过程中遇到不懂的问题或缺失功能?我们提供了多种求助渠道,同时也招募社区管理员参与。
84
+
85
+ #### 1. 社区支持(推荐)
86
+
87
+ 为让更多的人可以参与解答,同时让搜索引擎收录问题(避免重复劳动),请公开求助你的问题。
88
+
89
+ [前往知乎](https://www.zhihu.com/topic/736459154/unanswered) 创建一个问题并绑定话题 [#LeaferJS](https://www.zhihu.com/topic/736459154/unanswered):
90
+
91
+ ```
92
+ 提交模版
93
+
94
+ 【leaferjs】xxxxxxxxxxx 标题 xxxxxxxxxxxxxx
95
+
96
+ 环境:电脑 + window 11 + chrome 131 + leaferjs 1.4.1
97
+
98
+ #LeaferJS (点击知乎提问框底部的 # 号,可绑定话题)
99
+ ```
100
+
101
+ 我和社区管理员们会安排固定的时间查看、回复大家的问题,也可将链接转发到 [LeaferJS 技术交流群](https://leaferjs.com/#contact) 里。多次有效回答问题即视为有意愿成为 LeaferJS 社区管理员,可 [联系我们](https://leaferjs.com/#contact) 进管理群。
102
+
103
+ #### 2. 官方支持
104
+
105
+ 由于资源有限,我们优先为 [金牌以上赞助用户](https://www.leaferjs.com/ui/sponsor/#%E5%BC%80%E5%8F%91%E8%B5%9E%E5%8A%A9) 和社区管理员提供支持(如优先修复 Bug、补充缺失功能)。随着资源增加,我们将招募更多专业人员,并开发系统化的 LeaferJS 场景教程。
106
+
107
+ #### 3. 询问 AI (即将上线)
108
+
109
+ 我们计划训练、对接外部 AI 助手,预计 **未来几个月内** 上线,可自动解答 LeaferJS 相关问题。
110
+
111
+ ### 三、技术交流
112
+
113
+ 欢迎加入 [LeaferJS 技术交流群](https://leaferjs.com/#contact),与社区开发者交流、分享经验、改进产品。
114
+
115
+ 偶尔还有 **福利活动**,不容错过!
116
+
64
117
  ## 使命与愿景
65
118
 
66
119
  LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标准,表现力丰富,便于 AI 理解,人类可视化使用,并为数字化产品开发提供跨平台、轻量化、高性能的运行时。
@@ -71,6 +124,8 @@ LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
71
124
 
72
125
  我们的目标不仅是让它成为前沿的 2D 和未来的 3D 引擎技术,还希望它能够为开发者带来极致的开发体验,助力开发者快速构建 AI 时代的网页、应用、设计、画布、游戏和动画等可视化生产力工具(如下一代 local-first 的 Figma、Miro、Notion、Unity、Adobe、Canva、Webflow 等)。
73
126
 
127
+ ![leaferjs](https://www.leaferjs.com/ui/svg/leaferjs.svg?d=013007)
128
+
74
129
  ![覆盖场景](https://www.leaferjs.com/ui/image/blog/20241120/plan.jpg)
75
130
 
76
131
  这是一段漫长而又充满乐趣的旅程,我们正在年复一年、坚定地向这个目标持续前进,可以通过 [开发计划](https://www.leaferjs.com/ui/plan/) 了解更多信息。
@@ -99,8 +154,6 @@ LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
99
154
 
100
155
  [提问的智慧](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md#%E6%8F%90%E9%97%AE%E7%9A%84%E6%99%BA%E6%85%A7)
101
156
 
102
- 有问题、建议可以 提交 [issue](/https://github.com/leaferjs/leafer-ui/issues) 讨论,它更加开放与透明,能够帮助社区沉淀经验,避免重复劳动。
103
-
104
157
  ## 致谢贡献者
105
158
 
106
159
  [每一位贡献代码的社区成员](https://github.com/leaferjs/leafer-ui/graphs/contributors)
@@ -141,7 +194,10 @@ LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
141
194
  </p>
142
195
  <p><h3 align="center">银牌赞助</h3></p>
143
196
  <p style="display: flex;flex-wrap: wrap;justify-content: center;gap: 5px;">
144
- <a target="_blank" href="https://frameelf.com/">
197
+ <a target="_blank" href="https://www.u-tools.cn/plugins/detail/%E6%88%AA%E5%9B%BE%E5%B7%A5%E5%85%B7%20Plus/index.html">
198
+ <img width="40" title="截图工具 Plus" src="https://www.leaferjs.com/image/sponsor/user/135.png" loading="lazy" />
199
+ </a>
200
+ <a target="_blank" href="https://frameelf.com/">
145
201
  <img width="40" title="边框水印精灵" src="https://www.leaferjs.com/image/sponsor/user/134.jpg" loading="lazy" />
146
202
  </a>
147
203
  <a target="_blank" href="">
@@ -288,7 +344,7 @@ LeaferJS 致力于实现一套简洁、开放、现代化的 UI 绘图语言标
288
344
  </p>
289
345
  <p><h3 align="center">铜牌赞助</h3></p>
290
346
  <p style="display: flex;flex-wrap: wrap;justify-content: center;gap: 15px;">
291
- 张余🌈 &nbsp;&nbsp;Jerry &nbsp;&nbsp;李狗嗨。💢 &nbsp;&nbsp;李维亮 &nbsp;&nbsp;朝夕 &nbsp;&nbsp;SaltedFish &nbsp;&nbsp;zhk &nbsp;&nbsp;格子 &nbsp;&nbsp;等等 &nbsp;&nbsp;goosen &nbsp;&nbsp;建伟F4nniu &nbsp;&nbsp;梁福斌 &nbsp;&nbsp;江万江 &nbsp;&nbsp;杨超 &nbsp;&nbsp;ToB Dev &nbsp;&nbsp;前端之虎陈随易 &nbsp;&nbsp;A☀️云☀️A &nbsp;&nbsp;ʚ LMT ɞ &nbsp;&nbsp;爱发电用户_c9c82 &nbsp;&nbsp;轻简历 &nbsp;&nbsp;爱发电用户_0fac0 &nbsp;&nbsp;wangyesheji.cn &nbsp;&nbsp;风间 &nbsp;&nbsp;爱发电用户_Tqsm &nbsp;&nbsp;爱发电用户_6KpE &nbsp;&nbsp;dongdong &nbsp;&nbsp;zwm &nbsp;&nbsp;爱发电用户_3725c &nbsp;&nbsp;Noth1ng &nbsp;&nbsp;纳西妲の√ &nbsp;&nbsp;爱发电用户_Ahb9 &nbsp;&nbsp;爱发电用户_7617d &nbsp;&nbsp;冷漠 &nbsp;&nbsp;爱发电用户_9RXB &nbsp;&nbsp;今日值得读 &nbsp;&nbsp;爱发电用户_49sT &nbsp;&nbsp;爱发电用户_NFCS &nbsp;&nbsp;爱发电用户_43ad8 &nbsp;&nbsp;爱发电用户_30455 &nbsp;&nbsp;xiaozhang &nbsp;&nbsp;砖吐筷筷 &nbsp;&nbsp;爱发电用户_b47b3 &nbsp;&nbsp;longbow1998 &nbsp;&nbsp;爱发电用户_5d755 &nbsp;&nbsp;爱发电用户_b76b8 &nbsp;&nbsp;爱发电用户_e70c2 &nbsp;&nbsp;爱发电用户_039dc &nbsp;&nbsp;花祁 &nbsp;&nbsp;爱发电用户_99f39 &nbsp;&nbsp;坤坤 &nbsp;&nbsp;爱发电用户_X6hp &nbsp;&nbsp;爱发电用户_s5u9 &nbsp;&nbsp;曹吉美爸爸 &nbsp;&nbsp;啸沧海 &nbsp;&nbsp;Ronny &nbsp;&nbsp;Biu &nbsp;&nbsp;王志强 &nbsp;&nbsp;PD.新城คิดถึง &nbsp;&nbsp;糖颂缘冥倾 &nbsp;&nbsp;ALBERT. &nbsp;&nbsp;爱发电用户_UXEV &nbsp;&nbsp;SaltedFish &nbsp;&nbsp;爱发电用户_76f9d &nbsp;&nbsp;Leafer &nbsp;&nbsp;爱发电用户_Pbm7 &nbsp;&nbsp;</p>
347
+ 在路上 &nbsp;&nbsp;张余🌈 &nbsp;&nbsp;Jerry &nbsp;&nbsp;李狗嗨。💢 &nbsp;&nbsp;李维亮 &nbsp;&nbsp;朝夕 &nbsp;&nbsp;SaltedFish &nbsp;&nbsp;zhk &nbsp;&nbsp;格子 &nbsp;&nbsp;等等 &nbsp;&nbsp;goosen &nbsp;&nbsp;建伟F4nniu &nbsp;&nbsp;梁福斌 &nbsp;&nbsp;江万江 &nbsp;&nbsp;杨超 &nbsp;&nbsp;ToB Dev &nbsp;&nbsp;前端之虎陈随易 &nbsp;&nbsp;A☀️云☀️A &nbsp;&nbsp;ʚ LMT ɞ &nbsp;&nbsp;爱发电用户_c9c82 &nbsp;&nbsp;轻简历 &nbsp;&nbsp;爱发电用户_0fac0 &nbsp;&nbsp;wangyesheji.cn &nbsp;&nbsp;风间 &nbsp;&nbsp;爱发电用户_Tqsm &nbsp;&nbsp;爱发电用户_6KpE &nbsp;&nbsp;dongdong &nbsp;&nbsp;zwm &nbsp;&nbsp;爱发电用户_3725c &nbsp;&nbsp;Noth1ng &nbsp;&nbsp;纳西妲の√ &nbsp;&nbsp;爱发电用户_Ahb9 &nbsp;&nbsp;爱发电用户_7617d &nbsp;&nbsp;冷漠 &nbsp;&nbsp;爱发电用户_9RXB &nbsp;&nbsp;今日值得读 &nbsp;&nbsp;爱发电用户_49sT &nbsp;&nbsp;爱发电用户_NFCS &nbsp;&nbsp;爱发电用户_43ad8 &nbsp;&nbsp;爱发电用户_30455 &nbsp;&nbsp;xiaozhang &nbsp;&nbsp;砖吐筷筷 &nbsp;&nbsp;爱发电用户_b47b3 &nbsp;&nbsp;longbow1998 &nbsp;&nbsp;爱发电用户_5d755 &nbsp;&nbsp;爱发电用户_b76b8 &nbsp;&nbsp;爱发电用户_e70c2 &nbsp;&nbsp;爱发电用户_039dc &nbsp;&nbsp;花祁 &nbsp;&nbsp;爱发电用户_99f39 &nbsp;&nbsp;坤坤 &nbsp;&nbsp;爱发电用户_X6hp &nbsp;&nbsp;爱发电用户_s5u9 &nbsp;&nbsp;曹吉美爸爸 &nbsp;&nbsp;啸沧海 &nbsp;&nbsp;Ronny &nbsp;&nbsp;Biu &nbsp;&nbsp;王志强 &nbsp;&nbsp;PD.新城คิดถึง &nbsp;&nbsp;糖颂缘冥倾 &nbsp;&nbsp;ALBERT. &nbsp;&nbsp;爱发电用户_UXEV &nbsp;&nbsp;SaltedFish &nbsp;&nbsp;爱发电用户_76f9d &nbsp;&nbsp;Leafer &nbsp;&nbsp;爱发电用户_Pbm7 &nbsp;&nbsp;</p>
292
348
 
293
349
  ## License
294
350
 
package/dist/web.cjs CHANGED
@@ -122,7 +122,7 @@ class LeaferCanvas extends core.LeaferCanvasBase {
122
122
  }
123
123
  }
124
124
  else {
125
- window.addEventListener('resize', () => {
125
+ window.addEventListener('resize', this.windowListener = () => {
126
126
  const pixelRatio = core.Platform.devicePixelRatio;
127
127
  if (this.pixelRatio !== pixelRatio) {
128
128
  const { width, height } = this;
@@ -151,11 +151,9 @@ class LeaferCanvas extends core.LeaferCanvasBase {
151
151
  }
152
152
  stopAutoLayout() {
153
153
  this.autoLayout = false;
154
- this.resizeListener = null;
155
- if (this.resizeObserver) {
154
+ if (this.resizeObserver)
156
155
  this.resizeObserver.disconnect();
157
- this.resizeObserver = null;
158
- }
156
+ this.resizeListener = this.resizeObserver = null;
159
157
  }
160
158
  emitResize(size) {
161
159
  const oldSize = {};
@@ -176,6 +174,10 @@ class LeaferCanvas extends core.LeaferCanvasBase {
176
174
  destroy() {
177
175
  if (this.view) {
178
176
  this.stopAutoLayout();
177
+ if (this.windowListener) {
178
+ window.removeEventListener('resize', this.windowListener);
179
+ this.windowListener = null;
180
+ }
179
181
  if (!this.unreal) {
180
182
  const view = this.view;
181
183
  if (view.parentElement)
@@ -202,7 +204,10 @@ function useCanvas(_canvasType, _power) {
202
204
  canvas.height = height;
203
205
  return canvas;
204
206
  },
205
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
207
+ canvasToDataURL: (canvas, type, quality) => {
208
+ const imageType = mineType(type), url = canvas.toDataURL(imageType, quality);
209
+ return imageType === 'image/bmp' ? url.replace('image/png;', 'image/bmp;') : url;
210
+ },
206
211
  canvasToBolb: (canvas, type, quality) => new Promise((resolve) => canvas.toBlob(resolve, mineType(type), quality)),
207
212
  canvasSaveAs: (canvas, filename, quality) => {
208
213
  const url = canvas.toDataURL(mineType(fileType(filename)), quality);
@@ -247,14 +252,14 @@ function useCanvas(_canvasType, _power) {
247
252
  core.Platform.name = 'web';
248
253
  core.Platform.isMobile = 'ontouchstart' in window;
249
254
  core.Platform.requestRender = function (render) { window.requestAnimationFrame(render); };
250
- core.defineKey(core.Platform, 'devicePixelRatio', { get() { return Math.max(1, devicePixelRatio); } });
255
+ core.defineKey(core.Platform, 'devicePixelRatio', { get() { return devicePixelRatio; } });
251
256
  const { userAgent } = navigator;
252
257
  if (userAgent.indexOf("Firefox") > -1) {
253
258
  core.Platform.conicGradientRotate90 = true;
254
259
  core.Platform.intWheelDeltaY = true;
255
260
  core.Platform.syncDomFont = true;
256
261
  }
257
- else if (userAgent.indexOf("Safari") > -1 && userAgent.indexOf("Chrome") === -1) {
262
+ else if (userAgent.indexOf("AppleWebKit") > -1) {
258
263
  core.Platform.fullImageShadow = true;
259
264
  }
260
265
  if (userAgent.indexOf('Windows') > -1) {
@@ -523,7 +528,7 @@ class Layouter {
523
528
  }
524
529
  partLayout() {
525
530
  var _a;
526
- if (!((_a = this.__updatedList) === null || _a === undefined ? undefined : _a.length))
531
+ if (!((_a = this.__updatedList) === null || _a === void 0 ? void 0 : _a.length))
527
532
  return;
528
533
  const t = core.Run.start('PartLayout');
529
534
  const { target, __updatedList: updateList } = this;
@@ -988,9 +993,10 @@ class Selector {
988
993
  this.finder = core.Creator.finder && core.Creator.finder();
989
994
  }
990
995
  getByPoint(hitPoint, hitRadius, options) {
991
- if (core.Platform.backgrounder && this.target)
992
- this.target.updateLayout();
993
- return this.picker.getByPoint(hitPoint, hitRadius, options);
996
+ const { target, picker } = this;
997
+ if (core.Platform.backgrounder)
998
+ target && target.updateLayout();
999
+ return picker.getByPoint(hitPoint, hitRadius, options);
994
1000
  }
995
1001
  getBy(condition, branch, one, options) {
996
1002
  return this.finder ? this.finder.getBy(condition, branch, one, options) : core.Plugin.need('find');
@@ -1053,6 +1059,7 @@ class Interaction extends core$1.InteractionBase {
1053
1059
  'pointerdown': this.onPointerDown,
1054
1060
  'mousedown': this.onMouseDown,
1055
1061
  'touchstart': this.onTouchStart,
1062
+ 'pointerleave': this.onPointerLeave,
1056
1063
  'contextmenu': this.onContextMenu,
1057
1064
  'wheel': this.onWheel,
1058
1065
  'gesturestart': this.onGesturestart,
@@ -1135,11 +1142,15 @@ class Interaction extends core$1.InteractionBase {
1135
1142
  this.usePointer || (this.usePointer = true);
1136
1143
  this.pointerDown(PointerEventHelper.convert(e, this.getLocal(e)));
1137
1144
  }
1138
- onPointerMove(e) {
1145
+ onPointerMove(e, isLeave) {
1139
1146
  if (this.config.pointer.touch || this.useMultiTouch || this.preventWindowPointer(e))
1140
1147
  return;
1141
1148
  this.usePointer || (this.usePointer = true);
1142
- this.pointerMove(PointerEventHelper.convert(e, this.getLocal(e, true)));
1149
+ const data = PointerEventHelper.convert(e, this.getLocal(e, true));
1150
+ isLeave ? this.pointerHover(data) : this.pointerMove(data);
1151
+ }
1152
+ onPointerLeave(e) {
1153
+ this.onPointerMove(e, true);
1143
1154
  }
1144
1155
  onPointerUp(e) {
1145
1156
  if (this.downData)
@@ -1673,7 +1684,7 @@ function getPatternData(paint, box, image) {
1673
1684
  box = tempBox.set(box).shrink(paint.padding);
1674
1685
  if (paint.mode === 'strench')
1675
1686
  paint.mode = 'stretch';
1676
- const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
1687
+ const { opacity, mode, align, offset, scale, size, rotation, repeat, filters } = paint;
1677
1688
  const sameBox = box.width === width && box.height === height;
1678
1689
  const data = { mode };
1679
1690
  const swapSize = align !== 'center' && (rotation || 0) % 180 === 90;
@@ -1736,6 +1747,8 @@ function getPatternData(paint, box, image) {
1736
1747
  data.height = height;
1737
1748
  if (opacity)
1738
1749
  data.opacity = opacity;
1750
+ if (filters)
1751
+ data.filters = filters;
1739
1752
  if (repeat)
1740
1753
  data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat';
1741
1754
  return data;
@@ -1838,7 +1851,7 @@ function createPattern(ui, paint, pixelRatio) {
1838
1851
  scaleX = abs$1(scaleX);
1839
1852
  scaleY = abs$1(scaleY);
1840
1853
  const { image, data } = paint;
1841
- let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data;
1854
+ let imageScale, imageMatrix, { width, height, scaleX: sx, scaleY: sy, transform, repeat } = data;
1842
1855
  if (sx) {
1843
1856
  imageMatrix = get$1();
1844
1857
  copy$1(imageMatrix, transform);
@@ -1881,7 +1894,7 @@ function createPattern(ui, paint, pixelRatio) {
1881
1894
  }
1882
1895
  scale(imageMatrix, 1 / scaleX, 1 / scaleY);
1883
1896
  }
1884
- const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, opacity);
1897
+ const canvas = image.getCanvas(ceil(width) || 1, ceil(height) || 1, data.opacity, data.filters);
1885
1898
  const pattern = image.getPattern(canvas, repeat || (core.Platform.origin.noRepeat || 'no-repeat'), imageMatrix, paint);
1886
1899
  paint.style = pattern;
1887
1900
  paint.patternId = id;
@@ -1957,7 +1970,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1957
1970
  canvas.opacity *= data.opacity;
1958
1971
  if (data.transform)
1959
1972
  canvas.transform(data.transform);
1960
- canvas.drawImage(paint.image.view, 0, 0, data.width, data.height);
1973
+ canvas.drawImage(paint.image.getFull(data.filters), 0, 0, data.width, data.height);
1961
1974
  canvas.restore();
1962
1975
  return true;
1963
1976
  }
@@ -1967,7 +1980,7 @@ function checkImage(ui, canvas, paint, allowPaint) {
1967
1980
  }
1968
1981
  else {
1969
1982
  if (!paint.patternTask) {
1970
- paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, undefined, undefined, function* () {
1983
+ paint.patternTask = core.ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1971
1984
  paint.patternTask = null;
1972
1985
  if (canvas.bounds.hit(ui.__nowWorld))
1973
1986
  createPattern(ui, paint, pixelRatio);
@@ -2557,11 +2570,11 @@ const TextMode = 2;
2557
2570
  function layoutChar(drawData, style, width, _height) {
2558
2571
  const { rows } = drawData;
2559
2572
  const { textAlign, paraIndent, letterSpacing } = style;
2560
- let charX, addWordWidth, indentWidth, mode, wordChar;
2573
+ let charX, addWordWidth, indentWidth, mode, wordChar, wordsLength;
2561
2574
  rows.forEach(row => {
2562
2575
  if (row.words) {
2563
- indentWidth = paraIndent && row.paraStart ? paraIndent : 0;
2564
- addWordWidth = (width && (textAlign === 'justify' || textAlign === 'both') && row.words.length > 1) ? (width - row.width - indentWidth) / (row.words.length - 1) : 0;
2576
+ indentWidth = paraIndent && row.paraStart ? paraIndent : 0, wordsLength = row.words.length;
2577
+ addWordWidth = (width && (textAlign === 'justify' || textAlign === 'both') && wordsLength > 1) ? (width - row.width - indentWidth) / (wordsLength - 1) : 0;
2565
2578
  mode = (letterSpacing || row.isOverflow) ? CharMode : (addWordWidth > 0.01 ? WordMode : TextMode);
2566
2579
  if (row.isOverflow && !letterSpacing)
2567
2580
  row.textMode = true;
@@ -2573,7 +2586,7 @@ function layoutChar(drawData, style, width, _height) {
2573
2586
  row.x += indentWidth;
2574
2587
  charX = row.x;
2575
2588
  row.data = [];
2576
- row.words.forEach(word => {
2589
+ row.words.forEach((word, index) => {
2577
2590
  if (mode === WordMode) {
2578
2591
  wordChar = { char: '', x: charX };
2579
2592
  charX = toWordChar(word.data, charX, wordChar);
@@ -2583,7 +2596,7 @@ function layoutChar(drawData, style, width, _height) {
2583
2596
  else {
2584
2597
  charX = toChar(word.data, charX, row.data, row.isOverflow);
2585
2598
  }
2586
- if (addWordWidth && (!row.paraEnd || textAlign === 'both')) {
2599
+ if (addWordWidth && (!row.paraEnd || textAlign === 'both') && (index !== wordsLength - 1)) {
2587
2600
  charX += addWordWidth;
2588
2601
  row.width += addWordWidth;
2589
2602
  }
@@ -2863,3 +2876,4 @@ Object.keys(core$1).forEach(function (k) {
2863
2876
  get: function () { return core$1[k]; }
2864
2877
  });
2865
2878
  });
2879
+ //# sourceMappingURL=web.cjs.map