前言
Coding 應當是一生的事業,而不僅僅是 30 歲的青春飯
本文已收錄 GitHub https://github.com/ponkans/F2E,歡迎 Star,持續更新
網站瀏覽中,常常需要網頁水印,來防止使用者截圖或者錄屏暴露敏感資訊後無法追蹤使用者來源。比如釘釘、飛書等軟體,聊天背景會有你的花名。
水怪怪今天手把手帶你實現一個自定義水印的 npm 包,並釋出至 npm 倉庫。
思路
- 獲取標記資訊,比如使用者名稱、使用者 ID 等(也就是你想打上水印的目標物件)
- 繪製水印,繪製工具我們可以採用 canvas
實現
建立一個 npm 專案
mkdir watermarkly && cd watermarkly
npm init
touch index.js
touch README.md
複製程式碼
開放引數
- fontSize:水印字型大小
- color:水印字型顏色
- id:Canvas ID
- text:水印文案
- size:水印大小
- clarity:水印清晰度
建立畫布
根據 id 生成 canvas 畫布,如果沒有 id 引數傳入,則自動生成一個隨機字串,防止和頁面其他 DOM ID 衝突,如果已經存在該 id 對應的畫布,需要先清除再生成。
畫布大小為可用螢幕大小。畫布 fix 固定在可視視窗,z-index 為-1。
// 刪除已有畫布
let oldCanvas = document.getElementById(this.params.id);
if(oldCanvas){
oldCanvas.parentNode.removeChild(oldCanvas);
}
// 建立畫布
let body = document.getElementsByTagName('body');
let width = window.screen.width;
let height = window.screen.height;
let canvas = document.createElement('canvas');
let id = this.params.id
if(!id){
id = randomString(18);
}
// 設定畫布id
canvas.setAttribute('id', this.params.id);
canvas.width = width * this.params.clarity;
canvas.height = height * this.params.clarity;
canvas.style.cssText= 'position: fixed;width: 100%;height: 100%;left:0;top:0;z-index: -1;';
body[0].appendChild(canvas);
複製程式碼
填充畫布
計算 x 軸和 y 軸可展示水印個數,要做冗餘計算,防止出現邊界水印缺失
畫布逆時針旋轉 15 度
遍歷 x,y 依次繪製水印
let canvas = document.getElementById(this.params.id);
let cxt = canvas.getContext('2d');
let redundance = 10;
let xCount = window.screen.width * this.params.clarity / this.params.size + redundance;
let yCount = window.screen.height * this.params.clarity / this.params.size + redundance;
cxt.rotate(-15*Math.PI/180);
for(let i = 0; i < xCount; i++) {
for(let j = 0; j < yCount; j++) {
cxt.fillStyle = this.params.color;
cxt.font = this.params.fontSize + ' Arial';
cxt.fillText(this.params.text, this.params.density*(i-redundance/2), j*this.params.size);
}
}
複製程式碼
安全鎖
怪怪我興致勃勃的寫好了元件給老大看,結果,被吐槽說不嚴謹!what ?發生了什麼?
凶手原來……
有點 coding 經驗的同學,很容易通過各種騷操作抹掉水印,比如開啟除錯視窗刪除 canvas 或者修改 canvas 的樣式屬性。
所以我們還需要對水印加安全鎖,提高安全等級。
- 可以設定定時器,定時檢查水印狀態。
let self = this;
window.setInterval(function(){
let canvasDom = document.getElementById(self.params.id);
if (!canvasDom
|| canvasDom.style.cssText !== 'position: fixed; width: 100%; height: 100%; left: 0px; top: 0px; z-index: -1;'
|| canvasDom.width !== (window.screen.width * self.params.clarity)
|| canvasDom.height !== (window.screen.height * self.params.clarity)) {
self.init();
}
}, 500);
複製程式碼
釋出
- npm login
- npm publish
水印效果
npm i --save watermarkly
複製程式碼
import Watermark from 'watermarkly';
new Watermark({
text: 'test'
});
複製程式碼
總結
本文已收錄 GitHub https://github.com/ponkans/F2E,歡迎 Star,持續更新
很常見的一個小需求,抽下班時間簡單寫了下,主要也是因為前幾天看到技術交流群裡面一個小夥伴問了下,就順帶實現跟大家分享一把。
喜歡的小夥伴麻煩加個關注,點個在看哦,biubiubiu~
近期熱門原創推薦:
- 《吐血整理》系列 大廠前端元件庫工具集合(PC 端、移動端、JS、CSS 等)
- 《大前端進階 Node.js》系列 P6 必備腳手架/CI 構建能力
- 《吐血整理》系列 春招前端 17k 的水平 | 掘金技術徵文
公眾號後臺回覆【水印】,可獲取原始碼。
微信搜尋【接水怪】或掃描下面二維碼回覆”加群“,我會拉你進技術交流群。講真的,在這個群,哪怕您不說話,光看聊天記錄也是一種成長。(阿里技術專家、敖丙作者、Java3y、蘑菇街資深前端、螞蟻金服安全專家、各路大牛都在)。
接水怪也會定期原創,定期跟小夥伴進行經驗交流或幫忙看簡歷。加關注,不迷路,有機會一起跑個步? ↓↓↓