网站首页 > 博客文章 正文
作者:前端小黑
原文地址:https://juejin.im/post/5e75e2b16fb9a07cc10ac552
基本介绍
- 前阵子通过 前端水印生成方案(网页水印+图片水印) 这篇文章学习了一下水印的生成方案,对其中使用 Canvas 实现网页水印的方案十分感兴趣,于是对相关代码加以修改,实现了一个 React 水印组件并发布到 npm。
- 该组件是通过 Canvas 生成水印,并使用 MutationObserve (可以监听DOM结构变化的接口)监视 DOM 的变动,使得水印不可被删除、且属性不可被修改。
- 关于发布react组件的方法之前已在使用npm发布一个react组件(踩坑实践)中进行介绍,本文将不再进行阐述,本文着重介绍组件的使用效果及具体实现。
效果演示
- 该组件已发布到npm上,可使用以下命令安装:
npm install --save watermark-component-for-react
- 在项目中使用:
import React from 'react';
import WaterMark from 'watermark-component-for-react';
import * as styles from './index.css';
class ReactDemo extends React.Component{
render () {
const content = `内部文档,请勿外传 by-前端小黑`;
return (
<WaterMark content={content}>
<div className={styles.wrapper}>hello world</div>
</WaterMark>
);
}
}
export default ReactDemo;
复制代码
- 结果:img
- ??注意:需要加水印的组件需要包裹在 WaterMark 组件中,即作为 WaterMark 的子组件。
组件特点
- 使用 MutationObserve 监视 DOM 的变动,水印不可被删除、且属性不可被修改:img
- 丰富的 props 使得水印组件可实现定制化需求:
成员说明类型默认值stylewatermark最外层组件内联样式undefined | objectundefinedcontainer容器HTMLDivElementdocument.bodywidthcanvas元素宽string300heightcanvas元素高string200textAlign绘制文本的对齐方式stringlefttextBaseline文本基准线stringbottomfont字体大小及样式string16px Microsoft YaheifillStyle自定义水印的颜色stringblackcontent水印内容string内部文档,请勿外传globalAlpha设置图形和图像透明度的值number0.1rotate文字旋转角度number16zIndex元素堆叠顺序number1000
具体实现
- 水印组件的源码如下:
import * as React from 'react';
import { watermark } from '../../utils/lib'
export default class WaterMark extends React.Component {
constructor(props) {
super(props);
this.container = null;
}
componentDidMount () {
const { style, ...options } = this.props;
watermark({
container: this.container,
...options,
});
}
render () {
const style = {
position: 'relative',
...this.props.style,
};
return (
<div ref={(el) => this.container = el} id="watermark" style={style}>
{this.props.children}
</div>
);
}
}
- 核心代码是 watermark 这个方法,具体代码如下:
export function watermark (options) {
const {
container = document.body, // 容器
width = '300', // canvas元素宽
height = '200', // canvas元素高
textAlign = 'left', // 文字对齐
textBaseline = 'bottom', // 基准线
font = '16px Microsoft Yahei', // 字体大小及样式
fillStyle = '#000', // 自定义水印的颜色
content = '内部文档,请勿外传', // 水印内容
globalAlpha = 0.1, // 设置图形和图像透明度的值
rotate = 16, // 文字旋转角度
zIndex = 1000, // 元素堆叠顺序
} = options;
let canvas = document.createElement('canvas');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);
let ctx = canvas.getContext('2d'); // 获取 canvas2d 上下文
ctx.globalAlpha = globalAlpha;
ctx.textAlign = textAlign;
ctx.textBaseline = textBaseline;
ctx.font = font;
ctx.fillStyle = fillStyle;
ctx.rotate((Math.PI * rotate) / 180);
ctx.fillText(content, 50, 50);
const base64Url = canvas.toDataURL(); // 返回一个包含图片展示的 data URI
const __wm = document.querySelector('.__wm');//选择器
const watermarkDiv = __wm || document.createElement("div");
const styleStr = `
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
z-index:${zIndex};
pointer-events:none;
background-repeat:repeat;
background-image:url('${base64Url}')`;
watermarkDiv.setAttribute('style', styleStr);
watermarkDiv.classList.add('__wm'); // 为元素添加“__wm”类名
container.style.position = 'relative';
if (!__wm) {
container.appendChild(watermarkDiv); // 添加元素
}
const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
// 检查浏览器是否支持这个API
if (MutationObserver) {
const args = arguments[0];
let mo = new MutationObserver(function () {
const __wm = document.querySelector('.__wm');
// 只在__wm元素变动才重新调用
if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm || container.style.position !== 'relative') {
// 避免一直触发
mo.disconnect();
mo = null;
watermark(args);
}
});
mo.observe(container, {
attributes: true, // 观察目标节点的属性节点
subtree: true, // 观察目标节点的所有后代节点
childList: true, // 观察目标节点的子节点
})
}
};
- 为便于理解,已在以上文件加上了注释,可以看到,通过使用MutationObserve ,当水印组件被删除、属性被修改或水印组件的容器定位属性 position 不为 relative时,会重新调用watermark方法。
总结
- 为了避免公司的内部文档被截图外泄,有必要在系统页面上面增加水印。
- 为了避免某些用户将水印删除,需要对水印组件进行监听(通过 MutationObserve 实现),当组件被删除时动态插入新的水印。
- 本文介绍的水印组件(watermark-component-for-react)已发布到 NPM,欢迎大家下载使用。
?
以上内容如有遗漏错误,欢迎留言 ??指出,一起进步
?
?
如果觉得本文对你有帮助,留下你宝贵的 ?
推荐React 学习相关文章
《手把手教你从Mixin深入到HOC再到Hook【React】》
《深入Facebook 官方React 状态管理器Recoil讲解》
《React源码分析与实现(一):组件的初始化与渲染「实践篇」》
《React源码分析与实现(二):状态、属性更新->setState「实践篇」》
《手把手教你10个案例理解React hooks的渲染逻辑「实践」》
《Vue 3.0 Beta 和React 开发者分别杠上了》
《手把手深入Redux react-redux中间件设计及原理(上)【实践】》
《手把手深入Redux react-redux中间件设计及原理(下)【实践】》
《为了学好 React Hooks, 我解析了 Vue Composition API》
《【React 高级进阶】探索 store 设计、从零实现 react-redux》
《深入浅出掌握React 与 React Native这两个框架》
《你需要的 React + TypeScript 50 条规范和经验》
《手把手教你深入浅出实现Vue3 & React Hooks新UI Modal弹窗》
《全平台(Vue/React/微信小程序)任意角度旋图片裁剪组件》
作者:前端小黑
原文地址:https://juejin.im/post/5e75e2b16fb9a07cc10ac552
- 上一篇: vue定制播放器 弹幕 品牌logo
- 下一篇: 程序员:轻松教你使用纯css实现编辑器中的水波动画
猜你喜欢
- 2024-11-25 又一个布局利器,CSS 伪类 :placeholder-shown
- 2024-11-25 值得收藏的CSS小技巧
- 2024-11-25 尤娜v1.2.2内置函数用法-Part II(分页函数)
- 2024-11-25 总结7个工作中常用的css3案例,带你了解冷门却实用的特性
- 2024-11-25 带你手写一个轮播图之HTML结构和CSS布局设计
- 2024-11-25 稍微整理了几个经常在H5移动端开发遇到的东西
- 2024-11-25 七爪源码:如何使用 vanilla JS & CSS 创建滚动到顶部按钮
- 2024-11-25 吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【上】
- 2024-11-25 3个超秀的 Vue 卡片翻动组件Vue-Card-Slide
- 2024-11-25 揭秘前端无刷新提交数据的黑科技 - React Server Actions深度解析
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)