原創(chuàng) zcc date 2020-03-05
前些天突然發(fā)現(xiàn)內(nèi)網(wǎng)上的好多頁面都添加了水印,如下圖所示,每個人的名字作為背景圖整齊排列,這是怎么實現(xiàn)的呢?

首先想到的是給頁面加背景圖,但是背景圖的內(nèi)容要動態(tài)繪制,怎么辦呢?先思考再往下看:
鑒于現(xiàn)代瀏覽器的日益更新和IE舊家族的逐漸沒落,很容易想到使用canvas實現(xiàn)。
由于我的需求是使用用戶名或者其它指定文字,這里重點介紹一下fillText。
先來簡單了解一下fillText的語法吧:
fillText(text,x,y,maxWidth)
text:規(guī)定在畫布上輸出的文本。
x:開始繪制文本的 x 坐標位置(相對于畫布)。
y:開始繪制文本的 y 坐標位置(相對于畫布)。
maxWidth:可選,允許的最大文本寬度,以像素計。
下面再來想想實現(xiàn)一個靈活可定制的文字圖片,除了文字內(nèi)容,還需要傳些什么參數(shù)呢?
比如圖片大小,文字顏色,文字的旋轉角度,字體,顯示圖片的容器等等;
參數(shù)是供用戶自己根據(jù)實際情況調(diào)整的,假如用戶不希望一個個填寫這些差不多的內(nèi)容怎么辦呢?
對了,使用默認值;
綜上考慮,代碼大致如下:
function waterMark({
width=300, //畫布寬度
height=200, //畫布高度
rotate = 30, //旋轉角度
color = "#ccc", //字體顏色
textAlign = 'center', //文字對齊方式
textBaseline = 'middle',
font = "20px microsoft yahei",
content = "zcc", //最重要的,水印的內(nèi)容
opacity = '0.6',
zIndex = 999,
container = document.body, //水印顯示在哪里
} = {}){
let cvs =document.createElement('canvas');
let ctx = cvs.getContext('2d');
cvs.width = width;
cvs.height = height;
ctx.rotate(Math.PI / 180 * rotate);
ctx.fillStyle = color
ctx.font = font
ctx.textAlign = textAlign
ctx.textBaseline = textBaseline
ctx.fillText(content, parseFloat(width/2),parseFloat(height/2))
let url = cvs.toDataURL()
let div = document.createElement('div')
div.style = `
position:absolute;
width:100%;
height:${container.scrollHeight}px;
pointer-events:none;
top:0;
bottom:0;
opacity: ${opacity};
z-index: ${zIndex};
background-repeat:repeat;
background-image:url(${url});
`
container.appendChild(div)
}
實現(xiàn)很簡單是不是?使用就更簡單了,由于我們的代碼很貼心的給了很多默認參數(shù),最簡單的使用方式是直接調(diào)用waterMark();
不過這時候顯示的內(nèi)容可是作者我的名字哦,所以如果自己使用,最起碼這樣使用waterMark({content:'your name'});
下面我們再稍微擴展一下,假如用戶并不想要你給他自動加背景圖,就是想要一個圖片,自己來決定圖片的使用,又該怎么辦呢?
答案也很簡單, 在函數(shù)里加個參數(shù), onlyURL=false,默認false,如果為true,直接返回url,否則才去創(chuàng)建背景元素:
// 繪制圖片部分參考上文
let url = cvs.toDataURL()
if(onlyURL){
return url;
}
let div = document.createElement('div')
div.style = `
position:absolute;
width:100%;
height:${container.scrollHeight}px;
pointer-events:none;
top:0;
bottom:0;
opacity: ${opacity};
z-index: ${zIndex};
background-repeat:repeat;
background-image:url(${url});
`
container.appendChild(div)
簡單的加水印功能已經(jīng)完成了,是不是到這就結束了呢?
其實如果再擴展一下,還有很多可以實現(xiàn)的功能點,比如:
上述實現(xiàn)文字都是單行的,如果想要多行顯示要怎么做呢?
上述實現(xiàn)是作為一張背景圖添加到頁面,稍微懂點前端的人是知道怎么去掉水印的,水印的防護功能就沒用了,此時又該怎么處理呢?
上述實現(xiàn)只是單純的顯示文字,如果用戶提供一張圖片又該怎么做呢?
作為具有分享精神的互聯(lián)網(wǎng)人,我們怎樣提供給別人使用呢?
上面這些問題就留給感興趣的小伙伴去思考、實踐了。
前端的探索是無止境的,小伙伴們是不是躍躍欲試了,趕緊行動起來吧!