评论

如何实现快速生成朋友圈海报分享图

如何快速实现朋友圈海报分享图~

由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 Canvas 功能生成一张带有小程序码的图片,然后引导用户下载图片到本地后再分享到朋友圈。相信大家在绘制分享图中应该踩到 Canvas 的各种(坑)彩dan了吧~

这里首先推荐一个开源的组件:painter(通过该组件目前我们已经成功在支付宝小程序上也应用上了分享图功能)

咱们不多说,直接上手就是干。

首先我们新增一个自定义组件,在该组件的json中引入painter

{
  "component": true,
  "usingComponents": {
    "painter": "/painter/painter"
  }
}

然后组件的WXML (代码片段在最后)

// 将该组件定位在屏幕之外,用户查看不到。
<painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK" />

重点来了 JS (代码片段在最后)

Component({
  properties: {
    // 是否开始绘图
    isCanDraw: {
      type: Boolean,
      value: false,
      observer(newVal) {
        newVal && this.handleStartDrawImg()
      }
    },
    // 用户头像昵称信息
    userInfo: {
      type: Object,
      value: {
        avatarUrl: '',
        nickName: ''
      }
    }
  },
  data: {
    imgDraw: {}, // 绘制图片的大对象
    sharePath: '' // 生成的分享图
  },
  methods: {
    handleStartDrawImg() {
      wx.showLoading({
        title: '生成中'
      })
      this.setData({
        imgDraw: {
          width: '750rpx',
          height: '1334rpx',
          background: 'https://qiniu-image.qtshe.com/20190506share-bg.png',
          views: [
            {
              type: 'image',
              url: 'https://qiniu-image.qtshe.com/1560248372315_467.jpg',
              css: {
                top: '32rpx',
                left: '30rpx',
                right: '32rpx',
                width: '688rpx',
                height: '420rpx',
                borderRadius: '16rpx'
              },
            },
            {
              type: 'image',
              url: this.data.userInfo.avatarUrl || 'https://qiniu-image.qtshe.com/default-avatar20170707.png',
              css: {
                top: '404rpx',
                left: '328rpx',
                width: '96rpx',
                height: '96rpx',
                borderWidth: '6rpx',
                borderColor: '#FFF',
                borderRadius: '96rpx'
              }
            },
            {
              type: 'text',
              text: this.data.userInfo.nickName || '青团子',
              css: {
                top: '532rpx',
                fontSize: '28rpx',
                left: '375rpx',
                align: 'center',
                color: '#3c3c3c'
              }
            },
            {
              type: 'text',
              text: `邀请您参与助力活动`,
              css: {
                top: '576rpx',
                left: '375rpx',
                align: 'center',
                fontSize: '28rpx',
                color: '#3c3c3c'
              }
            },
            {
              type: 'text',
              text: `宇宙最萌蓝牙耳机测评员`,
              css: {
                top: '644rpx',
                left: '375rpx',
                maxLines: 1,
                align: 'center',
                fontWeight: 'bold',
                fontSize: '44rpx',
                color: '#3c3c3c'
              }
            },
            {
              type: 'image',
              url: 'https://qiniu-image.qtshe.com/20190605index.jpg',
              css: {
                top: '834rpx',
                left: '470rpx',
                width: '200rpx',
                height: '200rpx'
              }
            }
          ]
        }
      })
    },
    onImgErr(e) {
      wx.hideLoading()
      wx.showToast({
        title: '生成分享图失败,请刷新页面重试'
      })
      //通知外部绘制完成,重置isCanDraw为false
      this.triggerEvent('initData') 
    },
    onImgOK(e) {
      wx.hideLoading()
      // 展示分享图
      wx.showShareImageMenu({
        path:  e.detail.path,
        fail: err => {
          console.log(err)
        }
      })
      //通知外部绘制完成,重置isCanDraw为false
      this.triggerEvent('initData') 
    }
  }
})

那么我们该如何引用呢?

首先json里引用我们封装好的组件share-box
{
  "usingComponents": {
    "share-box": "/components/shareBox/index"
  }
}
以下示例为获取用户头像昵称后再生成图。
<button class="intro" bindtap="getUserInfo">点我生成分享图</button>
<share-box isCanDraw="{{isCanDraw}}" userInfo="{{userInfo}}"  bind:initData="handleClose" />
调用的地方:
const app = getApp()

