如何通过canvas 生成水印

259 阅读2分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:[2022首次更文挑战]

前言

水印,一般作用于标记知识产权,防止侵权的目的,作为这种烂大街的需求,似乎已经成了一个小前端的必会的技巧~

实现方式
  1. 默认使用公司logo 作为整个body的大背景,通过position形式(灵活性较弱)
  2. 通过canvas 动态的生成水印内容,在通过background-image添加指定dom
如何实现

(一)忽略第一种实现方式,略略略~ 😛

(二)首先了解canvas生成水印需要用到的Api

canvas.getContext('2d')画笔,返回画布可使用的方法和属性

常见属性和方法

canvas.fillText(content,x,y) 写入文本内容

canvas.rotate 画布旋转角度

canvas.save 保存当前操作

canvas.toDataUrl(type,encoderOptions)返回一个包含图片内容的data url

知道了上述的几个方法,我们就可以实现基础版本的动态内容水印了

开始实现

老办法,还是通过Class来实现,方便后期进行封装

/**
 * 初始化 options
 * @params {Object} options
 * options = {el: string; width: number; height: number}
 * */
class WaterMask {
    constructor(options = {}) {
        this.el = (options.el && document.querySelector(options.el)) ? options.el : 'body';
        this.width = options.width || 250;
        this.height = options.height || 100;

        // canvas
        this.ctx = null;
        this.initWaterMask();
    }

    // 初始化canvas 画布 设置基本信息
    initWaterMask() {
        this.ctx = document.createElement('canvas');
        this.ctx.width = this.width;
        this.ctx.height = this.height;
        this.ctx.style.display = 'none';
    }

    /**
     * 生成水印图片 添加到指定dom
     * @params {Object} options
     * { rotate: number; color: string; fonSize: number; content: string }
     * */
    createWaterMask(options = {}) {
        const { rotate = 0, color = 'rgba(17, 17, 17, 0.2)', fontSize = 12, content = 'water mask' } = options;
        // 创建画笔
        const cans = this.ctx.getContext('2d');
        // 设置水印内容旋转角度
        cans.rotate((rotate * Math.PI) / 180);

        // 设置字体和大小
        cans.font = `${ fontSize }px Microsoft YaHei`;
        // 画笔颜色
        cans.fillStyle = color;
        // 文本内容对其方式(基准值)
        cans.textAlign = 'left';
        // 数值方向对其(基准值)
        cans.textBaseline = 'Middle';
        cans.zIndex = '9999';
        // 写入内容
        cans.fillText(content, 0, 50);
        cans.save();

        // 生成图片data url对象
        const imgSrc = this.ctx.toDataURL();
        const style = document.createElement('style');

        // 写入style内容到(body 或 指定dom)
        style.innerHTML = `${ this.el }:before{
            content: "";
            width: 100%;
            height: 100%;
            display: block;
            position: absolute;
            z-index: 9999;
            pointer-events: none;
            background-image: url("${ imgSrc }");
        }`
        ;(document.head.append || document.head.appendChild).apply(document.head, [
            style
        ]);
    }
}
如何使用
// 生成到body元素
const waterMask = new WaterMask();
waterMask.createWaterMask({ rotate: -20, content: 'hello world!!', fontSize: 14 });

// 生成到 .water-master 元素
waterMask.createWaterMask({ rotate: -20, el: '.water-master', content: 'hello world!!', fontSize: 14 });
效果展示

image.png

ok!到此结束啦~