用canvas生成圖片爲頁面添加水印

作政府行業的項目常常會遇到須要爲頁面添加用戶登錄信息水印的功能。css

有幾個須要注意的點node

  1. 須要平鋪整個頁面
  2. 水印須要蓋在內容上,可是不能影響操做
  3. 須要自適應窗口大小
考慮到以上需求有兩種方案:

方案一:利用canvas生成圖片並給容器添加background背景,並設置repeat,可是這樣作有一個弊端,頁面的內容不能再設置背景顏色,不然水印會被遮擋,這就不能知足需求了。canvas

方案二:利用canvas生成圖片後建立一個div,並將圖片設置爲div背景圖,再將div定位到容器上。此時須要爲div設置pointer-events:none,但該屬性只兼容IE10+。數組

pointer-events就是用來進行事件穿透的,若是給父元素設置了pointer-events:none,那麼父元素再也不監聽 鼠標事件事件。也就是說設置該屬性後不會影響被遮蓋內容的操做,至關於透明的存在,點擊不到它。

在項目中須要兼容ie10以上,因此只能採起降級的方法,ie10以上及其餘瀏覽器採用方案二,ie10採用方案一。瀏覽器

具體的實現代碼app

function IEVersion() {
const userAgent = navigator.userAgent;
const isIE =
userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;
if (isIE) {
const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
reIE.test(userAgent);
const fIEVersion = parseFloat(RegExp['$1']);
if (fIEVersion == 10) {
return 10;
}
} else {
return -1;
}
}


/*@text 水印文字數組 ['姓名', '身份證']
@sel容器的css選擇器
@txtColor水印文字的顏色
*/
export function setWaterMarker(text, sel, txtColor = 'rgba(0, 0, 0, 0.1)') {
const sel= document.querySelector(sel);
let waterBox = null;
for (let node of sel.children) {
if (node.className === 'water-marker') {
waterBox = node;
}
}
//建立一個canvas並插入到body後隱藏
if (waterBox || sel.style.backgroundImage) {
return false;
}
let can = document.body.querySelector('#water-can');
if (!can) {
can = document.createElement('canvas');
can.setAttribute('id', 'water-can');
document.body.appendChild(can);
}
can.width = 280;
can.height = 280;
can.style.display = 'none';
const cans = can.getContext('2d');
cans.rotate((-20 * Math.PI) / 180); //旋轉20度
cans.font = '20px Microsoft YaHei'; //設置文字樣式
cans.fillStyle = txtColor; //設置文字顏色
cans.textBaseline = 'Middle';
for (let i = text.length - 1; i >= 0; i--) {
//將文字繪製到畫布
cans.fillText(text[i], 0, 70 + i * 30);
}
cans.rotate((20 * Math.PI) / 180); //恢復旋轉角度
if (IEVersion() === -1) {
//若是是ie10之外的瀏覽器
const box = document.createElement('div');
box.style.cssText = `background-image: url(${can.toDataURL(
'image/png'
)});background-repeat:repeat;position:absolute;top:0;bottom:0;left:0;right:0;pointer-events:none;z-index:99;`;
sel.appendChild(box);
} else {
//ie10
sel.style.cssText = `background-image: url(${can.toDataURL(
'image/png'
)});background-repeat:repeat;`;
}
}

//調用
setWaterMarker(
[
state.userInfo.principal.username,
state.userInfo.principal.certNo,
'192.168.1.23',
formatDate(new Date(), 'yyyy-MM-dd HH:mm')
],
'.container',
'rgba(255,255,255,0.2)'
);

(掘金的編輯器真是太爛了,從vscode複製出來就亂成一坨)編輯器

效果
url


如此已完成了全部需求,但仍是存在一個問題。假如用戶是一個開發人員,他可能會在控制檯將輕易水印去除掉,目前我尚未找到相應的解決方案。code

相關文章
相關標籤/搜索