评论

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

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

由于我们无法将小程序直接分享到朋友圈,但分享到朋友圈的需求又很多,业界目前的做法是利用小程序的 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 个评论

  • Mr.L
    Mr.L
    2020-07-21

    我用这个方法做了个海报效果不错,已经上线了!

    

    2020-07-21
    赞同 5
    回复 17
    • "
      2020-08-10回复Stern
      大佬,支持新版本2D接口吗
      2020-08-10
      回复
    • Believeヾ
      Believeヾ
      2020-09-02回复Stern
      大佬 可以支持base64的图片吗
      2020-09-02
      回复
    • 袁述~
      袁述~
      2020-09-17回复Stern
      现在支持canvas 2D 自定义字体了吗
      2020-09-17
      回复
    • Stern
      Stern
      2021-03-19回复袁述~
      支持
      2021-03-19
      1
      回复
    • Stern
      Stern
      2021-03-19回复
      支持
      2021-03-19
      回复
    查看更多(12)
  • 精彩极了
    精彩极了
    2019-11-08

    不好意思,刚发现问题就删掉了评论发表

    2019-11-08
    赞同 2
    回复 10
    • 精彩极了
      精彩极了
      2019-11-08回复Stern
      本地图片可以加载绘制进来,就是有一点错误提示,不太友好,哈哈
      2019-11-08
      1
      回复
    • 精彩极了
      精彩极了
      2019-11-11回复Stern
      用painter连续加载了三次,生成了三张图片,生成时会闪屏,然后左右滑动时也会闪屏,求解啊大佬
      2019-11-11
      回复
    • Stern
      Stern
      2019-11-11
      canvas绘制图,性能本来就差点。你这个连续绘制3次。建议你写三个painter的内容。写三个canvas
      2019-11-11
      3
      回复
    • 精彩极了
      精彩极了
      2019-11-12回复Stern
      这样生成图片之后,把临时路径放到swiper里面去,就一直闪一直闪,部分手机是正常的,小米的就狂闪,不知道为什么
      2019-11-12
      2
      回复
    • 精彩极了
      精彩极了
      2019-11-12回复Stern
      看了一下生成的图片,都控制在1.5M以内
      2019-11-12
      回复
    查看更多(5)
  • core
    core
    2020-07-09

    想问下楼主,如果我不知道页面结构的情况下,能实现截取整个页面的功能吗?

    2020-07-09
    赞同 1
    回复 1
    • Stern
      Stern
      2020-07-09
      不能。
      2020-07-09
      回复
  • 1638.
    1638.
    2020-05-11

    真机为什么不显示图片啊

    2020-05-11
    赞同 1
    回复 9
    • Stern
      Stern
      2020-05-11
      图片没配置合法域名。你试下开启调试是否可以显示了
      2020-05-11
      1
      回复
    • M_yyyyyy_
      M_yyyyyy_
      2020-06-24回复Stern
      您好,开启调试之后,可以显示了,但是关闭调试之后又不显示了;请问这个如何解决呢?
      2020-06-24
      回复
    • Stern
      Stern
      2020-06-24回复M_yyyyyy_
      小程序后台配置downloadFile合法域名。
      2020-06-24
      2
      回复
    • M_yyyyyy_
      M_yyyyyy_
      2020-06-24回复Stern
      您好,现在服务端下发给我的url是http,但是小程序后台配置的合法域名是https,开启调试之后,可以显示图片,但是关闭调试之后又不显示图片了,是和配置的https有关系么
      2020-06-24
      回复
    • Stern
      Stern
      2020-06-24回复M_yyyyyy_
      让你们后端返回的图片地址支持下https,downLoadFile域名都得是https的。http的不行
      2020-06-24
      2
      回复
    查看更多(4)
  • a'ゞ玉米粒 🌽
    a'ゞ玉米粒 🌽
    06-22

    你好,我想问下这个生成海报在企业微信小程序是没做兼容嘛,这是开发者工具里的报错,生成不了,但是发布之后在电脑企业微信里是可以生成的,只是样式都不太对了

    手机上企业微信里可以生成样式也是对的,想请问有没有大佬知道的

    06-22
    赞同
    回复 1
    • Stern
      Stern
      06-23
      电脑版企业微信或者电脑版微信都没有做适配的 我记得。
      06-23
      回复
  • 谢志杰
    谢志杰
    06-01

    textList 只有在填入数字的时候 可以展示,其他时候 就是整个图片都没法展示出来

    06-01
    赞同
    回复
  • 朱高
    朱高
    05-18

    是不是不支付选择本地的图片?wx.chooseImage 返回的临时图片路径

    05-18
    赞同
    回复 5
    • Stern
      Stern
      05-18
      这个是支持的
      05-18
      回复
    • 朱高
      朱高
      05-18回复Stern
      用的是 Taro,临时路径直接放在 url 对吗?报了这个错:
      Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)'
      05-18
      回复
    • Stern
      Stern
      05-18回复朱高
      用得绘图的Taro版本吗
      05-18
      回复
    • 朱高
      朱高
      05-18回复Stern
      切换一下基础库就行了。我真是服了,排查了一天,最后发现是基础库问题。


      开始用的是 2.18.1,不管用什么样的姿势,都是报这个错。


      后面换成 2.20.3,好了。


      再切回 2.18.1,又报错。


      可以断定是基础库的问题了。
      05-18
      回复
    • Stern
      Stern
      05-18回复朱高
      哈哈哈哈 好的
      05-18
      回复
  • 琦琦
    琦琦
    04-11

    楼主: 真机测试正常,上线体验版本之后保存到相册海报, 没有图片只有文字是怎么回事

    04-11
    赞同
    回复 1
    • Stern
      Stern
      04-11
      图片没有配置downloadFile合法域名
      04-11
      回复
  • 100+
    100+
    04-07

    下载后的图片有点模糊

    04-07
    赞同
    回复 1
    • Stern
      Stern
      04-07
      加上 scaleRatio="{{3}}"
      04-07
      回复
  • w.
    w.
    03-23

    大佬,请问这个组件可以实现页面直接转图片吗。因为我这里的页面是一个表格,使用画布绘画无法实现

    03-23
    赞同
    回复 1

正在加载...

登录 后发表内容