这篇主要讲canvas绘制以及保存到本地相册的方法
实现功能如下:
1.用户手动输入文字,并把这些文字绘制到canvas中
2.将图片绘制到canvas中
3.将canvas变成图片并保存到本地相册中
效果如图:
第一部分 wxml
<canvas type="2d" id='MyCanvas' style="width:{{widthC}}px;height:{{heightC}}px;" wx:if="{{showCanvas}}"
要注意写这种形式tpye='2d',这是新版本的,旧版本的如下图已经不维护了,所以建议写这种,另外要注意id,不是写canvas-id,而只是id
第二部分 js
第一步,先获取canvas标签
const canvasQuery = wx.createSelectorQuery()
//返回一个对象实例,通过实例可以获取canvas
canvasQuery.select('#MyCanvas')
.fields({
node: true,
size: true,
rect: true
})
.exec(this.CanvasInit.bind(this))
//bind(this)包含了canvas的node,size和rect
第二步,初始化并绘制canvas
const width = res[0].width
this.canvasWidth = width
const height = res[0].height
this.canvasHeight = height
const canvas = res[0].node
this.canvas = canvas
const ctx = canvas.getContext('2d')
//使canvas适应各种屏幕不至于大小不同
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = width * dpr
canvas.height = height * dpr
ctx.scale(dpr, dpr)
//画布背景颜色
ctx.fillStyle = '#fff'
ctx.fillRect(0, 0, width, height)
// 绘制图片 这里要注意drawImage方法中传入的是img对象,而不是img.src
const img = canvas.createImage()
img.src = ImgPath // 可以是本地地址也可以是网络地址
img.onload = () => ctx.drawImage(img, 0, 0, this.widthImg, this.heightImg)
// 绘制文字部分
// console.log(this.widthImg)
ctx.fillStyle = "#000000"
ctx.font = "normal 18px Arial"
ctx.fillText(this.time, 18, this.heightImg + 20)
ctx.fillText(this.wea, 150, this.heightImg + 20)
第三步,获取用户保存图片权限
通过wx.getSetting()来获取用户已经授权过的权限信息。注意如果用户已经授权
过,那么所获取的权限信息里面就会有scope.writePhotosAlbum,即使是没有同意
也会存在scope.writePhotosAlbum,所以不要误以为有scope.writePhotosAlbum
就是一定同意了。还有一个坑的地方就是如果用户第一次授权没有同意,那么之后就
不会再弹出授权对话框,需要自己进行判断。
if (['scope.writePhotosAlbum'] in res.authSetting) {
// 如果授权过且同意了
if (res.authSetting[`scope.writePhotosAlbum`]) {
this.canvasToImgSave()
} else {
wx.showModal({
title: "请求授权相册存储",
content: "需要获取您的相册存储权限,请确认授权",
success: res => {
if (res.confirm) {
wx.openSetting({
success: res => {
this.canvasToImgSave()
console.log(res)
},
fail: err => {
console.log(err)
}
})
} else if (res.cancel) {
console.log("你又取消了")
}
}
})
}
} else {
this.canvasToImgSave()
}
}
第四步,将canvas绘制成图片并保存
这里也有一个小坑,就是在绘制图片的时候会消耗一点时间,因此不能立即就绘制
成功。如果你没有等待绘制成功就直接保存图片的话就会使保存的图片为空白。这时
可以使用wx.showloading来提示用户图片在生成中。
wx.showLoading({
title: '生成中...',
})
wx.canvasToTempFilePath({
canvas: this.canvas,
x: 0,
y: 0,
width: this.canvasWidth * 2,
height: this.canvasHeight * 2,
destWidth: this.canvasWidth * 2,
destHeight: this.canvasHeight * 2,
success: res => {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: res => {
// console.log(this.saveTempFilePath)
wx.showModal({
title: "保存成功!",
content: "图片已保存到本地相册",
showCancel: false,
success(res) {
if (res.confirm) {
wx.reLaunch({
url: '/pages/joinU/joinU'
})
}
}
})
},
fail: err => {
console.log(err)
}
})
},
fail: err => {
console.log(err)
}
})
setTimeout(() => {
wx.hideLoading()
}, 1000)
这么一写下来也没有什么特别难的地方。其实还可以实现用户手动上传图片,这样可能会更有趣一点