@poster-render/taro-react
TypeScript icon, indicating that this package has built-in type declarations

3.6.3 • Public • Published

@poster-render/taro-react

通过配置的方式渲染海报,无需了解canvas语法。采用canvas2d api封装,支持同层渲染,支持微信/企微、支付宝、头条、h5

安装

npm install @poster-render/taro-react

使用

import { FC, useRef } from "react";
import { pxTransform } from "@tarojs/taro";
import { PosterRender, PosterRenderRef } from "@poster-render/taro-react";

const Index: FC = () => {
  const posterRender = useRef<PosterRenderRef>(null);

  return (
    <PosterRender
      ref={posterRender}
      canvasId="taro-poster-render"
      renderType={"canvas"}
      canvasWidth={644}
      canvasHeight={1104}
      debug
      style={{
        width: pxTransform(644),
        height: pxTransform(1104),
      }}
      onRender={() => console.log("onRender")}
      onLongTap={() => posterRender.current?.savePosterToPhoto())}
      onRenderFail={(err) => console.error("onRenderFail", err?.message)}
      onSave={(url) => console.log("onSave", url)}
      onSaveFail={(err) => console.error("onSaveFail", err?.message)}
      list={[
        {
          type: "rect",
          x: 0,
          y: 0,
          width: 644,
          height: 1104,
          radius: 0,
          backgroundColor: "black",
        },
        {
          type: "image",
          x: 0,
          y: 0,
          width: 644,
          height: 1104,
          mode: "cover",
          src: "https://img.1000.com/shumou/interaction/bg3.png",
          radius: 16,
        },
        {
          type: "line",
          x: 50,
          y: 50,
          destX: 200,
          destY: 50,
          color: "#fff",
          lineWidth: 4,
        },
        {
          type: "text",
          x: 100,
          y: 180,
          width: 150,
          height: 30,
          text: "中二猪猪猪",
          color: "#fff",
          fontSize: 28,
          textAlign: "left",
          baseLine: "top",
          textDecoration: "line-through",
        },
      ]}
    />
  );
};

export default Index;

如果不喜欢我的封装可以使用@poster-render/taro - npm (npmjs.com),以api的方式自己封装react组件或vue组件

props

基础props

字段 类型 是否必填 描述
className string
style React.CSSProperties
canvasId String 默认“poster-render”,当有多个canvas时,需要指定canvasId,否则默认为第一个canvas
canvasWidth number 画布宽度, 注意不是css width
canvasHeight number 画布高度, 高度不要超过4096(报错), 注意不是css height
destWidth number 输出图片宽度
destHeight number 输出图片高度
debug boolean 开启调试日志
fileType "png" | "jpg" 导出图片格式,默认png
quality number 导出图片质量0-1,默认为1,只对jpg生效
dpr number 指定dpr,默认会启用高清方案,画布最终会被放大dpr倍(默认为系统dpr),但是某些场景画布太大会报错,或者画布太大导致生成图片太慢,这种情况可以指定dpr调整画布大小解决问题;支付宝小程序不支持,固定为1,安卓下企微dpr为3时生成图片会报错,固定为1,另外,如果画布高度乘以dpr超过4096,则会取消放大
renderType "image" | "canvas" 渲染方式,默认是canvas, 新版canvas2d支持同层渲染(模拟器可能不支持),推荐canvas2d,如果想要实现长按海报识别二维码场景可以改为image,同时启用showMenuByLongpress
disableRerender boolean 禁用re-render。只有list发生变化才会导致re-render,但是list如果传了函数或者字体x或者width为函数时就会导致优化失效,可以采用disableRerender禁用
list PosterItemConfig[] | (instance: PosterRenderCore) => PosterItemConfig[] 图片、文字、图形配置,当为函数时接受PosterRenderCore实例。一般传数组即可,如果要实现上面多段文字联动局中效果,可以改用函数(如果传函数的话需要自己处理re-render的问题)
onSave (url: string) => void 保存成功事件
onSaveFail (err?: any) => void 保存失败事件
onRenderFail (err?: any) => void 渲染失败事件

renderType = "canvas"时

字段 类型 是否必填 描述
onLongTap () => void 长按事件
onRender () => void 渲染成功回调

renderType = "image"时

字段 类型 是否必填 描述
onLongTap (url: string) => void 长按事件
onRender (url: string) => void 渲染成功回调
showMenuByLongpress Boolean 开启长按图片显示识别小程序码菜单(支持转发、下载、收藏、识别二维码),微信生效(企微不支持)

list支持四种原子类型:imagetextrectline,复杂的效果可用通过相互组合实现,自由发挥吧(如果有无法实现的场景请一定要给我提个issue,我会尽快支持的)

image类型(PaintImage)

