共计 2239 个字符,预计需要花费 6 分钟才能阅读完成。
前些时候遇到了预览文档或图片加水印的需要,看材料理解到,水印明显水印和暗水印两类,明水印容易实现但也容易破解,暗水印更平安实现也更简单。
需要:在用户预览合同的时候给预览合同图片增加水印,因为是后盾管理系统中的性能,就抉择了明水印来实现。
明水印的实现形式大抵有两种:
- 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
正文完
发表至: javascript
2020-12-22