JavaScript和小程序写水印的方法示例
主要JavaScript方法:Canvas
文档地址:
绘制文本 - Web API | MDN在前一个章节中看过如何应用样式和颜色之后,我们现在来看一下如何在画布(canvas)中绘制文本。https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Drawing_text
说一下目前主流的两种实现方式:
1.使用for循环将文字依次填充到不同的坐标位置
html代码示例:
Canvas Text Water Mask Example drawWaterMask() function getDPR() { const dpr = devicePixelRatio || 1; return dpr; } function drawWaterMask() { const dpr = getDPR() const canvas = document.getElementById(\'myCanvas\'); const pageWidth = document.documentElement.clientWidth const pageHeight = document.documentElement.clientHeight const ctx = canvas.getContext(\'2d\'); // 提升水印清晰度,消除锯齿---start---- canvas.width = pageWidth * dpr; canvas.height = pageHeight * dpr; canvas.style.width = pageWidth * dpr + \'px\'; canvas.style.height = pageHeight * dpr + \'px\'; ctx.scale(dpr, dpr); // 缩放绘图上下文,提升水印清晰度 // 提升水印清晰度,消除锯齿---end---- const FOR_NUM = 10 const MAX_TEXT_Y = 200 const OPACITY_NUM = 0.5 // 水印文字透明度 ctx.rotate(45 * Math.PI / 180);//设置文字的旋转角度; const text = (\'张三 2025-07-29 00:00:00\'); // 在(x, y)位置写文字 //对斜对角线以左部分进行文字的填充(两个for循环的配合,使得文字充满斜对角线的左下部分) for (let j = 1; j < FOR_NUM; j++) { //用for循环达到重复输出文字的效果,这个for循环代表纵向循环 ctx.beginPath(); ctx.font = `bold 12px Arial`; ctx.fillStyle = `rgba(169,169,169,${OPACITY_NUM})`; ctx.fillText(text, 0, MAX_TEXT_Y / 2 * j); for (let i = 1; i < FOR_NUM; i++) {//这个for循环代表横向循环, ctx.beginPath(); ctx.font = `bold 12px Arial`; ctx.fillStyle = `rgba(169,169,169,${OPACITY_NUM})`; ctx.fillText(text, MAX_TEXT_Y * i, MAX_TEXT_Y / 2 * j); } } //对斜对角线以右部分进行文字的填充逻辑同上 for (let j = 0; j < FOR_NUM; j++) { ctx.beginPath(); ctx.font = `bold 12px Arial`; ctx.fillStyle = (`rgba(169,169,169,${OPACITY_NUM})`); ctx.fillText(text, 0, -MAX_TEXT_Y / 2 * j); for (let i = 1; i < FOR_NUM; i++) { ctx.beginPath(); ctx.font = `bold 12px Arial`; ctx.fillStyle = `rgba(169,169,169,${OPACITY_NUM})`; ctx.fillText(text, MAX_TEXT_Y * i, -MAX_TEXT_Y / 2 * j); } } }
小程序代码示例:
在wxml文件写下
具体方法如下:
drawWaterMask (text) { if(!text) { return } var ctx = wx.createCanvasContext(\"myCanvas1\"); ctx.rotate(45 * Math.PI / 180);//设置文字的旋转角度; const FONT_SIZE = 12 const FOR_NUM = 10 const MAX_TEXT_Y = 200 const OPACITY_NUM = 0.5 //对斜对角线以左部分进行文字的填充 for (let j = 1; j < FOR_NUM; j++) { ctx.beginPath(); ctx.setFontSize(FONT_SIZE); ctx.setFillStyle(`rgba(169,169,169,${OPACITY_NUM})`); ctx.fillText(text, 0, MAX_TEXT_Y/2 * j); for (let i = 1; i < FOR_NUM; i++) { ctx.beginPath(); ctx.setFontSize(FONT_SIZE); ctx.setFillStyle(`rgba(169,169,169,${OPACITY_NUM})`); ctx.fillText(text, MAX_TEXT_Y * i, MAX_TEXT_Y/2 * j); } } for (let j = 0; j < FOR_NUM; j++) { ctx.beginPath(); ctx.setFontSize(FONT_SIZE); ctx.setFillStyle(`rgba(169,169,169,${OPACITY_NUM})`); ctx.fillText(text, 0, -MAX_TEXT_Y/2 * j); for (let i = 1; i < FOR_NUM; i++) { ctx.beginPath(); ctx.setFontSize(FONT_SIZE); ctx.setFillStyle(`rgba(169,169,169,${OPACITY_NUM})`); ctx.fillText(text, MAX_TEXT_Y * i, -MAX_TEXT_Y/2 * j); } } ctx.draw(); }
然后在onLoad和onPullDownRefresh生命周期下使用
this.drawWaterMask(\'具体文案\')
注意:把按钮等的层级写高一点,以免被水印遮挡,点击不了
2.先填充一个文字,输出图片,作为页面的background,再利用background的repeat属性
html代码示例:
Canvas Text Water Mask Example const canvas = document.getElementById(\'myCanvas\'); const ctx = canvas.getContext(\'2d\'); const FONT_SIZE = 16 const MAX_TEXT_X = 10 const MAX_TEXT_Y = 10 const OPACITY_NUM = 0.5 ctx.rotate(45 * Math.PI / 180);//设置文字的旋转角度; const text = (\'张三 2025-07-29 00:00:00\'); ctx.fontSize = `${FONT_SIZE}px`; ctx.fillStyle = (`rgba(169,169,169,${OPACITY_NUM})`); // 在(X, Y)位置写文字 ctx.fillText(text, MAX_TEXT_X, MAX_TEXT_Y); // 当背景图片图片填充,巧用repeat属性就不用循环多次写水印文字了 const imageUrl = canvas.toDataURL(\'image/png\'); // 可以选择\'image/jpeg\'等其他格式 document.getElementById(\'outputImage\').style.background = `url(${imageUrl}) repeat`; document.getElementById(\'outputImage\').style.backgroundSize = \'40%\'; document.getElementById(\'outputImage\').style.backgroundPosition = \'left top\';