- 小程序分享图生成指南:告别 Canvas 踩坑,轻松实现朋友圈分享
由于微信小程序无法直接分享到朋友圈,业界普遍采用 Canvas 生成带小程序码的图片,引导用户保存后分享,相信不少开发者在绘制分享图时都曾遇到过各种 Canvas 的“彩蛋”(坑)。 今天推荐一个开源组件:Painter,它能够帮助我们轻松实现分享图绘制,并且已在支付宝小程序中验证可用。 快速开始 第一步:创建自定义组件 在组件的 JSON 文件中引入 Painter: [代码]{ "component": true, "usingComponents": { "painter": "/painter/painter" } } [代码] 第二步:编写组件 WXML 将 Painter 组件定位在屏幕外,避免影响用户界面: [代码]// 将该组件定位在屏幕之外,用户查看不到。 <painter style="position: absolute; top: -9999rpx;" palette="{{imgDraw}}" bind:imgOK="onImgOK" /> [代码] 第三步:实现组件逻辑 [代码]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') } } }) [代码] 如何使用 1. 引入组件 在页面的 JSON 文件中引入封装好的分享组件: [代码]{ "usingComponents": { "share-box": "/components/shareBox/index" } } [代码] 2. 页面布局 [代码]<!-- 触发按钮 --> <button class="intro" bindtap="getUserInfo">点我生成分享图</button> <!-- 分享组件 --> <share-box isCanDraw="{{isCanDraw}}" userInfo="{{userInfo}}" bind:initData="handleClose" /> [代码] 3. 页面逻辑 [代码]Page({ data: { isCanDraw: false, userInfo: {} }, // 重置绘制状态 handleClose() { this.setData({ isCanDraw: false }) }, // 获取用户信息并开始绘制 getUserInfo() { wx.getUserProfile({ desc: "获取您的头像昵称信息", success: (res) => { const { userInfo = {} } = res this.setData({ userInfo, isCanDraw: true // 触发绘制 }) }, fail: (err) => { console.log('获取用户信息失败:', err) } }) } }) [代码] 效果展示 完成上述步骤后,即可生成如下的分享图片: [图片] 实用技巧 文字居中:通过设置 [代码]align: 'center'[代码] 和合适的[代码]left[代码]值实现 文字换行:设置[代码]width[代码]和 [代码]maxLines[代码] 属性,当 [代码]maxLines: 1[代码] 时,超出一行会显示为省略号 资源链接 代码片段:点击查看 Painter 可视化工具:点击查看 常见问题 Q:为什么图片无法加载? A:需要在小程序后台配置 downloadFile 合法域名: 进入「开发」→「开发设置」→「服务器域名」 配置图片的域名前缀,如 https://qiniu-image.qtshe.com Q:真机调试注意事项? A:开发者工具中可在「详情」→「本地设置」中开启「不校验合法域名」,真机调试时需开启调试模式。 通过以上步骤,你就可以轻松实现小程序分享图生成功能了。如有任何问题,欢迎在评论区留言讨论!
星期四 10:32 - 关于云开发的一次性订阅消息
前段时间看到了这位老哥的一篇关于订阅消息的文章:https://developers.weixin.qq.com/community/develop/article/doc/0008802e8381e0eeabb92c9975b013 这篇文章对于程序员来说非常直观的说明了一次性订阅消息的逻辑:订阅1次,可以收到订阅消息一次,订阅10次,可以收到订阅消息10次。 但是我觉得这个方案对于一个普通用户来说,并不够友好,如果我是一个不懂订阅消息的普通用户,我根本不会花时间去点这样一个点1加1的订阅消息。我觉得对于开发者来说,用户能够点一次允许并且勾上不在询问就已经很不错了,剩下的完全可以交给程序来处理。下面是我的方案。让一次性订阅消息达到长期订阅的效果。 首先明确以下逻辑: 通过 wx.getSetting({ withSubscriptions: true }) 的 success 回调 res 可以得出订阅消息的以下5种状态[图片]当用户勾选了“不在询问”之后,不管你后面怎么调 wx.requestSubscribeMessage ,订阅消息的弹窗都是不会弹起的wx.requestSubscribeMessage 需要用户手动点击触发当得到以上几种状态之后,接下来就可以根据需要做自己想要做的操作 如我的小程序首页是一个版本列表 [图片] 我在列表的头部设计了一个跟小程序同风格的授权卡片,这样不会显得突兀同时告诉用户点击授权并且勾选“不在询问”,并告诉用户这样做的目的是什么。 然后根据上面得到的不同状态来显示不同的提示语: 总开关关闭了: [图片] 勾选了“不在询问”并且选项是取消 [图片] 接下来就是实现订阅消息+1的步骤,上面提到了当用户勾选了“不在询问”之后,不管你后面怎么调 wx.requestSubscribeMessage ,订阅消息的弹窗都是不会弹起的 这时在用户点击你应用中必点的操作时,比如知乎微博的点击列表进入详情,或者我这个小程序点击版本列表进入版本详情时就可以根据以上得到的状态来判断:当授权状态是“选择了不在询问并且选项是允许” 时,直接调用 wx.requestSubscribeMessage ,这时 wx.requestSubscribeMessage 的回调必定是success,而且不会出现授权弹窗,自然也就实现了+1效果。 最后把订阅次数+1记录到数据库,推送时推送订阅次数大于0的就ok了 [图片] 这样一个普通用户需要做的操作就只有点击授权-勾选不在询问-允许 这样一个步骤,同时就实现了无形中增加订阅次数的效果,替代让用户手动去点+1增加订阅消息的操作。 另外不用担心这种操作会使用户感觉像垃圾广告一样一直被推送,因为不管是在服务通知页面,还是在设置页面,用户都是可以很轻松的一键关闭通知。 [图片] 然后说下订阅消息的几个特殊情况: 1.当你的账号在开发者工具上面点过允许或取消的时候,wx.getSetting({ withSubscriptions: true }) 的 success 回调结果是这样的 [图片] 手机上的设置界面是这样的 [图片] 回调的itemSettings属性消失了,界面上有订阅消息的开关,但是订阅消息的选项却没了,正常情况应该是这样的 [图片] 这样的 [图片] 2.当用户点了“不在询问并允许”但是又手动通过服务通知页面,或者设置页面关闭了消息通知,这时就算该用户之前已经订阅过了很多次,都会被系统自动清0,这时你的数据库可能存的该用户还有比如5次订阅消息,但是通过cloud.openapi.subscribeMessage.send推送消息的时候,会进catch,errCode是43101。 3.当用户手速过快连续点击了授权按钮触发wx.requestSubscribeMessage时,会进入fail回调,errMsg是 requestSubscribeMessage:fail last call,这个文档是没写的。 最后可以扫码体验一下: [图片]
2020-07-14