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()

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

相关推荐
i1yo_kiki20 分钟前
Ajax快速入门教程
前端·javascript·ajax
霖001 小时前
同步/异步电路;同步/异步复位
开发语言·前端·javascript·嵌入式硬件·fpga开发·信号处理
三三十二1 小时前
Labview基础使用教程
服务器·前端·javascript
lyj1689972 小时前
vite搭建vue3项目及相关配置
开发语言·javascript·ecmascript
黑匣子~2 小时前
使用 electron-builder 打包与发布 Electron 应用
前端·javascript·electron
o0向阳而生0o2 小时前
50、js 中var { ipcRenderer } = require(‘electron‘);是什么意思?
开发语言·javascript·electron
前端小巷子3 小时前
JavaScript 垃圾回收与内存泄漏
开发语言·前端·javascript·面试
啊啊啊~~3 小时前
js拖拽事件实现简单选课功能
javascript·css·css3
老天文学家了4 小时前
HashMap的基础用法(java)
java·前端·javascript
xiangzhihong84 小时前
Node.js 24发布:性能与安全双提升
开发语言·javascript