Red packet rain of wechat applet implemented by css3

Keywords: Android network Attribute

Recently, the company needs to do a wechat red packet rain function. The basic online search is to use canvas, which is not very skilled in canvas, so I wrote one with css. This method works well for apple, but there will be a jam situation on Android. After several optimizations, there will be a little jam, not much nonsense, code:
wxml:

<view>
	//5 seconds before red packet starts
	<view wx:if="{{showBefore}}" class="beforeRain">
		<view bindtap="clearTimer" class="bfText">A wave of red envelopes is coming</view>
		<view class="timeing">{{beforeTime}}</view>
	</view>
	//Red bag begins to fall
	<view wx:if="{{showBegin}}" class="beginRain">
		<view wx:if="{{rainTime>0}}" class="beginText">
			{{pocketNum}}
		</view>
		<view wx:if="{{rainTime>0}}" class="ge">individual</view>
		<view wx:if="{{rainTime>0}}" class="rainTime">00:{{rainTime>9?'':'0'}}{{rainTime}}</view>
		<view class="pocketList">
			<block wx:for="{{imagesList}}" wx:key="index">
				<image wx:if="{{index==idx?false:true}}" 
					bindtap="getPocket" 
					data-idx='{{index}}' 
					class="pocket" 
					style="position:fixed;transform:translateY({{magtop}}px) rotate({{item.tranRota}}deg);left:{{item.magLeft}}rpx;transition:{{item.downTime}}ms linear {{item.delatTime}}ms;" 
					src="{{item.ulr}}" />
					//Here is to set the red packet to disappear after clicking the red packet. At the same time, the red packet drop and rotation angle are controlled through the transition attribute
			</block>
		</view>>
	</view>
	//Show that the red bag has been robbed and removed after the red bag is robbed
	<view wx:if="{{showAfter}}" class="afterCss">
		<view class="bgAllPoct" style="background-image: url({{'https://open.huaximeiyekeji.com/static/img/wx/redpack/bg-gos.png?'+suijiNum}});">
			<view class="allPoct">
				<view class="allbox">
					<block wx:for="{{allPocket}}" wx:for-index="index">
						<view bindtap="{{item.downId==1?'':'allOpenPoct'}}" data-Num="1" data-ind="{{index}}" class="{{item.downId==1?'openPock':'poct'}}" style="transform:rotateY({{item.downId}}turn);background-image:url({{item.imgUrl}});">
							<block wx:if="{{item.imgUrl!='https://open.huaximeiyekeji.com/static/img/wx/redpack/w-open.png'}}">
								<view class="money">¥{{item.money}}</view>
								<view class="mongName">{{item.type==0?'Sub card':item.type==1?'Discount card':item.type==2?'Rechargeable card':item.type==10?'Full and reduced coupon':item.type==11?'Cash coupon':item.type==12?'Air ticket':''}}</view>
							</block>
						</view>
					</block>
				</view>
				<view class="text">The right to explain the event belongs to our store</view>
			</view>
			<image class="allOpen" bindtap="allOpenPoct" data-Num="{{pocketNum}}" src="{{'https://open.huaximeiyekeji.com/static/img/wx/redpack/one-btn.png?'+suijiNum}}"></image>
			<image bindtap="closeImg" class="closeAll" src="./images/close.png"></image>
		</view>
	</view>
	<block wx:if="{{showCont}}">
		<view class="PoctCont">
			<image bindtap="closeImgSm" class="closeSm" src="./images/closed.png"></image>
			<view class="contTextBox">
				<view class="contText" wx:for="{{pocketList}}" wx:key="index">
					<view class="contName">{{item.name}}</view>
					<view class="contMoney"><span style="font-weight: bold;">{{item.mvalue}}</span>element</view>
				</view>
			</view>
		</view>
	</block>
</view>

js:

const app = getApp()  
Component({
	properties:{
		bcstId:Number,
		shopId:Number
	},
	options:{
	    multipleSlots: true
	},
data: {
    items: [],
    currentItem: 0,
    beforeTime:5,
    loanTime:'',
    topList:100,
    showBefore:true,
    showBegin:false,
    showAfter:false,
    rainTime:20,
	allPocket:[],
    minRotate:'',
	pocketImg:'https://open.huaximeiyekeji.com/static/img/wx/redpack/w-open.png',
    pocketNum:0,
    DropPocket0:'',
    maxRotate:'',
    beginLoan:'',
    magtop:0,
	numes:'',
    imagesList:[
      {ulr:'./images/redPacket.png',jiaodu:Math.floor(Math.random()*180)-100,downTime:Math.floor(Math.random()*7000)+5000,delatTime:Math.floor(Math.random()*10000),magLeft:(Math.random()*620)+30,tranRota:Math.floor(Math.random()*360),showPoc:true},
      {ulr:'./images/redPacket.png',jiaodu:Math.floor(Math.random()*180)-100,downTime:Math.floor(Math.random()*7000)+5000,delatTime:Math.floor(Math.random()*10000),magLeft:(Math.random()*620)+30,tranRota:Math.floor(Math.random()*360),showPoc:true},
      {ulr:'./images/redPacket.png',jiaodu:Math.floor(Math.random()*180)-100,downTime:Math.floor(Math.random()*7000)+5000,delatTime:Math.floor(Math.random()*10000),magLeft:(Math.random()*620)+30,tranRota:Math.floor(Math.random()*360),showPoc:true},
	  {ulr:'./images/redPacket.png',jiaodu:Math.floor(Math.random()*180)-100,downTime:Math.floor(Math.random()*7000)+5000,delatTime:Math.floor(Math.random()*10000),magLeft:(Math.random()*620)+30,tranRota:Math.floor(Math.random()*360),showPoc:true},
    ],
    idx:'',
	rotateX3D:0,
	ind:'',
	suijiNum:'',
	getPoctCont:'',
	pocketList:[],
	openNum:1,
	showCont:false
  },
  //Event triggering, prepare for falling. Note that several parameters, angles, falling time and delayed falling in the images array are all random. Falling time and delayed falling time are all in ms. otherwise, there will be wave by wave situations, and the feeling is inconsistent
	ready: function () {
		this.setData({
			suijiNum:Math.floor(Math.random()*7000)+5000
		})
      this.timer()
    },
	
	methods: {
		closeImg(){
			this.setData({
				showAfter:false
			})
		},
		//Dismantle a red envelope
		allOpenPoct(e){
			//Request interface
			this.setData({
				ind:e.currentTarget.dataset.ind,
			})
			//One or all
			if(e.currentTarget.dataset.num==1){
				this.setData({
					numes:1,
				})
			}else{
				this.setData({
					numes:this.data.pocketNum,
				})
			}
			app.get({
				url: 'bo/cc/open',
				login: true,
				data: {
					wxId:app.state.wxuser.id,
					id: this.data.bcstId,
					shopId:this.data.shopId,
					num:this.data.numes
				},
				success: e => {
					if (e.code !== 0) return;
					if(this.data.numes>1){
						for(var i=0;i<e.data.length;i++){
							e.data[i].cc.mvalue = e.data[i].cc.mvalue/100
							this.data.pocketList.push(e.data[i].cc)
						}
						this.setData({
							showCont:true,
							showAfter:false,
							pocketList:this.data.pocketList
						})
						console.log(this.data.pocketList)
					}else{
						this.data.openNum = this.data.openNum+1
						this.data.getPoctCont = e.data[0].cc
						this.data.getPoctCont.mvalue = this.data.getPoctCont.mvalue/100
						this.data.pocketList.push(this.data.getPoctCont)
						this.setData({
							pocketList:this.data.pocketList
						})
						
						console.log(this.data.pocketList)
						for(var i=0;i<this.data.allPocket.length;i++){
							if(this.data.ind==i){
								this.data.allPocket[i].type = this.data.getPoctCont.type
								this.data.allPocket[i].money = this.data.getPoctCont.mvalue
							}
						}
					}
				},
			})
			//Processing data

			for(var i=0;i<this.data.allPocket.length;i++){
				if(i==this.data.ind){
					this.data.allPocket[i].downId = 1
				}
			}
			this.setData({
				allPocket:this.data.allPocket
			})
			setTimeout(()=>{
				for(var n=0;n<this.data.allPocket.length;n++){
					if(n==this.data.ind){
						this.data.allPocket[n].imgUrl = 'https://open.huaximeiyekeji.com/static/img/wx/redpack/get.png?'+this.data.suijiNum
					}
				}
				this.setData({
					allPocket:this.data.allPocket
				})
			},2000)
			if(this.data.openNum==this.data.allPocket.length){
				setTimeout(()=>{
					this.setData({
						showCont:true,
						showAfter:false
					})
				},3000)
			}
			
		},
		closeImgSm(){
			this.setData({
				showCont:false
			})
		},
		//Click to grab red envelopes
		getPocket(e){
			if(this.data.pocketNum<3){
				var jsn ={}
				jsn.downId = 0
				jsn.imgUrl = this.data.pocketImg
				this.data.allPocket.push(jsn)
				this.setData({
				  idx:e.currentTarget.dataset.idx,
				  pocketNum:this.data.pocketNum+1,
				})
				
			}else{
				wx.showToast({
					title:"You've robbed three red envelopes",
					icon:"none"
				})
			}
		  },
		  timer() {
		    let that = this
		    that.data.loanTime = setInterval(function() {
		      if(that.data.beforeTime>0){
		        that.setData({
		          beforeTime: that.data.beforeTime-1
		        })
		      }else{
		        that.clearBeforTimer()
		        that.setData({
		          showBefore:false,
		          showBegin:true
		        })
		        that.beginRain()
		      }
		      
		    }, 1000)
		  },
		  beginRain(){
		    let that = this
		    // for(var i=0;i<that.data.imagesList.length;i++){
		    //   var jsObj = that.data.imagesList[i]
		    //   that.data.imagesList[i].magtop = 1000
        // }
			that.setData({
			  magtop:1200
			})
			console.log(that.data.magtop,"======")
		    // that.setData({
		    //   imagesList:that.data.imagesList
		    // })
		    that.data.beginLoan = setInterval(()=>{
		      if(that.data.rainTime>0){
		        that.setData({
		          rainTime:that.data.rainTime-1
		        })
		      }else{
		        that.clearBeginTimer()
		        that.setData({
		          showBegin:false,
		          showAfter:true,
				  allPocket:that.data.allPocket
		        })
		      }
		    },1000)
		  },
		  afterRain(){
			
		  },
		  clearBeforTimer(){
		     clearInterval(this.data.loanTime)
		  },
		  clearBeginTimer(){
		     clearInterval(this.data.beginLoan)
		  }
	}
	
})

