基于Canvas动态生成页面水印

基于Canvas生成全局页面水印

在传统开发过程中难免有动态给页面渲染水印的需求,本文将提供一个基于Canvas的水印解决方案。

效果

  • 实现网页全屏覆盖
  • 可动态调整水印文案
  • 水印图层不影响正常内容
    在这里插入图片描述

原理&完整代码

  • 基于Canvas动态绘制水印图形
  • 将Canvas转换为Base64信息
  • 通过background平铺、渲染Base64
  • 通过绝对定位和z-index将水印层置顶
  • 通过设置pointer-events = none取消水印图层的相应事件
  • 核心Base64方法可以在多个场景中使用
import React from 'react';

// 水印组件
function WaterMark() {
  const createWaterMark = function (markConfig) {
    // 水印样式配置
    const {
      text = 'catiihuang',
      height = 150,
      width = 150,
      fontSize = 12,
      color = '#ddd',
    } = markConfig || {};
    // canvas实例
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    // 设置宽高
    canvas.setAttribute('width', width);
    canvas.setAttribute('height', height);
    // 旋转
    ctx.translate(width / 2, height / 2);
    // 按宽高比旋转角度
    ctx.rotate((-45 * Math.PI * (height / width)) / 180);
    ctx.translate(-width / 2, -height / 2);
    // 字体样式
    ctx.font = `${fontSize}px 微软雅黑`;
    ctx.fillStyle = color;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    // 绘制文字 从中心
    ctx.fillText(text, width / 2, height / 2);
    // 转换为base64
    return canvas.toDataURL('image/png');
  };

  return (
    // 水印容器
    <div
      className="water-mask-wrap"
      style={{
        backgroundImage: `url(${createWaterMark({
          text: 'catiihuang',
          height: 120,
          width: 200,
          fontSize: 16,
          color: '#cecece',
        })})`,
        backgroundRepeat: 'repeat',
        pointerEvents: 'none',
        position: 'fixed',
        opacity: 1,
        left: 0,
        top: 0,
        height: '100vh',
        width: '100vw',
        zIndex: 16777271,
      }}
    ></div>
  );
}

// 容器组件
export default function Index() {
  return (
    // 页面容器
    <div className="page-wrap">
      {/* 渲染水印 */}
      <WaterMark />
      {/* 页面内容 */}
      <div
        className="page-cont-wrap"
        style={{
          display: 'flex',
          justifyContent: 'center',
          alignItems: 'center',
          height: '100vh',
          width: '100vw',
        }}
      >
        <h1 onClick={() => console.log('title clicked!')}>
          this is content wrap!!
        </h1>
      </div>
    </div>
  );
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值