antd,YYDS
大家先去antd看看,大佬们研发的防删水印是什么样的。
是不是嘎嘎酷。
我们按F12就可以看到其实现方法
base64图片内容
简单概括就是:将文字/图片渲染为base64格式的图片,使用该图片渲染为一个背景图,然后将DOM渲染到水印主体DOM下方。然后增加我们上一期的监听DOM,一旦有变动立刻重新渲染。
antd官方的使用方法
import React from 'react';
import { Watermark } from 'antd';
const App: React.FC = () => (
<Watermark content="Ant Design">
<div style={{ height: 500 }} />
</Watermark>
);
export default App;
我们就尽量做到一致就好了
首先我们回归到第一步,也是重点,如何根据图片或者文字来绘制出来一个base64格式的图片呢?
首先我们看看antd的接受参数
antd的接受参数
可以说非常的多了,
一些阅读提示
5版本更新的这个参数我们不做,反正我的组件库也没有Modal、Drawer这些东西,以后可能会参考代码,增加这个组件然后继续水一期。
然后为啥antd的水印是交错排列的?我一开始也懵逼,以为是CSS写了啥操作,后来发现原来是人家画的时候就是交错的。
手搓具体思想
水印hooks
这个hooks比较多,代码具体实现逻辑如下
先弄一个默认options,用来放置默认水印的值
const defaultOptions = {
rotate: -20, // 旋转角度
zIndex: 1, // z-index
width: 100, // 水印宽度
gap: [100, 100], // 水印间距
fontStyle: { // 文本样式
fontSize: "16px",
color: "rgba(0, 0, 0, 0.15)",
fontFamily: "sans-serif",
fontWeight: "normal",
},
getContainer: () => document.body, // 默认水印挂载的容器
};
合并水印配置
我们写一个水印配置获取方法,传参包含我们可以接受的全部值,但是要剔除(Omit)dom传参,就是className,style,children这些
然后我们与默认配置进行整合,使用新配置替换默认配置
再做好offset值操作,毕竟offset与gap可以接收这样的传参
然后我们就可以拿到水印的配置
根据传递宽高生成Canvas
操作思路很简单,我们根据已经拿到的gap,宽,高,实时获取显示器缩放
canvas大小:gap+宽*显示器缩放/gap+高*显示器缩放
然后再router进行旋转,返回Canvas即可
文本水印处理
即,我们根据fontSize, color, fontWeight, fontFamily这4个基本类型来组成Canvas的渲染内容。
看似简单,实际上要适配文本样式,要修改的细节非常多
文本可以是数组,也就是要循环增加文本
要根据行数,与实际文本渲染宽度计算出文本宽高,旋转后的宽高,以及每行文本的原点,然后你就可以渲染出来这个canvas了
以上需要纯JS操作。
然后异步返回渲染后的base64图片地址
如果不会没关系,我也不会,只知道流程,数学公式我也麻,直接去我组件库开抄一下,反正我也抄,写不出来,不抄怎么办,哈哈哈哈哈哈哈哈哈。
图片水印处理
同理,我们需要new Image(),然后获取图片宽高并距中旋转,获取宽高比例生成图片宽高,然后剧中渲染图片,返回base64格式图片地址。
返回base64图片地址格式方法
然后我们在一个大方法内调用,能img就img,img没有或者报错就使用文本渲染canvas
useWatermart方法核心
负责水印options的监听与绘制,导出setOptions方法,跟据options绘制水印dom,并监听dom的变化。如果有变化则重新进行绘制。
Watermart组件
引入useWatermart,获取挂载容器,监听水印所需值,如果该值变化重写绘制水印。