最近公司需求做一個微信紅包雨功能,網上搜索到的基本都是用的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就是安卓機上面顯示會卡頓,有沒有大神有好的建議,歡迎指導