Page({
  data: {
    isCanDraw: false
  },
  // 组件内部关掉或者绘制完成需重置状态
  handleClose() {
    this.setData({
      isCanDraw: !this.data.isCanDraw
    })
  },
  getUserInfo(e) {
    wx.getUserProfile({
      desc: "获取您的头像昵称信息",
      success: res => {
        const { userInfo = {} } = res
        this.setData({
          userInfo,
          isCanDraw: true // 开始绘制海报图
        })
      },
      fail: err => {
        console.log(err)
      }
    })
  }
})

最后绘制分享图的自定义组件就完成啦~效果图如下:

tips:

  • 文字居中实现可以看下代码片段
  • 文字换行实现(maxLines)只需要设置宽度,maxLines如果设置为1,那么超出一行将会展示为省略号

代码片段:https://developers.weixin.qq.com/s/J38pKsmK7Qw5

附上painter可视化编辑代码工具:点我直达,因为涉及网络图片,代码片段设置不了downloadFile合法域名,建议真机开启调试模式,开发者工具 详情里开启不校验合法域名进行代码片段的运行查看。
最后看下面大家评论问的较多的问题:downLoadFile合法域名在小程序后台 开发>开发设置里配置,域名为你图片的域名前缀 比如我文章里的图https://qiniu-image.qtshe.com/20190605index.jpg。配置域名时填写https://qiniu-image.qtshe.com即可。如果你图片cdn地址为https://aaa.com/xxx.png, 那你就配置https://aaa.com即可。
最后一次编辑于  01-20  
点赞 103
收藏
评论

