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