网站首页 > 基础教程 正文
效果图如下,用户每次点击分享图片的时候,从内容库中随机抽出一条数据,渲染在图片上,并且加上用户昵称和头像,用户可以保存到本地。
功能不难,但是有一些小细节,还是列出来记录下吧。
根据开发的顺序写一下吧,先要确定rpx单位,读取数据(昵称 头像、文字),再渲染圆角头像和本地的二维码图片,判断保存权限,关闭后再次点击再渲染。
目录
- 自适应rpx单位
- 读取用户昵称和头像
- 随机获取文字内容
- promisify.js的封装使用
- 渲染网络图片和本图片
- 圆角图片
- 保存权限
- 多次渲染清空
1. 自适应rpx单位
起初自己在css里用的px单位给canvas设置的样式,在模拟器里切换机型后不能自适应,又换成rpx单位。
canvas里渲染图片和文字也需要单位,需要把px转成rpx,1rpx = 窗口宽度px/750。
<!--rpx2px函数--> function createRpx2px() { const { windowWidth } = wx.getSystemInfoSync() return function(rpx) { return windowWidth / 750 * rpx } } <!--使用rpx2px--> const rpx2px = createRpx2px() ctx.setFontSize(rpx2px(28)) ctx.fillText('长按左侧二维码', rpx2px(220), rpx2px(640)) 复制代码
2. 读取用户昵称和头像
根据微信的api文档,需要使用open-type="getUserInfo"属性的按钮获取用户授权,授权成功后调用wx.getUserInfo方法获取用户详情。
<button class="button" open-type="getUserInfo" bindtap="share" >分享到朋友圈</button> 复制代码
封装获取用户详情的Promise,并且返回昵称和图片地址。
<!--获取用户详情--> getInfo(){ return new Promise((resolve, reject) => { wx.getUserInfo({ success: function(res) { let { nickName , avatarUrl } = res.userInfo resolve({ nickName , avatarUrl }) } }) }) } 复制代码
3. 随机获取文字内容
云数据库可以使用类mongo的sample方法随机抽取数据,具体可见官方网文档。
size为指定数量。
封装Promise返回数据
getMsg(){ const db = wx.cloud.database() return new Promise((resolve, reject) => { db.collection('shareMsg').aggregate().sample({ size: 1 }).end().then(res=>{ resolve(res.list[0]) }); }) }, 复制代码
4. promisify.js的封装使用
Nodejs 8 有一个工具函数 util.promisify()。将一个接收回调函数参数的函数转换成一个返回Promise的函数。
js的编程中有很多需要异步的场景,刚才我们获取昵称和随机数据都用到了Promise,这样写很麻烦,微信的api都遵循一样的规范,网上有封装好的代码,拿来主义。
promisify.js
const promisify = (api) => { return (options, ...params) => { return new Promise((resolve, reject) => { api(Object.assign({}, options, { success: resolve, fail: reject }), ...params); }); } } export default promisify 复制代码
使用示例
import promisify from '../../lib/promisify.js'; let userInfo = promisify(wx.getUserInfo); userInfo().then(res => { console.log(res) }) 复制代码
5. 渲染网络图片和本图片
读取网络图片要在公众平台设置合法域名。
接口返回的头像图片域名为https://wx.qlogo.cn,添加上就可以了。渲染网络图片需要使用wx.getImageInfo方法把网络图片变成本地图片再渲染,本地图片直接放入图片路径即可。
this.getInfo().then(userInfo => { Promise.all([ wxGetImageInfo({ src: userInfo.avatarUrl }) ]).then(res => { ctx = wx.createCanvasContext('shareCanvas') <!--网络图片--> ctx.drawImage(res[0].path, rpx2px(40), rpx2px(60), rpx2px(60), rpx2px(60)); <!--本地图片--> ctx.drawImage('../../images/qrcode.jpeg', rpx2px(20), rpx2px(580), rpx2px(160),rpx2px(160)); }) }) 复制代码
6. 圆角头像
ctx.save(); ctx.beginPath(); ctx.arc(rpx2px(70), rpx2px(90), rpx2px(30), 0, Math.PI * 2, false); ctx.clip(); ctx.drawImage(res[0].path, rpx2px(40), rpx2px(60), rpx2px(60), rpx2px(60)); ctx.restore(); 复制代码
7. 保存权限
第一步使用wx.canvasToTempFilePath从canvas导出图片,第二步使用wx.saveImageToPhotosAlbum要把导出的图片的图片保存到相册。
保存到相册是需要用户授权的,用户授权拒绝后七天之内是不会在出现的授权框的,所以需要增加判断,如果无权限,显示设置按钮,跳转到权限设置页面。
<!--保存按钮--> saveImg(){ const wxCanvasToTempFilePath = promisify(wx.canvasToTempFilePath) const wxSaveImageToPhotosAlbum = promisify(wx.saveImageToPhotosAlbum) wxCanvasToTempFilePath({ canvasId: 'shareCanvas' }, this).then(res => { return wxSaveImageToPhotosAlbum({ filePath: res.tempFilePath }) }).then(res => { wx.showToast({ title: '已保存到相册' }) }).catch(err => { wx.showToast({ icon: 'none', title: '授权失败' }) <!--显示授权按钮--> this.setData({setPage:true}) }) } 复制代码 <button hidden="{{!setPage}}" open-type="openSetting" >设置权限</button> 复制代码
8. 多次渲染清空
对canvas不是特别熟悉,从翻api说画一个图形,然后在清除图片范围内的内容。
ctx.fillRect(0,0,rpx2px(500),rpx2px(760)) ctx.clearRect(0,0,rpx2px(500),rpx2px(760)) ctx.draw() 复制代码
ctx对象要多次操作,需要提取为全局变量,另外创建时要保证DOM渲染完毕。
let ctx = wx.createCanvasContext('shareCanvas') 复制代码
不过在模拟器中多次渲染会出现空白的情况,但是手机实测是正常的。
猜你喜欢
- 2024-10-29 57个挑战之57(part6):客户端+web前端+服务端代码实现
- 2024-10-29 技术干货|MongoDB数据库常见操作命令
- 2024-10-29 ABP vNext框架文档解读28-数据过滤
- 2024-10-29 自建MongoDB实践:MongoDB 分片集群
- 2024-10-29 go-mongox:简单高效,让文档操作和 bson 数据构造更流畅
- 2024-10-29 当MongoDB遇见Spark mongodb campass
- 2024-10-29 MongoDB 5.0 官方文档学习笔记 mongodb教程
- 2024-10-29 好东西,MySQL 数据库 MongoDB详解
- 2024-10-29 MongoDB 入门 day04 mongodb27017
- 2024-10-29 优化MongoDB查询性能:针对百万级数据集的有效策略与实践
- 最近发表
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- mysql教程 (60)
- pythonif (86)
- location.href (69)
- deletesql (62)
- c++模板 (62)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)