Watermark高阶组件
Watermark作为高阶组件,包裹编辑器内容,即代码中的children,并传入用户信息做水印,其中的核心方法createWatermark(),传入当前的dom,方便讲水印作为背景印到div上。
export default class Watermark extends React.PureComponent {static propTypes = {userInfo: propTypes.object,children: propTypes.any,getCurrentUserInfo: propTypes.func.isRequired,isPrivate: propTypes.bool,};componentDidMount() {if (this.props.userInfo) {this.init();} else {this.props.getCurrentUserInfo();}}componentDidUpdate(preProps) {if (this.props.userInfo !== preProps.userInfo || this.props.isPrivate !== preProps.isPrivate) {this.init();}}init = () => {const { userInfo, isPrivate } = this.props;if (userInfo) {const {userVO: {name,// email,id,},} = userInfo;// console.log(`${name}(${id})`);createWatermark(this.container.current, `${name}(${id})`, isPrivate);}};render() {const { children } = this.props;return <div ref={this.container}>{children}</div>;}container = React.createRef();}
添加水印核心方法
import { getByteLength } from '@sjk/fe-components-react';import colorUtil from '@/utils/colorUtil';// 给元素加水印export default function(el, text, isPrivate) {const pageBackgroundColor = window.getComputedStyle(document.getElementsByTagName('body')[0]).backgroundColor;let backgroundColor = '#fff';let color = '#fefefe';const isDarkColorTheme = colorUtil.isDarkColor(pageBackgroundColor);if (isDarkColorTheme) {backgroundColor = pageBackgroundColor;color = colorUtil.getFontColorFromDarkStyle(pageBackgroundColor);}const textLength = getByteLength(text);let canvas = window.document.createElement('canvas');const fontSize = 14;// debugger;const width = (fontSize * textLength) / 2 + 30;const height = isPrivate ? 104 : fontSize;canvas.width = isPrivate ? (width > 260 ? width : 260) : width;canvas.height = height;let ctx = canvas.getContext('2d');ctx.font = `${fontSize}px sans-serif`;ctx.fillStyle = backgroundColor;ctx.fillRect(0, 0, width, height);// 隐藏个人信息的颜色ctx.fillStyle = color;ctx.fillText(text, 30, fontSize);if (isPrivate) {ctx.fillText(text, 60, fontSize * 2);ctx.fillText(text, 90, fontSize * 3);ctx.fillText(text, 120, fontSize * 4);ctx.rotate((35 * Math.PI) / 180);ctx.font = `32px sans-serif`;// 切换颜色显示警告信息ctx.fillStyle = 'rgba(242, 242, 242, 0.603921568627451)';if (isDarkColorTheme) {ctx.fillStyle = 'rgba(80, 80, 80, 0.603921568627451)';}ctx.fillText('私密文档', 10, 20);}const img = canvas.toDataURL('image/png');// debuggerel.style.background = `url("${img}") left top`;el = null;canvas = null;ctx = null;}
辅助函数
// 获取字符串字节长度,汉字两个字节,字母一个字节export default function getByteLength(str) {if (!str) return 0;if (typeof str != 'string') {str += '';}// eslint-disable-next-linereturn str.replace(/[^\x00-\xff]/g, '01').length;}
颜色深浅判断,从而显示字体颜色
export default {regex: {rgbStyleAll: /(^rgb\((\d+),\s*(\d+),\s*(\d+)\)$)|(^rgba\((\d+),\s*(\d+),\s*(\d+)(,\s*\d+\.\d+)*\)$)/,hexStyle: /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/,rgbaStyle: /^rgba\((\d+),\s*(\d+),\s*(\d+)(,\s*\d+\.\d+)*\)$/,rgbStyle: /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/,hexWidthStyle: /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i,},isRgbStyle(rgb) {return this.regex.rgbStyleAll.test(rgb);},isHexStyle(hex) {this.regex.hexStyle.test(hex);},isDarkColor(colorStyle) {if (this.isRgbStyle(colorStyle)) {if (colorStyle.indexOf('rgba') >= 0) {const rgba = this.regex.rgbaStyle.exec(colorStyle);const r = parseInt(rgba[1]);return r < 128;} else {const rgb = this.regex.rgbStyle.exec(colorStyle);const r = parseInt(rgb[1]);return r < 128;}} else if (this.isHexStyle(colorStyle)) {const rgb = this.regex.hexWidthStyle.exec(colorStyle);const r = parseInt(rgb[1], 16);return r < 128;} else {return false;}},/*** 获取背景色和字体颜色* @param colorStyle*/getFontColorFromDarkStyle(colorStyle) {if (this.isRgbStyle(colorStyle)) {if (colorStyle.indexOf('rgba') >= 0) {const rgba = this.regex.rgbaStyle.exec(colorStyle);return `rgba(${rgba[1] - 1}, ${rgba[2] - 1}, ${rgba[2] - 1}, ${rgba[4]})`;} else {const rgb = this.regex.rgbStyle.exec(colorStyle);return `rgb(${rgb[1] - 1}, ${rgb[2] - 1}, ${rgb[2] - 1})`;}} else {const rgb = this.regex.hexWidthStyle.exec(colorStyle);const r = parseInt(rgb[1], 16);const g = parseInt(rgb[2], 16);const b = parseInt(rgb[3], 16);return `rgb(${r}, ${g}, ${b})`;}},};
