js 实现水印功能
实现水印功能的几种方法
使用Canvas绘制水印
通过Canvas绘制文本或图片水印,生成Base64数据后设置为背景。
function createWatermark(text, options = {}) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const fontSize = options.fontSize || 16;
const color = options.color || 'rgba(180, 180, 180, 0.3)';
const angle = options.angle || -20;
canvas.width = 200;
canvas.height = 100;
ctx.font = `${fontSize}px Arial`;
ctx.fillStyle = color;
ctx.rotate(angle * Math.PI / 180);
ctx.fillText(text, 10, 50);
return canvas.toDataURL('image/png');
}
// 应用水印
const watermarkUrl = createWatermark('Confidential');
document.body.style.backgroundImage = `url(${watermarkUrl})`;
使用SVG生成水印
SVG水印适合需要矢量缩放或复杂效果的场景。

function createSvgWatermark(text) {
const svg = `
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<text x="20" y="50" fill="rgba(180,180,180,0.3)"
font-family="Arial" font-size="16" transform="rotate(-20)">
${text}
</text>
</svg>`;
return `data:image/svg+xml;base64,${btoa(svg)}`;
}
document.body.style.backgroundImage = `url(${createSvgWatermark('Draft')})`;
使用CSS伪元素实现简单水印
适合不需要旋转的静态水印。

const style = document.createElement('style');
style.innerHTML = `
body::after {
content: "SAMPLE";
position: fixed;
opacity: 0.3;
font-size: 80px;
z-index: 9999;
pointer-events: none;
transform: rotate(-15deg);
}
`;
document.head.appendChild(style);
防止水印被删除的增强方案
通过MutationObserver监测DOM变化,防止水印被移除。
function protectWatermark(watermarkId) {
const observer = new MutationObserver(() => {
if (!document.getElementById(watermarkId)) {
const watermark = document.createElement('div');
watermark.id = watermarkId;
watermark.style.position = 'fixed';
// 重新添加水印样式
document.body.appendChild(watermark);
}
});
observer.observe(document.body, { childList: true });
}
图片水印实现示例
为图片添加Canvas水印后导出。
function addImageWatermark(imgSrc, watermarkText) {
const img = new Image();
img.onload = function() {
const canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
ctx.font = '30px Arial';
ctx.fillStyle = 'rgba(255,0,0,0.5)';
ctx.fillText(watermarkText, 50, 50);
document.body.appendChild(canvas);
};
img.src = imgSrc;
}
注意事项
- 动态水印需考虑性能影响,避免频繁重绘
- 重要数据建议结合后端校验
- 移动端需测试兼容性
- 透明度和旋转角度根据实际需求调整






