Basic introduction 📝

  • Passed a while backFront-end Watermarking Generation Scheme (Webpage Watermarking + Image Watermarking)This article has studied the watermarking generation scheme, which is usedCanvasRealizing the scheme of web watermarking is very interested in, so the relevant code is modified to achieve aReactWatermark component and publish to 👉npm.
  • The component is passedCanvasGenerate a watermark and use itMutationObserve(interface that listens for DOM structure changes) monitoringDOMThe watermark cannot be deleted and the properties cannot be modified.
  • The react component has been published in NPM to publish a react component (stomp pit practice). This article will not elaborate on this. This article will focus on the use effect and implementation of the component.

Effect demonstration 🤩

  • This component has been published on NPM and can be installed using the following command:
npm install --save watermark-component-for-react
Copy the code
  • Used in the project:
import React from 'react';
import WaterMark from 'watermark-component-for-react';
import * as styles from './index.css';

class ReactDemo extends React.Component{
  render() {const content = 'internal document, do not pass out by- front small black';return( <WaterMark content={content}> <div className={styles.wrapper}>hello world</div> </WaterMark> ); }}export default ReactDemo;
Copy the code
  • Results:
  • ⚠️ Note: Components that need watermarking need to be wrapped inWaterMarkComponent, that is, asWaterMarkChild component of.

The component characteristics

  1. Using MutationObserve to monitor DOM changes, the watermark cannot be deleted and properties cannot be modified:

  2. Rich props enables the watermark component to implement customization requirements:

Members of the instructions type The default value
style Inline style of the outermost component of watermark undefined | object undefined
container The container HTMLDivElement document.body
width Canvas element width string 300
height Canvas element high string 200
textAlign Draws the alignment of the text string left
textBaseline Text reference line string bottom
font Font size and style string 16px Microsoft Yahei
fillStyle Custom watermark color string black
content Watermark content string Internal documents, do not pass out
globalAlpha Sets the values for the transparency of graphics and images number 0.1
rotate Text rotation Angle number 16
zIndex Element stack order number 1000

Concrete implementation 🧐

  • The source code of the watermark component is as follows:
import * as React from 'react';
import { watermark } from '.. /.. /utils/lib'

export default class WaterMark extends React.Component {
  constructor(props) {
    super(props);

    this.container = null;
  }

  componentDidMount() { const { style, ... options } = this.props; watermark({ container: this.container, ... options, }); }render () {
    const style = {
      position: 'relative'. this.props.style, };return (
      <div ref={(el) => this.container = el} id="watermark"style={style}> {this.props.children} </div> ); }}Copy the code
  • The core code iswatermarkThis method, the specific code is as follows:
export functionWatermark (options) {const {container = document.body, // container width ='300'// Canvas element width height ='200'// Canvas element height textAlign ='left', // Text alignment textBaseline ='bottom'// font-size: 14px'16px Microsoft Yahei'// Font size and style fillStyle ='# 000'// Customize the watermark color content ='Internal document, do not pass out'Rotate = 0, rotate = 0, rotate = 0, rotate = 0, rotate = 0, rotate = 0, rotate = 0;let canvas = document.createElement('canvas');
  canvas.setAttribute('width', width);
  canvas.setAttribute('height', height);
  let ctx = canvas.getContext('2d'); // Get canvas2D context ctx.globalAlpha = globalAlpha; ctx.textAlign = textAlign; ctx.textBaseline = textBaseline; ctx.font = font; ctx.fillStyle = fillStyle; ctx.rotate((Math.PI * rotate) / 180); ctx.fillText(content, 50, 50); const base64Url = canvas.toDataURL(); // Return a data URI containing the image display const __wm = document.querySelector('.__wm'); / / selector const watermarkDiv = __wm | | document. The createElement method ("div");
  const styleStr = `
    position:absolute;
    top:0px;
    left:0px;
    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'); // Add the "__wm" class name to the element container.style.position ='relative';
  if(! __wm) { container.appendChild(watermarkDiv); / / add elements} const MutationObserver = window. MutationObserver | | window. WebKitMutationObserver; // Check if the browser supports the APIif (MutationObserver) {
    const args = arguments[0];
    let mo = new MutationObserver(function () {
      const __wm = document.querySelector('.__wm'); // recalled only when the __wm element changesif ((__wm && __wm.getAttribute('style')! == styleStr) || ! __wm || container.style.position ! = ='relative') {// Avoid triggering Mo.disconnect () all the time; mo = null; watermark(args); }}); mo.observe(container, { attributes:true// Observe the attribute of the target node subtree:true// Observe all descendants of the target node childList:true, // Observe the children of the target node})}};Copy the code
  • For ease of understanding, comments have been added to the above file, which can be seen by usingMutationObserve, when the watermark component is deleted, the property is modified, or the watermark component’s container location propertypositionDon’t forrelativeIs called againwatermarkMethods.

Conclusion 👀

  • In order to prevent the company’s internal documents from being leaked by screenshots, it is necessary to add watermarks on the system pages.
  • To prevent some users from deleting the watermark, the watermark component needs to listen (throughMutationObserveDynamically insert a new watermark when the component is deleted.
  • The watermark- component-for-React component has been posted to NPM.

If there are any omissions in the above content, please leave a message ✍️ to point out, and progress together 💪💪💪

If you find this article helpful, 🏀🏀 leave your precious 👍

The resources

  1. Front-end Watermarking Generation Scheme (Webpage Watermarking + Image Watermarking)
  2. Canvas API MDN document
  3. MutationObserver MDN document
  4. Publish a React component using NPM