主頁 >  其他 > 小程式中關于紅包雨的實作

小程式中關于紅包雨的實作

2020-09-18 05:19:53 其他

一、原型依據

在我這個專案中小程式端所需要實作的只有紅包雨的下落影片和通屏背景圖的兼容,關于紅包點擊金額的計算是由后端實作的,首先來看下需要實作的效果圖,
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

二、實作代碼

首先是第一次進入的頁面,在這個頁面的時候會進行靜默登錄,靜默登錄成功的話會顯示當前剩余次數,否則在點擊開始的時候回跳轉登錄頁面,不論是否登錄成功都會去呼叫活動資訊監測的介面,判斷當前是否有可以參加的活動,在點擊開始后進行三秒鐘的倒計時,倒計時結束則轉入下一個界面實作紅包雨的下落,

<!--RedEnvelopes/pages/RedEnvelopes/index/index.wxml-->
<nav-bar navbar-data='{{nvabarData}}'></nav-bar>
<view style='padding-top: {{height}}px;' wx:if="{{ready}}">
  <block wx:if="{{!showTime}}">
    <view class="start" bindtap="participateIn" wx:if="{{readyTime != 0}}">
      <view class="start-aperture">
        <view class="start-aperture-bg">
          <text class="start-aperture-txt" wx:if="{{!showTime}}">開始</text>
          <text class="start-aperture-txt" wx:else>{{readyTime}}</text>
        </view>
      </view>
    </view>
  </block>
  <block wx:else>
    <view class="start" wx:if="{{readyTime != 0}}">
      <view class="start-aperture">
        <view class="start-aperture-bg">
          <text class="start-aperture-txt" wx:if="{{!showTime}}">開始</text>
          <text class="start-aperture-txt" wx:else>{{readyTime}}</text>
        </view>
      </view>
    </view>
  </block>
  <view class="remaTimes" wx:if="{{showLogin && !showTime}}">今日剩余次數: {{RemainingTimes}}/{{MaxSharingAwardTimes}}</view>
  <view class="rule" wx:if="{{!showTime}}">
    <view class="rule-top">
      <text class="iconfont iconxiangxia2"></text>
    </view>
    <view class="rule-body">
      <view class="rule-body-one">
        <view class="rule-body-title">規則:</view>
        <view class="rule-body-html">{{ActivityRules}}</view>
      </view>
    </view>
  </view>
</view>
<!-- 紅包雨組件 -->
<block wx:if="{{readyTime == 0}}">
  <sol-packet-rain visible="{{visible}}" createSpeed="{{createSpeed}}" time="{{time}}" min="{{min}}" max="{{max}}" bind:finish="success"></sol-packet-rain>
