工作项目里实现过的需求,学习了相关代码总结出这篇文章
实现水印的思路
从页面层次上来看,水印可以理解为覆盖在最高层的一层透明背景,虽然覆盖在最高层,但是不应该影响底层任何事件的触发
可以通过 canvas 绘制字符串的图片,然后转化为图片作为背景循环平铺到一个 div 里
这个 div 就是水印图
代码实现
绘制水印图片
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| function setWatermark(str: string): HTMLDivElement | null { const id = "1.1351.1561.215515"; const lastEle = document.getElementById(id);
if (lastEle !== null) { document.body.removeChild(lastEle); }
const canvas = document.createElement("canvas"); const body = document.querySelector("body");
const clientWidth = body?.clientWidth ?? 0; const clientHeight = body?.clientHeight ?? 0;
const ctx = canvas.getContext("2d"); if (!ctx) return null;
const strWidth = ctx.measureText(str).width; const canvasW = strWidth * Math.cos((30 / 180) * Math.PI) + 100; const canvasH = strWidth * Math.sin((30 / 180) * Math.PI) + 100;
canvas.style.width = `${canvasW}px`; canvas.style.height = `${canvasH}px`;
canvas.width = canvasW; canvas.height = canvasH;
ctx.rotate((-30 * Math.PI) / 180); ctx.font = "14px PingFang SC"; ctx.fillStyle = "rgba(0, 0, 0, 0.05)"; ctx.textAlign = "left"; ctx.textBaseline = "bottom"; ctx.fillText(str, 0, canvas.height);
const ele = document.createElement("div"); ele.id = id; ele.style.pointerEvents = "none"; ele.style.top = "0px"; ele.style.position = "fixed"; ele.style.zIndex = "100000"; ele.style.width = `${clientWidth}px`; ele.style.height = `${clientHeight}px`;
canvas.toBlob((blob) => { const newImg = document.createElement("img"); const url = URL.createObjectURL(blob || new Blob()); newImg.onload = function () { URL.revokeObjectURL(url); }; ele.style.background = `url(${url}) left top repeat`; }); document.body.appendChild(ele); return ele; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Watermark { static set(str: string) { let ele = setWatermark(str);
setInterval(() => { if ( !ele || document.getElementById(ele.id) === null || !ele.style.background ) { ele = setWatermark(str); } }, 500);
window.onresize = () => { setWatermark(str); }; }
static outWatermark(id: string) { const div = document.getElementById(id); if (div !== null && div) div.style.display = "none"; } static out() { const id = "1.1351.1561.215515"; Watermark.outWatermark(id); } }
|
设置水印
隐藏水印: