css3實現微信小程序紅包雨

最近公司需求做一個微信紅包雨功能,網上搜索到的基本都是用的canvas,對於canvas不是很熟練,於是用css自己寫了一個,這種方式對於蘋果機效果很好,但是在安卓機上會出現卡頓的情況,幾番優化,還是會有一點點卡頓,廢話不多說,上代碼:
wxml:

<view>
	//紅包開始前5秒倒計時
	<view wx:if="{{showBefore}}" class="beforeRain">
		<view bindtap="clearTimer" class="bfText">一大波紅包即將來襲</view>
		<view class="timeing">{{beforeTime}}</view>
	</view>
	//紅包開始下落
	<view wx:if="{{showBegin}}" class="beginRain">
		<view wx:if="{{rainTime>0}}" class="beginText">
			{{pocketNum}}
		</view>
		<view wx:if="{{rainTime>0}}" class="ge">個</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}}" />
					//這裏是設置點擊紅包讓紅包消失,同時通過transition屬性控制紅包下落以及旋轉角度
			</block>
		</view>>
	</view>
	//搶完紅包後展示已搶紅包以及拆紅包
	<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?'次卡':item.type==1?'折扣卡':item.type==2?'充值卡':item.type==10?'滿減券':item.type==11?'代金券':item.type==12?'手氣券':''}}</view>
							</block>
						</view>
					</block>
				</view>
				<view class="text">活動解釋權歸本店所有</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>元</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
  },
  //事件觸發,準備下落,注意images數組裏面的幾個參數,角度以及下落時間,還有延遲下落都是隨機的,下落時間和延遲下落時間都是用ms做單位,不然會出現一波一波的情況,感覺不連貫
	ready: function () {
		this.setData({
			suijiNum:Math.floor(Math.random()*7000)+5000
		})
      this.timer()
    },
	
	methods: {
		closeImg(){
			this.setData({
				showAfter:false
			})
		},
		//拆紅包
		allOpenPoct(e){
			//請求接口
			this.setData({
				ind:e.currentTarget.dataset.ind,
			})
			//拆一個還是全部拆
			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
							}
						}
					}
				},
			})
			//處理數據

			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
			})
		},
		//點擊搶紅包
		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:"您已經搶過3個紅包了",
					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);/*這裏一定是網絡圖片,本地圖片是顯示不出來的*/
  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);/*這裏一定是網絡圖片,本地圖片是顯示不出來的*/
  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;/*這裏是定義動畫的類型,選擇all就行了,但是一定要用transform屬性,這樣頁面性能高,如(height,left,margin)這樣的屬性性能就很低了具體晚上有詳細的教程
  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;
}

以上基本就是這樣,純css實現微信小程序紅包雨,bug就是安卓機上面顯示會卡頓,有沒有大神有好的建議,歡迎指導

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章