# Watermark 水印

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/watermark/freepass)
- 平台：PC
- 维护者：揭志胜
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Watermark]

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import React from 'react';
import { AnyObj, Button, Watermark } from "@weapp/ui";

import middleImg from '../images/middle.png';
import strongImg from '../images/strong.png';

const style = { marginRight: 10 };
export default class Demo extends React.Component {
  watermark: any = null;
  state = {
    defaultOptions: {
      text:
        '<p style="text-align: center;">泛微软件</p><p style="text-align: center;">2019-02-27</p>',
      fontStyle: "font-size:18px;color:#000;",
      src: "",
      rotate: -15,
      alpha: 0.15,
      interval: 2000,
      intervalCheck: true,
      clickCheck: true
    },
    newTextOptions: {
      text: "WEAVER",
      width: 3000,
      height: 3000,
      src: "",
    },
    imgOptions: {
      src: middleImg,
      width: 100,
      height: 80,
    },
    newImgOptions: {
      src: strongImg,
      width: 3000,
      height: 3000,
    },
  }

  handleWMShow = (options: AnyObj) => {
    this.watermark = this.watermark || new Watermark(options);
    this.watermark.updateOptions(options);
  }

  handleDefaultWM = () => this.handleWMShow(this.state.defaultOptions);

  handleTextWM = () => this.handleWMShow(this.state.newTextOptions);

  handleImgWM = () => this.handleWMShow(this.state.imgOptions);

  handleNewImgWM = () => this.handleWMShow(this.state.newImgOptions);

  handleWMDes = () => {
    if (this.watermark) {
      this.watermark.destory();
    }
  }

  render() {
    return (
      <div>
        <h3>基础使用</h3>
        <Button style={style} onClick={this.handleDefaultWM}>
          文字水印效果一
        </Button>
        <Button style={style} onClick={this.handleTextWM}>
          文字水印效果二
        </Button>
        <Button style={style} onClick={this.handleImgWM}>
          图片水印效果一
        </Button>
        <Button style={style} onClick={this.handleNewImgWM}>
          图片水印效果二
        </Button>
        <Button style={style} onClick={this.handleWMDes}>
          清除水印
        </Button>
      </div>
    );
  }
}
```

### 全局水印

```jsx
import React from 'react';
import { Button, watermarkSDK } from "@weapp/ui";

const style = { marginRight: 10 };
export default class Demo extends React.Component {
  state = {
    dialogVisible: false,
    defaultOptions: {
      text:
        '<p style="text-align: center;">全局水印</p><p style="text-align: center;">2019-02-27</p>',
      fontStyle: "font-size:18px;color:#000;",
      src: "",
      rotate: -15,
      alpha: 0.15,
      interval: 2000,
      intervalCheck: true,
      clickCheck: true
    },
  }

  handleWMShow = () => {
    watermarkSDK.set({
      ...this.state.defaultOptions,
    });
  }

  handleWMDes = () => {
    watermarkSDK.clear();
  }

  handleSystemWMShow = () => {
    // 获取全局水印配置
    const globalWMOption = watermarkSDK.getGlobalWMOption();
    if (globalWMOption) {
      watermarkSDK.set(globalWMOption);
    }
  }

  render() {
    return (
      <div>
        <h4>全局水印</h4>
        <Button style={style} onClick={this.handleWMShow}>
          开启全局水印
        </Button>
        <h4>系统水印</h4>
        <Button style={style} onClick={this.handleSystemWMShow}>
          开启系统水印
        </Button>
        <h4>清除全局水印</h4>
        <Button style={style} onClick={this.handleWMDes}>
          清除全局水印
        </Button>
      </div>
    );
  }
}
```

### 局部水印

```jsx
import React, { createRef } from 'react';
import { Button, watermarkSDK, Watermark, Dialog } from "@weapp/ui";

const style = { marginRight: 10 };
export default class Demo extends React.Component {
  divRef = createRef<HTMLDivElement>();
  divWatermark: Watermark | undefined;
  dialogRef = createRef<HTMLDivElement>();
  dialogWatermark: Watermark | undefined;
  state = {
    dialogVisible: false,
    defaultOptions: {
      text:
        '<p style="text-align: center;">局部水印</p><p style="text-align: center;">2019-02-27</p>',
      fontStyle: "font-size:18px;color:#000;",
      src: "",
      rotate: -15,
      alpha: 0.15,
      interval: 2000,
      intervalCheck: true,
      clickCheck: true
    },
  }

  handleWMShow = () => {
    if (this.divRef.current && !this.divWatermark) {
      this.divWatermark = watermarkSDK.set({
        ...this.state.defaultOptions,
        container: this.divRef.current
      });
    }
  }

  handleWMDes = () => {
    this.divWatermark?.destory();
    this.divWatermark = undefined;
  }

  handleDialogWMShow = () => {
    if (this.dialogRef.current && !this.dialogWatermark) {
      this.dialogWatermark = watermarkSDK.set({
        ...this.state.defaultOptions,
        container: this.dialogRef.current
      });
    }
  }

  handleDialogWMDes = () => {
    watermarkSDK.reset();
    this.dialogWatermark?.destory();
    this.dialogWatermark = undefined;
  }

  handleDialogOpen = () => {
    this.setState({ dialogVisible: true });
  }

  handleDialogClose = () => {
    this.setState({ dialogVisible: false });
    this.handleDialogWMDes();
  }

