npm package: @retailwe/ui-canvas-poster
Description: canvas-poster是一个生成二维码海报的组件，通过非常简单的配置就可以生成精美的海报
Latest version: 0.0.4

# canvas-poster 海报分享组件

canvas-poster是一个生成二维码海报的组件，通过非常简单的配置就可以生成精美的海报

<img src="https://cdn.qs.qq.com/mp/example/poster-temp2.png" alt="海报预览图" width="300" />

## 1 引入

全局引入，在miniprogram根目录下的`app.json`中配置，局部引入，在需要引入的页面或组件的`index.json`中配置。

```json
// app.json 或 index.json
"usingComponents": {
  "wr-canvas-poster": "@retailwe/ui-canvas-poster/index"
}
```

## 2 代码演示

### 2.1 基础用法

```html
  <wr-canvas-poster id="wr-canvas-poster" width="750" height="800"></wr-canvas-poster>
```

```js
import { DEFAULT_CONFIG } from './type';

Page({
  posterContext: null,

  handleGeneratePoster() {
    (this.getPosterContext() as any).showPoster(DEFAULT_CONFIG).then(res => {
      console.log('生成海报返回的临时路径', res);
    });
  },

  // 获取canvas-poster组件实例
  getPosterContext() {
    if (!this.posterContext) {
      (this.posterContext as any) = this.selectComponent('#wr-canvas-poster');
    }
    return this.posterContext;
  },
});
```

## 3 API说明

### 3.1 Props

| 参数 | 说明 | 类型 | 默认值 | 版本 |
|-----------|-----------|-----------|-------------|-------------|
| id | 用于父组件获取本组件实例，获取实例调用方法详见3.2 | *String* | - | - |
| width | 海报的宽度，单位`rpx` | *Number* | 750 | - |
| height | 海报的高度，单位`rpx` | *Number* | 1000 | - |
| quality | canvas海报生成的图片的质量，目前仅对 jpg 有效。取值范围为 (0, 1]，不在范围内时当作 1.0 处理 | *Number* | 1 | - |
| fileType | canvas海报生成的图片的类型 | *String* | 'jpg' | - |

### 3.2 实例可调用方法

| API | 说明 | 参数 | 参数默认值 | 返回值 |
|-----------|-----------|-----------| -----------| -----------|
| showPoster | 显示canvas画布，生成海报，返回生成图片的临时路径 | *ViewItem[]* | - | *Promise* |
| hidePoster | 隐藏canvas画布 | - | - | - |

`showPoster`用法如下，其中，`DEFAULT_CONFIG`是类型为`ViewItem[]`的海报配置信息，3.3将重点讲解。该函数返回`promise`回调，可以通过`then`方法获取canvas海报生成的图片的临时路径，用于保存到本地。

```js
    (this.getPosterContext() as any).showPoster(DEFAULT_CONFIG).then(res => {
      console.log('生成海报返回的临时路径', res);
    });
```

### 3.3 海报配置信息

海报配置信息的格式为`ViewItem[]`，其中，`ViewItem`的定义如下：

```js
type ViewItem =
  | {
      type: EnumViewType.LINE;
      start: Point;
      end: Point;
      css: LineStyle;
    }
  | {
      type: EnumViewType.VIEW;
      css: ViewStyle;
    }
  | {
      type: EnumViewType.IMAGE;
      url: string;
      css: ImageStyle;
    }
  | {
      type: EnumViewType.TEXT;
      text: string;
      css: TextStyle;
    }
  | {
      type: EnumViewType.QRCODE;
      content: string;
      css: QRcodeStyle;
    };

enum EnumViewType {
  LINE = 'line',
  VIEW = 'view',
  IMAGE = 'image',
  TEXT = 'text',
  QRCODE = 'qrcode',
}
```

下面将详细解释每种类别可传入的配置信息

#### 3.3.1 Line 配置

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| type | EnumViewType.LINE | 是   | 类别       |
| start | Point | 是   | 起点坐标       |
| end  | Point | 是   | 终点坐标       |
| css   | LineStyle | 是   | 线的样式       |

+ `Point`类型：

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| left | string / number | 是   | 距离左边的坐标       |
| top | string / number | 是   | 距离顶部的坐标       |

+ `LineStyle`类型：

| 字段   | 类型             | 必填 | 描述           | 默认值 ｜
| ------ | ---------------- | ---- | -------------- | -------- |
| width | string / number | 否   | 线的宽度     | 1px |
| color | string / function | 否   | 线的颜色，可渐变       | '#000' |
| shadow | string | 否   | 阴影，参考css阴影的样式编辑       | - |

其中，线性渐变的颜色可用函数传入，传入的格式为：

```js
(
  ctx: WechatMiniprogram.CanvasContext,
  start: Point,
  end: Point,
  width: number,
) => WechatMiniprogram.CanvasGradient;
```

#### 3.3.2 View 配置

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| type | EnumViewType.VIEW | 是   | 类别       |
| css | ViewStyle | 是   | 样式      |

+ `ViewStyle`类型：

| 字段   | 类型             | 必填 | 描述           | 默认值 ｜
| ------ | ---------------- | ---- | -------------- | ----- |
| width | string / number | 是   | 宽度     | - |
| height | string / number | 是   | 高度    | - |
| left | string / number | 是   | left坐标     | - |
| top | string / number | 是   | top坐标   | - |
| borderRaidus | string / number | 否   | 圆角   | - |
| borderWidth | string / number | 否   | 边框宽度  | - |
| borderColor | string / number | 否   | 边框颜色  | - |
| background | 见下方 | 否   | 背景   | - |
| shadow | string  | 否   | 阴影   | - |
| rotate | number | 否   | 顺时针旋转角度，以弧度计。 请使用 degrees*Math.PI/180 公式进行计算  | - |

