UNPKG

@acrodata/watermark

Version:
1 lines 29.5 kB
{"version":3,"file":"acrodata-watermark.mjs","sources":["../../../projects/watermark/src/lib/utils.ts","../../../projects/watermark/src/lib/watermark.ts","../../../projects/watermark/src/lib/watermark.directive.ts","../../../projects/watermark/src/public-api.ts","../../../projects/watermark/src/acrodata-watermark.ts"],"sourcesContent":["import { WatermarkOptions, DrawPatternResult } from './types';\n\n/** 用于标记是否需要保护 */\nexport const attributeNameTag = 'data-watermark-tag';\n\nexport const observeOptions = {\n childList: true,\n subtree: true,\n attributeFilter: ['style', 'class', attributeNameTag],\n};\n\n/** 获取 DataSetKey */\nexport function getDataSetKey(attributeName: string) {\n return attributeName\n .split('-')\n .slice(1)\n .reduce((prev, cur, index) => {\n if (index === 0) {\n return cur;\n }\n\n return `${prev}${cur[0].toUpperCase() + cur.slice(1)}`;\n });\n}\n\n/** 通过 CSSOM API 应用样式(CSP 安全,无需 unsafe-inline) */\nexport const applyStyle = (el: HTMLElement, style: Record<string, string | number>) => {\n el.style.cssText = '';\n\n Object.keys(style).forEach(key => {\n if (style[key] !== '' && style[key] != null) {\n const value = String(style[key]);\n const prop = key.replace(/([A-Z])/g, '-$1').toLowerCase();\n\n if (value.endsWith('!important')) {\n const cleanValue = value.replace(/\\s*!important$/, '');\n el.style.setProperty(prop, cleanValue, 'important');\n } else {\n el.style.setProperty(prop, value);\n }\n }\n });\n};\n\n/** 创建随机 ID */\nexport const getRandomId = (prefix = '') => {\n const uid = window.btoa(decodeURI(encodeURIComponent(prefix)));\n return `${uid}-${new Date().getTime()}-${Math.floor(Math.random() * Math.pow(10, 8))}`;\n};\n\n/** 获取水印挂载节点 */\nexport const getContainer = (container: WatermarkOptions['container']) => {\n let dom: HTMLElement | null;\n\n if (typeof container === 'string') {\n dom = document.querySelector(container);\n if (!dom) {\n throw new Error(`The watermark container element '${container}' not found!`);\n }\n } else {\n dom = container ?? document.body;\n }\n\n return dom;\n};\n\n/** 盲水印解密 */\nexport const decrypt = (ctx: CanvasRenderingContext2D) => {\n const originalData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);\n const data = originalData.data;\n for (let i = 0; i < data.length; i++) {\n // 筛选每个像素点的R值\n if (i % 4 == 0) {\n if (data[i] % 2 == 0) {\n // 如果 R 值为偶数,说明这个点是没有水印信息的,将其 R 值设为0\n data[i] = 0;\n } else {\n // 如果 R 值为奇数,说明这个点是有水印信息的,将其 R 值设为255\n data[i] = 255;\n }\n } else if (i % 4 == 3) {\n // 透明度不作处理\n continue;\n } else {\n // G、B 值设置为 0,不影响\n data[i] = 0;\n }\n }\n // 至此,带有水印信息的点都将展示为 `255,0,0`,而没有水印信息的点将展示为 `0,0,0`,将结果绘制到画布\n ctx.putImageData(originalData, 0, 0);\n};\n\nexport const createHost = (watermarkTag: string) => {\n const dom = document.createElement('div');\n // 可以隐藏元素的 CSS 属性\n const hiddenCSS = {\n 'display': 'block !important',\n 'position': 'static !important',\n 'opacity': '1 !important',\n 'visibility': 'visible !important',\n 'transform': 'none !important',\n 'clip-path': 'none !important',\n };\n applyStyle(dom, hiddenCSS);\n dom.setAttribute(attributeNameTag, watermarkTag);\n return dom;\n};\n\nexport function getDrawPattern(opts: WatermarkOptions): Promise<DrawPatternResult> {\n const {\n text,\n gapX,\n gapY,\n offsetY,\n offsetX,\n width,\n height,\n rotate,\n opacity,\n fontSize,\n fontStyle,\n fontVariant,\n fontWeight,\n fontFamily,\n fontColor,\n textAlign,\n textBaseline,\n image,\n blindText,\n blindFontSize,\n blindOpacity,\n } = opts as Required<WatermarkOptions>;\n return new Promise((resolve, reject) => {\n const canvas = document.createElement('canvas');\n\n const ctx = canvas.getContext('2d');\n const ratio = 1;\n\n const canvasWidth = (Number(gapX) + Number(width)) * ratio;\n const canvasHeight = (Number(gapY) + Number(height)) * ratio;\n const canvasOffsetLeft = Number(offsetX) || Number(gapX) / 2;\n const canvasOffsetTop = Number(offsetY) || Number(gapY) / 2;\n\n canvas.setAttribute('width', `${canvasWidth}px`);\n canvas.setAttribute('height', `${canvasHeight}px`);\n\n if (ctx) {\n const markWidth = width * ratio;\n const markHeight = height * ratio;\n\n // 1. 根据元素中心点旋转\n ctx.translate(canvasOffsetLeft * ratio, canvasOffsetTop * ratio);\n ctx.translate(markWidth / 2, markHeight / 2); // 1\n ctx.rotate((Math.PI / 180) * Number(rotate));\n ctx.translate(-markWidth / 2, -markHeight / 2); // 1\n\n // 是否需要增加盲水印文字\n if (blindText) {\n // 盲水印需要低透明度\n ctx.globalAlpha = blindOpacity;\n ctx.font = `${blindFontSize}px normal`;\n ctx.fillText(blindText, 0, 0);\n }\n\n // 设置透明度\n ctx.globalAlpha = opacity;\n\n // 优先使用图片\n if (image) {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.referrerPolicy = 'no-referrer';\n img.src = image;\n img.onload = () => {\n ctx.drawImage(img, 0, 0, markWidth, markHeight);\n resolve({\n url: ctx.canvas.toDataURL(),\n width: canvasWidth,\n height: canvasHeight,\n });\n };\n return;\n }\n\n // 获取文本的最大宽度\n const texts = typeof text === 'string' ? text.split('\\n') : text;\n const widths = texts.map(item => ctx.measureText(item).width);\n const maxWidth = Math.max(...widths);\n\n const markSize = Number(fontSize) * ratio;\n\n // 设置文本对齐方式\n ctx.textAlign = textAlign;\n // 设置文本位置\n ctx.textBaseline = textBaseline;\n // 设置字体颜色\n ctx.fillStyle = fontColor;\n // 设置字体\n ctx.font = getFont(`${markSize}px`);\n\n // 文案宽度大于画板宽度\n if (maxWidth > width) {\n ctx.font = getFont(`${markSize / 2}px`);\n }\n\n // 多行文本的上下间距\n const textGap = 4;\n\n // 获取行高\n const lineHeight = markSize;\n\n // 计算水印在 y 轴上的初始位置\n let initY = (markHeight - (fontSize + 4) * texts.length - textGap * (texts.length - 1)) / 2;\n initY = initY < 0 ? 0 : initY;\n\n for (let i = 0; i < texts.length; i++) {\n ctx.fillText(texts[i] || '', markWidth / 2, initY + lineHeight * (i + 1) + textGap * i);\n }\n resolve({\n url: ctx.canvas.toDataURL(),\n width: canvasWidth,\n height: canvasHeight,\n });\n }\n\n function getFont(fontSize: string) {\n return `${fontStyle} ${fontVariant} ${fontWeight} ${fontSize} ${fontFamily}`;\n }\n\n return reject();\n });\n}\n","import { WatermarkOptions } from './types';\nimport {\n applyStyle,\n attributeNameTag,\n createHost,\n decrypt,\n getContainer,\n getDataSetKey,\n getDrawPattern,\n getRandomId,\n observeOptions,\n} from './utils';\n\nexport const defaultOptions: WatermarkOptions = {\n gapX: 100,\n gapY: 100,\n offsetX: 0,\n offsetY: 0,\n width: 120,\n height: 60,\n opacity: 0.15,\n rotate: -24,\n fontSize: 16,\n fontWeight: '400',\n fontStyle: 'normal',\n fontVariant: 'normal',\n fontColor: '#000',\n fontFamily: 'sans-serif',\n textAlign: 'center',\n textBaseline: 'alphabetic',\n secure: true,\n blindFontSize: 16,\n blindOpacity: 0.005,\n repeat: 'multiply',\n zIndex: 9999,\n};\n\nexport class Watermark {\n /** 水印配置 */\n private options: WatermarkOptions = {};\n /** 水印挂载容器 */\n private container?: HTMLElement;\n /** 水印的宿主节点 */\n private watermarkHost?: HTMLElement;\n /** 水印节点 */\n private watermarkDom?: HTMLElement;\n /** 水印样式 */\n private style: Record<string, string | number> = {\n pointerEvents: 'none',\n position: 'absolute',\n inset: 0,\n };\n private watermarkTag = getRandomId('watermark');\n private shadowRoot?: ShadowRoot | HTMLElement;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(options: WatermarkOptions = {}) {\n this.options = Object.assign({}, defaultOptions, options);\n\n this._render();\n }\n\n static decrypt = decrypt;\n\n update(options: WatermarkOptions = {}) {\n this.options = {\n ...this.options,\n ...options,\n };\n\n this._render();\n }\n\n show() {\n if (this.watermarkDom) {\n this.style['display'] = 'block';\n applyStyle(this.watermarkDom, this.style);\n }\n }\n\n hide() {\n if (this.watermarkDom) {\n this.style['display'] = 'none';\n applyStyle(this.watermarkDom, this.style);\n }\n }\n\n destroy() {\n this.shadowRoot = undefined;\n\n if (this.watermarkHost) {\n this.watermarkHost.remove();\n this.watermarkHost = undefined;\n }\n\n if (this.watermarkDom) {\n this.watermarkDom.remove();\n this.watermarkDom = undefined;\n }\n\n this._destroyMutationObserver();\n }\n\n _shouldRerender = (mutation: MutationRecord) => {\n // 修改样式或属性\n if (mutation.type === 'attributes') {\n if (mutation.attributeName === attributeNameTag) {\n return true;\n }\n if (this.watermarkTag === this._getNodeRandomId(mutation.target)) {\n return true;\n }\n }\n\n // 删除节点\n if (\n mutation.removedNodes.length &&\n this.watermarkTag === this._getNodeRandomId(mutation.removedNodes[0])\n ) {\n return true;\n }\n\n return false;\n };\n\n _getNodeRandomId = (node: Node) => {\n return (node as HTMLElement)?.dataset?.[getDataSetKey(attributeNameTag)];\n };\n\n _destroyMutationObserver = () => {\n if (this.mutationObserver) {\n this.mutationObserver.takeRecords();\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n };\n\n _getWatermarkDom = async () => {\n if (!this.watermarkDom) {\n this.watermarkDom = document.createElement('div');\n }\n\n const bgConfig = await getDrawPattern(this.options);\n\n if (bgConfig?.url) {\n const bgImg = bgConfig.url;\n\n this.style['zIndex'] = this.options.zIndex!;\n\n if (this.options.repeat === 'multiply') {\n this.style['backgroundImage'] = `url(${bgImg}), url(${bgImg})`;\n this.style['backgroundRepeat'] = 'repeat';\n this.style['backgroundPosition'] = `${bgConfig.width / 2}px ${bgConfig.height / 2}px, 0 0`;\n } else {\n this.style['backgroundImage'] = `url(${bgImg})`;\n this.style['backgroundRepeat'] = 'repeat';\n this.style['backgroundPosition'] = '';\n\n if (this.options.repeat === 'none') {\n this.style['backgroundRepeat'] = 'no-repeat';\n this.style['backgroundPosition'] = this.options.position || 'center';\n }\n }\n\n if (!this.options.container) {\n this.style['position'] = 'fixed';\n }\n\n if (this.options.scrollHeight) {\n const height = this.options.scrollHeight;\n this.style['height'] = isNaN(Number(height)) ? height : height + 'px';\n }\n\n applyStyle(this.watermarkDom, this.style);\n }\n\n this.watermarkDom.setAttribute(attributeNameTag, this.watermarkTag);\n\n return this.watermarkDom;\n };\n\n async _render() {\n this._destroyMutationObserver();\n\n // 获取水印挂载节点\n this.container = getContainer(this.options.container);\n // 获取水印父节点\n if (!this.watermarkHost) {\n this.watermarkHost = createHost(this.watermarkTag);\n this.container.append(this.watermarkHost);\n }\n\n // 获取水印 DOM\n this.watermarkDom = await this._getWatermarkDom();\n\n // 删除已有水印\n if (this.watermarkHost) {\n const children = this.watermarkHost.childNodes || [];\n\n children.forEach(child => {\n this.watermarkHost!.removeChild(child);\n });\n }\n\n // 判断是否支持 Shadow DOM\n if (typeof this.watermarkHost.attachShadow === 'function') {\n if (!this.shadowRoot) {\n this.shadowRoot = this.watermarkHost.attachShadow({ mode: 'open' });\n }\n } else {\n this.shadowRoot = this.watermarkHost;\n }\n\n this.shadowRoot.append(this.watermarkDom);\n\n if (MutationObserver && this.options.secure) {\n this.mutationObserver = new MutationObserver(mutations => {\n mutations.forEach(mutation => {\n if (this._shouldRerender(mutation)) {\n this.destroy();\n this._render();\n return;\n }\n });\n });\n this.mutationObserver.observe(this.container, observeOptions);\n if (this.shadowRoot) {\n this.mutationObserver.observe(this.shadowRoot, observeOptions);\n }\n }\n }\n}\n","import {\n booleanAttribute,\n Directive,\n ElementRef,\n inject,\n Input,\n NgZone,\n numberAttribute,\n OnChanges,\n OnDestroy,\n OnInit,\n} from '@angular/core';\nimport { WatermarkOptions } from './types';\nimport { Watermark } from './watermark';\n\n@Directive({\n selector: '[watermark]',\n exportAs: 'watermark',\n host: {\n '[style.position]': '\"relative\"',\n },\n})\nexport class WatermarkDirective implements OnInit, OnChanges, OnDestroy {\n @Input({ alias: 'watermarkOptions' }) options: WatermarkOptions = {};\n\n @Input({ alias: 'watermarkContainer' }) container?: HTMLElement | string | null;\n\n @Input({ alias: 'watermarkSecure', transform: booleanAttribute }) secure = true;\n\n @Input({ alias: 'watermarkZIndex', transform: numberAttribute }) zIndex = 9999;\n\n @Input({ alias: 'watermarkScrollHeight' }) scrollHeight?: string | number;\n\n private _elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private _ngZone = inject(NgZone);\n\n private _watermark?: Watermark;\n\n ngOnInit(): void {\n const el = this._elementRef.nativeElement;\n\n this._watermark = this._ngZone.runOutsideAngular(\n () =>\n new Watermark({\n ...this.options,\n container: this.container || (el.childNodes.length > 0 ? el : null),\n secure: this.secure,\n zIndex: this.zIndex,\n scrollHeight: this.scrollHeight,\n })\n );\n }\n\n ngOnChanges(): void {\n this.update(this.options);\n }\n\n ngOnDestroy(): void {\n this.destroy();\n }\n\n update(options: WatermarkOptions) {\n this._watermark?.update(options);\n }\n\n show() {\n this._watermark?.show();\n }\n\n hide() {\n this._watermark?.hide();\n }\n\n destroy() {\n this._watermark?.destroy();\n }\n}\n","/*\n * Public API Surface of watermark\n */\n\nexport { WatermarkOptions } from './lib/types';\nexport * from './lib/watermark';\nexport * from './lib/watermark.directive';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}