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