leafer-x-watermark 2.0.0 → 3.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 CHANGED
@@ -129,7 +129,7 @@ app.tree.add(watermark)
129
129
  - **WatermarkAsync**: 异步生成,适用于包含外部资源的图形。
130
130
  - **WatermarkURL**: 直接使用 `tileURL` 属性设置图片 URL。
131
131
 
132
- 继承自 Leafer UI 的 [Rect](https://www.leaferjs.com/ui/display/Rect.html) 组件,拥有所有 Rect 属性,并额外支持:
132
+ 继承自 Leafer UI 的 [Rect](https://www.leaferjs.com/ui/reference/display/Rect.html) 组件,拥有所有 Rect 属性,并额外支持:
133
133
 
134
134
  | 属性 | 类型 | 默认值 | 说明 |
135
135
  |------|------|--------|------|
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IRectData, IUI, IRectInputData, IObject, IJSONOptions } from '@leafer-ui/interface';
2
- import { RectData, Rect } from '@leafer-ui/core';
2
+ import { RectData, Rect, PropertyEvent } from '@leafer-ui/core';
3
3
 
4
4
  type IStaggerType = 'x' | 'y';
5
5
  interface IStaggerData {
@@ -91,7 +91,9 @@ declare abstract class ProcessorDataBase extends RectData implements IProcessDat
91
91
 
92
92
  declare abstract class WatermarkBase<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
93
93
  __: ProcessorDataBase;
94
- get tileURL(): string;
94
+ constructor(data?: TConstructorData);
95
+ syncParentSize(e?: PropertyEvent): void;
96
+ destroy(): void;
95
97
  }
96
98
 
97
99
  declare class ProcessorDataAsync extends ProcessorDataBase {
@@ -108,6 +110,7 @@ declare class WatermarkAsync<TConstructorData = IWatermarkInputData> extends Wat
108
110
  tileGap: number | ITileGap;
109
111
  tileStagger: IStagger;
110
112
  tileRotation: number;
113
+ get tileURL(): string;
111
114
  }
112
115
 
113
116
  declare class ProcessorData$1 extends ProcessorDataBase {
@@ -124,13 +127,14 @@ declare class WatermarkSync<TConstructorData = IWatermarkInputData> extends Wate
124
127
  tileGap: number | ITileGap;
125
128
  tileStagger: IStagger;
126
129
  tileRotation: number;
130
+ get tileURL(): string;
127
131
  }
128
132
 
129
133
  declare class ProcessorData extends ProcessorDataBase {
130
134
  __leaf: WatermarkURL;
131
135
  regenerateImage(): void;
132
136
  }
133
- declare class WatermarkURL<TConstructorData = IWatermarkInputData> extends Rect<TConstructorData> implements IWatermark {
137
+ declare class WatermarkURL<TConstructorData = IWatermarkInputData> extends WatermarkBase<TConstructorData> {
134
138
  get __tag(): string;
135
139
  __: ProcessorData;
136
140
  tileURL?: string;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { Debug, RectData, isObject, UICreator, Rect, dataProcessor, boundsType, registerUI, Plugin, Creator, MatrixHelper, MathHelper, PaintImage, Platform } from '@leafer-ui/core';
1
+ import { Debug, RectData, isObject, UICreator, Rect, PropertyEvent, dataProcessor, boundsType, registerUI, Plugin, Creator, MatrixHelper, MathHelper, PaintImage, Platform } from '@leafer-ui/core';
2
2
 
3
3
  const console = Debug.get("leafer-x-watermark");
4
4
  class ProcessorDataBase extends RectData {
@@ -22,6 +22,8 @@ class ProcessorDataBase extends RectData {
22
22
  setTileMode(value) {
23
23
  this._tileMode = value;
24
24
  this.updateFill();
25
+ if (value && this.__leaf.syncParentSize)
26
+ this.__leaf.syncParentSize();
25
27
  }
26
28
  setTileSize(value) {
27
29
  this._tileSize = value;
@@ -125,8 +127,29 @@ class ProcessorDataBase extends RectData {
125
127
  }
126
128
 
127
129
  class WatermarkBase extends Rect {
128
- get tileURL() {
129
- return this.__._cachedUrl;
130
+ constructor(data) {
131
+ super(data);
132
+ this.syncParentSize = this.syncParentSize.bind(this);
133
+ this.waitParent(() => {
134
+ this.parent.on(PropertyEvent.CHANGE, this.syncParentSize);
135
+ this.syncParentSize();
136
+ });
137
+ }
138
+ syncParentSize(e) {
139
+ if (e && !["width", "height"].includes(e.attrName)) {
140
+ return;
141
+ }
142
+ if (this.__._tileMode && this.parent) {
143
+ this.width = this.parent.width;
144
+ this.height = this.parent.height;
145
+ this.y = this.x = 0;
146
+ }
147
+ }
148
+ destroy() {
149
+ if (this.parent) {
150
+ this.parent.off(PropertyEvent.CHANGE, this.syncParentSize);
151
+ }
152
+ super.destroy();
130
153
  }
131
154
  }
132
155
 
@@ -166,6 +189,9 @@ let WatermarkAsync = class extends WatermarkBase {
166
189
  get __tag() {
167
190
  return "WatermarkAsync";
168
191
  }
192
+ get tileURL() {
193
+ return this.__._cachedUrl;
194
+ }
169
195
  };
170
196
  __decorateClass$2([
171
197
  dataProcessor(ProcessorDataAsync)
@@ -235,6 +261,9 @@ let WatermarkSync = class extends WatermarkBase {
235
261
  get __tag() {
236
262
  return "WatermarkSync";
237
263
  }
264
+ get tileURL() {
265
+ return this.__._cachedUrl;
266
+ }
238
267
  };
239
268
  __decorateClass$1([
240
269
  dataProcessor(ProcessorData$1)
@@ -303,7 +332,7 @@ class ProcessorData extends ProcessorDataBase {
303
332
  });
304
333
  }
305
334
  }
306
- let WatermarkURL = class extends Rect {
335
+ let WatermarkURL = class extends WatermarkBase {
307
336
  get __tag() {
308
337
  return "WatermarkURL";
309
338
  }
@@ -336,13 +365,48 @@ WatermarkURL = __decorateClass([
336
365
  const { get, scale, copy } = MatrixHelper;
337
366
  const { getFloorScale } = MathHelper;
338
367
  const { abs } = Math;
339
- const originalCreatePattern = PaintImage.createPattern.bind(PaintImage);
368
+ const ORIGINAL_CREATE_PATTERN = Symbol.for("leafer-x-watermark:PaintImage.createPattern.original");
369
+ const STAGGER_PATTERN_ID = Symbol.for("leafer-x-watermark:paint.staggerPatternId");
370
+ function ensureOriginalCreatePattern() {
371
+ const anyPaintImage = PaintImage;
372
+ if (!anyPaintImage[ORIGINAL_CREATE_PATTERN]) {
373
+ anyPaintImage[ORIGINAL_CREATE_PATTERN] = PaintImage.createPattern.bind(PaintImage);
374
+ }
375
+ return anyPaintImage[ORIGINAL_CREATE_PATTERN];
376
+ }
377
+ const staggerCanvasCache = /* @__PURE__ */ new WeakMap();
340
378
  function normalizeStagger(stagger) {
341
379
  if (typeof stagger === "number") {
342
380
  return { type: "x", offset: stagger };
343
381
  }
344
382
  return { type: stagger.type || "x", offset: stagger.offset || 0 };
345
383
  }
384
+ function isSameStaggerParams(a, b) {
385
+ 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];
386
+ }
387
+ function getStaggerCanvas(image, width, height, xGap, yGap, stagger, opacity, smooth) {
388
+ const cached = staggerCanvasCache.get(image);
389
+ if (cached) {
390
+ const nextParams = [
391
+ width,
392
+ height,
393
+ xGap,
394
+ yGap,
395
+ stagger.type,
396
+ stagger.offset,
397
+ opacity,
398
+ smooth
399
+ ];
400
+ if (isSameStaggerParams(cached.params, nextParams))
401
+ return cached.canvas;
402
+ }
403
+ const canvas = createStaggerCanvas(image, width, height, xGap, yGap, stagger, opacity, smooth);
404
+ staggerCanvasCache.set(image, {
405
+ params: [width, height, xGap, yGap, stagger.type, stagger.offset, opacity, smooth],
406
+ canvas
407
+ });
408
+ return canvas;
409
+ }
346
410
  function createStaggerCanvas(image, imgWidth, imgHeight, xGap, yGap, stagger, opacity, smooth) {
347
411
  const unitWidth = imgWidth + xGap;
348
412
  const unitHeight = imgHeight + yGap;
@@ -378,8 +442,8 @@ function createStaggerCanvas(image, imgWidth, imgHeight, xGap, yGap, stagger, op
378
442
  return canvas;
379
443
  }
380
444
  function createPatternWithStagger(paint, ui, canvas, renderOptions) {
381
- const originPaint = paint.originPaint;
382
- const rawStagger = originPaint?.stagger;
445
+ const originalCreatePattern = ensureOriginalCreatePattern();
446
+ const rawStagger = paint.data?.stagger ?? paint.originPaint?.stagger;
383
447
  if (rawStagger === void 0 || rawStagger === 0) {
384
448
  originalCreatePattern(paint, ui, canvas, renderOptions);
385
449
  return;
@@ -390,59 +454,62 @@ function createPatternWithStagger(paint, ui, canvas, renderOptions) {
390
454
  return;
391
455
  }
392
456
  let { scaleX, scaleY } = PaintImage.getImageRenderScaleData(paint, ui, canvas, renderOptions);
393
- const id = `${scaleX}-${scaleY}-stagger-${stagger.type}-${stagger.offset}`;
394
- if (paint.patternId !== id && !ui.destroyed) {
395
- const { image, data } = paint;
396
- const { transform, gap } = data;
397
- const fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
398
- let imageMatrix;
399
- let xGap = 0;
400
- let yGap = 0;
401
- let { width, height } = image;
402
- if (fixScale) {
403
- scaleX *= fixScale;
404
- scaleY *= fixScale;
405
- }
406
- width *= scaleX;
407
- height *= scaleY;
408
- if (gap) {
409
- xGap = gap.x * scaleX / abs(data.scaleX || 1);
410
- yGap = gap.y * scaleY / abs(data.scaleY || 1);
411
- }
412
- const unitWidth = width + xGap;
413
- const unitHeight = height + yGap;
414
- const isXStagger = stagger.type === "x";
415
- const patternWidth = isXStagger ? unitWidth : unitWidth * 2;
416
- const patternHeight = isXStagger ? unitHeight * 2 : unitHeight;
417
- if (transform || scaleX !== 1 || scaleY !== 1) {
418
- const matrixScaleX = scaleX * getFloorScale(patternWidth);
419
- const matrixScaleY = scaleY * getFloorScale(patternHeight);
420
- imageMatrix = get();
421
- if (transform)
422
- copy(imageMatrix, transform);
423
- scale(imageMatrix, 1 / matrixScaleX, 1 / matrixScaleY);
424
- }
425
- const imageCanvas = createStaggerCanvas(
426
- image,
427
- width,
428
- height,
429
- xGap,
430
- yGap,
431
- stagger,
432
- data.opacity,
433
- ui.leafer?.config.smooth
434
- );
435
- const pattern = image.getPattern(
436
- imageCanvas,
437
- data.repeat || "repeat",
438
- imageMatrix,
439
- paint
440
- );
441
- paint.style = pattern;
442
- paint.patternId = id;
457
+ const baseId = `${scaleX}-${scaleY}`;
458
+ const staggerId = `${baseId}-stagger-${stagger.type}-${stagger.offset}`;
459
+ const anyPaint = paint;
460
+ if (ui.destroyed)
461
+ return;
462
+ if (paint.patternId === baseId && anyPaint[STAGGER_PATTERN_ID] === staggerId)
463
+ return;
464
+ if (Platform.image.isLarge(paint.image, scaleX, scaleY) && !paint.data.repeat)
465
+ return;
466
+ const { image, data } = paint;
467
+ const { transform, gap } = data;
468
+ const fixScale = PaintImage.getPatternFixScale(paint, scaleX, scaleY);
469
+ if (fixScale) {
470
+ scaleX *= fixScale;
471
+ scaleY *= fixScale;
472
+ }
473
+ let imageMatrix;
474
+ let xGap = 0;
475
+ let yGap = 0;
476
+ let { width, height } = image;
477
+ width *= scaleX;
478
+ height *= scaleY;
479
+ if (gap) {
480
+ xGap = gap.x * scaleX / abs(data.scaleX || 1);
481
+ yGap = gap.y * scaleY / abs(data.scaleY || 1);
482
+ }
483
+ if (transform || scaleX !== 1 || scaleY !== 1) {
484
+ scaleX *= getFloorScale(width + (xGap || 0));
485
+ scaleY *= getFloorScale(height + (yGap || 0));
486
+ imageMatrix = get();
487
+ if (transform)
488
+ copy(imageMatrix, transform);
489
+ scale(imageMatrix, 1 / scaleX, 1 / scaleY);
443
490
  }
491
+ const imageCanvas = getStaggerCanvas(
492
+ image,
493
+ width,
494
+ height,
495
+ xGap,
496
+ yGap,
497
+ stagger,
498
+ data.opacity,
499
+ ui.leafer?.config.smooth
500
+ );
501
+ const pattern = image.getPattern(
502
+ imageCanvas,
503
+ data.repeat || (Platform.origin.noRepeat || "no-repeat"),
504
+ imageMatrix,
505
+ paint
506
+ );
507
+ paint.style = pattern;
508
+ paint.patternId = baseId;
509
+ anyPaint[STAGGER_PATTERN_ID] = staggerId;
444
510
  }
445
511
  function installStaggerPattern() {
512
+ ensureOriginalCreatePattern();
446
513
  PaintImage.createPattern = createPatternWithStagger;
447
514
  }
448
515
  function processStaggerData(paint) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "leafer-x-watermark",
3
3
  "type": "module",
4
- "version": "2.0.0",
4
+ "version": "3.1.0",
5
5
  "packageManager": "pnpm@10.14.0",
6
6
  "description": "Leafer 水印插件",
7
7
  "author": "XiaDeYu <1579883916@qq.com>",