学习记录 留作参考
祝君好运
在页面中动态增加水印的几种方法:
- 使用
canvas
的 fillText() 结合 rotate() 方法直接生成,本文使用该方法 - 使用
canvas
生成一个base64编码的图片,并将其设置为背景元素,csdn的参考文章 - 使用
js
动态生成若干个div元素追加到页面中,博客园的参考文章
几种实现方式各有特点。本文通过计算获得了横向与纵向可写文字的组数,主要参数都直接列在了方法的顶部。也可以不用这么麻烦,直接暴力的给一个很大的画布,然后再画非常多的水印也行。
<!-- 可以通过控制canvas元素的 position属性、z-index属性 来控制该元素的展示情况 -->
<canvas id="canvas" style="position:fixed;z-index:-1;top:0;left:0;"></canvas>
<script type="text/javascript" src="./resource/jquery.min.js"></script>
<script type="text/javascript">
// 页面加载完成后去添加水印
$(function () {
water()
})
// 当页面大小发生改变时也要重新绘制水印,增加一个延迟,防止触发频率过高
let resizeId = null
$(window).resize(function () {
if (resizeId) {
clearTimeout(resizeId);
}
resizeId = setTimeout(() => {
water()
}, 80);
});
function water() {
const fontSize = 20; // 字体大小
const degree = -30; // 旋转角度,顺时针为正,逆时针为负
const areaWidth = window.innerWidth; // 水印区域的宽度
const areaHeight = window.innerHeight; // 水印区域的高度
const nameStr = 'XX国际贸易有限公司';
const timeStr = '2023/1/18 12:00';
const lineSpace = 250; // 每行文字的垂直间隔(包含文字高度),px
const colSpace = 2; // 显示文字的区域的宽度与文字宽度的比例
const canvas = document.getElementById('canvas');
canvas.setAttribute('width', areaWidth)
canvas.setAttribute('height', areaHeight)
const ctx = canvas.getContext('2d');
ctx.rotate(degree * Math.PI / 180);
ctx.font = `${fontSize}px Microsoft Yahei`; // 设置字体及大小
const textWidth = ctx.measureText(nameStr).width // 获取文字宽度
const textUnitWidth = textWidth * colSpace; // 一个文字单元的宽度(文字宽度+左右空白)
ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'; // 字体的颜色
ctx.textAlign = "center"; // 文本的对齐方式
ctx.textBaseline = "middle"; // 文本的基线属性
// ctx.globalAlpha = 0.5; // 透明度
ctx.translate(100, 100); // 给画面一个基础偏移量,也可以省略该值
let xNum = Math.ceil(areaWidth / textUnitWidth) //不旋转时横向可以展示的最多文字单元数
let yNum = Math.ceil(areaHeight / lineSpace)//(不旋转时)纵向可以展示的最多文字单元数
// 当文字旋转时,有一部分文字会被转走,需要扩展写字的范围,使用正弦函数确定扩展的最大范围
let xStart = 0, yStart = 0, sin = Math.sin(Math.abs(degree) * Math.PI / 180);
if (degree > 0) {
// 顺时针旋转时,右侧和上侧可能会有空余
xNum += Math.ceil(sin * areaHeight / textUnitWidth);
yStart = Math.ceil(sin * areaWidth / lineSpace) + -1;
} else {
// 逆时针旋转时,左侧和下侧可能会有空余
xStart = Math.ceil(sin * areaHeight / textUnitWidth) * -1;
yNum += Math.ceil(sin * areaWidth / lineSpace);
}
for (let x = xStart; x < xNum; x++) {
for (let y = yStart; y < yNum; y++) {
const offsetY = y % 2 == 0 ? 0 : textUnitWidth / 2; // 隔行横向偏移一半的距离
const startX = textUnitWidth * x + offsetY; // 文字的X轴起始点
const startY = lineSpace * y; // 文字的Y轴起始点
ctx.fillText(nameStr, startX, startY);
ctx.fillText(timeStr, startX, startY + fontSize * 1.5);
}
}
// 也可以使用图片水印,
// 可以使用具体图片,也可以使用后台传来的base64图片,也可以是使用canvas生成的base64图片
// let img = new Image();
// img.src = './resource/1.png';
// ctx.drawImage(img, 150, 350);
}
</script>
效果图如下