watermark-js-plus 1.6.4 → 1.6.6

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * watermark-js-plus v1.6.4
2
+ * watermark-js-plus v1.6.6
3
3
  * (c) 2022-2024 Michael Sun
4
4
  * Released under the MIT License.
5
5
  */
@@ -4273,6 +4273,187 @@ if (typeof CanvasRenderingContext2D !== 'undefined' && !CanvasRenderingContext2D
4273
4273
  };
4274
4274
  }
4275
4275
 
4276
+ var blindDecodeFallback;
4277
+ var registerBlindDecodeFallback = function (fallback) {
4278
+ blindDecodeFallback = fallback;
4279
+ };
4280
+ var applyBlindDecodeComposite = function (_a) {
4281
+ var ctx = _a.ctx, width = _a.width, height = _a.height, fillColor = _a.fillColor, compositeOperation = _a.compositeOperation, compositeTimes = _a.compositeTimes;
4282
+ if (!(compositeTimes > 0)) {
4283
+ return;
4284
+ }
4285
+ var previousCompositeOperation = ctx.globalCompositeOperation;
4286
+ ctx.globalCompositeOperation = compositeOperation;
4287
+ if (ctx.globalCompositeOperation !== compositeOperation && blindDecodeFallback) {
4288
+ ctx.globalCompositeOperation = previousCompositeOperation;
4289
+ blindDecodeFallback({
4290
+ ctx: ctx,
4291
+ fillColor: fillColor,
4292
+ compositeOperation: compositeOperation,
4293
+ compositeTimes: compositeTimes,
4294
+ });
4295
+ return;
4296
+ }
4297
+ ctx.fillStyle = fillColor;
4298
+ for (var i = 0; i < compositeTimes; i++) {
4299
+ ctx.fillRect(0, 0, width, height);
4300
+ }
4301
+ };
4302
+
4303
+ var MAX_CHANNEL_VALUE = 255;
4304
+ var overlay = function (backdrop, source) {
4305
+ if (backdrop <= 0.5) {
4306
+ return 2 * backdrop * source;
4307
+ }
4308
+ return 1 - 2 * (1 - backdrop) * (1 - source);
4309
+ };
4310
+ var colorBurn = function (backdrop, source) {
4311
+ if (backdrop === 1) {
4312
+ return 1;
4313
+ }
4314
+ if (source === 0) {
4315
+ return 0;
4316
+ }
4317
+ return 1 - Math.min(1, (1 - backdrop) / source);
4318
+ };
4319
+ var getBlendFunction = function (compositeOperation) {
4320
+ switch (compositeOperation) {
4321
+ case 'overlay':
4322
+ return overlay;
4323
+ case 'color-burn':
4324
+ return colorBurn;
4325
+ default:
4326
+ throw new Error("Unsupported blind watermark composite operation: ".concat(compositeOperation));
4327
+ }
4328
+ };
4329
+ var parseNormalizedColor = function (fillStyle) {
4330
+ var hexColor = /^#([\da-f]{6})$/i.exec(fillStyle);
4331
+ if (hexColor) {
4332
+ return {
4333
+ color: [
4334
+ parseInt(hexColor[1].slice(0, 2), 16),
4335
+ parseInt(hexColor[1].slice(2, 4), 16),
4336
+ parseInt(hexColor[1].slice(4, 6), 16),
4337
+ ],
4338
+ alpha: 1,
4339
+ };
4340
+ }
4341
+ var rgbColor = /^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)$/i.exec(fillStyle);
4342
+ if (rgbColor) {
4343
+ return {
4344
+ color: [Number(rgbColor[1]), Number(rgbColor[2]), Number(rgbColor[3])],
4345
+ alpha: rgbColor[4] === undefined ? 1 : Math.max(0, Math.min(1, Number(rgbColor[4]))),
4346
+ };
4347
+ }
4348
+ return undefined;
4349
+ };
4350
+ var getFillColor = function (ctx, fillColor) {
4351
+ var colorCanvas = (ctx.canvas.ownerDocument || document).createElement('canvas');
4352
+ colorCanvas.width = 1;
4353
+ colorCanvas.height = 1;
4354
+ var colorContext = colorCanvas.getContext('2d');
4355
+ if (!colorContext) {
4356
+ throw new Error('get context error');
4357
+ }
4358
+ colorContext.fillStyle = fillColor;
4359
+ if (typeof colorContext.fillStyle === 'string') {
4360
+ var parsedColor = parseNormalizedColor(colorContext.fillStyle);
4361
+ if (parsedColor) {
4362
+ return parsedColor;
4363
+ }
4364
+ }
4365
+ colorContext.fillRect(0, 0, 1, 1);
4366
+ var color = colorContext.getImageData(0, 0, 1, 1).data;
4367
+ return {
4368
+ color: [color[0], color[1], color[2]],
4369
+ alpha: color[3] / MAX_CHANNEL_VALUE,
4370
+ };
4371
+ };
4372
+ var isOpaque = function (data) {
4373
+ for (var i = 3; i < data.length; i += 4) {
4374
+ if (data[i] !== MAX_CHANNEL_VALUE) {
4375
+ return false;
4376
+ }
4377
+ }
4378
+ return true;
4379
+ };
4380
+ var applyCommonOpaqueBlend = function (data, sourceColor, compositeOperation, compositeTimes) {
4381
+ var isBlack = sourceColor[0] === 0 && sourceColor[1] === 0 && sourceColor[2] === 0;
4382
+ var isWhite = sourceColor[0] === 1 && sourceColor[1] === 1 && sourceColor[2] === 1;
4383
+ if (compositeOperation === 'color-burn' && (isBlack || isWhite)) {
4384
+ if (isBlack) {
4385
+ for (var offset = 0; offset < data.length; offset += 4) {
4386
+ for (var channel = 0; channel < 3; channel++) {
4387
+ data[offset + channel] = data[offset + channel] === MAX_CHANNEL_VALUE ? MAX_CHANNEL_VALUE : 0;
4388
+ }
4389
+ }
4390
+ }
4391
+ return true;
4392
+ }
4393
+ if (compositeOperation !== 'overlay' || (!isBlack && !isWhite)) {
4394
+ return false;
4395
+ }
4396
+ var iterations = Math.ceil(compositeTimes);
4397
+ var multiplier = Math.pow(2, Math.min(iterations, 8));
4398
+ for (var offset = 0; offset < data.length; offset += 4) {
4399
+ for (var channel = 0; channel < 3; channel++) {
4400
+ var value = data[offset + channel];
4401
+ data[offset + channel] = isBlack
4402
+ ? Math.max(0, multiplier * value - MAX_CHANNEL_VALUE * (multiplier - 1))
4403
+ : Math.min(MAX_CHANNEL_VALUE, multiplier * value);
4404
+ }
4405
+ }
4406
+ return true;
4407
+ };
4408
+ var applyOpaqueBlend = function (data, sourceColor, compositeTimes, blend) {
4409
+ for (var i = 0; i < compositeTimes; i++) {
4410
+ for (var offset = 0; offset < data.length; offset += 4) {
4411
+ for (var channel = 0; channel < 3; channel++) {
4412
+ data[offset + channel] =
4413
+ blend(data[offset + channel] / MAX_CHANNEL_VALUE, sourceColor[channel]) * MAX_CHANNEL_VALUE;
4414
+ }
4415
+ }
4416
+ }
4417
+ };
4418
+ var applyAlphaBlend = function (data, sourceColor, sourceAlpha, compositeTimes, blend) {
4419
+ for (var i = 0; i < compositeTimes; i++) {
4420
+ for (var offset = 0; offset < data.length; offset += 4) {
4421
+ var backdropAlpha = data[offset + 3] / MAX_CHANNEL_VALUE;
4422
+ var outputAlpha = sourceAlpha + backdropAlpha * (1 - sourceAlpha);
4423
+ for (var channel = 0; channel < 3; channel++) {
4424
+ var backdrop = data[offset + channel] / MAX_CHANNEL_VALUE;
4425
+ var blendedSource = (1 - backdropAlpha) * sourceColor[channel] + backdropAlpha * blend(backdrop, sourceColor[channel]);
4426
+ var premultipliedOutput = sourceAlpha * blendedSource + backdropAlpha * (1 - sourceAlpha) * backdrop;
4427
+ data[offset + channel] = outputAlpha === 0 ? 0 : (premultipliedOutput / outputAlpha) * MAX_CHANNEL_VALUE;
4428
+ }
4429
+ data[offset + 3] = outputAlpha * MAX_CHANNEL_VALUE;
4430
+ }
4431
+ }
4432
+ };
4433
+ var softwareBlindDecodeFallback = function (_a) {
4434
+ var ctx = _a.ctx, fillColor = _a.fillColor, compositeOperation = _a.compositeOperation, compositeTimes = _a.compositeTimes;
4435
+ var blend = getBlendFunction(compositeOperation);
4436
+ var _b = getFillColor(ctx, fillColor), color = _b.color, alpha = _b.alpha;
4437
+ if (alpha === 0 || !(compositeTimes > 0)) {
4438
+ return;
4439
+ }
4440
+ var imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
4441
+ var sourceColor = [
4442
+ color[0] / MAX_CHANNEL_VALUE,
4443
+ color[1] / MAX_CHANNEL_VALUE,
4444
+ color[2] / MAX_CHANNEL_VALUE,
4445
+ ];
4446
+ if (alpha === 1 && isOpaque(imageData.data)) {
4447
+ if (!applyCommonOpaqueBlend(imageData.data, sourceColor, compositeOperation, compositeTimes)) {
4448
+ applyOpaqueBlend(imageData.data, sourceColor, compositeTimes, blend);
4449
+ }
4450
+ }
4451
+ else {
4452
+ applyAlphaBlend(imageData.data, sourceColor, alpha, compositeTimes, blend);
4453
+ }
4454
+ ctx.putImageData(imageData, 0, 0);
4455
+ };
4456
+
4276
4457
  function styleInject(css, ref) {
4277
4458
  if ( ref === void 0 ) ref = {};
4278
4459
  var insertAt = ref.insertAt;
@@ -5277,17 +5458,18 @@ var Watermark = /** @class */ (function () {
5277
5458
  return [2 /*return*/];
5278
5459
  }
5279
5460
  this.isCreating = true;
5461
+ _h.label = 1;
5462
+ case 1:
5463
+ _h.trys.push([1, , 3, 4]);
5280
5464
  if (!this.validateUnique()) {
5281
- this.isCreating = false;
5282
5465
  return [2 /*return*/];
5283
5466
  }
5284
5467
  if (!this.validateContent()) {
5285
- this.isCreating = false;
5286
5468
  return [2 /*return*/];
5287
5469
  }
5288
5470
  firstDraw = isUndefined(this.watermarkDom);
5289
5471
  return [4 /*yield*/, ((_a = this.watermarkCanvas) === null || _a === void 0 ? void 0 : _a.draw())];
5290
- case 1:
5472
+ case 2:
5291
5473
  _h.sent();
5292
5474
  this.layoutCanvas = renderLayout(this.options, (_b = this.watermarkCanvas) === null || _b === void 0 ? void 0 : _b.getCanvas());
5293
5475
  image = convertImage(this.layoutCanvas);
@@ -5297,22 +5479,25 @@ var Watermark = /** @class */ (function () {
5297
5479
  this.watermarkDom.__WATERMARK__ = 'watermark';
5298
5480
  this.watermarkDom.__WATERMARK__INSTANCE__ = this;
5299
5481
  parentElementType = this.checkParentElementType();
5300
- this.watermarkDom.style.cssText = "\n z-index:".concat(this.options.zIndex, "!important;display:block!important;visibility:visible!important;transform:none!important;scale:none!important;\n ").concat(parentElementType === 'custom' ? 'top:0!important;bottom:0!important;left:0!important;right:0!important;height:100%!important;pointer-events:none!important;position:absolute!important;' : 'position:relative!important;', "\n ");
5482
+ this.watermarkDom.style.cssText = "\n z-index:".concat(this.options.zIndex, "!important;display:block!important;visibility:visible!important;transform:none!important;scale:none!important;\n ").concat(parentElementType === 'custom' ? 'top:0!important;bottom:0!important;left:0!important;right:0!important;height:100%!important;pointer-events:none!important;position:absolute!important;' : 'position:relative!important;', "\n ");
5301
5483
  backgroundSize = generateBackgroundSize(this.options);
5302
- watermarkInnerDom.style.cssText = "\n display:block!important;visibility:visible!important;pointer-events:none;top:0;bottom:0;left:0;right:0;transform:none!important;scale:none!important;\n position:".concat(parentElementType === 'root' ? 'fixed' : 'absolute', "!important;-webkit-print-color-adjust:exact!important;width:100%!important;height:100%!important;\n z-index:").concat(this.options.zIndex, "!important;background-image:url(").concat(image, ")!important;background-repeat:").concat(this.options.backgroundRepeat, "!important;\n background-size:").concat(backgroundSize[0], "px ").concat(backgroundSize[1], "px!important;background-position:").concat(this.options.backgroundPosition, ";\n ").concat(generateAnimationStyle(this.options.movable, this.options.backgroundRepeat), "\n ");
5484
+ watermarkInnerDom.style.cssText = "\n display:block!important;visibility:visible!important;pointer-events:none;top:0;bottom:0;left:0;right:0;transform:none!important;scale:none!important;\n position:".concat(parentElementType === 'root' ? 'fixed' : 'absolute', "!important;-webkit-print-color-adjust:exact!important;width:100%!important;height:100%!important;\n z-index:").concat(this.options.zIndex, "!important;background-image:url(").concat(image, ")!important;background-repeat:").concat(this.options.backgroundRepeat, "!important;\n background-size:").concat(backgroundSize[0], "px ").concat(backgroundSize[1], "px!important;background-position:").concat(this.options.backgroundPosition, ";\n ").concat(generateAnimationStyle(this.options.movable, this.options.backgroundRepeat), "\n ");
5303
5485
  this.watermarkDom.appendChild(watermarkInnerDom);
5304
5486
  this.parentElement.appendChild(this.watermarkDom);
5305
5487
  if (this.options.mutationObserve) {
5306
5488
  try {
5307
- this.bindMutationObserve();
5489
+ this.bindMutationObserver();
5308
5490
  }
5309
5491
  catch (_j) {
5310
5492
  (_e = (_d = this.options).onObserveError) === null || _e === void 0 ? void 0 : _e.call(_d);
5311
5493
  }
5312
5494
  }
5313
5495
  firstDraw && ((_g = (_f = this.options).onSuccess) === null || _g === void 0 ? void 0 : _g.call(_f));
5496
+ return [3 /*break*/, 4];
5497
+ case 3:
5314
5498
  this.isCreating = false;
5315
- return [2 /*return*/];
5499
+ return [7 /*endfinally*/];
5500
+ case 4: return [2 /*return*/];
5316
5501
  }
5317
5502
  });
5318
5503
  });
