前些时候遇到了预览文档或图片加水印的需要,看材料理解到,水印明显水印和暗水印两类,明水印容易实现但也容易破解,暗水印更平安实现也更简单。
需要:在用户预览合同的时候给预览合同图片增加水印,因为是后盾管理系统中的性能,就抉择了明水印来实现。
明水印的实现形式大抵有两种:
- div实现
- canvas背景图实现
上面是demo演示
index.html
<div id="app"> <img id="poster" src="./poster.jpeg" alt=""></div>
index.css
#app{ width: 400px; margin: 0 auto; position: relative;}#app #poster{ width: 100%;}
成果如下:
首先咱们试试用增加div的形式实现水印
markByDiv.js
function cssHelper(el, prototype) { for (let i in prototype) { el.style[i] = prototype[i] }}function handleWaterMark(waterMkrText, waterMkrWidth, waterMkrHeight, target){ const { clientWidth, clientHeight } = target; const columns = Math.ceil(clientWidth / waterMkrWidth); const rows = Math.ceil(clientHeight / waterMkrHeight); const shadow = document.createElement('div'); cssHelper(shadow, { position: 'absolute', fontSize: `16px`, color: '#ffffff', opacity: 0.3, left: '0px', top: '0px', bottom: '0px', right: '0px', display: 'flex', flexWrap: 'wrap' //可转行 }) for (let i = 0; i < columns * rows; i++) { const item = document.createElement('div'); item.innerHTML = waterMkrText cssHelper(item, { flexBasis: `1/${columns}`, //几列 width: `${waterMkrWidth}px`, height: `${waterMkrHeight}px`, lineHeight: `${waterMkrHeight}px`, transform: `rotate(-15deg)`, userSelect: 'none', //禁用框选 whiteSpace: 'nowrap', overflow: 'hidden', textAlign: 'center' }); shadow.appendChild(item) } target.parentNode.appendChild(shadow)}handleWaterMark('鬼灭之刃',80,80,document.getElementById('poster'))
成果实现如下:
实现思路:
1.生成和图片尺寸一样的shadow,通过相对定位盖在图片上
2.通过图片的尺寸和水印的尺寸计算出水印有几行几列
3.通过flex布局将水印排列到shadow上
再来试试canvas背景图实现水印
markByCanvas.js
function createWaterMark(waterMkrText, waterMkrWidth, waterMkrHeight) { const angle = -20; const canvas = document.createElement('canvas'); canvas.width = waterMkrWidth; canvas.height = waterMkrHeight; const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, waterMkrWidth, waterMkrHeight); ctx.fillStyle = '#fff'; ctx.globalAlpha = 0.5; ctx.font = `16px` ctx.rotate(Math.PI / 180 * angle); ctx.fillText(waterMkrText, 0, waterMkrHeight/2); return canvas.toDataURL();} const watermakr = document.createElement('div'); cssHelper(watermakr, { position: 'absolute', left: '0px', top: '0px', bottom: '0px', right: '0px', pointerEvents: 'none', backgroundRepeat: 'repeat', backgroundImage: `url(${createWaterMark('鬼灭之刃', 80, 80)})` }) document.getElementById('app').appendChild(watermakr);
成果实现如下:
实现思路:
1.利用canvas
绘制一个水印
2.通过canvas.toDataURL()
来拿到文件流的url
3.将url填充在一个元素的背景中,设置背景图片的属性为repeat