PS系统页面水印解决方案

目的

实现PS系统页面水印的需求,提升系统的信息保密性。

实现原理

通过canvas绘制水印,将水印作为蒙层覆盖页面。

实现步骤

  1. 在Application Designer中创建HTML对象,将watermark.js中代码写入;

  2. 在PeopleTools/门户网站/品牌化/品牌化系统选项中,添加JavaScript对象,即上一步创建的HTML对象;

水印效果

img.png

watermark.js内容

/**
 * @description 水印
 * @author LeaFish <[email protected]>
 * @date 2019-03-13
 * @param {string} [id="watermark"] 水印元素ID
 * @param {number} [height=80] 单个水印块高度
 * @param {number} [width=150] 单个水印块宽度
 * @param {string} [text] 水印文本
 * @param {number} [fontSize=13] 文本字体大小
 * @param {string} [color="rgba(100,100,100,0.2)"] 文本颜色
 * @param {string} [displayMethod] 展现方式:background 背景图(采用repeat特性) canvas 画布(采用画布方式,建议isOnResize=true)
 * @param {boolean} [isOnResize=false] 是否监听浏览器窗口变化,重绘水印
 */
function Watermark(options) {
  options = options || {};
  this.id = options.id || "watermark";
  this.canvas = document.createElement("canvas");
  this.ctx = this.canvas.getContext("2d");
  this.height = options.height || 80;
  this.width = options.width || 150; // 控制水印的间隙大小
  this.text = options.text || "";
  this.fontSize = options.fontSize || 13;
  this.color = options.color || "rgba(100,100,100,0.2)";
  this.displayMethod = options.displayMethod || "background";
  this.isOnResize = options.isOnResize || false;

  // 获取设备像素比
  this.PIXEL_RATIO = (function () {
    var dpr = window.devicePixelRatio || 1;
    var bsr = this.ctx.webkitBackingStorePixelRatio ||
      this.ctx.mozBackingStorePixelRatio ||
      this.ctx.msBackingStorePixelRatio ||
      this.ctx.oBackingStorePixelRatio ||
      this.ctx.backingStorePixelRatio || 1;
    return dpr / bsr;
  }.bind(this))();

  /**
   * @description 初始化执行函数
   * @author LeaFish <[email protected]>
   * @date 2019-03-13
   */
  this.init = function () {
    this.draw();
    this.addToBody();

    this.isOnResize && (window.onresize = function () {
      this.draw();
      this.displayMethod === "canvas" || this.addToBody();
    }.bind(this));
  }

  /**
   * @description 绘制水印
   * @author LeaFish <[email protected]>
   * @date 2019-03-13
   */
  this.draw = function () {
    var canvasWidth = window.innerWidth;
    var canvasHeight = window.innerHeight * 2;

    // 适配高清屏,canvas内容的宽高是实际的宽高的PIXEL_RATIO倍
    this.canvas.width = canvasWidth * this.PIXEL_RATIO;
    this.canvas.height = canvasHeight * this.PIXEL_RATIO;
    this.canvas.style.width = canvasWidth + "px";
    this.canvas.style.height = canvasHeight + "px";
    // 缩放绘图
    this.ctx.setTransform(this.PIXEL_RATIO, 0, 0, this.PIXEL_RATIO, 0, 0);

    this.ctx.font = this.fontSize + "px 黑体";
    this.ctx.rotate(-20 * Math.PI / 180);
    this.ctx.fillStyle = this.color;

    // 绘制文字
    for (var y = 1; y < window.innerHeight * 2 / this.height + 1; y++) {
      for (var x = 1; x < window.innerWidth * 2 / this.width; x++) {
        this.ctx.fillText(this.text, (y % 2 ? 0 : this.width / 2) + x * this.width - window.innerWidth, y * this.height);
      }
    }
  };

  /**
   * @description 将水印添加到body上
   * @author LeaFish <[email protected]>
   * @date 2019-03-13
   */
  this.addToBody = function () {
    var element = null;

    if (this.displayMethod === "canvas") {
      element = this.canvas;
    } else {
      var base64 = this.canvas.toDataURL("image/png");
      element = document.createElement('div');
      element.style.backgroundSize = innerWidth + "px";
      element.style.backgroundImage = "url(" + base64 + ")";
      element.style.backgroundRepeat = "repeat";
    }

    element.id = this.id;
    element.style.position = "fixed";
    element.style.left = 0;
    element.style.right = 0;
    element.style.top = 0;
    element.style.bottom = 0;
    element.style.pointerEvents = "none"; // 蒙层事件穿透
    element.style.zIndex = 20000000;

    document.getElementById(this.id) && document.body.removeChild(document.getElementById(this.id));
    document.body.appendChild(element);
  }
}

/**
 * @description 处理多load事件回调函数覆盖问题
 * @author LeaFish <[email protected]>
 * @date 2019-03-13
 * @param {*} x
 */
function addOnloadEvent(x) {
  var oldOnLoad = window.onload;
  if (typeof oldOnLoad != "function") {
    window.onload = x;
  } else {
    window.onload = function () {
      oldOnLoad();
      x();
    }
  }
}

addOnloadEvent(function () {
  // 避免iframe间多层水印层叠
  document.getElementById("ptifrmtemplate") && setTimeout(function () {
    var options = {
      text: parent.document.getElementsByClassName("greeting")[0].innerText.split(":")[1], // 从欢迎语中获取要作为水印的文本内容
      isOnResize: false,
      displayMethod: "background"
    }
    new Watermark(options).init();
  }, 50);
})

watermark.js使用注意事项

  1. 代码中水印文本内容是从欢迎语中获取的,可根据自身需求修改水印文本的获取方式,例如请求数据接口获取;

  2. Watermark对象绘制水印可同时支持移动端和PC端;

开发者可理解实现思路,实现出更符合自身需求的水印排版。

你可能感兴趣的:(PS系统页面水印解决方案)