@@ -5335,7 +5520,7 @@ var Watermark = /** @class */ (function () {
5335
5520
  var _a, _b, _c, _d, _e, _f, _g, _h;
5336
5521
  (_b = (_a = this.options).onBeforeDestroy) === null || _b === void 0 ? void 0 : _b.call(_a);
5337
5522
  (_c = this.observer) === null || _c === void 0 ? void 0 : _c.disconnect();
5338
- (_d = this.parentObserve) === null || _d === void 0 ? void 0 : _d.disconnect();
5523
+ (_d = this.parentObserver) === null || _d === void 0 ? void 0 : _d.disconnect();
5339
5524
  (_f = (_e = this.watermarkDom) === null || _e === void 0 ? void 0 : _e.parentNode) === null || _f === void 0 ? void 0 : _f.removeChild(this.watermarkDom);
5340
5525
  (_h = (_g = this.options).onDestroyed) === null || _h === void 0 ? void 0 : _h.call(_g);
5341
5526
  };
@@ -5395,56 +5580,55 @@ var Watermark = /** @class */ (function () {
5395
5580
  }
5396
5581
  return 'custom';
5397
5582
  };
5398
- Watermark.prototype.bindMutationObserve = function () {
5399
- var _this = this;
5400
- if (!this.watermarkDom) {
5401
- return;
5402
- }
5403
- this.observer = new MutationObserver(function (mutationsList) { return __awaiter(_this, void 0, void 0, function () {
5404
- return __generator(this, function (_a) {
5405
- switch (_a.label) {
5583
+ Watermark.prototype.recreateOnMutation = function () {
5584
+ return __awaiter(this, void 0, void 0, function () {
5585
+ var _b, _c;
5586
+ return __generator(this, function (_d) {
5587
+ switch (_d.label) {
5406
5588
  case 0:
5407
- if (!(mutationsList.length > 0)) return [3 /*break*/, 2];
5589
+ _d.trys.push([0, 2, , 3]);
5408
5590
  this.remove();
5409
5591
  return [4 /*yield*/, this.create()];
5410
5592
  case 1:
5411
- _a.sent();
5412
- _a.label = 2;
5413
- case 2: return [2 /*return*/];
5593
+ _d.sent();
5594
+ return [3 /*break*/, 3];
5595
+ case 2:
5596
+ _d.sent();
5597
+ (_c = (_b = this.options).onObserveError) === null || _c === void 0 ? void 0 : _c.call(_b);
5598
+ return [3 /*break*/, 3];
5599
+ case 3: return [2 /*return*/];
5414
5600
  }
5415
5601
  });
5416
- }); });
5602
+ });
5603
+ };
5604
+ Watermark.prototype.bindMutationObserver = function () {
5605
+ var _this = this;
5606
+ if (!this.watermarkDom) {
5607
+ return;
5608
+ }
5609
+ this.observer = new MutationObserver(function (mutationsList) {
5610
+ if (mutationsList.length > 0) {
5611
+ void _this.recreateOnMutation();
5612
+ }
5613
+ });
5417
5614
  this.observer.observe(this.watermarkDom, {
5418
5615
  attributes: true, // 属性的变动
5616
+ attributeFilter: ['style', 'class', 'hidden', 'id'], // 仅监听会影响水印展示或标识的属性
5419
5617
  childList: true, // 子节点的变动(指新增,删除或者更改)
5420
5618
  subtree: true, // 布尔值,表示是否将该观察器应用于该节点的所有后代节点。
5421
5619
  characterData: true, // 节点内容或节点文本的变动。
5422
5620
  });
5423
- this.parentObserve = new MutationObserver(function (mutationsList) { return __awaiter(_this, void 0, void 0, function () {
5424
- var _i, mutationsList_1, item, watermarkRemoved;
5425
- return __generator(this, function (_a) {
5426
- switch (_a.label) {
5427
- case 0:
5428
- _i = 0, mutationsList_1 = mutationsList;
5429
- _a.label = 1;
5430
- case 1:
5431
- if (!(_i < mutationsList_1.length)) return [3 /*break*/, 4];
5432
- item = mutationsList_1[_i];
5433
- watermarkRemoved = Array.from(item.removedNodes).includes(this.watermarkDom);
5434
- if (!watermarkRemoved) return [3 /*break*/, 3];
5435
- this.remove();
5436
- return [4 /*yield*/, this.create()];
5437
- case 2:
5438
- _a.sent();
5439
- _a.label = 3;
5440
- case 3:
5441
- _i++;
5442
- return [3 /*break*/, 1];
5443
- case 4: return [2 /*return*/];
5444
- }
5445
- });
5446
- }); });
5447
- this.parentObserve.observe(this.parentElement, {
5621
+ this.parentObserver = new MutationObserver(function (mutationsList) {
5622
+ var watermarkDom = _this.watermarkDom;
5623
+ if (!watermarkDom) {
5624
+ return;
5625
+ }
5626
+ var watermarkRemoved = mutationsList.some(function (item) { return Array.from(item.removedNodes).includes(watermarkDom); });
5627
+ if (watermarkRemoved) {
5628
+ void _this.recreateOnMutation();
5629
+ }
5630
+ });
5631
+ this.parentObserver.observe(this.parentElement, {
5448
5632
  childList: true, // 子节点的变动(指新增,删除或者更改)
5449
5633
  });
5450
5634
  };
@@ -5511,11 +5695,14 @@ var BlindWatermark = /** @class */ (function (_super) {
5511
5695
  throw new Error('get context error');
5512
5696
  }
5513
5697
  ctx.drawImage(img_1, 0, 0, width, height);
5514
- ctx.globalCompositeOperation = compositeOperation;
5515
- ctx.fillStyle = fillColor;
5516
- for (var i = 0; i < compositeTimes; i++) {
5517
- ctx.fillRect(0, 0, width, height);
5518
- }
5698
+ applyBlindDecodeComposite({
5699
+ ctx: ctx,
5700
+ width: width,
5701
+ height: height,
5702
+ fillColor: fillColor,
5703
+ compositeOperation: compositeOperation,
5704
+ compositeTimes: compositeTimes,
5705
+ });
5519
5706
  var resultImage = convertImage(canvas);
5520
5707
  if (isFunction(onSuccess)) {
5521
5708
  onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(resultImage);
@@ -5582,6 +5769,8 @@ var ImageWatermark = /** @class */ (function () {
5582
5769
  return ImageWatermark;
5583
5770
  }());
5584
5771
 
5772
+ registerBlindDecodeFallback(softwareBlindDecodeFallback);
5773
+
5585
5774
  exports.BlindWatermark = BlindWatermark;
5586
5775
  exports.ImageWatermark = ImageWatermark;
5587
5776
  exports.Watermark = Watermark;