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 +219 -210
- package/dist/index.d.mts +72 -28
- package/dist/index.mjs +199 -54
- package/package.json +1 -1
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
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
#
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
- `
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- `
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
##
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
78
|
-
url: string;
|
|
79
|
-
bounds: _leafer_ui_interface.IBoundsData;
|
|
80
|
-
};
|
|
116
|
+
private _simpleExport;
|
|
81
117
|
}
|
|
82
|
-
declare class
|
|
118
|
+
declare class WatermarkSync<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
|
|
83
119
|
get __tag(): string;
|
|
84
|
-
__:
|
|
120
|
+
__: ProcessorData$1;
|
|
85
121
|
tileContent?: string;
|
|
86
122
|
tileMode: boolean;
|
|
87
123
|
tileSize: number;
|
|
88
|
-
tileGap: number |
|
|
89
|
-
|
|
90
|
-
|
|
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 {
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
110
|
-
return;
|
|
102
|
+
this.__leaf.fill = void 0;
|
|
103
|
+
return null;
|
|
111
104
|
}
|
|
112
|
-
let itemData;
|
|
113
105
|
try {
|
|
114
|
-
|
|
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
|
-
|
|
120
|
-
|
|
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
|
|
233
|
+
};
|
|
234
|
+
let WatermarkSync = class extends WatermarkBase {
|
|
149
235
|
get __tag() {
|
|
150
|
-
return "
|
|
236
|
+
return "WatermarkSync";
|
|
151
237
|
}
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
156
|
-
|
|
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
|
-
],
|
|
313
|
+
], WatermarkURL.prototype, "__", 2);
|
|
162
314
|
__decorateClass([
|
|
163
315
|
boundsType()
|
|
164
|
-
],
|
|
316
|
+
], WatermarkURL.prototype, "tileURL", 2);
|
|
165
317
|
__decorateClass([
|
|
166
318
|
boundsType(true)
|
|
167
|
-
],
|
|
319
|
+
], WatermarkURL.prototype, "tileMode", 2);
|
|
168
320
|
__decorateClass([
|
|
169
321
|
boundsType(100)
|
|
170
|
-
],
|
|
171
|
-
__decorateClass([
|
|
172
|
-
boundsType(0)
|
|
173
|
-
], Watermark.prototype, "tileGap", 2);
|
|
322
|
+
], WatermarkURL.prototype, "tileSize", 2);
|
|
174
323
|
__decorateClass([
|
|
175
324
|
boundsType(0)
|
|
176
|
-
],
|
|
325
|
+
], WatermarkURL.prototype, "tileGap", 2);
|
|
177
326
|
__decorateClass([
|
|
178
327
|
boundsType(0)
|
|
179
|
-
],
|
|
328
|
+
], WatermarkURL.prototype, "tileStagger", 2);
|
|
180
329
|
__decorateClass([
|
|
181
330
|
boundsType(0)
|
|
182
|
-
],
|
|
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
|
-
],
|
|
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 {
|
|
455
|
+
export { WatermarkAsync, WatermarkSync, WatermarkURL, installStaggerPattern, normalizeStagger, processStaggerData };
|