美文网首页
【REACT】 水印生成方案

【REACT】 水印生成方案

作者: 菜菜菜菜_97 | 来源:发表于2018-07-28 17:03 被阅读0次

今天学习了一下水印的生成方案
转自:https://juejin.im/entry/5b55db355188251b11097366

主要学习的是通过canvas生成水印,加上MutationObserve监视DOM的变动

修改了一些代码如下:

import React from 'react'
const watermark = ({
    container = document.body,    //容器
    width = '300px',  //水印的大小
    height = '200px',
    textAlign = 'center',  //文字对齐
    textBaseline = 'middle',  //基准线
    font = "20px Microsoft Yahei", //字体大小及样式
    fillStyle = 'rgba(184, 184, 184, 0.4)',//自定义水印的颜色以及透明度
    content = 'Open Components',//内容
    rotate = '24',//文字旋转角度
    zIndex = 1000,//元素堆叠顺序,-1是在最下面
} = {}) => {
    const args = arguments[0];
    const canvas = document.createElement('canvas');
//HTML5 <canvas> 元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成

    canvas.setAttribute('width', width);
    canvas.setAttribute('height', height);
    const ctx = canvas.getContext("2d");//当前唯一的合法值是 "2d",它指定了二维绘图

    ctx.textAlign = textAlign;
    ctx.textBaseline = textBaseline;
    ctx.font = font;
    ctx.fillStyle = fillStyle;
    ctx.rotate(Math.PI / 180 * rotate);
    ctx.fillText(content, parseFloat(width) / 2, parseFloat(height) / 2);

    const base64Url = canvas.toDataURL();
//返回一个包含图片展示的 data URI 。可以使用 type 参数其类型,默认为 PNG 格式。
    const __wm = document.querySelector('.__wm');//选择器

    const watermarkDiv = __wm || document.createElement("div");
    const styleStr = `
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    z-index:${zIndex};
    pointer-events:none;
    background-repeat:repeat;
    background-image:url('${base64Url}')`;

    watermarkDiv.setAttribute('style', styleStr);
    watermarkDiv.classList.add('__wm');//在元素中添加类名,可以加载CSS样式

    if (!__wm) {
        container.style.position = 'relative';
        container.insertBefore(watermarkDiv, container.firstChild);//添加元素
    }

    const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;        
//检查浏览器是否支持这个API
    if (MutationObserver) {
        let mo = new MutationObserver(function () {
            const __wm = document.querySelector('.__wm');
            // 只在__wm元素变动才重新调用 __canvasWM
            if ((__wm && __wm.getAttribute('style') !== styleStr) || !__wm) {
                // 避免一直触发
                mo.disconnect();
                mo = null;
                watermark(JSON.parse(JSON.stringify(args)));
            }
        });

        mo.observe(container, {
            attributes: true,//观察目标节点的属性节点
            subtree: true,//观察目标节点的所有后代节点
            childList: true,//观察目标节点的子节点
        })
    }

}

export default watermark;

这样我们就可以在界面里面引用生成水印的方法啦!
但是,在引用时我发现,引用这一方法只能在生命周期中写,如果我用的是stateless写法,在使用getElementById等获取dom对象的方法时无效,获取的是NULL。这是因为我们的方法应当在react加载完所有dom后再使用。所以要写进生命周期中

 import watermark from ‘ ’

componentDidMount() {
            watermark({ content: 'Open Components' ,
                       container: document.getElementById('waterbody')
    });
}

如果有其他想覆盖的属性只要在方法里面覆盖就好啦!

接下来试了一下给图片加水印

export const picWaterMark = ({
    url = '',
    textAlign = 'center',
    textBaseline = 'middle',
    font = "20px Microsoft Yahei",
    fillStyle = 'rgba(255, 255, 255, 0.8)',
    content = '请勿外传',
    cb = null,
    textX = 500,
    textY = 500,
} = {}) => {
    const img = new Image();
    img.src = url;
    img.crossOrigin = 'anonymous';
    img.onload = function () {
        const canvas = document.createElement('canvas');
        canvas.width = img.width;
        canvas.height = img.height;
        const ctx = canvas.getContext('2d');

        ctx.drawImage(img, 0, 0);
        ctx.textAlign = textAlign;
        ctx.textBaseline = textBaseline;
        ctx.font = font;
        ctx.fillStyle = fillStyle;
        ctx.fillText(content, img.width - textX, img.height - textY);


        const base64Url = canvas.toDataURL();
        cb && cb(base64Url);
    }
}

接下来在要添加水印的图片里这么写:

import React from 'react'
import { picWaterMark } from '../../utils/shuiyin'

class MyImage extends React.Component {
  componentDidMount() {
    picWaterMark({
      url: document.getElementById('myimage').src,
      content: 'QQMusicFE',
      cb: (base64Url) => {
        document.querySelector('img').src = base64Url
      },
      
    });
    //console.log( document.getElementById('myimage').src)
  }
  render() {
    
    return (
      <div>
        <img id={"myimage"} src={require("../../../assets/85456383705460.jpg")} style={{ width: 1200, height: 800 }} />
      </div>
    );
  }
}
export default MyImage

一开始遇到了困难是调用方法中的URL是不对的,但我明明写的是../../../assets/85456383705460.jpg,
最后console了一下发现URL已经变成
http://localhost:8000/static/85456383705460.846d9ef5.jpg
于是换了方法,改成
url: document.getElementById('myimage').src,

显示出来啦,不过不细看是真的看不出在哪


image.png

【完】
如果有不对的地方希望大家能帮我指出三克斯

相关文章

  • 【REACT】 水印生成方案

    今天学习了一下水印的生成方案转自:https://juejin.im/entry/5b55db355188251b...

  • 常见问题03:php实现海报生成(包含多行文本与水印)

    源码地址:实现海报生成(包含多行文本与水印) 场景 生成一张海报,海报内容可以渲染多行文本与水印。 解决方案 1)...

  • 前端生成水印方案

    前段时间做某系统审核后台,出现了审核人员截图把内容外泄露的情况,虽然截图内容不是特别敏感,但是安全问题还是不能忽视...

  • 前端水印生成方案

    先看下效果: 思路1: 使用canvas进行生成图片,然后动态生成div填充整个背景,将生成的图片用与 backg...

  • 前端生成pdf水印解决方案

    最近有需求需要做一个小工具:生成pdf水印的网页工具。一开始是想前端传递文件、水印文案给后端,然后由服务器生成,然...

  • React 加载PDF、加水印

    插件 加载PDFreact-pdf网页水印插件water-mark-oc加载pdf及水印react-pdf-wat...

  • 水印(文字、图片)

    笼统的概括一下添加水印的步骤 1.生成画布2.在画布中绘制文字水印或者图片水印3.生成新的图片 萌萌,站起来~~~~~~

  • php 生成水印图片左下角(替换掉原图片)

    生成水印图片 content水印多行需要换行的文字(必须靠边写换行) 另外水印位置 函数内部可修改 【图片地址】 ...

  • 自己写个小工具——图片水印生成器

    自己写个小工具——图片水印生成器 自己写个小工具——图片水印生成器介绍安装使用说明其他TODO LIST 介绍 做...

  • ios绘图实列

    1> 水印PPT简介 * 图片水印作用:防止他人盗取图片,加一些Logo,生成一张新的图片。 * 怎么生成新的图片...

网友评论

      本文标题:【REACT】 水印生成方案

      本文链接:https://www.haomeiwen.com/subject/yzeomftx.html