  render() {
    const { dialogVisible } = this.state;
    return (
      <div>
        <div style={{ height: 400, textAlign: 'center', backgroundColor: '#f6f6f6' }} ref={this.divRef}>
          <p style={{ lineHeight: '300px' }}>局部水印</p>
          <Button style={style} onClick={this.handleWMShow}>
            开启水印
          </Button>
          <Button style={style} onClick={this.handleWMDes}>
            清除水印
          </Button>
        </div>
        <h3>Dialog 中显示水印</h3>
        <Button style={style} onClick={this.handleDialogOpen}>
          打开 Dialog
        </Button>
        <Dialog
          title="基本用法"
          visible={dialogVisible}
          closable
          destroyOnClose
          scale
          mask
          width={800}
          height={600}
          bodyStyle={{ width: '100%', height: '100%', padding: 0 }}
          maskClosable
          onClose={this.handleDialogClose}
        >
          <div style={{ width: '100%', height: '100%', padding: 8 }} ref={this.dialogRef}>
            <Button style={style} onClick={this.handleDialogWMShow}>
              开启 Dialog 水印
            </Button>
            <Button style={style} onClick={this.handleDialogWMDes}>
              清除 Dialog 水印
            </Button>
          </div>
        </Dialog>
      </div>
    );
  }
}
```

## Watermark 水印 WatermarkOptions 配置说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| alpha | 透明度，0 - 1 | number | 否 | 0.15 |
| container | 局部水印的父容器 | Element | 否 | - |
| fontStyle | 文本水印字体样式 | string | 否 | 'font-size:14px;color:#000;' |
| height | 水印高度，最小值 100 | number | 否 | 150 |
| rotate | 旋转角度，逆时针为负数 | number | 否 | -15 |
| src | 图片水印地址，必须要能够直接访问的图片地址 | string | 否 | - |
| text | 文本水印内容，支持富文本格式数据 | string | 否 | - |
| width | 水印宽度，最小值 100 | number | 否 | 200 |
| zIndex | 设置水印显示层级 | number | 否 | 9999 |
## watermarkSDK API 说明

### 1. set 设置水印

```ts
// 用法
watermarkSDK.set(options: WatermarkOptions)

// 返回值：创建的水印实例
```

#### 局部水印

在 option 中指定 container ，传入水印需要插入的容器 dom 对象

```ts
watermarkSDK.set({
  // 水印配置...
  container: dom,
})
```

**注：设置局部水印时，全局水印的显示层级会低于弹框的显示层级，也就是说弹框会显示在全局水印的上面**

### 2. getGlobalWMOption 获取系统默认水印

```ts
// 获取系统默认水印
const globalWMOption = watermarkSDK.getGlobalWMOption()

// 设置系统水印
if (globalWMOption) {
  // 系统默认水印可能不存在
  watermarkSDK.set(globalWMOption)
}
```

### 3. formatWMSetting 格式化系统水印配置信息

将系统水印配置转换为标准水印需要的数据格式

```ts
// 获取系统默认水印
const globalWMOption = watermarkSDK.getGlobalWMOption()

// 转换系统水印配置
const wmOptions = watermarkSDK.formatWMSetting(globalWMOption)

// 其中文本中特殊标识支持自定义扩展
const wmOptions = watermarkSDK.formatWMSetting(WMSetting, {
  $WORKFLOW_FIELDID: 'fieldid_123',
})
```

系统水印配置数据格式和系统水印组件配置数据格式说明

```ts
// 系统水印配置
type SystemWMSetting = {
  /* 文字水印宽度 */
  wmWidth: string
  /* 文字水印高度 */
  wmHeight: string
  /* 文字水印内容 */
  wmText: string
  /* 图片水印数据 */
  wmImg: string
  /* 水印不透明 */
  wmNoTransparent: string
  /* 水印逆时针旋转角度 */
  wmRotate: string
}

// 转换后的格式
type WatermarkOptions = {
  /* 文本水印内容 */
  text?: string
  /* 图片水印地址 */
  src?: string
  /* 水印宽 */
  width?: number
  /* 水印高 */
  height?: number
  /* 旋转角度，逆时针为负数 */
  rotate?: number
  /* 透明度, 0-1 */
  alpha?: number
}
```

### 4. reset 重置全局水印

```ts
// 用法
watermarkSDK.reset()
```

**注：主要是用于弹框关闭时重置全局水印的显示层级**

### 5. hasGlobalWM 是否存在全局水印

**注：hasGlobalWM 方法获取的是当前是否存在全局水印，但是不一定是通用系统水印，也有可能是业务设置的全局水印**

```ts
// 用法
watermarkSDK.hasGlobalWM()

// 返回值：当前是否存在全局水印
```

### 6. hasGlobalWMInIframe ifram嵌套场景下判断上层是否存在全局水印

**注：如果iframe页面存在跨域访问问题，那么这里是无法访问上层页面的也就无法判断出来**

```ts
watermarkSDK.hasGlobalWMInIframe()
```

### 7. clear 清除全局水印

```ts
// 用法
watermarkSDK.clear()
```

### 8. initSystemWM 初始化加载系统水印

**注：如果没有开启系统水印，则会销毁全局水印**

```ts
// 用法
watermarkSDK.initSystemWM();
```

### 9. isSystemWMOpen 是否系统水印开启

```ts
// 用法
watermarkSDK.isSystemWMOpen()

// 返回值：当前是否开启了系统通用水印
```

### 10. getGlobalSetting 获取通用水印的配置

**注：这里获取到的是原始的配置信息，包含了开关之类的，但是没有对格式进行处理，所以禁止将结果传给 set 方法**

```ts
// 用法
watermarkSDK.getGlobalSetting()

// 返回值：系统通用水印配置信息
```
