刮刮乐微信小程序的记录

一.刮刮乐功能

1.做法

主要是要使用canvas画布去绘制刮奖图层,再监听划动,清除掉绘制的区域,达到某个占比之后直接清空刮奖图层。

首先wxml里面就是常规的设置canvas,需要设置好宽高。注意canvas会盖住其他图层。

<canvas canvas-id='scratchCanvas' id='scratchCanvas' style="width:{{width}}px;height:{{height}}px;" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas>

先在onReady的时候设置一下 wx.createCanvasContext('scratchCanvas'),然后在touchStart跟touchMove的时候设置清空函数eraser。earser中记录划动的时候的点,let x = e.touches[0].x, y = e.touches[0].y,并加上触碰的范围大小,保存到clearPoints数组。

定义了一个scale来控制实现的达到某个比例之后清空图层

if (this.data.clearPoints.length && this.data.r * this.data.r * this.data.clearPoints.length > this.data.scale * this.data.totalArea) {
      this.data.showAward = true;//刮完奖品,是可领奖状态
    }
    this.data.scratchCanvas.clearRect(x1, y1, this.data.r, this.data.r);
    this.data.scratchCanvas.draw(true);
2.遇到的问题
2.1 canvas绘制圆角

canvas需要绘制刮奖图层,最开始使用常规fillRect就可以绘制,

this.data.scratchCanvas.setFillStyle(this.data.maskColor);
this.data.scratchCanvas.fillRect(0, 0, this.data.width, this.data.height);
this.data.scratchCanvas.draw();

但是后来展示需要圆角,那就不能直接使用了,使用arc可以绘制4个边角的圆角,如:

ctx.arc(320/2, 320/2, 320/2, 0, 2 * Math.PI);
2.2 刮奖层使用图片

原先是一个纯色的一个刮奖图层,要使用图片的话,只需要奖fillRect相关的,替换成图片的处理drawImage,再结合圆角需求的处理,如:

    const ctx = wx.createCanvasContext(this.data.canvasId)
    // 图片的x坐标
    let bg_x = 0
    // 图片的y坐标
    let bg_y = 0
    // 图片宽度
    let bg_w = this.data.width
    // 图片高度
    let bg_h = this.data.height
    // 图片圆角
    let bg_r = 10

    ctx.beginPath()
    //ctx.arc(320/2, 320/2, 320/2, 0, 2 * Math.PI);
    ctx.arc(bg_x + bg_r, bg_y + bg_r, bg_r, Math.PI, Math.PI*1.5)
    ctx.arc(bg_x + bg_w - bg_r, bg_y + bg_r, bg_r, Math.PI * 1.5, Math.PI * 2)
    ctx.arc(bg_x + bg_w - bg_r, bg_y + bg_h - bg_r, bg_r, 0, Math.PI * 0.5)
    ctx.arc(bg_x + bg_r, bg_y + bg_h - bg_r, bg_r, Math.PI * 0.5, Math.PI)
    ctx.clip();
    ctx.drawImage('../../images/mask1.png', bg_x, bg_y,  this.data.width, this.data.height)
    // ctx.setFillStyle(this.data.maskColor);
    // ctx.fillRect(0, 0, this.data.width, this.data.height);
    ctx.draw()

本来还想使用filter,开发者工具能生效,但是真机无效,所以没动。 

2.3 canvas层级问题

问题:弹窗点开之后在canvas下层。开发者工具不会,但是真机被盖住了。

解决:这里做的处理是先打开的时候设置了一下canvas的witdh为0,需要注意绘制的时候,要修改为设定的宽度。

3.其他常规逻辑
3.1返回的时候弹出领奖提示

需求是刮中大奖之后需要提交对应的信息的,所以希望退出的时候有二次确认

3.1.1小程序页面返回询问对话框。

使用微信自带API

    wx.enableAlertBeforeUnload({
      message:'跳出当前页面,刮奖记录将不会保存',
    })

出现条件: 

  • 当用户在小程序内非首页页面/最底层页
  • 官方导航栏上的的返回
  • 全屏模式下自绘返回键
  • android 系统 back 键时
3.1.2 领奖信息弹窗关闭时候提示

使用官方的showModal

 wx.showModal({
        content: '您还没领取奖励,确认再刮?',
        confirmText: "确认",
        cancelText: "取消",
        success: (res) => {
          console.log(res);
          //点击“确认”时打开设置页面
          if (res.confirm) {
            console.log('用户点击确认')
            this.init();
          } else {
            console.log('用户点击取消')
          }
        }
      });
3.2 云函数与普通URL的下载处理

功能需要保存图片,在最初未确定如何存储的时候,做了两手准备。

3.2.1 云函数处理

先检测是否有授权打开相册权限,确认后可以打开设置。

    wx.openSetting({
              success: (res) => {

              }
            })

如果打开了直接使用云函数下载,这里的地址需要在wxml文件中设置data-url='xxx'(资源文件的fileID),再使用wx.saveImageToPhotosAlbum下载

    wx.cloud.downloadFile({
      fileID: e.currentTarget.dataset.url,
      success: res => {
        // get temp file path
        console.log(res.tempFilePath)
        wx.saveImageToPhotosAlbum({//保存到本地
          filePath: res.tempFilePath,
          success(res) {
            wx.showToast({
              title: '保存成功',
              icon: 'success',
              duration: 2000
            })
          },
          fail: function (err) {
            if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
              fail && fail();
            }
          }
        })
      },
      fail: err => {
        // handle error
      }
    })
3.2.2 常规的地址下载

使用的是wx.downloadFile。

    wx.downloadFile({
      url: e.currentTarget.dataset.url,       //需要下载的图片url
      success: function (res) {            //成功后的回调函数
        wx.saveImageToPhotosAlbum({         //保存到本地
          filePath: res.tempFilePath,
          success(res) {
            wx.showToast({
              title: '保存成功',
              icon: 'success',
              duration: 2000
            })
          },
          fail: function (err) {
            if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
              fail && fail();
            }
          }
        })
      },
      fail:function(res){
        // fail && fail();
        console.log('resss=',res)
        wx.showToast({
          title: '保存失败',
          icon: 'none',
          duration: 2000
        })
      }
    });
3.3 预览图片

如果刮开的是梗图,那还点击打开还需要大图展示,所以还需要图片预览功能,使用wx.previewImage

    wx.previewImage({
      urls: [url],
      current: 0,
    });
3.4 ‘再刮一次’分享按钮处理
3.4.1 分享按钮

因为目前是包含免费次数以及分享增加次数,所以其中需要有分享按钮。微信小程序需要设置对应的button的open-type属性才可以分享。这里使用了一个button一个view节点来处理2种情况。

            <button class="bottomBtn" open-type="share"  plain="{{true}}" wx:if="{{!canScratch}}" >
                <image  src="../../assets/btn_common_blue.png" mode="scaleToFill" class="btn_img1"/>
                <text>再刮一次</text>
            </button>
            <view class="bottomBtn" bindtap="again" wx:if="{{canScratch}}">
                <image  src="../../assets/btn_common_blue.png" mode="scaleToFill" class="btn_img1"/>
                <text>再刮一次</text>
            </view>

只有有次数的时候才显示view的内容,否则显示open-type为share的button按钮,点击之后拉起分享。

3.4.2 分享按钮记录次数

分享的时候需要记录按钮点击次数以及分享的次数,需要在onShareAppMessage中调用云函数并刷新页面

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值