</block>
// RedEnvelopes/pages/RedEnvelopes/index/index.js
const api = require('../../../../server/api.js');
const http = require('../../../../server/request.js');
const appJs = require('../../../../utils/uselogn.js');
const app = getApp()
let readyTimer = null
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    // 導航頭組件所需的引數
    nvabarData: {
      showCapsule: 1, //是否顯示左上角圖示   1表示顯示    0表示不顯示
      title: '搶紅包', //導航欄 中間的標題
      white: true, // 是就顯示白的,不是就顯示黑的,
      address: api.pictureServer + '/res/shopImg/RedEnvelopes.png' // 加個背景 不加就是沒有
    },
    // 導航頭的高度
    height: app.globalData.height * 2 + 20,
    readyTime: 3,
    showTime: false,
    btnText: '獲取驗證碼',
    phone: '',
    VerificationCode: '',
    unbind: false,
    showLogin: true,
    ready: false,
    tell: '',
    redId: '', //搶紅包活動標識
    BackgroundMap: '', //活動背景圖
    ThemeMap: '', //活動主題圖
    ActivityRules: '', //活動規則
    ShareDescription: '', //分享描述
    ShareIcon: '', //分享圖示
    MaxSharingAwardTimes: '0',
    RemainingTimes: '0'
  },
  onLogin: appJs.userLogin,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    if (options.refer && options.ShareMemberId) {
      let SharedMemberId = wx.getStorageSync('CustomerService').MemberId;
      let parm = {
        Id: options.refer,
        ShareMemberId: options.ShareMemberId,
        SharedMemberId: SharedMemberId
      }
      this.getRedEnvelopeLotteryShare(parm)
      let white = 'nvabarData.white'
      this.setData({
        [white]: false
      })
    }
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {
    this.setData({
      ready: true,
      showTime: false,
      readyTime: 3
    })
    this.onLogin(this.authCallback, this.authCallback1);
  },
  authCallback() {
    let that = this
    // 獲取當前時間搶紅包資訊
    that.getGrabRed();
    that.setData({
      showLogin: true
    })
  },
  authCallback1() {
    let that = this
    // 獲取當前時間搶紅包資訊
    that.getGrabRed();
    that.setData({
      showLogin: false
    })
  },
  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {},

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {

  },
  // 開始準備倒計時
  cultdown: function() {
    let _this = this
    let {
      readyTime
    } = this.data
    readyTimer = setInterval(function() {
      if (--readyTime <= 0) {
        clearInterval(readyTimer)
        // 顯示紅包雨
        _this.run();
      }
      _this.setData({
        readyTime: readyTime
      })
    }, 1000)
  },
  start: function() {
    if (!this.data.showLogin) {
      setTimeout(() => {
        wx.navigateTo({
          url: '/pages/member/loginAndRegister/loginAndRegister',
        })
      }, 500)
      return
    }
    if (this.data.RemainingTimes == 0){
      return
    }
    if (!this.data.showTime) {
      this.cultdown();
      this.setData({
        showTime: true
      })
    }
  },
  run: function() {
    let address = 'nvabarData.address'
    this.setData({
      visible: true,
      createSpeed: 5, // 速度
      time: 10, // 游戲時間
      min: 1, // 金幣最小是0
      max: 1, // 金幣最大是10
      [address]: this.data.ThemeMap || api.pictureServer + '/res/shopImg/RedEnvelopes1.png'
    })
    clearInterval(this.readyTimer);
  },
  // 結束
  success(e) {
    let that = this;
    let redId = this.data.redId;
    console.log('bind:finish', e.detail)
    let RedEnvelopeNum = e.detail;
    // 中獎
    let parm = {
      Id: redId,
      RedEnvelopeNum: RedEnvelopeNum
    }
    http.requestLoading('/api/services/app/RedEnvelope/ExcuteGrabRedEnvelope', parm, '', 'POST').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          visible: false //  隱藏界面
        })
        wx.navigateTo({
          url: '/RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope?Id=' + res.data.Result.Data.Id + '&PartId=' + res.data.Result.Data.PartId + '&ShareDescription=' + that.data.ShareDescription + '&ShareIcon=' + that.data.ShareIcon
        })
      }
    })
  },
  // 立即參與
  participateIn() {
    let that = this;
    let redId = this.data.redId;
    let parm = {
      Id: redId
    }
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeAppSingle', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        if (redId != res.data.Result.Data.Id) {
          wx.showToast({
            title: '當前活動資訊不符',
            icon: 'none'
          })
        } else {
          that.setData({
            redId: res.data.Result.Data.Id
          })
          // 驗證會員是否可以參加該活動
          let parms = {
            Id: res.data.Result.Data.Id,
            RedEnvelopeNum: 0
          }
          if (!this.data.showLogin) {
            setTimeout(() => {
              wx.navigateTo({
                url: '/pages/member/loginAndRegister/loginAndRegister',
              })
            }, 500)
            return
          }
          http.requestLoading('/api/services/app/RedEnvelope/DrawGrabRedEnvelope', parms, '', 'POST').then(res => {
            if (res.data.Result.Code === 0) {
              that.setData({
                ready: true
              })
              that.start();
            }
          })
        }
      }
    })
  },
  // 獲取當前時間搶紅包資訊
  getGrabRed: function(redId) {
    let that = this;
    let address = 'nvabarData.address'
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeAppSingle', {}, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          redId: res.data.Result.Data.Id,
          BackgroundMap: res.data.Result.Data.BackgroundMap,
          ThemeMap: res.data.Result.Data.ThemeMap, //活動主題圖
          ActivityRules: res.data.Result.Data.ActivityRules, //活動規則
          ShareDescription: res.data.Result.Data.ShareDescription, //分享描述
          ShareIcon: res.data.Result.Data.ShareIcon, //分享圖示
          [address]: res.data.Result.Data.BackgroundMap
        })
        if (that.data.showLogin) {
          that.getRemainingTimes();
        }
      }
    })
  },
  // 分享得額外抽獎次數
  getRedEnvelopeLotteryShare(parm) {
    http.requestLoading('/api/services/app/RedEnvelope/RedEnvelopeLotteryShare', parm, '', 'POST').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
      }
    })
  },
  // 獲取總次數
  getRemainingTimes() {
    let that = this;
    let parm = {
      Id: this.data.redId
    }
    http.requestLoading('/api/services/app/RedEnvelope/GetRemainingTimes', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          MaxSharingAwardTimes: res.data.Result.Data.MaxSharingAwardTimes,
          RemainingTimes: res.data.Result.Data.RemainingTimes
        })
      }
    })
  }
})
/* RedEnvelopes/pages/RedEnvelopes/index/index.wxss */
page {
  position: relative;
}

.login {
  width: 626rpx;
  height: 554rpx;
  background: #fff;
  border-radius: 10rpx;
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  margin: auto;
}

.login-center {
  width: 501rpx;
  height: 138rpx;
  border-bottom: 1rpx solid #e2e2e2;
  margin: auto;
  display: flex;
  align-items: center;
}

.userIpt {
  font-size: 28rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #999;
}

.posion {
  position: relative;
}

.zc_view {
  position: absolute;
  right: 0;
  top: 40rpx;
  width: 170rpx;
  height: 52rpx;
  line-height: 52rpx;
  margin-left: 12rpx;
  border: 1rpx solid #e2e2e2;
  text-align: center;
  font-size: 24rpx;
  border-radius: 10rpx;
}

.login-state {
  font-size: 40rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #333;
  text-align: center;
  margin-top: 146rpx;
}

.login-ready {
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #333;
  text-align: center;
  margin-top: 89rpx;
}

