最近文章文档频繁被用户截屏,所以新派发了一个需求,给文章文档添加水印功能。
用户在上传文章、上传文档时,可选择是否需要加水印。
if(this.detail.waterMark){ //判断该篇文章是否加水印
this.addWaterMarker()
}
addWaterMarker() {
// 这里限制了不超过10个字,实际按需求来
let str = this.userInfo.account
var cpyName = str;
if (str.length > 10) {
cpyName = str.substring(0, 10);
}
// 创建 canvas 元素
var can = document.createElement('canvas');
// 获取 content 元素
if(this.type === 'article'){
var report = document.getElementsByClassName('prcontent')[0] //获取文章中要需要加水印的盒子
}else{
var report = document.getElementsByClassName('iframe-box1')[0] //获取文档中需要加水印的盒子
}
if(!report){
return
}
// 将 canvas 元素添加到 content 中
report.appendChild(can);
// 设置 canvas页面宽度,这里的 800 是因为我司水印文件大小固定,可按需求更改
can.width = 1000;
// 获取整个body高度
can.height = document.body.offsetHeight;
// 隐藏 canvas 元素
can.style.display = 'none';
can.style.zIndex = '9'
// 获取 canvas 元素工具箱
var cans = can.getContext('2d');
// 设置文字倾斜角度为 -25 度以及样式
cans.rotate(-25 * Math.PI / 180);
cans.font = "800 30px Microsoft JhengHei";
cans.fillStyle = "#B8BECC";
cans.textAlign = 'center';
cans.textBaseline = 'Middle';
cans.globalAlpha = 0.2
// 动态改变字体大小
if(cans.measureText(cpyName).width > 180) {
var size = 180 / cpyName.length
cans.font = '1000 ' + size +'px '+ ' Microsoft JhengHei'
}
/*
双重遍历,
当 宽度小于页面宽度时,
当 高度小于页面高度时,
这里的宽高可以适当写大,目的是为了让水印文字铺满
*/
for(let i = (document.body.offsetHeight*0.5)*-1; i<800; i+=160) {
for(let j = 0; j<document.body.offsetHeight*1.5; j+=60) {
// 填充文字,x 间距, y 间距
cans.fillText(cpyName, i, j)
}
}
// 将 canvas 转化为图片并且设置为背景
report.style.backgroundImage = "url(" + can.toDataURL("image/png") + ")";
this.style = report.style.backgroundImage
}
无水印效果时:


添加水印后:


最后来补一个踩坑记录:
由于项目中的pdf是iframe,所以想实现跨域获取iframe内部的高度,有难度,还待研究,但是有个简便的方法,可以给pdf加一个遮罩层
<div class="preview-doc" v-else-if="needDocTrans(detail.ext)">
<DocIframe v-if="detail.ext == 'pptx'" class="iframe-box iframe-item"
:url="detail.url"></DocIframe>
<DocIframe class="iframe-item" v-else :url="detail.url"></DocIframe>
<div class="iframe-box1"></div>
</div>
.preview-doc{
position relative
.iframe-box1{
position absolute
pointer-events: none;
left 10%
top 10%
width 80%
height 80%
background: transparent;
overflow: hidden
}
iframe{
width 100%
height 1000px
}
.iframe-box,+iframe{
height 500px
}
}
由于加了遮罩层之后,底层的iframe失去了滚动效果,原因是滚动事件没法穿透到下层,所以我们就需要用到下面这个属性pointer-events: none
顾名思义,就是鼠标事件拜拜的意思。元素应用了该 CSS 属性,链接啊,点击啊什么的都变成了 “浮云牌酱油”。pointer-events: none 的作用是让元素实体 “虚化”。例如一个应用 pointer-events: none 的按钮元素,则我们在页面上看到的这个按钮,只是一个虚幻的影子而已,您可以理解为海市蜃楼,幽灵的躯体。当我们用手触碰它的时候可以轻易地没有任何感觉地从中穿过去,至此,我们的水印效果就完美的实现了。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