其中，`background`字段的类型如下所示：

```js
type Background =
  | number
  | string
  | GetBackgroundGradient
  | WechatMiniprogram.CanvasGradient;
```

#### 3.3.3 Image 配置

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| type | EnumViewType.IMAGE | 是   | 类别       |
| url | string | 是   | 图片的链接      |
| css | ImageStyle | 是   | 样式      |

+ `ImageStyle`类型：

| 字段   | 类型             | 必填 | 描述           | 默认值 ｜
| ------ | ---------------- | ---- | -------------- | ----- |
| left | string / number | 是   | left坐标     | - |
| top | string / number | 是   | top坐标   | - |
| width | string / number | 否   | 宽度     | 原始图片宽度 |
| height | string / number | 否   | 高度    | 原始图片高度 |
| borderRaidus | string / number | 否   | 圆角   | - |
| shadow | string  | 否   | 阴影   | - |
| rotate | number | 否   | 顺时针旋转角度，以弧度计。 请使用 degrees*Math.PI/180 公式进行计算  | - |

#### 3.3.4 Text 配置

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| type | EnumViewType.TEXT |  是   | 类别   |
| text | string |  是   |  文本内容    |
| css | TextStyle |  是   |  样式   |
| positionId | string |  否   |  用于文本定位，与`relativePositionId`配合使用   |
| relativePositionId | string |  否   |  用于文本定位，基于前一个`postionId`相同的文本右下角进行定位  |


+ `TextStyle`类型：

| 字段   | 类型             | 必填 | 描述           | 默认值 ｜
| ------ | ---------------- | ---- | -------------- | ----- |
| left | string / number | 是   | left坐标     | - |
| top | string / number | 是   | top坐标   | - |
| width | string / number | 否   | 宽度     | AUTO |
| height | string / number | 否   | 高度    | AUTO |
| padding | string / number | 否   | 内边距    | 0 |
| borderRaidus | string / number | 否   | 圆角   | 0 |
| borderWidth | string / number | 否   | 边框宽度  | 0 |
| borderColor | string / number | 否   | 边框颜色  | - |
| background | 见下方 | 否   | 背景   | - |
| fontSize | string / number | 否   | 文字大小  | 18 |
| fontWeight | string / number | 否   | 文字权重  | 'normal' |
| fontStyle | string  | 否   | 文字样式   | 'normal' |
| fontFamily | string  | 否   | 文字字体   | 'sans-serif' |
| textDecoration | string  | 否   | 文字修饰   | - |
| textAlign | string  | 否   | 文本水平对齐方式  | 'left' |
| verticalAlign | string  | 否   | 文本垂直对齐方式  | 'top' |
| color | string  | 否   | 文字颜色   | '#000' |
| lineHeight | string  | 否   | 文字行高   | '1.4em' |
| lineClamp | number | 否   | 指定行数省略  | - |
| shadow | string  | 否   | 阴影   | - |
| rotate | number | 否   | 顺时针旋转角度，以弧度计。 请使用 degrees*Math.PI/180 公式进行计算  | - |

其中，`background`字段的类型如下所示：

```js
type Background =
  | number
  | string
  | GetBackgroundGradient
  | WechatMiniprogram.CanvasGradient;
```

+ **新功能**

为满足同一行字体大小不一致的情况，比如价格标签，新功能支持基于前一个文本右下角进行定位。

使用方法参考如下：

```js
// 自定义的id
const PRICE = 'price';

// 配置如下：
  {
    type: 'text',
    text: '98.',
    positionId: PRICE, // 定义一个positionId
    css: {
      left: '32rpx',
      top: '644rpx',
      fontSize: '28rpx',
      color: '#ff0000',
      fontWeight: 600,
      lineHeight: '28rpx',
    },
  },
  {
    type: 'text',
    text: '00',
    relativePositionId: PRICE,  // 相对前一个 positionId 为 PRICE 的文本右下脚进行定位
    css: {
      left: 0,
      top: '-20rpx',
      fontSize: '20rpx',
      color: '#ff0000',
      fontWeight: 600,
      lineHeight: '20rpx',
    },
  },
```

#### 3.3.5 QRcode 配置

| 字段   | 类型             | 必填 | 描述           |
| ------ | ---------------- | ---- | -------------- |
| type | EnumViewType.TEXT |  是   | 类别   |
| content | string |  是   |  文本内容    |
| css | QRcodeStyle |  是   |  样式  |

+ `QRcodeStyle`类型

| 字段   | 类型             | 必填 | 描述           | 默认值 ｜
| ------ | ---------------- | ---- | -------------- | ----- |
| left | string / number | 是   | left坐标     | - |
| top | string / number | 是   | top坐标   | - |
| width | string / number | 是   | 宽度     | - |
| height | string / number | 是   | 高度    | - |
| color | string  | 否   | 文字颜色   | - |
| background | 见下方 | 否   | 背景   | - |
| shadow | string  | 否   | 阴影   | - |
| rotate | number | 否   | 顺时针旋转角度，以弧度计。 请使用 degrees*Math.PI/180 公式进行计算  | - |

其中，`background`字段的类型如下所示：

```js
type Background =
  | number
  | string
  | GetBackgroundGradient
  | WechatMiniprogram.CanvasGradient;
```