小程序分享海报绘制神器 - Painter

  由于最近接触到商务类型的小程序开发较多,其中必不可少的一个功能就是小程序分享海报的绘制,海报绘制无非就是将元素在 canvas 上绘制并生成图片,常用的方法有 Wxml2Canvas 及 Painter。由于 Wxml2Canvas 的局限性较大,而且绘制出来的效果比较一般,如果较为简单的海报可以尝试使用,本文着重分享一下 Painter 以及使用方法。

  

 

 

   Painter 的原理相当于我们把需要出现在画板的元素列出来传给 Painter,它就会调用 Pen 去将元素一一绘制出来。Painter 支持绘制的格式有 text(文本)、image(图片)、rect(矩形)、qrcode(二维码)。

  并且 Painter 的强大在于它不仅可支持圆角、阴影、边框、渐变色的绘制,还可支持旋转(rotate)、分辨率调整,功能十分强大,可满足业务中的大部分需求。相关文档及安装方式:https://github.com/Kujiale-Mobile/Painter

  Painter 中的元素基本都是以绝对定位形式存在的,但也可支持相对定位,操作起来也不麻烦,只需要给相对元素设置一个 id,后续元素即可根据该元素进行相对偏移。至于元素的层级关系,由于 Painter 中没有 z-index 用于控制层级,所以采用的方式是出现在后面的元素则层级较高。 

  下面简单给一个 demo,方便读者理解:

// wxml 文件
// drawPosterData 相当于画板上的元素,需要手动配置
// widthPixels 为生成的图片的像素宽度,如不传则根据模版动态生成
// sharePosterDone 当 canvas 绘制完毕时会触发该钩子函数,通过读取 res.detail.path 可获取生成图片的临时存储路径
// tips: 该组件会占用一定空间,可根据实际布局将该组件隐藏。本项目中将其宽高都设置为 0,position 改为 absolute,达到隐藏效果
<painter-2d palette="{{drawPosterData}}" bind:imgOK="sharePosterDone" widthPixels="1080" class="hidden" />

  palette 配置 demo:

export const initPosterConfig = function(data) {
  const config = Object.create(null)
  config.background = '#000000'
  config.width = '540rpx'
  config.height = '958rpx'
  config.views = [
    // background image
    {
      type: 'image',
      url: 'https://cloud-minapp-37887.cloud.ifanrusercontent.com/1lJ5j1YODUdcYLH3.jpg',
      css: {
        width: '100%',
        height: '100%',
        top: '0',
      },
    },
    // cover image
    {
      type: 'rect',
      css: {
        width: '394.3rpx',
        height: '302.3rpx',
        top: '196rpx',
        left: '76rpx',
        rotate: '7',
        color: '#FFFFFF',
        shadow: '0px 10px 15px rgba(119, 7, 9, 0.25)',
      },
    },
    {
      type: 'image',
      url: data.cover_image,
      css: {
        width: '371.78rpx',
        height: '279.76rpx',
        top: '207.44rpx',
        left: '87.44rpx',
        rotate: '7',
        mode: 'scaleToFit',
      },
    },
    // user info
    {
      type: 'image',
      url: data.created_by.avatar,
      css: {
        width: '76rpx',
        height: '76rpx',
        borderRadius: '100%',
        top: '542rpx',
        left: '104rpx',
      },
    },
    {
      type: 'text',
      text: data.created_by.nickname,
      css: {
        top: '554rpx',
        left: '196rpx',
        color: '#606060',
        fontSize: '21rpx',
        lineHeight: '30rpx',
        fontWieght: 'bold',
        // width: '200rpx',
        // maxLines: '1',
      },
    },
    // rank
    {
      type: 'text',
      text: 'No.' + `${data.serial_number}`.padStart(5, 0),
      css: {
        top: '586rpx',
        left: '198rpx',
        fontSize: '22rpx',
        lineHeight: '30rpx',
        color: '#D8D7D7',
        fontWeight: 'bold',
      },
    },
    // congratulation
    {
      type: 'text',
      text: data.congratulation.split(',').join('\n'),
      css: {
        top: '632rpx',
        left: '104rpx',
        fontSize: '40rpx',
        lineHeight: '50rpx',
        maxLines: '2',
        color: '#BC8D92',
      },
    },
    // tips
    {
      type: 'text',
      text: '识别二维码进入活动\n为她点赞',
      css: {
        top: '796rpx',
        left: '104rpx',
        fontSize: '18rpx',
        lineHeight: '30rpx',
        maxLines: '2',
        color: '#606060',
      },
    },
    // 分享二维码
    {
      type: 'image',
      url: data.qrcode,
      css: {
        width: '124rpx',
        height: '124rpx',
        right: '22rpx',
        bottom: '32rpx',
        borderRadius: '100%',
        borderWidth: '4rpx',
        borderColor: '#FFFFFF',
      },
    },
  ]
  return config
}

  至于 config 的配置,根据设计稿来完成就行啦。绘制完成后拿到临时存储路径,用个 image 标签将图片展示即可。图片保存请参考微信官方文档 wx.saveImageToPhotosAlbum。

  放几个 demo 展示效果:

  

  

  

  

 

  

  

posted @ 2021-03-08 21:38  卑微小陈的随笔  阅读(1135)  评论(0编辑  收藏  举报