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