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

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

相关推荐
谢尔登15 小时前
defineProperty如何弥补数组响应式不足的缺陷
前端·javascript·vue.js
T***u33317 小时前
前端框架在性能优化中的实践
javascript·vue.js·前端框架
jingling55518 小时前
vue | 在 Vue 3 项目中集成高德地图(AMap)
前端·javascript·vue.js
芳草萋萋鹦鹉洲哦1 天前
【elemen/js】阻塞UI线程导致的开关卡顿如何优化
开发语言·javascript·ui
1***s6321 天前
Vue图像处理开发
javascript·vue.js·ecmascript
槁***耿1 天前
JavaScript在Node.js中的事件发射器
开发语言·javascript·node.js
一叶茶1 天前
移动端平板打开的三种模式。
前端·javascript
U***49831 天前
JavaScript在Node.js中的Strapi
开发语言·javascript·node.js
老前端的功夫1 天前
前端浏览器缓存深度解析:从网络请求到极致性能优化
前端·javascript·网络·缓存·性能优化
颜酱1 天前
Monorepo 架构以及工具选型、搭建
前端·javascript·node.js