.login-btn {
  width: 299rpx;
  height: 74rpx;
  background: #fc7297;
  border-radius: 37rpx;
  box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(3, 0, 6, 0.1);
  margin: auto;
  margin-top: 65rpx;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-txt {
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 500;
  color: #fff;
}

/* 開始按鈕 */

.start {
  position: absolute;
  top: 45%;
  padding: 0 250rpx;
}

.start-aperture {
  width: 250rpx;
  height: 250rpx;
  background: rgb(247, 136, 44, 0.29);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.start-aperture-bg {
  width: 210rpx;
  height: 210rpx;
  background: linear-gradient(0deg, #f0510b 0%, #ffc350 100%);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.start-aperture-txt {
  font-size: 60rpx;
  font-family: Source Han Sans CN Medium, Source Han Sans CN Medium-Medium;
  font-weight: 500;
  color: #fff;
}

/* 規則 */

.rule {
  position: absolute;
  left: 0;
  right: 0;
  top: 73%;
}

.rule-top {
  width: 160rpx;
  height: 36rpx;
  background: rgb(237, 216, 255, 0.4);
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  margin: auto;
  text-align: center;
}

.iconxiangxia2 {
  font-size: 28rpx;
  color: #fff;
}

.rule-body {
  width: 660rpx;
  /* height: 208rpx; */
  background: rgb(237, 216, 255, 0.4);
  border-radius: 20rpx;
  margin: auto;
  padding: 38rpx 0 38rpx 38rpx;
}
.rule-body-one{
  display: flex;
}
.rule-body-title {
  display: inline-block;
  width: 81rpx;
  font-size: 26rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
}

.rule-body-html {
  display: inline-block;
  width: 417rpx;
  font-size: 26rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
}
/* 新 */
.remaTimes{
  position: absolute;
  left: 0;
  right: 0;
  top: 65%;
  font-size: 30rpx;
  font-family: Microsoft YaHei Regular, Microsoft YaHei Regular-Regular;
  font-weight: 400;
  color: #fff;
  text-align: center;
  margin-top: 20rpx;
}

在當前的頁面中引入了兩個組件,第一個是實作自定義導航欄的,因為在當前的界面中背景圖的要求是全屏的,第二個組件就是紅包雨的下落是參考網上一大佬的紅包雨實作的,

//app.js
// 引入請求檔案
App({
  onLaunch: function(e) {
    //獲取設備頂部視窗的高度(不同設備視窗高度不一樣,根據這個來設定自定義導航欄的高度)
    wx.getSystemInfo({
      success: res => {
        this.globalData.height = res.statusBarHeight
      }
    })
    this.getSystemInfo();
  },
  globalData: {
    share: false, // 分享默認為false
    height: 0, // 頂部高度
    systemInfo: {} //設備資訊
  },
  getSystemInfo: function() {
    var info = util.getSystemInfoSync();
    var iphoneX = "";
    if (info) {
      var statusBarHeight = info.statusBarHeight;
      var model = info.model;
      var windowHeight = info.windowHeight;
      var totalTopHeight = 68;
      model.indexOf("iPhone X") !== -1 ?
        ((totalTopHeight = 94), (iphoneX = "iphone-x")) :
        -1 !== model.indexOf("iPhone") ? (totalTopHeight = 64) : -1 !== model.indexOf("MI 8") && (totalTopHeight = 88);
      var titleBarHeight = totalTopHeight - statusBarHeight;
      this.globalData.systemInfo = Object.assign({}, info, {
        statusBarHeight,
        titleBarHeight,
        totalTopHeight,
        iphoneX,
        windowHeight
      })
    }
  }
})

app.js中針對不同的設備的導航條的高度進行了處理,使之能夠實作適配,

<!--componets/shoppingMall-components/navbar/navbar.wxml-->
<view class='nav-wrap' style='height: {{height*2 + 20}}px;'>
  <!-- 導航欄背景圖片 -->
  <image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
  <!-- // 導航欄 中間的標題 -->
  <view class='nav-title' wx:if='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px;'>
    {{navbarData.title}}
  </view>
  <view class='nav-title' wx:else='{{!navbarData.white}}' style='line-height: {{height*2 + 44}}px; color:#ffffff'>
    {{navbarData.title}}
  </view>
  <view style='display: flex; justify-content: space-around;flex-direction: column'>
    <!-- // 導航欄  左上角的回傳按鈕 -->
    <!-- //  其中wx:if='{{navbarData.showCapsule}}' 是控制左上角按鈕的顯示隱藏,首頁不顯示 -->
    <view class='nav-capsule' style='height: {{height*2 + 44}}px;' wx:if='{{navbarData.showCapsule}}'>
      <!-- //左上角的回傳按鈕,wx:if='{{!share}}'空制回傳按鈕顯示 -->
      <!-- //從分享進入小程式時 回傳上一級按鈕不應該存在 -->
      <!-- navbarData.white是控制按鈕顏色的,因為背景有深淺色,回傳按鈕自己找圖片 -->
      <view bindtap='_navback' wx:if='{{showBack}}'>
        <text class="iconfont iconxiangzuo"></text>
      </view>
      <view bindtap='_navbackTo' wx:else>
        <text class="iconfont iconxiaochengxushouye"></text>
      </view>
    </view>
  </view>
</view>
<!-- 導航欄下面的背景圖片 -->
<image class="backgroundimg" src="{{navbarData.address}}" bindload="imgLoaded" style="width:{{imageWidth}}px;height:{{imageHeight}}px" />
// componets/shoppingMall-components/navbar/navbar.js
const app = getApp()
const util = require('../../../utils/indexPage.js');
Component({
  /**
   * 組件的屬性串列
   */
  properties: {
    navbarData: {
      //navbarData   由父頁面傳遞的資料,變數名字自命名
      type: Object,
      value: {},
      observer: function(newVal, oldVal) {}
    }
  },
  options: {
    styleIsolation: 'apply-shared'
  },
  /**
   * 組件的初始資料
   */
  data: {
    height: '',
    //默認值  默認顯示左上角
    navbarData: {
      showCapsule: 1
    },
    imageWidth: wx.getSystemInfoSync().windowWidth, // 背景圖片的高度
    imageHeight: '', // 背景圖片的長度,通過計算獲取
    showBack:false
  },
  attached: function() {
    // 獲取是否是通過分享進入的小程式
    this.setData({
      share: app.globalData.share
    })
    let pages = getCurrentPages();
    if (pages.length > 1){
      this.setData({
        showBack: true
      })
    }
    // 定義導航欄的高度   方便對齊
    this.setData({
      height: app.globalData.height
    })
  },
  /**
   * 組件的方法串列
   */
  methods: {
    // 回傳上一頁面
    _navback() {
      wx.navigateBack()
    },
    _navbackTo(){
      util.indexPage();
    },
    // 計算圖片高度
    imgLoaded(e) {
      // console.log(e, wx.getSystemInfoSync())
      this.setData({
        imageHeight: e.detail.height *
          (wx.getSystemInfoSync().windowHeight / e.detail.height)
      })
    }
    //回傳到首頁
    // _backhome() {
    //   wx.switchTab({
    //     url: '/pages/index/index'
    //   })
    // }
  }
})
/* componets/shoppingMall-components/navbar/navbar.wxss */

/* 頂部要固定定位   標題要居中   自定義按鈕和標題要和右邊微信原生的膠囊上下對齊 */

.nav-wrap {
  /* display: none; */
  position: fixed;
  width: 100%;
  top: 0;
  background: #fff;
  color: #000;
  z-index: 9999999;
  background: #000;
  overflow: hidden;
}

/* 背景圖 */

.backgroundimg {
  position: absolute;
  z-index: -1;
}

/* 標題要居中 */

.nav-title {
  position: absolute;
  text-align: center;
  max-width: 400rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  font-size: 36rpx;
  color: #2c2b2b;
  font-weight: 450;
}

.nav-capsule {
  display: flex;
  align-items: center;
  margin-left: 30rpx;
  width: 140rpx;
  justify-content: space-between;
  height: 100%;
}

.back-pre {
  width: 36rpx;
  height: 40rpx;
  margin-top: 4rpx;
  padding: 10rpx;
}

.nav-capsule {
  width: 36rpx;
  height: 40rpx;
  margin-top: 3rpx;
}

.iconxiangzuo{
  font-size: 41rpx;
  color: #fff;
}

.iconxiaochengxushouye {
  font-size: 41rpx;
  color: #fff;
}

在自定義導航欄中針對不同的進入情況對左上角的按鈕做不同的處理,當是通過掃碼或分享進入的時候左上角是回傳首頁的小房子,通過其他頁面跳轉過來時則是回傳上一級的箭頭,

<view wx:if="{{visible}}" class="red-envelope-popup">
  <view class="container flex-center">
    <view bind:tap="handleClose" catch:touchmove="handleScrollTouch" class="close-bg"></view>
    <block>
      <block wx:if="{{showStatus===2}}">
        <view class="rain-wrapper flex-column">

          <view class="canvas-wrapper">
            <view class='score-change' animation="{{scoreAni}}">
              +{{showChangeScore}}
            </view>
            <canvas disableScroll binderror="canvasIdErrorCallback" bindtouchstart="handleClickRain" canvasId="rain-canvas" style="width: 100vw; height: 100vh;z-index: 9999999;"></canvas>
          </view>
        </view>
      </block>
      <block wx:if="{{showStatus===3}}">
        <view class="result-wrapper flex-column-center">
          <block>
            <view class="group-content flex-column-center" bindtap="handleClose">
              
            </view>
          </block>
        </view>
      </block>
    </block>
  </view>
</view>
const innerAudioContext = wx.createInnerAudioContext()
const api = require('../../../server/api.js');
const APP = getApp()
let readyTimer = null
let rainTimer = null
let redEnvelopes = []
let animation = null
const minWidth = 30 // 紅包圖片最小寬度
const maxWidth = 40 // 紅包圖片最大寬度
Component({
  properties: {
    // 是否開始展示游戲
    visible: {
      type: Boolean,
      value: false
    },
    // 游戲時間
    time: {
      type: Number,
      value: 10
    },
    //  速度
    createSpeed: {
      type: Number,
      value: 5
    },
    // 單個最小金額
    min: {
      type: Number,
      value: 0
    },
    // 單個最大金額
    max: {
      type: Number,
      value: 3
    }
  },
  data: {
    showRainTotalTime: 10, // 紅包雨時間
    showStatus: 1, // 紅包雨狀態:1:準備倒計時,2:正在紅包雨,3:紅包雨結束
    windowWidth: 375,
    windowHeight: 555,
    rainResult: {},
    loading: false,
    showScore: 0,
    showChangeScore: 0,
    scoreStyle: ''
  },
  ready: function() {
    // 重置
    redEnvelopes = []
    // clearTimeout(readyTimer) 
    clearTimeout(rainTimer)
    this.cancelCustomAnimationFrame(animation)
    // 開始準備倒計時
    this.showRain()
    const {
      windowWidth,
      windowHeight
    } = APP.globalData.systemInfo
    this.data.windowWidth = windowWidth
    this.data.windowWidth = windowHeight
  },
  detached: function() {
    // readyTimer && clearInterval(readyTimer)
    rainTimer && clearInterval(rainTimer)
    animation && this.cancelCustomAnimationFrame(animation)
  },
  methods: {
    // 展示紅包雨界面
    showRain: function() {
      let _this = this
      // 顯示紅包雨
      this.setData({
        showStatus: 2
      })
      // 初始化紅包雨
      this.initRain()

      // 倒計時進度條
      this.ininProgress()
      // 紅包雨倒計時
      let showRainTotalTime = this.data.time
      rainTimer = setInterval(function() {
        if (--showRainTotalTime <= 0) {
          clearInterval(rainTimer)
          if (animation) {
            // 結束
            _this.showRainResult()
            _this.cancelCustomAnimationFrame(animation)
          }
        }
        _this.setData({
          showRainTotalTime
        });
      }, 1000);
    },
    // 倒計時進度條
    ininProgress() {
      const {
        time
      } = this.data
      const animation = wx.createAnimation({
        duration: time * 1000
      })
      animation.translateX(-120).step()
      this.setData({
        progressAni: animation.export()
      })
    },
    //分數影片
    animationOfScore(x, y) {
      const position = wx.createAnimation({
        duration: 0
      })
      position.left(x).top(y).step()
      this.setData({
        scoreAni: position.export()
      })
      const animation = wx.createAnimation({
        duration: 300,
        timingFunction: 'ease'
      })
      animation.opacity(1).step()
      setTimeout(function() {
        animation.opacity(0).step()
        this.setData({
          scoreAni: animation.export()
        })
      }.bind(this), 10)
    },
    // 關閉
    handleClose: function() {
      this.triggerEvent("finish", this.data.showScore)
    },
    // 顯示結果
    showRainResult: function() {
      // 結束影片
      this.cancelCustomAnimationFrame(animation)
      this.setData({
        showStatus: 3,
        rainResult: {
          amount: 100
        }
      });
    },
    // 紅包下落函式
    customRequestAnimationFrame: function(e) {
      let _this = this
      let timer = setTimeout(function() {
        e.call(_this), clearTimeout(timer);
      }, 1000 / 60)
      return timer
    },
    // 清除紅包下落函式
    cancelCustomAnimationFrame: function(e) {
      e && (clearTimeout(e), animation = null)
    },
    // 開始下落
    doDrawRain: function() {
      const context = this.context
      const {
        windowWidth,
        windowHeight
      } = this.data
      context.clearRect(0, 0, windowWidth, windowHeight)
      for (let n = 0; n < redEnvelopes.length; n += 1) {
        const i = redEnvelopes[n] // 紅包
        const {
          x,
          y,
          vx,
          vy,
          width,
          height,
          open
        } = i
        const img = open ? this.openEnvelopeImg : this.redEnvelopeImg
        const imgWidth = open ? width + 20 : width
        const imgHeight = open ? height + 25 : height
        if (x < 0) {
          x += 50;
        } else if (x > 750) {
          x -= 50;
        }
        context.drawImage(img, x, y, imgWidth, imgHeight)
        i.x += vx
        i.y += vy
        i.y >= windowHeight && (i.y = 0, i.open = false)
        i.x + width <= 0 && (i.x = windowWidth - width, i.open = false)
      }
      context.draw()
      // 下落函式
      animation = this.customRequestAnimationFrame(this.doDrawRain);
    },
    // 亂數
    randNum: function(min, max) {
      return Math.floor(min + Math.random() * (max - min));
    },
    // 準備紅包雨下落
    initRainDrops: function() {
      const {
        windowWidth,
        windowHeight,
        createSpeed,
        max,
        min
      } = this.data
      for (let n = 0; n < 10; n += 1) {
        const startX = Math.floor(Math.random() * windowWidth)
        // 優化位置,防止紅包越界現象,保證每個紅包都在螢屏之內
        if (startX < 0) {
          startX += 50;
        } else if (startX > windowWidth) {
          startX -= 50;
        }
        const startY = Math.floor(Math.random() * windowHeight)
        // 紅包圖片寬度大小30~40
        const width = this.randNum(minWidth, maxWidth)
        // 寬度為紅包高度的百分之八十
        const height = Math.floor(width / .8)
        // 速度
        const vy = 1 * Math.random() + createSpeed
        // 紅包金額
        const score = this.randNum(min, max + 1)
        redEnvelopes.push({
          x: startX,
          y: startY,
          vx: -1, // x軸速度
          vy: vy, // y軸速度
          score: score,
          width: width,
          height: height,
          open: false
        });
      }
      this.doDrawRain();
    },
    // 點擊紅包事件
    handleClickRain: function(e) {
      let touch = e.touches[0]
      let touchX = touch.x
      let touchY = touch.y
      let _this = this
      for (let o = 0; o < redEnvelopes.length; o += 1) {
        let i = redEnvelopes[o],
          rainX = i.x,
          rainY = i.y,
          width = i.width,
          height = i.height,
          gapX = touchX - rainX,
          gapY = touchY - rainY;
        if (gapX >= -20 && gapX <= width + 20 && gapY >= -20 && gapY <= height + 20) {
          _this.animationOfScore(touchX, touchY)
          innerAudioContext.play()
          i.open = true;
          let score = _this.data.showScore + i.score
          _this.setData({
            showScore: score,
            showChangeScore: i.score
          })
          break;
        }
      }
    },
    // 初始化 canvas
    initRain: function() {
      this.context = wx.createCanvasContext("rain-canvas", this)
      this.redEnvelopeImg = "./images/red-packet-rain.png",
        this.openEnvelopeImg = "./images/red-packet-rain-open.png"
      // 初始化紅包雨
      this.initRainDrops()
      // 音效
      this.audioOfClick()
    },
    handleScrollTouch: function() {},
    audioOfClick() {
      innerAudioContext.autoplay = false
      innerAudioContext.src = 'https://imgs.solui.cn/weapp/dianji.mp3'
      innerAudioContext.onPlay(() => {})
      innerAudioContext.onError(res => {})
    },
  }
});
.flex {
  display: -ms-flexbox;
  display: flex
}
.flex-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center;
  width: 100%;
  height: 100%
}
.flex-column {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column
}
.flex-column-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center
}
.flex-column-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-column-c {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-row {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center
}
.flex-row-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  width: 100%
}
.flex-content-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: center;
  justify-content: center;
  width: 100%
}
.flex-column-right {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: end;
  align-items: flex-end
}
.flex-column-left {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-direction: column;
  flex-direction: column;
  -ms-flex-align: start;
  align-items: flex-start
}
.flex-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-sa {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: distribute;
  justify-content: space-around
}
.flex-c {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-sb-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: start;
  justify-content: flex-start
}
.flex-end {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: end;
  justify-content: flex-end
}
.flex-center-end {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  -ms-flex-pack: end;
  justify-content: flex-end
}
.flex-end-center {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end;
  -ms-flex-pack: center;
  justify-content: center
}
.flex-end-sb {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end;
  -ms-flex-pack: justify;
  justify-content: space-between
}
.flex-end-start {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: end;
  align-items: flex-end
}
.red-envelope-popup {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 999;
  /* background: rgba(0,0,0,.8) */
}
.red-envelope-popup .close-bg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0
}
.red-envelope-popup .reminder-wrapper {
  position: relative;
  width: 750rpx;
  height: 716rpx;
  color: #fff;
  box-sizing: border-box
}
.red-envelope-popup .reminder-wrapper .title {
  font-size: 60rpx;
  color: #fffdc5
}
.red-envelope-popup .reminder-wrapper .time {
  margin-top: 100rpx;
  font-size: 240rpx;
  color: #fffdc5
}
.red-envelope-popup .rain-wrapper {
  /* width: 100%; */
  /* height: 100%; */
  /* background-image: url(https://imgs.solui.cn/weapp/redBacketBG.jpg); */
  /* background-size: 100% 100%; */
  /* background-repeat: no-repeat */
}
.red-envelope-popup .rain-wrapper .time-info {
  position: absolute;
  top: 80rpx;
  left: 45rpx;
  font-size: 24rpx;
  color: #fff
}
.red-envelope-popup .rain-wrapper .time-info .progress-wrapper {
  position: relative;
  height: 16rpx;
  width: 240rpx;
  margin-left: 20rpx;
  margin-right: 20rpx;
  border-radius: 16rpx;
  background: #fff;
  overflow: hidden
}
.red-envelope-popup .rain-wrapper .time-info .progress-wrapper .progress {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 240rpx;
  border-radius: 16rpx;
  background: #fe2e00;
  z-index: 1
}
.red-envelope-popup .rain-wrapper .time-info .total-score {
  font-size: 40rpx
}
.red-envelope-popup .rain-wrapper .canvas-wrapper {
  position: relative
}
.red-envelope-popup .rain-wrapper .canvas-wrapper .score-change {
  position: absolute;
  width: 50rpx;
  height: 50rpx;
  font-size: 40rpx;
  color: #fffdc5;
  opacity: 0
}
.red-envelope-popup .result-wrapper {
  width: 100%;
  height: 100%;
  display: -ms-flexbox;
  display: flex;
  -ms-flex-pack: center;
  justify-content: center
}
.red-envelope-popup .result-wrapper .group-content {
  position: relative;
  width: 550rpx;
  height: 700rpx;
  /* background-image: url(https://imgs.solui.cn/weapp/l-rain-gold@2x.png); */
  background-image: url(http://hmspimg.afarsoft.com/static/crmmicroapp/res/shopImg/Demolition.png);
  background-size: 100% 100%;
  background-repeat: no-repeat
}
.red-envelope-popup .result-wrapper .group-content .result-title {
  margin-top: 50rpx;
  font-size: 40rpx;
  color: #fff
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper {
  margin-top: 56rpx;
  color: #fff
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper .money {
  font-size: 120rpx
}
.red-envelope-popup .result-wrapper .group-content .money-wrapper .unit {
  position: relative;
  top: 34rpx;
  font-size: 32rpx
}
.red-envelope-popup .result-wrapper .group-content .result-btn {
  margin-top: 158rpx;
  width: 300rpx;
  height: 70rpx;
  background-color: #fff9e8;
  text-align: center;
  line-height: 70rpx;
  border-radius: 40rpx;
  font-size: 30rpx;
  color: #b10000
}

在這個組件中,在attached這個生命周期的時候進是紅包下落的方法開始執行,在創建紅包橫向坐標的時候需要對坐標進行優化防止紅包出現在螢屏外,

<!--RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.wxml-->
<view wx:if="{{showMode}}">
  <image src="{{url}}" class="winning"></image>
  <view class="congratulations" wx:if="{{NotWinning}}">很遺憾!</view>
  <view class="congratulations" wx:else>恭喜您!</view>
  <view class="prize" wx:if="{{NotWinning}}">您本次沒有中獎,</view>
  <view class="prize" wx:else>您一共獲得<block wx:if="{{RedEnvelope.AmountCount}}">{{RedEnvelope.AmountCount}}個紅包</block><block wx:if="{{RedEnvelope.AmountCount && RedEnvelope.CouponCount}}">,</block><block wx:if="{{RedEnvelope.CouponCount}}">{{RedEnvelope.CouponCount}}張優惠券</block></view>
  <block wx:for="{{RedEnvelope.CouponWinInfoList}}" wx:key="index">
    <view class="prize-details">
      <view class="prize-quan">
        <image src="{{quan}}" class="quan"></image>
        <text class="quan-txt" wx:if="{{item.UseType == 0}}">{{item.DiscountAmount}}元</text>
        <text class="quan-txt" wx:else>{{item.DiscountRate}}折</text>
        <text class="quan-type coupon">優惠券</text>
      </view>
      <view class="prize-name">{{item.CouponName}}</view>
      <view class="prize-num">數量:{{item.Num}}</view>
    </view>
  </block>
  <block wx:for="{{RedEnvelope.AmountWinInfoList}}" wx:key="index">
    <view class="prize-details">
      <view class="prize-quan">
        <image src="{{quan}}" class="quan"></image>
        <text class="quan-txt">{{item.RedEnvelopeAmount}}元</text>
        <text class="quan-type cash">現金</text>
      </view>
      <view class="prize-name">{{item.RedEnvelopeAmount}}元現金紅包</view>
      <view class="prize-num">數量:{{item.Num}}</view>
    </view>
  </block>
  <view class="share">
    <view class="share-left">邀請好友參加活動</view>
    <view class="share-left lower">每天可獲得
      <text class="share-num" wx:if="{{NotWinning}}">{{MaxSharingAwardTimes}}次</text>
      <text class="share-num" wx:else>{{RedEnvelope.MaxSharingAwardTimes}}次</text>分享獎勵</view>
    <button class="share-btn" open-type="share">
      <text class="share-txt">去分享</text>
    </button>
  </view>
</view>
// RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.js
const api = require('../../../../server/api.js');
const http = require('../../../../server/request.js');
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    url: api.pictureServer + '/res/shopImg/winning.png',
    quan: api.pictureServer + '/res/shopImg/redCoupon.png',
    Id: '', //搶紅包活動標識
    PartId: '', //搶紅包參與資訊標識
    RedEnvelope: {},
    ShareDescription: '', //分享描述
    ShareIcon: '', //分享圖示
    NotWinning: true, //未中獎
    showMode: false
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    console.log(options)
    this.setData({
      Id: options.Id,
      PartId: options.PartId,
      ShareDescription: options.ShareDescription,
      ShareIcon: options.ShareIcon,
    })
    let parm = {
      Id: options.Id,
      PartId: options.PartId
    }
    this.getGrabRedEnvelopeWinInfo(parm);
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {
    let ShareMemberId = wx.getStorageSync('CustomerService').MemberId
    return {
      title: this.data.ShareDescription,
      // desc: '快來搶紅包雨',
      imageUrl: this.data.ShareIcon,
      path: '/RedEnvelopes/pages/RedEnvelopes/index/index?refer=' + this.data.Id + '&ShareMemberId=' + ShareMemberId,
      success: function(res) {
        // 轉發成功
        wx.showToast({
          title: '分享成功',
          icon: 'none'
        })
      },
      fail: function(res) {
        // 轉發失敗
      }
    }
  },
  // 拆開紅包得到中獎資訊
  getGrabRedEnvelopeWinInfo: function(parm) {
    let that = this;
    http.requestLoading('/api/services/app/RedEnvelope/GetGrabRedEnvelopeWinInfo', parm, '', 'GET').then(res => {
      if (res.data.Result.Code === 0) {
        console.log(res)
        that.setData({
          NotWinning: false,
          RedEnvelope: res.data.Result.Data,
          showMode: true
        })
      } else if (res.data.Result.Code === 1) {
        //未中獎
        that.setData({
          NotWinning: true,
          MaxSharingAwardTimes: res.data.Result.Data.MaxSharingAwardTimes,
          showMode: true
        })
      }
    })
  }
})
/* RedEnvelopes/pages/RedEnvelopes/WinningRedEnvelope/WinningRedEnvelope.wxss */
page {
  width: 100%;
  background: rgb(254, 177, 198, 0.2);
}
/* 禮品 */
.winning {
  width: 286rpx;
  height: 294rpx;
  display: block;
  margin: 20rpx auto;
}

.congratulations {
  font-size: 46rpx;
  font-family: Adobe Heiti Std R, Adobe Heiti Std R-R;
  color: #ff3005;
  text-align: center;
}

.prize {
  font-size: 28rpx;
  font-family: Adobe Heiti Std R, Adobe Heiti Std R-R;
  color: #fc7297;
  text-align: center;
  margin: 38rpx auto;
}
/* 獎勵內容 */
.prize-details {
  width: 668rpx;
  height: 150rpx;
  background: #fff;
  border-radius: 10rpx;
  display: block;
  margin: auto;
  padding: 38rpx 0 38rpx 38rpx;
  margin-bottom: 20rpx;
  position: relative;
}

.prize-quan {
  width: 177rpx;
  position: relative;
}

.quan {
  width: 177rpx;
  height: 74rpx;
}

.quan-txt {
  position: absolute;
  top: 20rpx;
  left: 30rpx;
  font-size: 28rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #fff;
}

.quan-type {
  width: 19rpx;
  font-size: 20rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  text-align: left;
  color: #fff;
  line-height: 22rpx;
}

.coupon {
  position: absolute;
  top: 7rpx;
  right: 16rpx;
  height: 63rpx;
}

.cash {
  position: absolute;
  top: 15rpx;
  right: 16rpx;
  height: 39rpx;
}

.prize-name {
  font-size: 30rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #333;
  position: absolute;
  top: 37rpx;
  left: 244rpx;
}

.prize-num {
  font-size: 24rpx;
  font-family: Source Han Sans CN Regular, Source Han Sans CN Regular-Regular;
  font-weight: 400;
  color: #333;
  position: absolute;
  top: 86rpx;
  left: 244rpx;
}
/* 分享 */
.share {
  width: 668rpx;
  height: 150rpx;
  background: #f77b7b;
  border-radius: 10rpx;
  margin: 40rpx auto;
  position: relative;
}

.share-left {
  font-size: 30rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  color: #fff;
  position: absolute;
  top: 32rpx;
  left: 47rpx;
}

.lower {
  position: absolute;
  top: 73rpx;
  left: 47rpx;
}

.share-num {
  font-size: 38rpx;
}

.share-btn {
  width: 170rpx;
  height: 49rpx;
  background: linear-gradient(0deg, #fa8d35 0%, #ffc341 100%);
  border-radius: 25rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 55rpx;
  right: 35rpx;
}

.share-txt {
  font-size: 30rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 500;
  color: #fff;
}

在查看紅包界面中沒有太多需要主要的東西,主要實作分享即可,

<!--RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.wxml-->
<wxs module="func">
  module.exports = {
    strSplit: function(str, con) {
      return str.split(con);
    }
  }
</wxs>
<view>
  <view class="calendar_container container">
    <view class="select" bindtap="dateClick">
      <view>{{showStartDate||showEndDate?showStartDate+'-'+showEndDate:'全部'}}</view>
    </view>
    <i class="iconfont iconrili" bindtap="dateClick"></i>
  </view>
  <view class="container">
    <block wx:for="{{DrawRecordlist}}" wx:key="{{index}}">
      <view class="DrawRecordItem">
        <view class="item0">
          <view class="item_txt">{{item.CreateTime}}</view>
        </view>
        <view class="item1">
          <block wx:for="{{item.HongBaoWinningRecordList}}" wx:key="{{index}}">
            <view class="item_txt dib mr-5">{{item.RedEnvelopeAmount}}元紅包
              <text class="lookCode lookCodes">X{{item.HongBaoNum}}</text>
            </view>
          </block>
          <block wx:for="{{item.CouponWinningRecordList}}" wx:key="{{index}}">
            <view class="item_txt dib mr-5">{{item.CouponName}}
              <text class="lookCode">X{{item.CouponNum}}</text>
            </view>
          </block>
        </view>
      </view>
    </block>
  </view>
  <CalendarComponent id="calendar-component" startDate="{{startDate}}" endDate="{{endDate}}" bind:myevent="getDate"></CalendarComponent>
</view>
// RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.js
// 引入URL
const http = require('../../../../server/request.js');
//呼叫公共js物件以便呼叫其方法
var app = require('../../../../utils/uselogn.js'); //獲取應用實體
var util = require('../../../../utils/util.js') //公用方法
const api = require('../../../../server/api.js');
var pageNum = 1;
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    //組件資料
    componentData: null,
    // 僅支持 年-月-1
    startDate: "1960/1/1",
    endDate: new Date().getFullYear() + "/" + (new Date().getMonth() + 1) + "/" + new Date().getDate(),
    pictureServer: api.pictureServer,
    tabIndex: 0,
    skinStyle: "",
    userDaysAward: [], //用戶簽到獎勵
    signInReward: [], //連續簽到獎勵
    showStartDate: "", //顯示用的
    showEndDate: "", //顯示用的
    time1: "",
    time2: "",
    DrawRecordlist: [],
    ActivityId: ""
  },
  onLogin: app.userLogin,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function(options) {
    pageNum = 1;
    //創建自定義組件實體
    this.setData({
      componentData: this.selectComponent('#calendar-component')
    })
    this.setData({
      skinStyle: wx.getStorageSync("skin")
    })
    if (options.ActivityId) {
      this.setData({
        ActivityId: options.ActivityId
      })
    }
    this.onLogin(this.callback)

  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function() {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function() {},

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function() {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function() {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function() {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function() {
    pageNum++;
    this.getLotteryRecord();
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function() {

  },
  callback() {
    this.getLotteryRecord(this.data.time1,
      this.data.time2)
  },
  /**
   * tab切換
   */
  //獲取會員的中獎紀錄資訊
  getLotteryRecord(s, e) {
    http.requestLoading("/api/services/app/RedEnvelope/MemberWinningRecord", {
      "StartDate": s ? s + " 00:00:00" : '',
      "EndDate": e ? e + " 23:59:59" : '',
      "page": pageNum,
      "rows": 10
    }, "", "POST").then(res => {
      if (res.data.Result.Code === 0) {
        if (!res.data.Result.Rows) {
          wx.showToast({
            title: '無更多資料了',
            icon: "none"
          })
          return
        }
        this.setData({
          DrawRecordlist: this.data.DrawRecordlist.concat(res.data.Result.Rows)
        })
      }
    })
  },
  showClick(e) {
    const {
      index
    } = e.currentTarget.dataset
    const data = this.data.signInReward
    data[index].show = !data[index].show
    this.setData({
      signInReward: data
    })
  },
  //顯示組件
  dateClick() {
    this.data.componentData.createAni()
  },
  //獲取開始結束
  getDate(e) {
    const startDate = e.detail[0]
    const endDate = e.detail[1]
    this.setData({
      showStartDate: startDate.replace(/-/g, '/'),
      showEndDate: endDate ? endDate.replace(/-/g, '/') : "",
      time1: startDate,
      time2: endDate ? endDate : "",
      DrawRecordlist: []
    })
    this.getLotteryRecord(startDate, endDate)
  }
})
/* RedEnvelopes/pages/RedEnvelopes/WinningRecord/WinningRecord.wxss */

page {
  background-color: #f5f6f7;
}

.container {
  padding: 0 40rpx;
  box-sizing: border-box;
}

/* 選擇日歷 */

.calendar_container {
  width: 100%;
  height: 86rpx;
  display: flex;
  align-items: center;
}

.select {
  width: 320rpx;
  height: 58rpx;
  background: #fff;
  border-radius: 10rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #999;
  font-size: 24rpx;
  padding-left: 20rpx;
  padding-right: 10rpx;
}

.iconrili {
  margin-left: 22rpx;
  font-size: 32rpx;
  color: rgba(205, 205, 205, 0.97);
}

.DrawRecordItem {
  margin-top: 16rpx;
  background: #fff;
  border-radius: 10rpx;
}

.item1 {
  padding: 0 22rpx 22rpx 22rpx;
  width: 100%;
  background: #fff;
  border-radius: 10rpx;
}

.lookCode {
  font-size: 24rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 400;
  color: #4ace8c;
}

.lookCodes {
  color: #fc7297;
}

.item0 {
  padding: 0 16rpx 0 26rpx;
  width: 100%;
  height: 66rpx;
  background: #fff;
  border-radius: 10rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.item_txt {
  font-size: 24rpx;
  font-family: Source Han Sans CN Normal, Source Han Sans CN Normal-Normal;
  font-weight: 400;
  color: #666;
}

.mr-5 {
  margin-right: 20rpx;
}

在中獎紀錄查看的頁面中使用的自己封裝的日歷組件,僅是為了復合專案的要求,在此就不做展示了,
紅包雨整個流程到此就結束了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/70950.html

標籤:其他

上一篇:[題解]the moon

下一篇:js 防抖和節流的區別和使用 函式去抖(debounce)函式節流(throttle)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more