leafer-x-watermark 1.3.1 → 2.0.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 CHANGED
@@ -1,210 +1,219 @@
1
- # leafer-x-watermark
2
-
3
- [![npm version][npm-version-src]][npm-version-href]
4
- [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
- [![bundle][bundle-src]][bundle-href]
6
- [![License][license-src]][license-href]
7
-
8
- Leafer UI 水印插件,支持任意 LeaferJS 元素平铺水印
9
-
10
- ## 特性
11
-
12
- - 🎨 **任意图形** - 支持任意 LeaferJS 元素作为水印内容
13
- - 🔄 **平铺模式** - 支持平铺(repeat)和拉伸(stretch)两种模式
14
- - 📐 **灵活缩放** - 支持自定义水印尺寸比例
15
- - 🔲 **间距控制** - 支持自定义水印间距
16
- - 🎯 **错位排列** - 支持水印错位(stagger)效果
17
- - 🔃 **旋转支持** - 支持水印旋转角度设置
18
- - **性能优化** - 智能缓存,仅在必要时重新生成图片
19
-
20
- ## 📦 安装
21
-
22
- ```bash
23
- # pnpm
24
- pnpm add leafer-x-watermark
25
-
26
- # npm
27
- npm install leafer-x-watermark
28
-
29
- # yarn
30
- yarn add leafer-x-watermark
31
- ```
32
-
33
- ## 🚀 快速开始
34
-
35
- ### 基础使用
36
-
37
- ```typescript
38
- import { App } from 'leafer-ui'
39
- import { Watermark } from 'leafer-x-watermark'
40
-
41
- const app = new App({ view: 'app' })
42
-
43
- const watermark = new Watermark({
44
- tileContent: JSON.stringify({
45
- tag: 'Text',
46
- text: '水印文字',
47
- fill: 'rgba(0, 0, 0, 0.1)',
48
- fontSize: 16,
49
- }),
50
- width: 800,
51
- height: 600,
52
- })
53
-
54
- app.tree.add(watermark)
55
- ```
56
-
57
- ### 平铺模式
58
-
59
- ```typescript
60
- const watermark = new Watermark({
61
- tileContent: JSON.stringify({
62
- tag: 'Text',
63
- text: 'CONFIDENTIAL',
64
- fill: 'rgba(255, 0, 0, 0.1)',
65
- fontSize: 20,
66
- }),
67
- tileMode: true, // 开启平铺
68
- tileSize: 100, // 100% 原始大小
69
- tileGap: 20, // 20% 间距
70
- tileRotation: -30, // 旋转 -30 度
71
- width: 800,
72
- height: 600,
73
- })
74
- ```
75
-
76
- ### 错位排列
77
-
78
- ```typescript
79
- const watermark = new Watermark({
80
- tileContent: JSON.stringify({
81
- tag: 'Text',
82
- text: '机密文件',
83
- fill: 'rgba(0, 0, 0, 0.1)',
84
- fontSize: 14,
85
- }),
86
- tileMode: true,
87
- tileStagger: 50, // 50% 错位偏移
88
- tileGap: 10,
89
- width: 800,
90
- height: 600,
91
- })
92
- ```
93
-
94
- ### 图形水印
95
-
96
- ```typescript
97
- const watermark = new Watermark({
98
- tileContent: JSON.stringify({
99
- tag: 'Group',
100
- children: [
101
- { tag: 'Ellipse', width: 20, height: 20, fill: 'rgba(0, 100, 255, 0.2)' },
102
- { tag: 'Text', text: 'LOGO', x: 25, y: 3, fill: 'rgba(0, 100, 255, 0.2)', fontSize: 12 },
103
- ],
104
- }),
105
- tileMode: true,
106
- tileSize: 80,
107
- tileGap: 30,
108
- width: 800,
109
- height: 600,
110
- })
111
- ```
112
-
113
- ## 📖 API 文档
114
-
115
- ### Watermark 属性
116
-
117
- 继承自 Leafer UI 的 [Rect](https://www.leaferjs.com/ui/display/Rect.html) 组件,拥有所有 Rect 属性,并额外支持:
118
-
119
- | 属性 | 类型 | 默认值 | 说明 |
120
- |------|------|--------|------|
121
- | `tileContent` | string | - | 水印内容,LeaferJS 元素的 JSON 字符串 |
122
- | `tileMode` | boolean | `true` | 平铺模式:`true` 平铺,`false` 拉伸 |
123
- | `tileSize` | number | `100` | 显示比例(%),100 为原始大小 |
124
- | `tileGap` | `number \| { x?: number, y?: number }` | `0` | 间距比例(%),支持统一数值或分别设置 x/y 间距 |
125
- | `tileStagger` | `number \| { type?: 'x' \| 'y', offset: number }` | `0` | 错位偏移,支持数值(0-100)或详细配置 |
126
- | `tileRotation` | number | `0` | 水印旋转角度(度) |
127
-
128
- ### 属性说明
129
-
130
- #### tileContent
131
-
132
- 水印内容为 LeaferJS 元素的 JSON 字符串,支持所有 LeaferJS 图形类型:
133
-
134
- ```typescript
135
- // 文本
136
- JSON.stringify({ tag: 'Text', text: '水印', fill: '#000', fontSize: 16 })
137
-
138
- // 图片
139
- JSON.stringify({ tag: 'Image', url: 'logo.png', width: 50, height: 50 })
140
-
141
- // 组合图形
142
- JSON.stringify({
143
- tag: 'Group',
144
- children: [
145
- { tag: 'Rect', width: 30, height: 30, fill: '#f00' },
146
- { tag: 'Text', text: 'A', x: 10, y: 5, fill: '#fff' },
147
- ],
148
- })
149
- ```
150
-
151
- #### tileSize
152
-
153
- 控制水印显示大小的比例:
154
- - `100` = 原始大小
155
- - `50` = 缩小 50%
156
- - `200` = 放大 200%
157
- - `0` 或负数 = 不显示水印
158
-
159
- #### tileGap
160
-
161
- 间距基于显示尺寸的百分比计算:
162
- - `tileGap: 10` 表示间距为水印宽/高的 10%
163
- - 支持分别设置:`{ x: 20, y: 10 }`
164
-
165
- #### tileStagger
166
-
167
- 错位排列效果,支持数值 (0-100) 或对象配置:
168
- - `tileStagger: 50` = 水平方向(x)相邻行偏移 50%
169
- - `{ type: 'y', offset: 50 }` = 垂直方向(y)相邻列偏移 50%
170
- - `0` = 无错位
171
- - `100` = 完全错位(等于一个完整水印尺寸)
172
-
173
- ## 💡 使用场景
174
-
175
- - 📄 文档版权保护
176
- - 🖼️ 图片水印
177
- - 🔒 机密文件标识
178
- - 🏢 企业 Logo 背景
179
- - 📑 证书防伪
180
-
181
- ## 🔗 相关链接
182
-
183
- - [在线演示](https://leafer-x-watermark.vercel.app/)
184
- - [Leafer UI 文档](https://www.leaferjs.com/ui/guide/)
185
-
186
- ## 🤝 贡献
187
-
188
- 欢迎提交 Issue 和 Pull Request!
189
-
190
- ## License
191
-
192
- [MIT](./LICENSE) License © 2024-PRESENT [XiaDeYu](https://github.com/Xdy1579883916)
193
-
194
- <!-- Badges -->
195
-
196
- [npm-version-src]: https://img.shields.io/npm/v/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
197
-
198
- [npm-version-href]: https://npmjs.com/package/leafer-x-watermark
199
-
200
- [npm-downloads-src]: https://img.shields.io/npm/dm/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
201
-
202
- [npm-downloads-href]: https://npmjs.com/package/leafer-x-watermark
203
-
204
- [bundle-src]: https://img.shields.io/bundlephobia/minzip/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669&label=minzip
205
-
206
- [bundle-href]: https://bundlephobia.com/result?p=leafer-x-watermark
207
-
208
- [license-src]: https://img.shields.io/github/license/Xdy1579883916/leafer-x-watermark.svg?style=flat&colorA=080f12&colorB=1fa669
209
-
210
- [license-href]: https://github.com/Xdy1579883916/leafer-x-watermark/blob/master/LICENSE
1
+ # leafer-x-watermark
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![bundle][bundle-src]][bundle-href]
6
+ [![License][license-src]][license-href]
7
+
8
+ Leafer UI 水印插件,支持任意 LeaferJS 元素平铺水印
9
+
10
+ > ⚠️ **重要提示**:如果需要使用 `tileStagger`(错位排列)功能,必须在 `new App()` 后立即调用 `installStaggerPattern()` 进行补丁安装(此为临时方案,待官方支持后将移除)。
11
+
12
+ ## 特性
13
+
14
+ - 🎨 **任意图形** - 支持任意 LeaferJS 元素作为水印内容
15
+ - 🔄 **平铺模式** - 支持平铺(repeat)和拉伸(stretch)两种模式
16
+ - 📐 **灵活缩放** - 支持自定义水印尺寸比例
17
+ - 🔲 **间距控制** - 支持自定义水印间距
18
+ - 🎯 **错位排列** - 支持水印错位(stagger)效果
19
+ - 🔃 **旋转支持** - 支持水印旋转角度设置
20
+ - **性能优化** - 智能缓存,仅在必要时重新生成图片
21
+ - 🚀 **多版本支持** - 提供同步、异步及 URL 三种版本,适配不同场景需求
22
+
23
+ ## 📦 安装
24
+
25
+ ```bash
26
+ # pnpm
27
+ pnpm add leafer-x-watermark
28
+
29
+ # npm
30
+ npm install leafer-x-watermark
31
+
32
+ # yarn
33
+ yarn add leafer-x-watermark
34
+ ```
35
+
36
+ ## 🚀 快速开始
37
+
38
+ ### 版本选择
39
+
40
+ 根据水印内容选择合适的版本:
41
+
42
+ - **WatermarkSync(同步版本)** - 适用于纯文本、矩形等基础图形,性能更好
43
+ - **WatermarkAsync(异步版本)** - 适用于包含图片URL、自定义字体等需要加载的异步资源
44
+ - **WatermarkURL(URL版本)** - 直接通过图片URL创建水印,更加便捷
45
+
46
+ ```typescript
47
+ import { WatermarkSync } from 'leafer-x-watermark' // 同步版本
48
+ import { WatermarkAsync } from 'leafer-x-watermark' // 异步版本
49
+ import { WatermarkURL } from 'leafer-x-watermark' // URL版本
50
+ ```
51
+
52
+ ### 基础使用(同步版本)
53
+
54
+ ```typescript
55
+ import { App } from 'leafer-ui'
56
+ import { WatermarkSync, installStaggerPattern } from 'leafer-x-watermark'
57
+
58
+ const app = new App({ view: 'app' })
59
+ installStaggerPattern() // 全局安装一次即可
60
+
61
+ const watermark = new WatermarkSync({
62
+ tileContent: JSON.stringify({
63
+ tag: 'Text',
64
+ text: '水印文字',
65
+ fill: 'rgba(0, 0, 0, 0.1)',
66
+ fontSize: 16,
67
+ }),
68
+ width: 800,
69
+ height: 600,
70
+ })
71
+
72
+ app.tree.add(watermark)
73
+ ```
74
+
75
+ ### URL版本使用
76
+
77
+ 可以直接使用图片 URL 作为水印内容:
78
+
79
+ ```typescript
80
+ import { App } from 'leafer-ui'
81
+ import { WatermarkURL, installStaggerPattern } from 'leafer-x-watermark'
82
+
83
+ const app = new App({ view: 'app' })
84
+ installStaggerPattern()
85
+
86
+ const watermark = new WatermarkURL({
87
+ tileURL: 'https://example.com/logo.png',
88
+ tileMode: true,
89
+ tileSize: 50,
90
+ width: 800,
91
+ height: 600,
92
+ })
93
+
94
+ app.tree.add(watermark)
95
+ ```
96
+
97
+ ### 异步版本使用
98
+
99
+ 当水印内容包含图片资源时,使用异步版本:
100
+
101
+ ```typescript
102
+ import { App } from 'leafer-ui'
103
+ import { WatermarkAsync, installStaggerPattern } from 'leafer-x-watermark'
104
+
105
+ const app = new App({ view: 'app' })
106
+ installStaggerPattern()
107
+
108
+ const watermark = new WatermarkAsync({
109
+ tileContent: JSON.stringify({
110
+ tag: 'Image',
111
+ url: 'https://example.com/logo.png',
112
+ width: 100,
113
+ height: 100,
114
+ }),
115
+ tileMode: true,
116
+ width: 800,
117
+ height: 600,
118
+ })
119
+
120
+ app.tree.add(watermark)
121
+ ```
122
+
123
+ ## 📖 API 文档
124
+
125
+ ### WatermarkSync / WatermarkAsync / WatermarkURL
126
+
127
+ 三个版本的 API 基本相同,主要区别:
128
+ - **WatermarkSync**: 同步生成,适用于纯图形。
129
+ - **WatermarkAsync**: 异步生成,适用于包含外部资源的图形。
130
+ - **WatermarkURL**: 直接使用 `tileURL` 属性设置图片 URL。
131
+
132
+ 继承自 Leafer UI [Rect](https://www.leaferjs.com/ui/display/Rect.html) 组件,拥有所有 Rect 属性,并额外支持:
133
+
134
+ | 属性 | 类型 | 默认值 | 说明 |
135
+ |------|------|--------|------|
136
+ | `tileContent` | string | - | 水印内容,LeaferJS 元素的 JSON 字符串(URL版本不支持) |
137
+ | `tileURL` | string | - | 直接设置图片 URL 作为水印(仅限 URL版本) |
138
+ | `tileMode` | boolean | `true` | 平铺模式:`true` 平铺,`false` 拉伸 |
139
+ | `tileSize` | number | `100` | 显示比例(%),100 为原始大小 |
140
+ | `tileGap` | `number \| { x?: number, y?: number }` | `0` | 间距比例(%),支持统一数值或分别设置 x/y 间距 |
141
+ | `tileStagger` | `number \| { type?: 'x' \| 'y', offset: number }` | `0` | 错位偏移,支持数值(0-100)或详细配置 |
142
+ | `tileRotation` | number | `0` | 水印旋转角度(度) |
143
+
144
+ ### 属性说明
145
+
146
+ #### tileContent / tileURL
147
+
148
+ 水印内容支持 LeaferJS 元素的 JSON 字符串(Sync/Async版本)或直接图片 URL(URL版本):
149
+
150
+ ```typescript
151
+ // Sync / Async 版本使用 tileContent
152
+ JSON.stringify({ tag: 'Text', text: '水印', fill: '#000', fontSize: 16 })
153
+
154
+ // URL 版本使用 tileURL
155
+ const tileURL = 'https://example.com/logo.png'
156
+ ```
157
+
158
+ #### tileSize
159
+
160
+ 控制水印显示大小的比例:
161
+ - `100` = 原始大小
162
+ - `50` = 缩小 50%
163
+ - `200` = 放大 200%
164
+ - `0` 或负数 = 不显示水印
165
+
166
+ #### tileGap
167
+
168
+ 间距基于显示尺寸的百分比计算:
169
+ - `tileGap: 10` 表示间距为水印宽/高的 10%
170
+ - 支持分别设置:`{ x: 20, y: 10 }`
171
+
172
+ #### tileStagger
173
+
174
+ 错位排列效果,支持数值 (0-100) 或对象配置:
175
+ - `tileStagger: 50` = 水平方向(x)相邻行偏移 50%
176
+ - `{ type: 'y', offset: 50 }` = 垂直方向(y)相邻列偏移 50%
177
+ - `0` = 无错位
178
+ - `100` = 完全错位(等于一个完整水印尺寸)
179
+
180
+ ⚠️ **注意**:使用 `tileStagger` 功能前必须先调用 `installStaggerPattern()`
181
+
182
+ ## 💡 使用场景
183
+
184
+ - 📄 文档版权保护
185
+ - 🖼️ 图片水印
186
+ - 🔒 机密文件标识
187
+ - 🏢 企业 Logo 背景
188
+ - 📑 证书防伪
189
+
190
+ ## 🔗 相关链接
191
+
192
+ - [在线演示](https://leafer-x-watermark.vercel.app/)
193
+ - [Leafer UI 文档](https://www.leaferjs.com/ui/guide/)
194
+
195
+ ## 🤝 贡献
196
+
197
+ 欢迎提交 Issue 和 Pull Request!
198
+
199
+ ## License
200
+
201
+ [MIT](./LICENSE) License © 2024-PRESENT [XiaDeYu](https://github.com/Xdy1579883916)
202
+
203
+ <!-- Badges -->
204
+
205
+ [npm-version-src]: https://img.shields.io/npm/v/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
206
+
207
+ [npm-version-href]: https://npmjs.com/package/leafer-x-watermark
208
+
209
+ [npm-downloads-src]: https://img.shields.io/npm/dm/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
210
+
211
+ [npm-downloads-href]: https://npmjs.com/package/leafer-x-watermark
212
+
213
+ [bundle-src]: https://img.shields.io/bundlephobia/minzip/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669&label=minzip
214
+
215
+ [bundle-href]: https://bundlephobia.com/result?p=leafer-x-watermark
216
+
217
+ [license-src]: https://img.shields.io/github/license/Xdy1579883916/leafer-x-watermark.svg?style=flat&colorA=080f12&colorB=1fa669
218
+
219
+ [license-href]: https://github.com/Xdy1579883916/leafer-x-watermark/blob/master/LICENSE
package/dist/index.d.mts CHANGED
@@ -1,4 +1,3 @@
1
- import * as _leafer_ui_interface from '@leafer-ui/interface';
2
1
  import { IRectData, IUI, IRectInputData, IObject, IJSONOptions } from '@leafer-ui/interface';
3
2
  import { RectData, Rect } from '@leafer-ui/core';
4
3
 
@@ -24,6 +23,7 @@ interface ITileGap {
24
23
  }
25
24
  interface IWatermarkAttrData {
26
25
  tileContent?: string;
26
+ tileURL?: string;
27
27
  tileMode?: boolean;
28
28
  tileSize?: number;
29
29
  tileGap?: number | ITileGap;
@@ -32,6 +32,7 @@ interface IWatermarkAttrData {
32
32
  }
33
33
  interface IProcessDataType extends IRectData {
34
34
  _tileContent?: string;
35
+ _tileURL?: string;
35
36
  _tileMode?: boolean;
36
37
  _tileSize?: number;
37
38
  _tileGap?: number | ITileGap;
@@ -43,63 +44,106 @@ interface IProcessDataType extends IRectData {
43
44
  height: number;
44
45
  };
45
46
  updateFill: () => void;
46
- regenerateImage: () => void;
47
+ regenerateImage: () => void | Promise<void>;
47
48
  }
48
49
  interface IWatermark extends IWatermarkAttrData, IUI {
49
50
  __: IProcessDataType;
50
51
  }
51
52
  interface IWatermarkInputData extends IWatermarkAttrData, IRectInputData {
52
53
  }
53
- declare class ProcessorData extends RectData implements IProcessDataType {
54
- __leaf: Watermark;
55
- _tileContent?: string;
54
+
55
+ declare abstract class ProcessorDataBase extends RectData implements IProcessDataType {
56
+ __leaf: any;
56
57
  _cachedUrl?: string;
57
58
  _cachedBounds?: {
58
59
  width: number;
59
60
  height: number;
60
61
  };
61
- setTileContent(value: string): void;
62
+ _tileContent?: string;
63
+ _tileURL?: string;
62
64
  _tileMode?: boolean;
63
- setTileMode(value: boolean): void;
64
65
  _tileSize?: number;
65
- setTileSize(value: number): void;
66
66
  _tileGap?: number | ITileGap;
67
- setTileGap(value: number): void;
68
- _tileStagger?: IStagger;
69
- setTileStagger(value: number): void;
67
+ _tileStagger?: number;
70
68
  _tileRotation?: number;
69
+ abstract regenerateImage(): void | Promise<void>;
70
+ setTileContent(value: string): void;
71
+ setTileURL(value: string): void;
72
+ setTileMode(value: boolean): void;
73
+ setTileSize(value: number): void;
74
+ setTileGap(value: number | ITileGap): void;
75
+ setTileStagger(value: number): void;
71
76
  setTileRotation(value: number): void;
72
77
  updateFill(): void;
73
78
  __getData(): IObject;
74
79
  __getInputData(names?: string[] | IObject, options?: IJSONOptions): IObject;
75
- private createTileItem;
80
+ protected createTileItem(itemData: object): IUI;
81
+ protected parseAndValidateTileContent(): object | null;
82
+ protected updateLeafDimensions(bounds: {
83
+ width: number;
84
+ height: number;
85
+ }): void;
86
+ protected finalizeCachedData(url: string, bounds: {
87
+ width: number;
88
+ height: number;
89
+ }): void;
90
+ }
91
+
92
+ declare abstract class WatermarkBase<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
93
+ __: ProcessorDataBase;
94
+ get tileURL(): string;
95
+ }
96
+
97
+ declare class ProcessorDataAsync extends ProcessorDataBase {
98
+ __leaf: WatermarkAsync;
99
+ setTileContent(value: string): Promise<void>;
100
+ regenerateImage(): Promise<void>;
101
+ }
102
+ declare class WatermarkAsync<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
103
+ get __tag(): string;
104
+ __: ProcessorDataAsync;
105
+ tileContent?: string;
106
+ tileMode: boolean;
107
+ tileSize: number;
108
+ tileGap: number | ITileGap;
109
+ tileStagger: IStagger;
110
+ tileRotation: number;
111
+ }
112
+
113
+ declare class ProcessorData$1 extends ProcessorDataBase {
114
+ __leaf: WatermarkSync;
76
115
  regenerateImage(): void;
77
- _simpleExport(ui: IUI): {
78
- url: string;
79
- bounds: _leafer_ui_interface.IBoundsData;
80
- };
116
+ private _simpleExport;
81
117
  }
82
- declare class Watermark<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
118
+ declare class WatermarkSync<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
83
119
  get __tag(): string;
84
- __: IProcessDataType;
120
+ __: ProcessorData$1;
85
121
  tileContent?: string;
86
122
  tileMode: boolean;
87
123
  tileSize: number;
88
- tileGap: number | {
89
- x?: number;
90
- y?: number;
91
- };
124
+ tileGap: number | ITileGap;
125
+ tileStagger: IStagger;
126
+ tileRotation: number;
127
+ }
128
+
129
+ declare class ProcessorData extends ProcessorDataBase {
130
+ __leaf: WatermarkURL;
131
+ regenerateImage(): void;
132
+ }
133
+ declare class WatermarkURL<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
134
+ get __tag(): string;
135
+ __: ProcessorData;
136
+ tileURL?: string;
137
+ tileMode: boolean;
138
+ tileSize: number;
139
+ tileGap: number | ITileGap;
92
140
  tileStagger: IStagger;
93
141
  tileRotation: number;
94
- width: number;
95
- height: number;
96
- get tileURL(): string;
97
- constructor(data?: TConstructorData);
98
142
  }
99
143
 
100
144
  declare function normalizeStagger(stagger: IStagger): INormalizedStagger;
101
145
  declare function installStaggerPattern(): void;
102
146
  declare function processStaggerData(paint: any): INormalizedStagger | null;
103
147
 
104
- export { ProcessorData, Watermark, installStaggerPattern, normalizeStagger, processStaggerData };
105
- export type { INormalizedStagger, IProcessDataType, IStagger, IStaggerData, IStaggerType, IWatermark, IWatermarkAttrData, IWatermarkInputData };
148
+ export { WatermarkAsync, WatermarkSync, WatermarkURL, installStaggerPattern, normalizeStagger, processStaggerData };
149
+ export type { INormalizedStagger, IProcessDataType, IStagger, IStaggerData, IStaggerType, ITileGap, IWatermark, IWatermarkAttrData, IWatermarkInputData };
package/dist/index.mjs CHANGED
@@ -1,45 +1,40 @@
1
- import { Debug, dataProcessor, boundsType, registerUI, Plugin, RectData, isObject, UICreator, Rect, MatrixHelper, MathHelper, PaintImage, Platform } from '@leafer-ui/core';
1
+ import { Debug, RectData, isObject, UICreator, Rect, dataProcessor, boundsType, registerUI, Plugin, Creator, MatrixHelper, MathHelper, PaintImage, Platform } from '@leafer-ui/core';
2
2
 
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __decorateClass = (decorators, target, key, kind) => {
6
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
7
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
8
- if (decorator = decorators[i])
9
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
10
- if (kind && result) __defProp(target, key, result);
11
- return result;
12
- };
13
3
  const console = Debug.get("leafer-x-watermark");
14
- class ProcessorData extends RectData {
15
- _tileContent = "";
4
+ class ProcessorDataBase extends RectData {
16
5
  _cachedUrl;
17
6
  _cachedBounds;
7
+ _tileContent = "";
8
+ _tileURL = "";
9
+ _tileMode = true;
10
+ _tileSize = 100;
11
+ _tileGap = 0;
12
+ _tileStagger = 0;
13
+ _tileRotation = 0;
18
14
  setTileContent(value) {
19
15
  this._tileContent = value;
20
- return this.regenerateImage();
16
+ this.regenerateImage();
17
+ }
18
+ setTileURL(value) {
19
+ this._tileURL = value;
20
+ this.regenerateImage();
21
21
  }
22
- _tileMode = true;
23
22
  setTileMode(value) {
24
23
  this._tileMode = value;
25
24
  this.updateFill();
26
25
  }
27
- _tileSize = 100;
28
26
  setTileSize(value) {
29
27
  this._tileSize = value;
30
28
  this.updateFill();
31
29
  }
32
- _tileGap = 0;
33
30
  setTileGap(value) {
34
31
  this._tileGap = value;
35
32
  this.updateFill();
36
33
  }
37
- _tileStagger = 0;
38
34
  setTileStagger(value) {
39
35
  this._tileStagger = value;
40
36
  this.updateFill();
41
37
  }
42
- _tileRotation = 0;
43
38
  setTileRotation(value) {
44
39
  this._tileRotation = value;
45
40
  this.updateFill();
@@ -99,34 +94,125 @@ class ProcessorData extends RectData {
99
94
  around: "center"
100
95
  });
101
96
  }
102
- regenerateImage() {
103
- const leaf = this.__leaf;
97
+ parseAndValidateTileContent() {
104
98
  const { _tileContent } = this;
105
- const { width, height } = leaf;
106
99
  if (!_tileContent) {
107
100
  this._cachedUrl = void 0;
108
101
  this._cachedBounds = void 0;
109
- leaf.fill = void 0;
110
- return;
102
+ this.__leaf.fill = void 0;
103
+ return null;
111
104
  }
112
- let itemData;
113
105
  try {
114
- itemData = JSON.parse(_tileContent);
106
+ return JSON.parse(_tileContent);
115
107
  } catch (e) {
116
108
  console.error("Invalid tileContent JSON:", e);
117
- return;
109
+ return null;
118
110
  }
119
- const tempItem = this.createTileItem(itemData);
120
- const { url, bounds } = this._simpleExport(tempItem);
111
+ }
112
+ updateLeafDimensions(bounds) {
113
+ const leaf = this.__leaf;
114
+ const { width, height } = leaf;
121
115
  if (!width || !height) {
122
116
  leaf.width = bounds.width;
123
117
  leaf.height = bounds.height;
124
118
  }
119
+ }
120
+ finalizeCachedData(url, bounds) {
125
121
  this._cachedUrl = url;
126
122
  this._cachedBounds = bounds;
127
- tempItem.destroy();
128
123
  this.updateFill();
129
124
  }
125
+ }
126
+
127
+ class WatermarkBase extends Rect {
128
+ get tileURL() {
129
+ return this.__._cachedUrl;
130
+ }
131
+ }
132
+
133
+ var __defProp$2 = Object.defineProperty;
134
+ var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
135
+ var __decorateClass$2 = (decorators, target, key, kind) => {
136
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
137
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
138
+ if (decorator = decorators[i])
139
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
140
+ if (kind && result) __defProp$2(target, key, result);
141
+ return result;
142
+ };
143
+ class ProcessorDataAsync extends ProcessorDataBase {
144
+ // 异步版本需要覆盖,以便正确 await
145
+ async setTileContent(value) {
146
+ this._tileContent = value;
147
+ await this.regenerateImage();
148
+ }
149
+ async regenerateImage() {
150
+ const itemData = this.parseAndValidateTileContent();
151
+ if (!itemData)
152
+ return;
153
+ const tempItem = this.createTileItem(itemData);
154
+ const bounds = tempItem.getBounds("box", "local");
155
+ this.updateLeafDimensions(bounds);
156
+ const exportWidth = 1e3;
157
+ const { data: url } = await tempItem.export("png", {
158
+ blob: false,
159
+ size: { width: exportWidth }
160
+ });
161
+ tempItem.destroy();
162
+ this.finalizeCachedData(url, bounds);
163
+ }
164
+ }
165
+ let WatermarkAsync = class extends WatermarkBase {
166
+ get __tag() {
167
+ return "WatermarkAsync";
168
+ }
169
+ };
170
+ __decorateClass$2([
171
+ dataProcessor(ProcessorDataAsync)
172
+ ], WatermarkAsync.prototype, "__", 2);
173
+ __decorateClass$2([
174
+ boundsType()
175
+ ], WatermarkAsync.prototype, "tileContent", 2);
176
+ __decorateClass$2([
177
+ boundsType(true)
178
+ ], WatermarkAsync.prototype, "tileMode", 2);
179
+ __decorateClass$2([
180
+ boundsType(100)
181
+ ], WatermarkAsync.prototype, "tileSize", 2);
182
+ __decorateClass$2([
183
+ boundsType(0)
184
+ ], WatermarkAsync.prototype, "tileGap", 2);
185
+ __decorateClass$2([
186
+ boundsType(0)
187
+ ], WatermarkAsync.prototype, "tileStagger", 2);
188
+ __decorateClass$2([
189
+ boundsType(0)
190
+ ], WatermarkAsync.prototype, "tileRotation", 2);
191
+ WatermarkAsync = __decorateClass$2([
192
+ registerUI()
193
+ ], WatermarkAsync);
194
+
195
+ var __defProp$1 = Object.defineProperty;
196
+ var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
197
+ var __decorateClass$1 = (decorators, target, key, kind) => {
198
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
199
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
200
+ if (decorator = decorators[i])
201
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
202
+ if (kind && result) __defProp$1(target, key, result);
203
+ return result;
204
+ };
205
+ let ProcessorData$1 = class ProcessorData extends ProcessorDataBase {
206
+ regenerateImage() {
207
+ const itemData = this.parseAndValidateTileContent();
208
+ if (!itemData)
209
+ return;
210
+ const tempItem = this.createTileItem(itemData);
211
+ const { url, bounds } = this._simpleExport(tempItem);
212
+ this.updateLeafDimensions(bounds);
213
+ tempItem.destroy();
214
+ this.finalizeCachedData(url, bounds);
215
+ }
130
216
  _simpleExport(ui) {
131
217
  const exportWidth = 1e3;
132
218
  const bounds = ui.getBounds("render", "local");
@@ -144,49 +230,108 @@ class ProcessorData extends RectData {
144
230
  canvas.destroy();
145
231
  return { url, bounds };
146
232
  }
147
- }
148
- let Watermark = class extends Rect {
233
+ };
234
+ let WatermarkSync = class extends WatermarkBase {
149
235
  get __tag() {
150
- return "Watermark";
236
+ return "WatermarkSync";
151
237
  }
152
- get tileURL() {
153
- return this.__._cachedUrl;
238
+ };
239
+ __decorateClass$1([
240
+ dataProcessor(ProcessorData$1)
241
+ ], WatermarkSync.prototype, "__", 2);
242
+ __decorateClass$1([
243
+ boundsType()
244
+ ], WatermarkSync.prototype, "tileContent", 2);
245
+ __decorateClass$1([
246
+ boundsType(true)
247
+ ], WatermarkSync.prototype, "tileMode", 2);
248
+ __decorateClass$1([
249
+ boundsType(100)
250
+ ], WatermarkSync.prototype, "tileSize", 2);
251
+ __decorateClass$1([
252
+ boundsType(0)
253
+ ], WatermarkSync.prototype, "tileGap", 2);
254
+ __decorateClass$1([
255
+ boundsType(0)
256
+ ], WatermarkSync.prototype, "tileStagger", 2);
257
+ __decorateClass$1([
258
+ boundsType(0)
259
+ ], WatermarkSync.prototype, "tileRotation", 2);
260
+ WatermarkSync = __decorateClass$1([
261
+ registerUI()
262
+ ], WatermarkSync);
263
+ Plugin.add("leafer-x-watermark");
264
+
265
+ var __defProp = Object.defineProperty;
266
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
267
+ var __decorateClass = (decorators, target, key, kind) => {
268
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
269
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
270
+ if (decorator = decorators[i])
271
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
272
+ if (kind && result) __defProp(target, key, result);
273
+ return result;
274
+ };
275
+ async function toBase64(url) {
276
+ return new Promise((resolve) => {
277
+ const leaferImage = Creator.image({ url });
278
+ leaferImage.load((image) => {
279
+ const { width, height } = image;
280
+ const canvas = Creator.hitCanvas({ width, height, pixelRatio: 1 });
281
+ canvas.drawImage(image.view, 0, 0);
282
+ const data = canvas.toDataURL();
283
+ canvas.destroy();
284
+ leaferImage.destroy();
285
+ resolve({ data, bounds: { width, height } });
286
+ });
287
+ });
288
+ }
289
+ class ProcessorData extends ProcessorDataBase {
290
+ regenerateImage() {
291
+ const url = this._tileURL;
292
+ if (!url) {
293
+ this._cachedUrl = void 0;
294
+ this._cachedBounds = void 0;
295
+ this.__leaf.fill = void 0;
296
+ return;
297
+ }
298
+ toBase64(url).then(({ data, bounds }) => {
299
+ this._cachedUrl = data;
300
+ this._cachedBounds = bounds;
301
+ this.updateLeafDimensions(bounds);
302
+ this.updateFill();
303
+ });
154
304
  }
155
- constructor(data) {
156
- super(data);
305
+ }
306
+ let WatermarkURL = class extends Rect {
307
+ get __tag() {
308
+ return "WatermarkURL";
157
309
  }
158
310
  };
159
311
  __decorateClass([
160
312
  dataProcessor(ProcessorData)
161
- ], Watermark.prototype, "__", 2);
313
+ ], WatermarkURL.prototype, "__", 2);
162
314
  __decorateClass([
163
315
  boundsType()
164
- ], Watermark.prototype, "tileContent", 2);
316
+ ], WatermarkURL.prototype, "tileURL", 2);
165
317
  __decorateClass([
166
318
  boundsType(true)
167
- ], Watermark.prototype, "tileMode", 2);
319
+ ], WatermarkURL.prototype, "tileMode", 2);
168
320
  __decorateClass([
169
321
  boundsType(100)
170
- ], Watermark.prototype, "tileSize", 2);
171
- __decorateClass([
172
- boundsType(0)
173
- ], Watermark.prototype, "tileGap", 2);
322
+ ], WatermarkURL.prototype, "tileSize", 2);
174
323
  __decorateClass([
175
324
  boundsType(0)
176
- ], Watermark.prototype, "tileStagger", 2);
325
+ ], WatermarkURL.prototype, "tileGap", 2);
177
326
  __decorateClass([
178
327
  boundsType(0)
179
- ], Watermark.prototype, "tileRotation", 2);
328
+ ], WatermarkURL.prototype, "tileStagger", 2);
180
329
  __decorateClass([
181
330
  boundsType(0)
182
- ], Watermark.prototype, "width", 2);
183
- __decorateClass([
184
- boundsType(0)
185
- ], Watermark.prototype, "height", 2);
186
- Watermark = __decorateClass([
331
+ ], WatermarkURL.prototype, "tileRotation", 2);
332
+ WatermarkURL = __decorateClass([
187
333
  registerUI()
188
- ], Watermark);
189
- Plugin.add("leafer-x-watermark");
334
+ ], WatermarkURL);
190
335
 
191
336
  const { get, scale, copy } = MatrixHelper;
192
337
  const { getFloorScale } = MathHelper;
@@ -307,4 +452,4 @@ function processStaggerData(paint) {
307
452
  return null;
308
453
  }
309
454
 
310
- export { ProcessorData, Watermark, installStaggerPattern, normalizeStagger, processStaggerData };
455
+ export { WatermarkAsync, WatermarkSync, WatermarkURL, installStaggerPattern, normalizeStagger, processStaggerData };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "leafer-x-watermark",
3
3
  "type": "module",
4
- "version": "1.3.1",
4
+ "version": "2.0.0",
5
5
  "packageManager": "pnpm@10.14.0",
6
6
  "description": "Leafer 水印插件",
7
7
  "author": "XiaDeYu <1579883916@qq.com>",