【小程序】保存到相册,头像裁圆,文字图片头像定位响应,兼容各种机型,随机背景图完全指南优化篇
上一篇写了大概思路,这一片是代码优化,增加一些解决方案。
https://segmentfault.com/a/11...
功能点(痛点)
- 保存到相册
- 文字定位
- 头像定位(远程图片)
- 背景随机变化(远程图片)
- 定位适应各种机型(兼容)
- 在canvas上面增加按钮 浮层
- 保存到相册失真问题
- canvas 上面覆添加按钮,不能覆盖问题
解决方案
封装常用函数
// 下载图片
export const downLoadImg = (imgurl, msg) => {
return new Promise((resolve, reject) => {
let that = this
// util.showToast(msg + 'download...')
wx.downloadFile({
url: imgurl,
complete: function (res) {
console.log(res)
if (res.statusCode === 200) {
resolve(res.tempFilePath)
} else {
reject(new Error('download fail'))
}
}
})
})
}
export const promiseImage = (url) =>{
return new Promise(function (resolve, reject) {
resolve(url)
})
}
远程图片解决方案
因为是远程图片,需要使用promise 方式加载,不然会出现白屏
// let tempBg = promiseImage('../../images/base.png')
let tempBg = downLoadImg(result.backgroundImage)
let tempAvatarUrl = downLoadImg(userInfo.avatarUrl)
响应式解决方案
根据屏幕尺寸 算出每个屏幕的偏移量,这样在生成和裁剪的时候,都会在任何机型等比缩放,笔记吻合,不至于每个机型位置不同。
const that = this
// 定义海报的原始尺寸
const poster = {"width": 375,"height": 534}
// 设备的信息
const systemInfo = wx.getSystemInfoSync()
let windowWidth = systemInfo.windowWidth
let windowHeight = systemInfo.windowHeight
// 计算后海报的高度
let posterHeight = parseInt((windowWidth / poster.width) * poster.height)
// 匹配每个屏幕偏移量
let widthOffset = windowWidth / poster.width
let heightOffset = posterHeight / poster.height
this.setData({
widthOffset: widthOffset,
heightOffset: heightOffset,
windowWidth: windowWidth,
posterHeight: posterHeight,
})
写入画布
Promise.all([
tempBg, tempAvatarUrl
]).then(res => {
const ctx = wx.createCanvasContext('shareImg')
// 背景
that.drawBg(ctx, res[0])
// 用户头像
that.drawAvatarUrl(ctx, res[1])
// 用户昵称
that.drawText(ctx, userInfo.nickName.slice(0, 4), 12, 76, 184)
// 文字
that.drawText(ctx, result.accuracy, 30, 40, 384,'#EF4545')
ctx.draw(true, function () {
that.generateTempImage()
})
})
//背景
drawBg(ctx, img) {
let { windowWidth, posterHeight } = this.data
ctx.drawImage(img, 0, 0, windowWidth, posterHeight)
ctx.save()
},
//头像
drawAvatarUrl(ctx, img) {
let { widthOffset, heightOffset } = this.data
ctx.beginPath()
ctx.arc(48 * widthOffset, 180 * heightOffset, 16, 0, 2 * Math.PI)
ctx.clip();
ctx.drawImage(img, 30 * widthOffset, 160 * heightOffset, 46, 46, 0, 0)
ctx.restore()
ctx.save()
},
//文字
drawText(ctx, text, fontSize = 14, x, y, color = 'black') {
let { widthOffset, heightOffset } = this.data
ctx.beginPath()
ctx.setFontSize(fontSize)
ctx.setFillStyle(color)
ctx.fillText(text, x * widthOffset, y * heightOffset)
ctx.stroke()
ctx.save()
},
把canvas生成临时的url,方便下面去调用保存到相册
在裁剪的时候,记得把这两个参数(destWidth,destHeight)比原始大小放大两倍,这样保证保存到相册的图片不至于模糊
// 把canvas生成临时的图片
generateTempImage: function () {
var that = this
let { widthOffset, heightOffset } = this.data
wx.showLoading({
title: '努力生成中...'
})
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: 375 * widthOffset,
height: 534 * heightOffset,
destWidth: 750 * widthOffset,
destHeight: 1068 * heightOffset,
canvasId: 'shareImg',
success: function (res) {
that.setData({
prurl: res.tempFilePath,
answerDisplay: true
})
wx.hideLoading()
},
fail: function (res) {
console.log(res)
}
})
},
保存到相册
小程序api 可以直接保存到相册,不过需要临时地址
save: function () {
var that = this
//生产环境时 记得这里要加入获取相册授权的代码
wx.saveImageToPhotosAlbum({
filePath: that.data.prurl,
success(res) {
wx.showToast({
title: '图片已经保存到相册',
icon: 'none',
duration: 1500,
mask: false,
});
},
fail: function (res) {
console.log(res)
}
})
},
如果在生成的画布上面 需要操作按钮
<canvas canvas-id="shareImg" style="width:100%;height:{{posterHeight}}px;">
<cover-view class="answer" bindtap="answer" hover-class="none" hover-stop-propagation="false">
<cover-image class="answer" src="./answer.png"></cover-image>
</cover-view>
</canvas>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。