leafer-x-watermark 3.2.0 → 4.1.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 +141 -219
- package/dist/index.d.mts +3 -54
- package/dist/index.mjs +25 -343
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,219 +1,141 @@
|
|
|
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
|
|
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
|
-
| `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
|
|
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 水印插件,基于 Leafer 2.0.0 构建,使用更加简单高效。
|
|
9
|
+
|
|
10
|
+
## ✨ 特性
|
|
11
|
+
|
|
12
|
+
- 🖼️ **图片水印** - 直接使用图片 URL 创建水印
|
|
13
|
+
- 🔄 **平铺模式** - 支持平铺(repeat)和拉伸(stretch)两种模式
|
|
14
|
+
- 📐 **灵活缩放** - 支持自定义水印尺寸比例
|
|
15
|
+
- 🔲 **间距控制** - 支持自定义水印间距
|
|
16
|
+
- 🎯 **错位排列** - 支持水印错位效果:基于 Leafer 2.0.0版本(interlace)支持
|
|
17
|
+
- 🔃 **旋转支持** - 支持水印旋转角度设置
|
|
18
|
+
|
|
19
|
+
## 📦 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
# pnpm
|
|
23
|
+
pnpm add leafer-x-watermark
|
|
24
|
+
|
|
25
|
+
# npm
|
|
26
|
+
npm install leafer-x-watermark
|
|
27
|
+
|
|
28
|
+
# yarn
|
|
29
|
+
yarn add leafer-x-watermark
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 🚀 快速开始
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { App } from 'leafer-ui'
|
|
36
|
+
import { WatermarkURL } from 'leafer-x-watermark'
|
|
37
|
+
|
|
38
|
+
const app = new App({ view: 'app' })
|
|
39
|
+
|
|
40
|
+
const watermark = new WatermarkURL({
|
|
41
|
+
tileURL: 'https://leaferjs.com/image/logo.svg',
|
|
42
|
+
tileMode: true,
|
|
43
|
+
tileSize: 50, // 缩放 50%
|
|
44
|
+
tileGap: 20, // 间距 20%
|
|
45
|
+
tileStagger: 50, // 错位 50%
|
|
46
|
+
width: 800,
|
|
47
|
+
height: 600,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
app.tree.add(watermark)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 📖 API 文档
|
|
54
|
+
|
|
55
|
+
### WatermarkURL
|
|
56
|
+
|
|
57
|
+
继承自 Leafer UI 的 [Rect](https://www.leaferjs.com/ui/reference/display/Rect.html) 组件,拥有所有 Rect 属性。
|
|
58
|
+
|
|
59
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
60
|
+
|------|------|--------|------|
|
|
61
|
+
| `tileURL` | string | - | 水印图片的 URL 地址 |
|
|
62
|
+
| `tileMode` | boolean | `true` | 平铺模式:`true` 平铺,`false` 拉伸 |
|
|
63
|
+
| `tileSize` | number | `100` | 显示比例(%),100 为原始大小 |
|
|
64
|
+
| `tileGap` | `number \| { x?: number, y?: number }` | `0` | 间距比例(%),支持统一数值或分别设置 x/y 间距 |
|
|
65
|
+
| `tileStagger` | `number \| { type?: 'x' \| 'y', offset: number }` | `0` | 错位偏移,支持数值(0-100)或详细配置 |
|
|
66
|
+
| `tileRotation` | number | `0` | 水印旋转角度(度) |
|
|
67
|
+
|
|
68
|
+
### 属性说明
|
|
69
|
+
|
|
70
|
+
#### tileURL
|
|
71
|
+
|
|
72
|
+
设置水印图片的地址,支持网络图片 URL 或 Base64 字符串。
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// 使用网络图片
|
|
76
|
+
watermark.tileURL = 'https://example.com/logo.png'
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### tileSize
|
|
80
|
+
|
|
81
|
+
控制水印显示大小的比例:
|
|
82
|
+
- `100` = 原始大小
|
|
83
|
+
- `50` = 缩小 50%
|
|
84
|
+
- `200` = 放大 200%
|
|
85
|
+
- `0` = 不显示
|
|
86
|
+
|
|
87
|
+
#### tileGap
|
|
88
|
+
|
|
89
|
+
间距基于显示尺寸的百分比计算:
|
|
90
|
+
- `tileGap: 10` 表示间距为水印宽/高的 10%
|
|
91
|
+
- 支持分别设置:`{ x: 20, y: 10 }`
|
|
92
|
+
|
|
93
|
+
#### tileStagger
|
|
94
|
+
|
|
95
|
+
错位排列效果(Interlace),支持数值 (0-100) 或对象配置:
|
|
96
|
+
- `tileStagger: 50` = 水平方向(x)相邻行偏移 50%
|
|
97
|
+
- `{ type: 'y', offset: 50 }` = 垂直方向(y)相邻列偏移 50%
|
|
98
|
+
- `0` = 无错位
|
|
99
|
+
|
|
100
|
+
#### tileMode
|
|
101
|
+
|
|
102
|
+
- `true`: 启用平铺模式(Repeat),支持间距、错位等效果。
|
|
103
|
+
- `false`: 启用拉伸模式(Stretch),图片将填满整个区域。
|
|
104
|
+
|
|
105
|
+
## 💡 使用场景
|
|
106
|
+
|
|
107
|
+
- 📄 文档版权保护
|
|
108
|
+
- 🖼️ 图片水印
|
|
109
|
+
- 🔒 机密文件标识
|
|
110
|
+
- 🏢 企业 Logo 背景
|
|
111
|
+
|
|
112
|
+
## 🔗 相关链接
|
|
113
|
+
|
|
114
|
+
- [在线演示](https://leafer-x-watermark.vercel.app/)
|
|
115
|
+
- [Leafer UI 文档](https://www.leaferjs.com/ui/guide/)
|
|
116
|
+
|
|
117
|
+
## 🤝 贡献
|
|
118
|
+
|
|
119
|
+
欢迎提交 Issue 和 Pull Request!
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
[MIT](./LICENSE) License © 2024-PRESENT [XiaDeYu](https://github.com/Xdy1579883916)
|
|
124
|
+
|
|
125
|
+
<!-- Badges -->
|
|
126
|
+
|
|
127
|
+
[npm-version-src]: https://img.shields.io/npm/v/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
|
|
128
|
+
|
|
129
|
+
[npm-version-href]: https://npmjs.com/package/leafer-x-watermark
|
|
130
|
+
|
|
131
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669
|
|
132
|
+
|
|
133
|
+
[npm-downloads-href]: https://npmjs.com/package/leafer-x-watermark
|
|
134
|
+
|
|
135
|
+
[bundle-src]: https://img.shields.io/bundlephobia/minzip/leafer-x-watermark?style=flat&colorA=080f12&colorB=1fa669&label=minzip
|
|
136
|
+
|
|
137
|
+
[bundle-href]: https://bundlephobia.com/result?p=leafer-x-watermark
|
|
138
|
+
|
|
139
|
+
[license-src]: https://img.shields.io/github/license/Xdy1579883916/leafer-x-watermark.svg?style=flat&colorA=080f12&colorB=1fa669
|
|
140
|
+
|
|
141
|
+
[license-href]: https://github.com/Xdy1579883916/leafer-x-watermark/blob/master/LICENSE
|
package/dist/index.d.mts
CHANGED
|
@@ -7,10 +7,6 @@ interface IStaggerData {
|
|
|
7
7
|
offset: number;
|
|
8
8
|
}
|
|
9
9
|
type IStagger = number | IStaggerData;
|
|
10
|
-
interface INormalizedStagger {
|
|
11
|
-
type: IStaggerType;
|
|
12
|
-
offset: number;
|
|
13
|
-
}
|
|
14
10
|
declare module '@leafer-ui/interface' {
|
|
15
11
|
interface IImagePaint {
|
|
16
12
|
stagger?: IStagger;
|
|
@@ -32,7 +28,6 @@ interface IWatermarkAttrData {
|
|
|
32
28
|
tileRotation?: number;
|
|
33
29
|
}
|
|
34
30
|
interface IProcessDataType extends IRectData {
|
|
35
|
-
_tileContent?: string;
|
|
36
31
|
_tileURL?: string;
|
|
37
32
|
_tileMode?: boolean;
|
|
38
33
|
_tileSize?: number;
|
|
@@ -61,15 +56,13 @@ declare abstract class ProcessorDataBase extends RectData implements IProcessDat
|
|
|
61
56
|
width: number;
|
|
62
57
|
height: number;
|
|
63
58
|
};
|
|
64
|
-
_tileContent?: string;
|
|
65
59
|
_tileURL?: string;
|
|
66
60
|
_tileMode?: boolean;
|
|
67
61
|
_tileSize?: number;
|
|
68
62
|
_tileGap?: number | ITileGap;
|
|
69
|
-
_tileStagger?:
|
|
63
|
+
_tileStagger?: IStagger;
|
|
70
64
|
_tileRotation?: number;
|
|
71
65
|
abstract regenerateImage(): void | Promise<void>;
|
|
72
|
-
setTileContent(value: string): void;
|
|
73
66
|
setTileURL(value: string): void;
|
|
74
67
|
setTileMode(value: boolean): void;
|
|
75
68
|
setTileSize(value: number): void;
|
|
@@ -79,16 +72,10 @@ declare abstract class ProcessorDataBase extends RectData implements IProcessDat
|
|
|
79
72
|
updateFill(): void;
|
|
80
73
|
__getData(): IObject;
|
|
81
74
|
__getInputData(names?: string[] | IObject, options?: IJSONOptions): IObject;
|
|
82
|
-
protected createTileItem(itemData: object): IUI;
|
|
83
|
-
protected parseAndValidateTileContent(): object | null;
|
|
84
75
|
protected updateLeafDimensions(bounds: {
|
|
85
76
|
width: number;
|
|
86
77
|
height: number;
|
|
87
78
|
}): void;
|
|
88
|
-
protected finalizeCachedData(url: string, bounds: {
|
|
89
|
-
width: number;
|
|
90
|
-
height: number;
|
|
91
|
-
}): void;
|
|
92
79
|
}
|
|
93
80
|
|
|
94
81
|
declare abstract class WatermarkBase<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
|
|
@@ -99,40 +86,6 @@ declare abstract class WatermarkBase<TConstructorData = IWatermarkInputData> ext
|
|
|
99
86
|
destroy(): void;
|
|
100
87
|
}
|
|
101
88
|
|
|
102
|
-
declare class ProcessorDataAsync extends ProcessorDataBase {
|
|
103
|
-
__leaf: WatermarkAsync;
|
|
104
|
-
setTileContent(value: string): Promise<void>;
|
|
105
|
-
regenerateImage(): Promise<void>;
|
|
106
|
-
}
|
|
107
|
-
declare class WatermarkAsync<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
|
|
108
|
-
get __tag(): string;
|
|
109
|
-
__: ProcessorDataAsync;
|
|
110
|
-
tileContent?: string;
|
|
111
|
-
tileMode: boolean;
|
|
112
|
-
tileSize: number;
|
|
113
|
-
tileGap: number | ITileGap;
|
|
114
|
-
tileStagger: IStagger;
|
|
115
|
-
tileRotation: number;
|
|
116
|
-
get tileURL(): string;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
declare class ProcessorData$1 extends ProcessorDataBase {
|
|
120
|
-
__leaf: WatermarkSync;
|
|
121
|
-
regenerateImage(): void;
|
|
122
|
-
private _simpleExport;
|
|
123
|
-
}
|
|
124
|
-
declare class WatermarkSync<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
|
|
125
|
-
get __tag(): string;
|
|
126
|
-
__: ProcessorData$1;
|
|
127
|
-
tileContent?: string;
|
|
128
|
-
tileMode: boolean;
|
|
129
|
-
tileSize: number;
|
|
130
|
-
tileGap: number | ITileGap;
|
|
131
|
-
tileStagger: IStagger;
|
|
132
|
-
tileRotation: number;
|
|
133
|
-
get tileURL(): string;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
89
|
declare class ProcessorData extends ProcessorDataBase {
|
|
137
90
|
__leaf: WatermarkURL;
|
|
138
91
|
regenerateImage(): void;
|
|
@@ -148,9 +101,5 @@ declare class WatermarkURL<TConstructorData = IWatermarkInputData> extends Water
|
|
|
148
101
|
tileRotation: number;
|
|
149
102
|
}
|
|
150
103
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
declare function processStaggerData(paint: any): INormalizedStagger | null;
|
|
154
|
-
|
|
155
|
-
export { WatermarkAsync, WatermarkSync, WatermarkURL, installStaggerPattern, normalizeStagger, processStaggerData };
|
|
156
|
-
export type { INormalizedStagger, IProcessDataType, IStagger, IStaggerData, IStaggerType, ITileContentParser, ITileGap, IWatermark, IWatermarkAttrData, IWatermarkInputData };
|
|
104
|
+
export { WatermarkURL };
|
|
105
|
+
export type { IProcessDataType, ITileContentParser, ITileGap, IWatermark, IWatermarkAttrData, IWatermarkInputData };
|
package/dist/index.mjs
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RectData, isObject, Rect, PropertyEvent, dataProcessor, boundsType, registerUI, Creator } from '@leafer-ui/core';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return JSON.parse(content);
|
|
7
|
-
} catch (e) {
|
|
8
|
-
console.error("Invalid tileContent JSON:", e);
|
|
9
|
-
return null;
|
|
3
|
+
function normalizeStagger(stagger) {
|
|
4
|
+
if (typeof stagger === "number") {
|
|
5
|
+
return { type: "x", offset: stagger };
|
|
10
6
|
}
|
|
7
|
+
return { type: stagger.type || "x", offset: stagger.offset || 0 };
|
|
11
8
|
}
|
|
12
9
|
class ProcessorDataBase extends RectData {
|
|
13
10
|
_cachedUrl;
|
|
14
11
|
_cachedBounds;
|
|
15
|
-
_tileContent = "";
|
|
16
12
|
_tileURL = "";
|
|
17
13
|
_tileMode = true;
|
|
18
14
|
_tileSize = 100;
|
|
19
15
|
_tileGap = 0;
|
|
20
16
|
_tileStagger = 0;
|
|
21
17
|
_tileRotation = 0;
|
|
22
|
-
setTileContent(value) {
|
|
23
|
-
this._tileContent = value;
|
|
24
|
-
this.regenerateImage();
|
|
25
|
-
}
|
|
26
18
|
setTileURL(value) {
|
|
27
19
|
this._tileURL = value;
|
|
28
20
|
this.regenerateImage();
|
|
@@ -30,7 +22,7 @@ class ProcessorDataBase extends RectData {
|
|
|
30
22
|
setTileMode(value) {
|
|
31
23
|
this._tileMode = value;
|
|
32
24
|
this.updateFill();
|
|
33
|
-
if (
|
|
25
|
+
if (this.__leaf.syncParentSize)
|
|
34
26
|
this.__leaf.syncParentSize();
|
|
35
27
|
}
|
|
36
28
|
setTileSize(value) {
|
|
@@ -76,13 +68,21 @@ class ProcessorDataBase extends RectData {
|
|
|
76
68
|
}
|
|
77
69
|
const gapX = xGap / 100 * sizeWidth;
|
|
78
70
|
const gapY = yGap / 100 * sizeHeight;
|
|
71
|
+
const interlace = normalizeStagger(_tileStagger);
|
|
79
72
|
leaf.fill = {
|
|
80
73
|
type: "image",
|
|
81
74
|
url: this._cachedUrl,
|
|
82
75
|
mode: "repeat",
|
|
83
76
|
gap: { x: gapX, y: gapY },
|
|
84
77
|
size: { width: sizeWidth, height: sizeHeight },
|
|
85
|
-
|
|
78
|
+
interlace: {
|
|
79
|
+
type: interlace.type || "x",
|
|
80
|
+
offset: {
|
|
81
|
+
type: "percent",
|
|
82
|
+
// 为 0 时有bug,不渲染了,待修复。先手动改为1。
|
|
83
|
+
value: (interlace.offset || 1) / 100
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
86
|
rotation: _tileRotation,
|
|
87
87
|
align: "center"
|
|
88
88
|
};
|
|
@@ -98,23 +98,6 @@ class ProcessorDataBase extends RectData {
|
|
|
98
98
|
delete data.fill;
|
|
99
99
|
return data;
|
|
100
100
|
}
|
|
101
|
-
createTileItem(itemData) {
|
|
102
|
-
return UICreator.get("Group", {
|
|
103
|
-
children: [itemData],
|
|
104
|
-
around: "center"
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
parseAndValidateTileContent() {
|
|
108
|
-
const { _tileContent } = this;
|
|
109
|
-
if (!_tileContent) {
|
|
110
|
-
this._cachedUrl = void 0;
|
|
111
|
-
this._cachedBounds = void 0;
|
|
112
|
-
this.__leaf.fill = void 0;
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
const parser = this.__leaf.tileContentParser || defaultTileContentParser;
|
|
116
|
-
return parser(_tileContent);
|
|
117
|
-
}
|
|
118
101
|
updateLeafDimensions(bounds) {
|
|
119
102
|
const leaf = this.__leaf;
|
|
120
103
|
const { width, height } = leaf;
|
|
@@ -123,11 +106,6 @@ class ProcessorDataBase extends RectData {
|
|
|
123
106
|
leaf.height = bounds.height;
|
|
124
107
|
}
|
|
125
108
|
}
|
|
126
|
-
finalizeCachedData(url, bounds) {
|
|
127
|
-
this._cachedUrl = url;
|
|
128
|
-
this._cachedBounds = bounds;
|
|
129
|
-
this.updateFill();
|
|
130
|
-
}
|
|
131
109
|
}
|
|
132
110
|
|
|
133
111
|
class WatermarkBase extends Rect {
|
|
@@ -141,13 +119,17 @@ class WatermarkBase extends Rect {
|
|
|
141
119
|
});
|
|
142
120
|
}
|
|
143
121
|
syncParentSize(e) {
|
|
144
|
-
if (e && !["width", "height"].includes(e.attrName)) {
|
|
122
|
+
if (e && !["width", "height", "x", "y"].includes(e.attrName)) {
|
|
145
123
|
return;
|
|
146
124
|
}
|
|
147
125
|
if (this.__._tileMode && this.parent) {
|
|
148
126
|
this.width = this.parent.width;
|
|
149
127
|
this.height = this.parent.height;
|
|
150
|
-
this.y = this.x = 0;
|
|
128
|
+
this.y = this.x = this.rotation = 0;
|
|
129
|
+
this.scaleX = this.scaleY = 1;
|
|
130
|
+
} else {
|
|
131
|
+
this.width = this.__._cachedBounds?.width;
|
|
132
|
+
this.height = this.__._cachedBounds?.height;
|
|
151
133
|
}
|
|
152
134
|
}
|
|
153
135
|
destroy() {
|
|
@@ -158,144 +140,6 @@ class WatermarkBase extends Rect {
|
|
|
158
140
|
}
|
|
159
141
|
}
|
|
160
142
|
|
|
161
|
-
var __defProp$2 = Object.defineProperty;
|
|
162
|
-
var __getOwnPropDesc$2 = Object.getOwnPropertyDescriptor;
|
|
163
|
-
var __decorateClass$2 = (decorators, target, key, kind) => {
|
|
164
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$2(target, key) : target;
|
|
165
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
166
|
-
if (decorator = decorators[i])
|
|
167
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
168
|
-
if (kind && result) __defProp$2(target, key, result);
|
|
169
|
-
return result;
|
|
170
|
-
};
|
|
171
|
-
class ProcessorDataAsync extends ProcessorDataBase {
|
|
172
|
-
// 异步版本需要覆盖,以便正确 await
|
|
173
|
-
async setTileContent(value) {
|
|
174
|
-
this._tileContent = value;
|
|
175
|
-
await this.regenerateImage();
|
|
176
|
-
}
|
|
177
|
-
async regenerateImage() {
|
|
178
|
-
const itemData = this.parseAndValidateTileContent();
|
|
179
|
-
if (!itemData)
|
|
180
|
-
return;
|
|
181
|
-
const tempItem = this.createTileItem(itemData);
|
|
182
|
-
const bounds = tempItem.getBounds("box", "local");
|
|
183
|
-
this.updateLeafDimensions(bounds);
|
|
184
|
-
const exportWidth = 1e3;
|
|
185
|
-
const { data: url } = await tempItem.export("png", {
|
|
186
|
-
blob: false,
|
|
187
|
-
size: { width: exportWidth }
|
|
188
|
-
});
|
|
189
|
-
tempItem.destroy();
|
|
190
|
-
this.finalizeCachedData(url, bounds);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
let WatermarkAsync = class extends WatermarkBase {
|
|
194
|
-
get __tag() {
|
|
195
|
-
return "WatermarkAsync";
|
|
196
|
-
}
|
|
197
|
-
get tileURL() {
|
|
198
|
-
return this.__._cachedUrl;
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
__decorateClass$2([
|
|
202
|
-
dataProcessor(ProcessorDataAsync)
|
|
203
|
-
], WatermarkAsync.prototype, "__", 2);
|
|
204
|
-
__decorateClass$2([
|
|
205
|
-
boundsType()
|
|
206
|
-
], WatermarkAsync.prototype, "tileContent", 2);
|
|
207
|
-
__decorateClass$2([
|
|
208
|
-
boundsType(true)
|
|
209
|
-
], WatermarkAsync.prototype, "tileMode", 2);
|
|
210
|
-
__decorateClass$2([
|
|
211
|
-
boundsType(100)
|
|
212
|
-
], WatermarkAsync.prototype, "tileSize", 2);
|
|
213
|
-
__decorateClass$2([
|
|
214
|
-
boundsType(0)
|
|
215
|
-
], WatermarkAsync.prototype, "tileGap", 2);
|
|
216
|
-
__decorateClass$2([
|
|
217
|
-
boundsType(0)
|
|
218
|
-
], WatermarkAsync.prototype, "tileStagger", 2);
|
|
219
|
-
__decorateClass$2([
|
|
220
|
-
boundsType(0)
|
|
221
|
-
], WatermarkAsync.prototype, "tileRotation", 2);
|
|
222
|
-
WatermarkAsync = __decorateClass$2([
|
|
223
|
-
registerUI()
|
|
224
|
-
], WatermarkAsync);
|
|
225
|
-
|
|
226
|
-
var __defProp$1 = Object.defineProperty;
|
|
227
|
-
var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor;
|
|
228
|
-
var __decorateClass$1 = (decorators, target, key, kind) => {
|
|
229
|
-
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$1(target, key) : target;
|
|
230
|
-
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
231
|
-
if (decorator = decorators[i])
|
|
232
|
-
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
233
|
-
if (kind && result) __defProp$1(target, key, result);
|
|
234
|
-
return result;
|
|
235
|
-
};
|
|
236
|
-
let ProcessorData$1 = class ProcessorData extends ProcessorDataBase {
|
|
237
|
-
regenerateImage() {
|
|
238
|
-
const itemData = this.parseAndValidateTileContent();
|
|
239
|
-
if (!itemData)
|
|
240
|
-
return;
|
|
241
|
-
const tempItem = this.createTileItem(itemData);
|
|
242
|
-
const { url, bounds } = this._simpleExport(tempItem);
|
|
243
|
-
this.updateLeafDimensions(bounds);
|
|
244
|
-
tempItem.destroy();
|
|
245
|
-
this.finalizeCachedData(url, bounds);
|
|
246
|
-
}
|
|
247
|
-
_simpleExport(ui) {
|
|
248
|
-
const exportWidth = 1e3;
|
|
249
|
-
const bounds = ui.getBounds("render", "local");
|
|
250
|
-
const scaleRatio = exportWidth / bounds.width;
|
|
251
|
-
const scaledWidth = Math.floor(bounds.width * scaleRatio);
|
|
252
|
-
const scaledHeight = Math.floor(bounds.height * scaleRatio);
|
|
253
|
-
const canvas = UICreator.get("Canvas", {
|
|
254
|
-
x: 0,
|
|
255
|
-
y: 0,
|
|
256
|
-
width: scaledWidth,
|
|
257
|
-
height: scaledHeight
|
|
258
|
-
});
|
|
259
|
-
canvas.draw(ui, void 0, scaleRatio);
|
|
260
|
-
const url = canvas.canvas.toDataURL("image/png");
|
|
261
|
-
canvas.destroy();
|
|
262
|
-
return { url, bounds };
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
let WatermarkSync = class extends WatermarkBase {
|
|
266
|
-
get __tag() {
|
|
267
|
-
return "WatermarkSync";
|
|
268
|
-
}
|
|
269
|
-
get tileURL() {
|
|
270
|
-
return this.__._cachedUrl;
|
|
271
|
-
}
|
|
272
|
-
};
|
|
273
|
-
__decorateClass$1([
|
|
274
|
-
dataProcessor(ProcessorData$1)
|
|
275
|
-
], WatermarkSync.prototype, "__", 2);
|
|
276
|
-
__decorateClass$1([
|
|
277
|
-
boundsType()
|
|
278
|
-
], WatermarkSync.prototype, "tileContent", 2);
|
|
279
|
-
__decorateClass$1([
|
|
280
|
-
boundsType(true)
|
|
281
|
-
], WatermarkSync.prototype, "tileMode", 2);
|
|
282
|
-
__decorateClass$1([
|
|
283
|
-
boundsType(100)
|
|
284
|
-
], WatermarkSync.prototype, "tileSize", 2);
|
|
285
|
-
__decorateClass$1([
|
|
286
|
-
boundsType(0)
|
|
287
|
-
], WatermarkSync.prototype, "tileGap", 2);
|
|
288
|
-
__decorateClass$1([
|
|
289
|
-
boundsType(0)
|
|
290
|
-
], WatermarkSync.prototype, "tileStagger", 2);
|
|
291
|
-
__decorateClass$1([
|
|
292
|
-
boundsType(0)
|
|
293
|
-
], WatermarkSync.prototype, "tileRotation", 2);
|
|
294
|
-
WatermarkSync = __decorateClass$1([
|
|
295
|
-
registerUI()
|
|
296
|
-
], WatermarkSync);
|
|
297
|
-
Plugin.add("leafer-x-watermark");
|
|
298
|
-
|
|
299
143
|
var __defProp = Object.defineProperty;
|
|
300
144
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
301
145
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -306,17 +150,12 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
306
150
|
if (kind && result) __defProp(target, key, result);
|
|
307
151
|
return result;
|
|
308
152
|
};
|
|
309
|
-
async function
|
|
153
|
+
async function getBounds(url) {
|
|
310
154
|
return new Promise((resolve) => {
|
|
311
155
|
const leaferImage = Creator.image({ url });
|
|
312
156
|
leaferImage.load((image) => {
|
|
313
157
|
const { width, height } = image;
|
|
314
|
-
|
|
315
|
-
canvas.drawImage(image.view, 0, 0);
|
|
316
|
-
const data = canvas.toDataURL();
|
|
317
|
-
canvas.destroy();
|
|
318
|
-
leaferImage.destroy();
|
|
319
|
-
resolve({ data, bounds: { width, height } });
|
|
158
|
+
resolve({ data: url, bounds: { width, height } });
|
|
320
159
|
});
|
|
321
160
|
});
|
|
322
161
|
}
|
|
@@ -329,7 +168,7 @@ class ProcessorData extends ProcessorDataBase {
|
|
|
329
168
|
this.__leaf.fill = void 0;
|
|
330
169
|
return;
|
|
331
170
|
}
|
|
332
|
-
|
|
171
|
+
getBounds(url).then(({ data, bounds }) => {
|
|
333
172
|
this._cachedUrl = data;
|
|
334
173
|
this._cachedBounds = bounds;
|
|
335
174
|
this.updateLeafDimensions(bounds);
|
|
@@ -367,161 +206,4 @@ WatermarkURL = __decorateClass([
|
|
|
367
206
|
registerUI()
|
|
368
207
|
], WatermarkURL);
|
|
369
208
|
|
|
370
|
-
|
|
371
|
-
const { getFloorScale } = MathHelper;
|
|
372
|
-
const { abs } = Math;
|
|
373
|
-
const ORIGINAL_CREATE_PATTERN = Symbol.for("leafer-x-watermark:PaintImage.createPattern.original");
|
|
374
|
-
const STAGGER_PATTERN_ID = Symbol.for("leafer-x-watermark:paint.staggerPatternId");
|
|
375
|
-
function ensureOriginalCreatePattern() {
|
|
376
|
-
const anyPaintImage = PaintImage;
|
|
377
|
-
if (!anyPaintImage[ORIGINAL_CREATE_PATTERN]) {
|
|
378
|
-
anyPaintImage[ORIGINAL_CREATE_PATTERN] = PaintImage.createPattern.bind(PaintImage);
|
|
379
|
-
}
|
|
380
|
-
return anyPaintImage[ORIGINAL_CREATE_PATTERN];
|
|
381
|
-
}
|
|
382
|
-
const staggerCanvasCache = /* @__PURE__ */ new WeakMap();
|
|
383
|
-
function normalizeStagger(stagger) {
|
|
384
|
-
if (typeof stagger === "number") {
|
|
385
|
-
return { type: "x", offset: stagger };
|
|
386
|
-
}
|
|
387
|
-
return { type: stagger.type || "x", offset: stagger.offset || 0 };
|
|
388
|
-
}
|
|
389
|
-
function isSameStaggerParams(a, b) {
|
|
390
|
-
return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7];
|
|
391
|
-
}
|
|
392
|
-
function getStaggerCanvas(image, width, height, xGap, yGap, stagger, opacity, smooth) {
|
|
393
|
-
const cached = staggerCanvasCache.get(image);
|
|
394
|
-
if (cached) {
|
|
395
|
-
const nextParams = [
|
|
396
|
-
width,
|
|
397
|
-
height,
|
|
398
|
-
xGap,
|
|
399
|
-
yGap,
|
|
400
|
-
stagger.type,
|
|
401
|
-
stagger.offset,
|
|
402
|
-
opacity,
|
|
403
|
-
smooth
|
|
404
|
-
];
|
|
405
|
-
if (isSameStaggerParams(cached.params, nextParams))
|
|
406
|
-
return cached.canvas;
|
|
407
|
-
}
|
|
408
|
-
const canvas = createStaggerCanvas(image, width, height, xGap, yGap, stagger, opacity, smooth);
|
|
409
|
-
staggerCanvasCache.set(image, {
|
|
410
|
-
params: [width, height, xGap, yGap, stagger.type, stagger.offset, opacity, smooth],
|
|
411
|
-
canvas
|
|
412
|
-
});
|
|
413
|
-
return canvas;
|
|
414
|
-
}
|
|
415
|
-
function createStaggerCanvas(image, imgWidth, imgHeight, xGap, yGap, stagger, opacity, smooth) {
|
|
416
|
-
const unitWidth = imgWidth + xGap;
|
|
417
|
-
const unitHeight = imgHeight + yGap;
|
|
418
|
-
const isXStagger = stagger.type === "x";
|
|
419
|
-
const patternWidth = isXStagger ? unitWidth : unitWidth * 2;
|
|
420
|
-
const patternHeight = isXStagger ? unitHeight * 2 : unitHeight;
|
|
421
|
-
const canvas = Platform.origin.createCanvas(
|
|
422
|
-
Math.max(Math.floor(patternWidth), 1),
|
|
423
|
-
Math.max(Math.floor(patternHeight), 1)
|
|
424
|
-
);
|
|
425
|
-
const ctx = canvas.getContext("2d");
|
|
426
|
-
if (opacity && opacity < 1)
|
|
427
|
-
ctx.globalAlpha = opacity;
|
|
428
|
-
ctx.imageSmoothingEnabled = smooth !== false;
|
|
429
|
-
const imgView = image.view;
|
|
430
|
-
const drawImg = (x, y) => {
|
|
431
|
-
ctx.drawImage(imgView, 0, 0, image.width, image.height, x, y, imgWidth, imgHeight);
|
|
432
|
-
};
|
|
433
|
-
const offset = stagger.offset / 100 * (isXStagger ? unitWidth : unitHeight);
|
|
434
|
-
if (isXStagger) {
|
|
435
|
-
drawImg(0, 0);
|
|
436
|
-
drawImg(offset, unitHeight);
|
|
437
|
-
if (offset + imgWidth > unitWidth) {
|
|
438
|
-
drawImg(offset - unitWidth, unitHeight);
|
|
439
|
-
}
|
|
440
|
-
} else {
|
|
441
|
-
drawImg(0, 0);
|
|
442
|
-
drawImg(unitWidth, offset);
|
|
443
|
-
if (offset + imgHeight > unitHeight) {
|
|
444
|
-
drawImg(unitWidth, offset - unitHeight);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
return canvas;
|
|
448
|
-
}
|
|
449
|
-
function createPatternWithStagger(paint, ui, canvas, renderOptions) {
|
|
450
|
-
const originalCreatePattern = ensureOriginalCreatePattern();
|
|
451
|
-
const rawStagger = paint.data?.stagger ?? paint.originPaint?.stagger;
|
|
452
|
-
if (rawStagger === void 0 || rawStagger === 0) {
|
|
453
|
-
originalCreatePattern(paint, ui, canvas, renderOptions);
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
const stagger = normalizeStagger(rawStagger);
|
|
457
|
-
if (stagger.offset === 0) {
|
|
458
|
-
originalCreatePattern(paint, ui, canvas, renderOptions);
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
let { scaleX, scaleY } = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
|
|
462
|
-
const baseId = `${scaleX}-${scaleY}`;
|
|
463
|
-
const staggerId = `${baseId}-stagger-${stagger.type}-${stagger.offset}`;
|
|
464
|
-
const anyPaint = paint;
|
|
465
|
-
if (ui.destroyed)
|
|
466
|
-
return;
|
|
467
|
-
if (paint.patternId === baseId && anyPaint[STAGGER_PATTERN_ID] === staggerId)
|
|
468
|
-
return;
|
|
469
|
-
if (Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)
|
|
470
|
-
return;
|
|
471
|
-
const { image, data } = paint;
|
|
472
|
-
const { transform, gap } = data;
|
|
473
|
-
const fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
|
|
474
|
-
if (fixScale) {
|
|
475
|
-
scaleX *= fixScale;
|
|
476
|
-
scaleY *= fixScale;
|
|
477
|
-
}
|
|
478
|
-
let imageMatrix;
|
|
479
|
-
let xGap = 0;
|
|
480
|
-
let yGap = 0;
|
|
481
|
-
let { width, height } = image;
|
|
482
|
-
width *= scaleX;
|
|
483
|
-
height *= scaleY;
|
|
484
|
-
if (gap) {
|
|
485
|
-
xGap = gap.x * scaleX / abs(data.scaleX || 1);
|
|
486
|
-
yGap = gap.y * scaleY / abs(data.scaleY || 1);
|
|
487
|
-
}
|
|
488
|
-
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
489
|
-
scaleX *= getFloorScale(width + (xGap || 0));
|
|
490
|
-
scaleY *= getFloorScale(height + (yGap || 0));
|
|
491
|
-
imageMatrix = get();
|
|
492
|
-
if (transform)
|
|
493
|
-
copy(imageMatrix, transform);
|
|
494
|
-
scale(imageMatrix, 1 / scaleX, 1 / scaleY);
|
|
495
|
-
}
|
|
496
|
-
const imageCanvas = getStaggerCanvas(
|
|
497
|
-
image,
|
|
498
|
-
width,
|
|
499
|
-
height,
|
|
500
|
-
xGap,
|
|
501
|
-
yGap,
|
|
502
|
-
stagger,
|
|
503
|
-
data.opacity,
|
|
504
|
-
ui.leafer?.config.smooth
|
|
505
|
-
);
|
|
506
|
-
const pattern = image.getPattern(
|
|
507
|
-
imageCanvas,
|
|
508
|
-
data.repeat || (Platform.origin.noRepeat || "no-repeat"),
|
|
509
|
-
imageMatrix,
|
|
510
|
-
paint
|
|
511
|
-
);
|
|
512
|
-
paint.style = pattern;
|
|
513
|
-
paint.patternId = baseId;
|
|
514
|
-
anyPaint[STAGGER_PATTERN_ID] = staggerId;
|
|
515
|
-
}
|
|
516
|
-
function installStaggerPattern() {
|
|
517
|
-
ensureOriginalCreatePattern();
|
|
518
|
-
PaintImage.createPattern = createPatternWithStagger;
|
|
519
|
-
}
|
|
520
|
-
function processStaggerData(paint) {
|
|
521
|
-
if (paint.stagger !== void 0) {
|
|
522
|
-
return normalizeStagger(paint.stagger);
|
|
523
|
-
}
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
export { WatermarkAsync, WatermarkSync, WatermarkURL, installStaggerPattern, normalizeStagger, processStaggerData };
|
|
209
|
+
export { WatermarkURL };
|