用canvas生成圖片為頁面新增水印

tao892509844發表於2018-12-22

做政府行業的專案經常會遇到需要為頁面新增使用者登陸資訊水印的功能。

有幾個需要注意的點

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

方案一:利用canvas生成圖片並給容器新增background背景,並設定repeat,但是這樣做有一個弊端,頁面的內容不能再設定背景顏色,否則水印會被遮擋,這就不能滿足需求了。

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

pointer-events就是用來進行事件穿透的,如果給父元素設定了pointer-events:none,那麼父元素不再監聽滑鼠事件事件。也就是說設定該屬性後不會影響被遮蓋內容的操作,相當於透明的存在,點選不到它。

在專案中需要相容ie10以上,所以只能採取降級的方法,ie10以上及其他瀏覽器採用方案二,ie10採用方案一。

具體的實現程式碼

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複製出來就亂成一坨)

效果

用canvas生成圖片為頁面新增水印

如此已完成了所有需求,但還是存在一個問題。假如使用者是一個開發人員,他可能會在控制檯將輕易水印去除掉,目前我還沒有找到相應的解決方案。


相關文章