css:

/* pages/index/index.wxss */
.beforeRain{
  height: 100vh;
  width: 100vw;
  position: fixed;
  top: 0;
  left: 0;
  background-color: rgba(0, 0, 0, 0.5);
  color: #FCFED9;
}
.bfText{
  margin-top: 30vh;
  font-size: 60rpx;
  text-align: center;
}
.timeing{
  font-size: 200rpx;
  text-align: center;
}
.beginRain{
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 100vw;

  background-image: url(https://open.huaximeiyekeji.com/static/img/wx/redpack/bg.png); / * this must be a network picture. The local picture cannot be displayed*/
  background-size: 100% 100%;
  background-repeat: no-repeat
}
.beginText{
  width: 88rpx;
  height: 115rpx;
  text-align: center;
  background-image: url(https://open.huaximeiyekeji.com/static/img/wx/redpack/redpack.png); / * this must be a network picture. The local picture cannot be displayed*/
  background-size: 100% 100%;
  background-repeat: no-repeat;
  font-size: 30rpx;
  color: #FCFED9;
  position: fixed;
  right: 20rpx;
  line-height: 70rpx;
  top: 170rpx;
}
.ge{
	font-size: 18rpx;
	font-weight: 200;
	color: #FCFED9;
	right: 28rpx;
	top: 195rpx;
	position: fixed;
	z-index: 1;
}
.rainTime{
	position: fixed;
	right: 20rpx;
	top: 290rpx;
	color: #ffebcd;
	width: 88rpx;
	text-align: center;
	font-size: 30rpx;
}
.pocket{
  height: 100rpx;
  width: 80rpx;
  transition-property:all;/*Here is to define the type of animation, select all It's OK, but it must be used transform Property, so the page performance is high, such as( height,left,margin)This property performance is very low. There are detailed tutorials at night
  transform-origin:50% 50% 0;
}
.pocketList{
  position: fixed;
  top: -250rpx;
}
.allPoct{
	height: 400rpx;
	width: 555rpx;
	position: fixed;
	top: 500rpx;
	left:105rpx;
}
.poct{
	height: 206rpx;
	margin-top: 40rpx;
	width: 162rpx;
	margin-left: 19rpx;
	float: left;
	background-repeat: no-repeat;
	background-size: 100%;
	vertical-align: bottom;
	transition: transform 2s linear;
}
.openPock{
	height: 262rpx;
	width: 162rpx;
	margin-left: 19rpx;
	float: left;
	vertical-align: bottom;
	background-repeat: no-repeat;
	background-size: 100%;
	transition: transform 2s linear;
}
.bgAllPoct{
	width: 708rpx;
	height: 868rpx;
	position: fixed;
	left: 21rpx;
	top: 150rpx;
	background-size: 100% 100%;
	background-repeat: no-repeat;
	z-index: 2;
}
.afterCss{
	width: 100vw;
	height: 100vh;
	position: fixed;
	background-color: rgba(0,0,0,0.4);
	top: 0;
	left: 0;
	z-index: 1;
}
.allOpen{
	width: 440rpx;
	height: 100rpx;
	position: fixed;
	top: 875rpx;
	left:155rpx ;
}
.closeAll{
	height: 56rpx;
	width: 56rpx;
	position: fixed;
	top: 1050rpx;
	left: 347rpx;
}
.text{
	font-size: 21rpx;
	color: #977144;
	text-align: center;
}
.allbox{
	height: 280rpx;
	width: 100%;
}
.money{
	margin-top: 48rpx;
	text-align: center;
	font-size: 24rpx;
	color: #977144;
}
.mongName{
	text-align: center;
	font-size: 20rpx;
	color: #977144;
}
.PoctCont{
	background-image: url('https://open.huaximeiyekeji.com/static/img/wx/redpack/bg-list.png');
	background-repeat: no-repeat;
	background-size: 100%;
	height: 650rpx;
	width: 420rpx;
	position: fixed;
	top: 350rpx;
	left: 165rpx;
}
.closeSm{
	height: 28rpx;
	width: 28rpx;
	margin-left: 20rpx;
	margin-top: 20rpx;
}
.getPoctCont{
	display: flex;
}
.contTextBox{
	margin-top: 150rpx;
}
.contText{
	padding:20rpx;
	display: flex;
	font-size: 24rpx;
	color: #D4870E;
}
.contName{
	flex: 1;
	text-align: left;
}
.contMoney{
	width: 130rpx;
	text-align: right;
}

The above is basically the case. Pure css realizes the red packet rain of wechat applet. The bug is that the Android machine will display a jam. Do you have any good suggestions? Welcome to guide

Published 18 original articles, won praise 1, visited 20000+
Private letter follow

Posted by [Demonoid] on Tue, 17 Mar 2020 08:03:26 -0700