文章目录
- 一、文章前言
- 二、实现原理
- 三、开发步骤
- 四、完整代码
- 五、国庆临近,祝祖国永远繁荣昌盛!
一、文章前言
2022年是新中国成立73周年,在这个举国欢庆的日子里,让我们给头像上加上小红旗,迎国庆换新颜,一起为祖国母亲庆生吧!
二、实现原理
使用canvas配合image来实现,将canvas隐藏在所展示的image图片后面,点击保存时将canvas画布上的内容进行绘制并保存图片至手机相册。
三、开发步骤
2.1、创建微信公众平台账号并安装微信Web开发者工具。
2.2、打开开发工具,新建一个项目,因为实现起来不需要服务器也不需要云函数,所以我们这里选择不使用云服务。
2.3、在pages文件夹下面创建一个文件夹并新建对应的page文件。
2.4、在wxml文件绘制两个image以及两个view标签,给两个view增加触摸或者点击事件。
<image class="bg" src="{{bgSrc}}" /><image class="img" src="{{imgSrc}}" /><view catchtap="choose" class="btn1">选择底片图</view><view catchtap="choose1" class="btn1">选择覆盖图</view>
2.5、在js文件中实现对应的绑定事件,将选择的图片在界面上进行展示。
let that= this;wx.chooseImage({success: function (res) {that.bgSrc = res.tempFilePaths[0];that.setData({bgSrc: res.tempFilePaths[0]})}});
2.6、回到wxml文件中,绘制canvas标签。这里要注意的是需要将image标签置于canvas标签上面,通过css样式中的z-index和position属性值来实现,如果将canvas画布置于顶层的话,那我们就无法直观的预览上传图片之后的效果,用户也能够直接在这个画布上操作涂画,这对我们最终导出的海报图片影响是很大的。
<canvas class="myCanvas" canvas-id="myCanvas" style="width: 375px; height: 375px;"></canvas>
2.7、在wxml文件中绘制view标签,增加触摸或点击事件,给用户提供保存海报的入口。
<view catchtap="saveImg" class="btn2">保存海报</view>
2.8、js文件在保存海报的响应事件中,我们需要提前向用户发起请求,以此来询问用户是否同意授权小程序能否将图片保存至手机的权限,如果用户之前已经同意授权,则不会出现授权弹窗,会直接进入成功的回调。
wx.getSetting({success(res) {if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success() {that.saveImageFunction();}});} else {that.saveImageFunction();}}});
2.9、实现saveImageFunction()函数,该函数的作用是将canvas画布上面的内容进行导出。在处理的时候可以增加一些加载中的动画,增强用户体验。
wx.showLoading({title: '保存中...'});let that= this;const ctx = wx.createCanvasContext('myCanvas');ctx.drawImage(self.bgSrc, 0, 0, 375, 375);ctx.drawImage(self.imgSrc, 1, -20, 175, 175);ctx.draw(false, function (e) {// 保存到本地wx.canvasToTempFilePath({x: 0,y: 0,width: 375,height: 417,canvasId: 'myCanvas',success: function (res) {let pic = res.tempFilePath;wx.saveImageToPhotosAlbum({filePath: pic,success(res) {wx.hideLoading();wx.showToast({title: '保存成功',icon: 'success',duration: 2000});}, fail: function (res) {wx.hideLoading();}});},fail: function (res) {wx.hideLoading();}});});
四、完整代码
<!--index.wxml-->
<view class="content"><view class="show_block"><image class="bg" src="{{bgSrc}}" /><image class="img" src="{{imgSrc}}" /><canvas class="myCanvas" canvas-id="myCanvas" style="width: 375px; height: 375px;"></canvas></view><view style="display: flex;"><view catchtap="choose" class="btn1">选择底片图</view><view catchtap="choose1" class="btn1">选择覆盖图</view><view catchtap="save" class="btn2">保存海报</view></view>
</view>
.content .show_block {position: relative;width: 750rpx;height: 750rpx;
}.content .bg {display: block;width: 100%;height: 100%;
}.content .img {position: absolute;top: -20rpx;left: 1rpx;display: block;width: 350rpx;height: 350rpx;
}.content .myCanvas {z-index: -1;position: absolute;top: 0;left: 0;
}.btn1 {margin-top: 24rpx;margin-left: 50rpx;text-align: center;line-height: 62rpx;font-size: 28rpx;width: 181rpx;height: 62rpx;background: #4FAFF2;border-radius: 10rpx;color: white;
}
.btn2 {margin-top: 24rpx;margin-left: 50rpx;text-align: center;line-height: 62rpx;font-size: 28rpx;width: 181rpx;height: 62rpx;background: #AD302C;border-radius: 10rpx;color: white;
}
choose: function () {let self = this;wx.chooseImage({success: function (res) {self.bgSrc = res.tempFilePaths[0];self.setData({bgSrc: res.tempFilePaths[0]})}});},save: function () {let self = this;if (!this.imgSrc) {wx.showToast({title: '请先选择图片',icon: 'none',duration: 2000});return false;}wx.getSetting({success(res) {if (!res.authSetting['scope.writePhotosAlbum']) {wx.authorize({scope: 'scope.writePhotosAlbum',success() {self.saveImage();}});} else {self.saveImage();}}});},saveImage() {wx.showLoading({title: '保存中...'});let self = this;const ctx = wx.createCanvasContext('myCanvas');ctx.drawImage(self.bgSrc, 0, 0, 375, 375);ctx.drawImage(self.imgSrc, 1, -20, 175, 175);ctx.draw(false, function (e) {// 保存到本地wx.canvasToTempFilePath({x: 0,y: 0,width: 375,height: 417,canvasId: 'myCanvas',success: function (res) {let pic = res.tempFilePath;wx.saveImageToPhotosAlbum({filePath: pic,success(res) {wx.hideLoading();wx.showToast({title: '保存成功',icon: 'success',duration: 2000});}, fail: function (res) {wx.hideLoading();}});},fail: function (res) {wx.hideLoading();}});});}