「喜迎华诞」手把手教你用微信小程序给头像带上小旗帜

一、文章前言

  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();
        }
      });
    });
  }

五、国庆临近,祝祖国永远繁荣昌盛!

猜你喜欢

转载自blog.csdn.net/weixin_42794881/article/details/127123508