字段 类型 是否必填 描述
cacheKey string 缓存key,使用base64建议指定
type string 固定为image
x number 左上角x坐标
y number 左上角y坐标
sx number 源图片被截取部分左上角顶点的横坐标,cover模式下生效,默认长边局中显示
sy number 源图片被截取部分左上角顶点的纵坐标,cover模式下生效,默认长边局中显示
width number 图片宽
height number 图片高
src string 图片路径,支持https、wxfile、base64
defaultSrc string 默认图片,src下载失败采用下载默认图
backgroundColor string 背景色
radius number \ [number, number, number, number]
mode "fill" \ "cover" \ "contain"

text类型(PaintText)

字段 类型 是否必填 描述
type String 固定为text
x ((textWidth: number, instance: PosterRenderCore) => number) | number; 左上角x坐标。当为函数时参数为text宽度,可以根据文字宽度动态计算x坐标
y number 左上角y坐标
width ((textWidth: number, instance: PosterRenderCore) => number) | number; 文字宽,当为函数时参数为text宽度
height number 文字高
text string 文字内容
textAlign "left" | "center" | "right" 文字对齐方式,默认left,注意这里跟css文字对齐方式不一样,请仔细查看文档
fontWeight "normal" | "bold" 默认normal
color string 字体颜色
fontSize number 字体大小
fontStyle "normal" | "italic" | "oblique" 默认normal
fontFamily string
lineHeight number 行高
baseLine "top" | "bottom" | "middle" | "normal" 默认top,方便计算坐标
opacity number 字体透明度
lineNum number 行数,默认1行,超出自动显示...
textDecoration "line-through" | "underline" | "overline" 文字装饰线,支持下划线、上划线、删除(线的y坐标计算的可能不是很准,不满意的话用线自己绘制吧)
textDecorationWidth number 文字装饰线宽

rect类型(PaintRect)

字段 类型 是否必填 描述
type String 固定为rect
x number 左上角x坐标
y number 左上角y坐标
width number 图片宽
height number 图片高
borderColor string 边框颜色
borderWidth number 边框宽
backgroundColor string 填充色
radius number | [number, number, number,number] 圆角半径,顺序:左上 -> 右上 -> 右下 -> 左下,如果要绘制圆形,宽高一致,radius设为宽高一半
lineDash number[] 虚线设置
lineDashOffset number 虚线偏移量

line类型(PaintLine)

字段 类型 是否必填 描述
type String 固定为line
x number 起始点x
y number 起始点y
destX number 目标点x
destY number 目标点y
color string 线颜色
lineWidth number 线款
lineDash number[] 虚线设置
lineDashOffset number 虚线偏移量
lineCap string 指定如何绘制每一条线段末端的属性。有 3 个可能的值,分别是:butt, round and square。默认值是 butt

实例方法

方法 类型 描述
savePosterToPhoto () => Promise<string | undefined> 保存到相册,返回图片路径
preview () => Promise 预览图片
render (config?: PosterItemConfig[] | ((instance: PosterRenderCore) => PosterItemConfig[])) => Promise 渲染方法

PosterRenderCore实例方法

参考@poster-render/taro - npm (npmjs.com)

注意

  • 建议renderType传canvas,canvas2d支持同层渲染了(模拟器不一定支持),当要实现长按识别二维码场景场景时可以使用image方式,同时启用showMenuByLongpress

  • renderType为image时会先展示canvas,图片生成后会盖在canvas上面,至于为啥这样做,ios下如果把canvas移出可视区域会导致图片模糊,暂时先这么处理吧,有好的方案可以给我提个issue

  • canvas没有层级,后渲染的可能会盖住之前的内容,所以list要注意顺序,这里使用了for await...of特性实现“同步”渲染

  • 小程序图片域名要提前配置到下载白名单

  • 建议预加载图,否则图片会按顺序下载,增加渲染时长

  • 受网路影响图片可能会下载失败,这里做了两次下载重试

  • canvas宽高跟css宽高不是一个概念不要搞混了

  • 微信小程序canvas2d 画布高度不能超过4096(其他小程序没测试),所以初始化时画布超过4096会抛错

  • 默认渲染会开启高清模式,即画布会放大dpr倍,但是放大后画布尺寸可能会超限,所以,检测到画布高度超过4096后会取消高清模式,避免报错

  • 部分安卓手机企微下会报“canvasToTempFilePath:fail:convert native buffer parameter fail. native buffer exceed size limit.”,查了下说是高清方案引起的,dpr超过3都会出现该问题,为了不报错,安卓手机企微下默认不启用高清模式,如果觉着海报不清楚,可以手动指定dpr

  • 生成海报模糊?采用高清图、画布调大点、调高dpr(注意渲染速度,自己权衡吧)

  • 支付宝小程序要启用基础库2.0

  • 如果想要兼容其他小程序可以给我提个issue

2.x升级到3.x

# 卸载2.x版本包
npm uninstall taro-poster-render
# 安装3.x版本包
npm install @poster-render/taro-react

有较大的break changes,但功能没怎么变,基本上就是修改了下api,字段名,对照新文档即可迁移

Package Sidebar

Install

npm i @poster-render/taro-react

Weekly Downloads

17

Version

3.6.3

License

MIT

Unpacked Size

107 kB

Total Files

10

Last publish

Collaborators

  • lf7817