canvas水印生成

canvas水印生成

在大多数内部项目中,水印是一个常见需求。过去,当新项目需要添加水印时,通常是从旧项目中复制水印代码。这种做法不仅带来了大量重复工作,还导致了可维护性差的问题。另外,当前的方法在手动调整水印位置时,常常无法根据内容自动对齐。

本文旨在根据产品侧的规范设计方法,解决现有方法中的问题:

  • 统一格式,遵循需求文档
  • 自动居中对齐
  • 参数可配置,例如间距、旋转角度、透明度

以下是改进后的水印代码:

typescript 复制代码
import dayjs from 'dayjs'

class WatermarkManager {
  private watermarkId = 'custom-watermark-canvas'

  // 创建水印
  private createWatermark(username: string, angle: number, xGap: number, yGap: number): void {
    // 创建 canvas 元素
    const canvas = document.createElement('canvas')
    canvas.id = this.watermarkId
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    canvas.style.position = 'fixed'
    canvas.style.top = '0'
    canvas.style.left = '0'
    canvas.style.zIndex = '1000'
    canvas.style.pointerEvents = 'none'
    canvas.style.opacity = '0.5'

    const ctx = canvas.getContext('2d')
    if (ctx) {
      ctx.clearRect(0, 0, canvas.width, canvas.height)

      ctx.font = '18px Arial'
      const firstContent = `xxxxx平台 ${username} ${dayjs().format('YYYY/MM/DD')}`
      const secondContent = '未经允许,不得外泄'
      const textWidth = ctx.measureText(firstContent).width
      const textHeight = 18

      ctx.font = '16px Arial'
      const subTextWidth = ctx.measureText(secondContent).width
      const subTextHeight = 16

      const totalHeight = textHeight + subTextHeight + 10 // 两行文字的总高度
      const maxWidth = Math.max(textWidth, subTextWidth) // 两行文字的最大宽度

      for (let x = 0; x < canvas.width; x += xGap) {
        for (let y = 0; y < canvas.height; y += yGap) {
          ctx.save()
          ctx.translate(x + maxWidth / 2, y + totalHeight / 2)
          ctx.rotate(angle * Math.PI / 180)

          // 绘制第一行文字
          ctx.font = '18px Arial'
          ctx.fillStyle = 'rgba(0, 0, 0, 0.15)'
          ctx.fillText(firstContent, -textWidth / 2, 0)

          // 绘制第二行文字
          ctx.font = '16px Arial'
          ctx.fillStyle = 'rgba(0, 0, 0, 0.15)'
          ctx.fillText(secondContent, -subTextWidth / 2, textHeight + 10)

          ctx.restore()
        }
      }
    }

    // 添加 canvas 到页面
    document.body.appendChild(canvas)
  }

  // 移除水印
  private removeWatermark(): void {
    const canvas = document.getElementById(this.watermarkId)
    if (canvas)
      canvas.remove()
  }

  // 设置水印
  public setWatermark(username: string, angle: number = -30, xGap: number = 200, yGap: number = 100): void {
    this.removeWatermark()
    this.createWatermark(username, angle, xGap, yGap)
  }

  // 清理水印
  public clearWatermark(): void {
    this.removeWatermark()
  }
}

const watermarkManager = new WatermarkManager()

export default watermarkManager

使用示例

js 复制代码
const watermarkManager = new WatermarkManager()

// 设置水印
watermarkManager.setWatermark('用户名', -30, 280, 280)

// 清空水印
watermarkManager.clearWatermark()

通过以上改进,实现水印的统一格式,自动对齐以及参数配置,避免了重复工作并提升了代码的可维护性。

相关推荐
OEC小胖胖1 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水2 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
老虎06272 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台2 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
烛阴2 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
CN-Dust3 小时前
[FMZ][JS]第一个回测程序--让时间轴跑起来
javascript
全宝4 小时前
🎨前端实现文字渐变的三种方式
前端·javascript·css
yanlele5 小时前
前端面试第 75 期 - 2025.07.06 更新前端面试问题总结(12道题)
前端·javascript·面试
妮妮喔妮5 小时前
【无标题】
开发语言·前端·javascript
fie88895 小时前
浅谈几种js设计模式
开发语言·javascript·设计模式