从上面截图能够看出,canvas的主体组成部分包括:javascript
背景图css
微信头像和昵称信息html
小程序码(小程序码会携带分享者的信息)java
经过小程序提供的画布,咱们能很容易的完成上面的整个海报的绘制。可是,canvas的绘制都是基于像素(px)级别的,可是在小程序中,咱们的预览图和最终生成的图,都须要根据机型进行适配。git
底部弹出的模态框
模态框的实现见下面的XML内容,能够看出具体组成以下:github
canvas外面套了一个modals,主要目的是让预览图看起来在DOM的最上面canvas
shareCanvas就是咱们要绘制全部内容的画布小程序
modals-cancel-black是一层半透明的蒙层,尽可能将页面的其它元素遮盖到它的下面api
其次就是一个关闭按钮和相应的文字说明微信
<!-- 分享图 -->
<view class="modals" hidden="{{isCanvasHidden}}">
<canvas canvas-id="shareCanvas" class="share-canvas" style="width:680rpx;height:1000rpx" hidden="{{isCanvasHidden}}"></canvas>
<view class="modals-cancel-black"></view>
<view class="cancal-canvas-container" bindtap="hideCanvas">
<image src="http://lc-adna4hf0.cn-n1.lcfile.com/13cb9cd1d79bbed4a47c.png" class="cancel-button"></image>
</view>
<view class="save-album-wrapper text-center">图片已保存到相册,可分享给好友</view>
</view>
复制代码
.modals {
position: fixed;
z-index: 999;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.modals-cancel-black {
position: absolute;
z-index: 1000;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .8);
}
复制代码
从动图能够发现,canvas的绘制是从点击底部模态框的“生成分享图”就开始了
drawShareCanvas: function () {
// 1.计算相对比例rpx
// 2.根据rpx绘制背景图片
// 3.根据rpx绘制微信用户信息部分
// 4.根据rpx绘制小程序码部分
}
复制代码
上述的1-4的步骤之间,可能存在具体的前后关系,能够根据本身的状况来定制前后顺序
wx.getSystemInfo的返回值中能够获得移动端屏幕的具体宽度,小程序WXSS是以rpx做为衡量单位,咱们的canvas宽高都是以rpx计算的宽高。可是canvas绘制时以px为单位绘制。那么咱们须要计算当前设备相对于375px的倍数。
后续的全部关于坐标、长宽或者距离都须要乘以这个rpx倍数,才能达到适配全部倍数。
var rpx = 1
wx.getSystemInfo({
success (res) {
rpx = res.windowWidth / 375
// ...
}
})
复制代码
由于背景图稍微比较大,在绘制时,经过ctx.scale()方法将画布总体都缩放了0.5倍
wx.showLoading({
title: '绘制背景图'
})
wx.getImageInfo({
src: 'http://lc-adna4hf0.cn-n1.lcfile.com/33111f0ba3409c8fdef9.png',
success (res) {
// 隐藏背景图loading
wx.hideLoading()
const ctx = wx.createCanvasContext('shareCanvas')
// 绘制背景图
ctx.scale(0.5, 0.5)
ctx.drawImage(res.path, 0, 0, 680 * rpx, 1000 * rpx)
ctx.stroke()
// 绘制其它
},
fail () {
wx.showToast({
title: '背景图获取失败',
icon: 'none'
})
}
})
复制代码
微信我的图像须要绘制成圆形的,能够用CanvasContext.arc(...)来绘制一个圆弧实现。圆弧会有默认的黑色边框。清除边框使用ctx.setLineWidth(0)。若是须要自定义边框颜色,可使用ctx.setStrokeStyle('red')来设定。
未指定ctx.clip()时,图片不会被裁剪,看到的图片仍是正方形。经过不指定裁剪的方式(注释ctx.clip),能够来精确肯定图像的开始点的位置。图像的开始绘制点位置为:圆心横坐标 - 圆弧的半径 = point - radius
let userinfo = wx.getStorageSync('userinfo')
if (userinfo) {
wx.showLoading({
title: '绘制用户信息',
})
// 绘制我的信息部分
wx.getImageInfo({
src: userinfo.avatarUrl,
success (avatar) {
// 隐藏用户信息loading
wx.hideLoading()
let radius = 50 * rpx
let point = 70 * rpx
ctx.scale(1, 1)
ctx.save()
ctx.beginPath()
ctx.setLineWidth(0)
ctx.arc(point, point, radius, 0, 2 * Math.PI)
ctx.setLineWidth(0)
ctx.closePath()
ctx.save()
ctx.clip()
ctx.drawImage(avatar.path, (point - radius), (point - radius), 100 * rpx, 100 * rpx)
ctx.restore()
},
fail (err) {
wx.showToast({
title: '获取用户头像失败',
icon: 'none'
})
}
})
// 昵称
ctx.setFontSize(32 * rpx)
ctx.setFillStyle('white')
ctx.fillText(userinfo.nickName, 140 * rpx, 60 * rpx)
ctx.stroke()
// 称谓
ctx.setFontSize(24 * rpx)
ctx.setFillStyle('#FEFEFE')
ctx.fillText('尚德学习大使', 140 * rpx, 100 * rpx)
ctx.stroke()
}
复制代码
绘制小程序码
小程序码由于会携带分享着信息,须要经过调用后台接口来动态生成,因此是异步的。能够在生成期间loading给用户返回进度。获得小程序码的url地址后,就能够根据前面的绘制方法,找到小程序码的位置绘制便可。
保存到系统相册
全部绘制步骤完成后,此时还剩两个事情是待作的。1、保存canvas画布内容到系统相册;2、显示预览图。
根据整张图的制做顺序,小程序码是最后一步完成的,因此小程序码绘制到canvas后,算是全部绘制动做完成,须要执行
ctx.draw()
// 下一步?=> 保存图片到相册
saveAlbum()
// 显示预览图
that.setData({
isCanvasHidden: false
})
复制代码
按照上面的方式,咱们执行saveAlbum后发现,在开发工具上,每次都能正常的弹出保存图片。可是在真机上测试时,偶尔会发现预览图已经出来了,可是到系统相册查看,却发现没有生成想要的图片。
经过查看小程序开发文档才知道,wx.canvasToTempFilePath方法须要在ctx.draw的回调中执行(文档地址)。因此,实际得这么干,毕竟人家定义接口的是大爷(嘻嘻)。
ctx.stroke()
ctx.draw(false, () => {
that.saveAlbum()
})
// 这个段也能够放第四行以后
that.setData({
isCanvasHidden: false
})
复制代码
保存到相册的相关代码
saveAlbum() {
var that = this
wx.canvasToTempFilePath({
x: 0,
y: 0,
canvasId: 'shareCanvas',
success: function (res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(saveRes) {
wx.showToast({
title: '保存成功',
icon: 'success'
})
},
fail() {
wx.showToast({
title: '保存失败',
icon: 'none'
})
that.hideCanvas()
}
})
}
})
}
复制代码
不支持mp4预览,转换成gif太大了。
WeChat_20181031180605.mp4
小程序Canvas API: developers.weixin.qq.com/miniprogram…
本篇文章由一文多发平台ArtiPub自动发布