现在的小程序红包、优惠劵满天飞,So,老板终于忍不住把产品经理叫了过去,苦逼的我只好摸了摸头,瞬间安心了。
好了,接下来分享个小程序红包(优惠劵)弹窗给大家,效果看我录制的GIF。
- 首先梳理一下我的思路,先是设置一遮罩层悬浮,宽高沾满
- 然后在遮罩层的上一层再设置一个盒子也是悬浮且宽高沾满,里面内容居中的话用弹性布局就好了
- 然后再内容用
catchtouchmove
禁用滚动条,禁用滚动条没必要放到遮罩层,因为内容层已经覆盖它了 - 弄好界面后用hidden来控制弹窗的开关,用bindload监听图片加载后触发开启弹窗方法
- 然后利用CSS的
transform: scale(0);
属性将弹窗缩小到0,即看不见 - 然后再用js的animation动画(点击查看官网API)的scale将其放大到1,即原始大小,从而达到动画的效果
- 最后关闭时设置相反的动画将scale缩小到0后关闭弹窗就好了
wxml:
录制时的弹出红包gif就不给了,因为这是公司的东西,我把gif换成了图片,自己有gif的替换就好。
<view>
<!-- 弹窗遮罩层 -->
<view wx:if="{{isShowCouponPopUp}}" class="popover-mask-layer"></view>
<!-- 优惠劵弹窗 //用hidden而不用wx:if原因是hidden条件不成立时候也会加载图片-->
<view hidden="{{!isShowCouponPopUp}}" class="coupon-pop-up" catchtouchmove="onPreventTouchMove" animation="{{animationData}}">
<view class="body">
<view class="top-images">
<!-- 顶部gif背景图 //监听图片加载完后再开启弹窗-->
<image bindload="openTheCouponPopUp" src="{{topImages}}"></image>
</view>
<view class="mid-coupons">
<view class="content">
<scroll-view scroll-y="true">
<block wx:for="{{couponArr}}" for-index="index" wx:key="index">
<view class="row">
<view class="coupon">
<view class="left">
<image src="{{couponLeftImages}}"></image>
</view>
<view class="mid">
<view>{{item.CouponName}}</view>
<view>{{item.CouponTypeName}}</view>
</view>
<view class="right">
<view>¥<text>{{item.CouponMoney}}</text></view>
<view bindtap="getCoupons" data-index="{{index}}" wx:if="{{!item.HasItBeenClaimed}}" class="unclaimed">领取</view>
<view bindtap="alreadyReceived" wx:if="{{item.HasItBeenClaimed}}" class="already-received">已领取</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
<view class="bottom-get-btn">
<view bindtap="getAllCoupons">全部领取</view>
</view>
</view>
<view class="bottom-close-btn">
<view class="bottom-close-btn-child" bindtap="closeTheCouponPopUp">
<image src="{{closeBtnImages}}"></image>
</view>
</view>
</view>
</view>
</view>
wxss:
wxss需要注意的是.mid-coupons .content scroll-view {max-height: 510rpx;overflow-y: auto;}
这个属性,认真看了GIF的你肯定会发现页面最多可以显示3个item然后第四个就隐藏了,而一个item的高度我设置是170rpx,所以设置510rpx是因为显示4个item以上关闭按钮会超出屏幕(这里屏幕不是特变长是设备),想要放更多个item的话自行修改高度或者把关闭按钮悬浮到右上角就好。
.popover-mask-layer {
height: 100vh;
width: 100vw;
background-color: rgba(0, 0, 0, 0.5);
position: fixed;
top: 0;
z-index: 1002;
}
.coupon-pop-up {
height: 100vh;
width: 100vw;
position: fixed;
top: 0;
z-index: 1003;
display: flex;
justify-content: center;
align-items: center;
transform: scale(0);
}
.coupon-pop-up .body {
width: 650rpx;
}
.coupon-pop-up .top-images {
width: 650rpx;
height: 260rpx;
position: relative;
}
.coupon-pop-up .top-images image {
width: 100%;
height: 100%;
position: relative;
z-index: 1004;
}
.coupon-pop-up .top-images .coupon-bg {
position: absolute;
height: 240rpx;
width: 650rpx;
z-index: 1003;
bottom: 0;
}
.coupon-pop-up .mid-coupons {
width: 650rpx;
background-color: #E41B3F;
border-radius: 0 0 30rpx 30rpx;
padding: 20rpx;
box-sizing: border-box;
box-shadow:-5px 5px 10px -4px #222,5px 5px 10px -4px #222;
}
.mid-coupons .content scroll-view {
max-height: 510rpx;
min-height: 340rpx;
overflow-y: auto;
}
.coupon-pop-up .mid-coupons .row {
height: 170rpx;
padding: 20rpx 20rpx 0 20rpx;
box-sizing: border-box;
}
.mid-coupons .row .coupon {
height: 100%;
background-color: white;
display: flex;
justify-content: space-around;
align-items: center;
}
.mid-coupons .row .coupon .left,
.right {
width: 27%;
display: flex;
justify-content: center;
text-align: center;
border-radius: 50%;
}
.coupon .left image {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.coupon .mid {
width: 48%;
}
.coupon .mid view:first-child {
font-size: 30rpx;
color: black;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.coupon .mid view:last-child {
font-size: 20rpx;
color: #C5C5C5;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 4rpx;
}
.coupon .right {
flex-direction: column;
}
.coupon .right view:first-child {
color: #FF5D42;
font-weight: 700;
}
.coupon .right view:first-child text {
font-size: 50rpx;
}
.coupon .right .unclaimed {
background-color: #FF9327;
color: white;
margin: 10rpx 15rpx;
padding: 2rpx 0 4rpx 0;
font-size: 26rpx;
border-radius: 50rpx;
}
.coupon .right .already-received {
background-color: #E9E7E8;
color: #675D5A;
margin: 10rpx 15rpx;
padding: 2rpx 0 4rpx 0;
font-size: 26rpx;
border-radius: 50rpx;
}
.mid-coupons .bottom-get-btn {
display: flex;
justify-content: center;
align-items: center;
margin: 25rpx 0 20rpx 0;
}
.mid-coupons .bottom-get-btn view {
width: 80%;
height: 80rpx;
border-radius: 80rpx;
text-align: center;
line-height: 80rpx;
background-image: linear-gradient(to bottom, #FFF6D3, #DEB219);
color: #B65023;
}
.coupon-pop-up .bottom-close-btn {
height: 60rpx;
display: flex;
justify-content: center;
align-items: center;
margin-top: 20rpx;
}
.coupon-pop-up .bottom-close-btn-child {
width: 70rpx;
height: 70rpx;
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
}
.bottom-close-btn-child image {
width: 40rpx;
height: 40rpx;
}
.coupon-suspension-window {
position: fixed;
bottom: 300rpx;
right: 20rpx;
width: 70rpx;
height: 70rpx;
}
.coupon-suspension-window image {
width: 70rpx;
height: 70rpx;
}
.shopping-cart-suspension-window {
position: fixed;
bottom: 200rpx;
right: 20rpx;
background-color: white;
box-shadow: 0 0 10rpx #888;
border-radius: 50%;
width: 70rpx;
height: 70rpx;
display: flex;
justify-content: center;
align-items: center;
}
.shopping-cart-suspension-window image {
width: 50rpx;
height: 50rpx;
}
js
js的话我把开启弹窗放到onLoad方法了,根据需求自行放到onReady或onShow也是没问题的
如果animation动画看不懂的话建议上官网或度娘学习一下就好
// pages/coupon/coupon.js
Page({
/**
* 页面的初始数据
*/
data: {
couponArr: [{
CouponName: 'weianl红包',
CouponTypeName: '满30元可用',
CouponMoney: 5,
HasItBeenClaimed: false,
},
{
CouponName: 'weianl红包',
CouponTypeName: '满100元可用',
CouponMoney: 20,
HasItBeenClaimed: false,
},
{
CouponName: 'weianl红包',
CouponTypeName: '满5000元可用',
CouponMoney: 500,
HasItBeenClaimed: false,
},
{
CouponName: 'weianl红包',
CouponTypeName: '满10000元可用',
CouponMoney: 1000,
HasItBeenClaimed: true,
}
],
topImages: 'http://m.qpic.cn/psc?/V14ZaBeY40XWC8/zkoezU7GGNbZGOF.DPhgQVgKh0Fw63ZhFQsd0hetQ8T6CBTPzbnz3dz1WfeDXiG6wY3NwfQcy1Y7Ry49HK1QdM9SKG1QzVXMBdXM0bH80fc!/b&bo=nQLyAJ0C8gADCSw!&rf=viewer_4',
couponLeftImages: 'http://m.qpic.cn/psc?/V14ZaBeY40XWC8/zkoezU7GGNbZGOF.DPhgQXDCLspq1L1upRR.ZiRnZuFvq1XezxpUwmIc4ky9cr0DEpxn.YXOFA15Y03Wwkk2zJSBTVERFZsf3KTl5vSZorE!/b&bo=lgCWAJYAlgADCSw!&rf=viewer_4',
closeBtnImages: 'http://m.qpic.cn/psc?/V14ZaBeY40XWC8/zkoezU7GGNbZGOF.DPhgQZjV2a5npNMM5D47K1jMLBHO3ccXXkEwsTHa*69Gi8pCGkdmz4imEISAR0fRbZj7*malDMMANN7ZzH8oI6XDWDk!/b&bo=QABAAEAAQAADCSw!&rf=viewer_4',
// 是否显示优惠劵弹窗
isShowCouponPopUp: false
},
//阻止弹出层滑动事件,空函数,不做任何处理
onPreventTouchMove: function () {
return false;
},
//打开优惠劵弹窗
openTheCouponPopUp: function () {
var that = this;
setTimeout(() => {
// 先开启优惠劵弹窗
that.setData({
isShowCouponPopUp: true
})
// 设置优惠劵弹窗打开动画
var animation = wx.createAnimation({
duration: 600,
timingFunction: 'ease',
})
that.animation = animation;
animation.scale(1).step();
that.setData({
animationData: animation.export()
})
}, 1000)
},
//关闭优惠劵弹窗
closeTheCouponPopUp: function () {
// 设置优惠劵弹窗关闭动画
var animation = wx.createAnimation({
duration: 300,
timingFunction: 'ease',
})
this.animation = animation;
animation.scale(0).step();
this.setData({
animationData: animation.export(),
})
//执行完动画后再关闭
setTimeout(() => {
this.setData({
isShowCouponPopUp: false
})
}, 200)
},
//领取单个优惠劵
getCoupons: function (e) {
// console.log(e.currentTarget.dataset.index)
var index = e.currentTarget.dataset.index;
var couponArr = this.data.couponArr;
couponArr[index].HasItBeenClaimed = true;
this.setData({
couponArr: couponArr
})
},
//已领取优惠劵
alreadyReceived: function () {
wx.showToast({
title: '已领取,可在卡包查看',
icon: 'none'
})
},
//领取全部优惠劵
getAllCoupons: function () {
var couponArr = this.data.couponArr;
couponArr.forEach((item) => {
item.HasItBeenClaimed = true;
})
this.setData({
couponArr: couponArr
})
wx.showToast({
title: '领取成功,已放入卡包',
icon: 'none'
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
})