103 个评论

  • 余温无痕
    余温无痕
    01-20

    请问下,我只要开启use2D就报错,不管是在开发者工具上还是真机上,代码是最新的,从github下载下来的,图中两个打印日志是wx.getImageInfo得到的头像和小程序码

    如果我不用2d情况下,就不会报错能正常渲染出来

    <!-- use2D -->
    <painter style="position: absolute; top: -9999rpx;" use2D scaleRatio="{{3}}" palette="{{imgDraw}}" bind:imgOK="onImgOK" />
    
    <!-- 页面上使用,增加了头像和小程序码的参数 -->
    <share-box isCanDraw="{{isCanDraw}}" headimg="{{ headimg }}" codePath="{{ qrcodeUrl }}" bind:close="handleClose" />
    

    微信开发者工具上

    真机

    01-20
    赞同
    回复 5
    • Stern
      Stern
      01-20
      开了真机调试?2d不支持真机调试。用真机预览。我更新了代码片段。你把2D加上试试
      01-20
      回复
    • 余温无痕
      余温无痕
      01-21回复Stern
      我用体验版测试还是一样的,会停留在生成中... 小程序后台服务器域名也早配置好了
      01-21
      回复
    • Stern
      Stern
      01-21回复余温无痕
      配置好域名后 需要删除线上版本、开发版本、体验版本。配置的才会生效。
      01-21
      回复
    • 余温无痕
      余温无痕
      01-22回复Stern
      那个都已经删除了,确认不是域名的问题,我现在是扫体验版,之前的体验版也删除了,不可能说开启2D后就有问题,不开启2D就没有问题,这个不是域名造成的,我现在是开启2D,然后用体验版体验就生成不了,不开启就可以
      01-22
      回复
    • Stern
      Stern
      01-24回复余温无痕
      真机打开调试。查看报错信息 截图,或者把你的问题代码写个代码片段发我 我来改。
      01-24
      回复
  • XJX
    XJX
    01-20

    微信头像不显示也是域名配置的问题吗


    01-20
    赞同
    回复 3
    • Stern
      Stern
      01-20
      微信头像的获取方式 换了。使用 my.getUserProfile
      01-20
      回复
    • XJX
      XJX
      01-20回复Stern
      如果是不要再次授权,就用之前登录缓存里的https的头像链接呢
      01-20
      回复
    • Stern
      Stern
      01-20回复XJX
      也可以的。但是 缓存里的https头像得是你们自己的cdn的。不能是微信域名的。你微信改了头像,小程序缓存里的头像地址就会是无法显示的图。
      01-20
      回复
  • 七大大
    七大大
    2021-11-29

    drawPic可以正常的执行

    但一直没有走onImgOK或onImgErr的方法 什么原因?



    2021-11-29
    赞同
    回复 1
    • Stern
      Stern
      2021-11-29
      贴代码?
      2021-11-29
      回复
  • -
    -
    2021-11-17

    文字超出的话 能省略吗


    2021-11-17
    赞同
    回复 6
    • Stern
      Stern
      2021-11-17
      可以。
      2021-11-17
      回复
    • Stern
      Stern
      2021-11-17
      设置maxLine 为1 就1排省略为2就2排省略
      2021-11-17
      回复
    • -
      -
      2021-11-17回复Stern
      可以了 谢谢
      2021-11-17
      回复
    • Stern
      Stern
      2021-11-18回复-
      好的
      2021-11-18
      回复
    • -
      -
      2021-11-18回复Stern
      有交流群吗我们
      2021-11-18
      回复
    查看更多(1)
  • 一点甜
    一点甜
    2021-10-16
    手机在小商店里怎么加上收款海报功能?
    2021-10-16
    赞同
    回复 1
    • Stern
      Stern
      2021-10-18
      小商店可以加自己的代码么,没开发过。
      2021-10-18
      回复
  • X
    X
    2021-09-08

    在QQ小程序中生成的海报很模糊啊,大小被压缩到原图的20%,请问是不是不兼容QQ小程序?

    2021-09-08
    赞同
    回复 10
    • Stern
      Stern
      2021-09-08
      截图看下。
      2021-09-08
      回复
    • X
      X
      2021-09-08回复Stern
      用开发者工具没有这个问题,真机才会出现
      2021-09-08
      回复
    • Stern
      Stern
      2021-09-08回复X
      加了scaleRatio么?
      2021-09-08
      回复
    • X
      X
      2021-09-08回复Stern
      没有啊,代码是一模一样的
      2021-09-08
      回复
    • Stern
      Stern
      2021-09-08回复X
      那加widthPixels了么?painter的代码截图看下。
      2021-09-08
      回复
    查看更多(5)
  • Lynch Bel
    Lynch Bel
    2021-08-20

    我写了个快速绘制海报图+保存到相册的插件,使用的是2d接口

    https://github.com/kiccer/wx-canvas-2d

    2021-08-20
    赞同
    回复
  • Youngwell
    Youngwell
    2021-08-16

    将页面生成长图而且页面中有循环渲染的列表,也就是页面的高度不定,这个需求用这个插件怎么解决呢,大佬

    2021-08-16
    赞同
    回复 4
    • now
      now
      2021-08-20
      你好,请问你这边实现了吗?
      2021-08-20
      1
      回复
    • Stern
      Stern
      2021-09-09
      2021-09-09
      回复
    • 满目山河
      满目山河
      2021-12-23回复now
      你好 请问你这边实现了吗
      2021-12-23
      回复
    • now
      now
      01-11回复满目山河
      异步获取到需要生成海报的所有数据,图片文字按照固定的排列格式进行计算宽高间距,然后进行遍历生成
      01-11
      回复
  • 阳台
    阳台
    2021-06-08

    canvas 2d 接口支持同层渲染且性能更佳,建议切换使用。

    需要提升个版本么 嘿嘿

    2021-06-08
    赞同
    回复 14
    • Stern
      Stern
      2021-06-09
      需要哦~ 下载文档上最新的包,base64测试版那个
      2021-06-09
      回复
    • 阳台
      阳台
      2021-06-09回复Stern
      想动态改文字 怎么传参啊?
      2021-06-09
      回复
    • Stern
      Stern
      2021-06-09回复阳台
      通过变量传递到组件里就好了吖
      2021-06-09
      回复
    • 阳台
      阳台
      2021-06-09回复Stern
      通过createShareImage传参吗?  小白求指教
      2021-06-09
      回复
    • Stern
      Stern
      2021-06-09回复阳台
      上面可以绑定方法呀。<share-box 你的变量="{{你的变量}}" 例如: content="{{content}}"  组件内进行接收就行了 />
      2021-06-09
      回复
    查看更多(9)
  • 🙈
    🙈
    2021-06-02

    加群加不上啊

    2021-06-02
    赞同
    回复 2
    • Stern
      Stern
      2021-06-02
      可以啊
      2021-06-02
      回复
    • Stern
      Stern
      2021-06-02
      chrispengtao
      2021-06-02
      1
      回复

正在加载...

登录 后发表内容