需求:
固定在底部的 显示/隐藏 按钮,当它点击时,从底部显示一开始设置了隐藏的 modal 层;然后再点击时隐藏modal 层。主要通过 modalStatus bool变量 来控制,若不用视觉效果只需设置 modalStatus;然而想要视觉效果,则就可以加入 animation 来设置了。
小程序 动画对象 animation
1.创建一个animation对象 ------ wx.createAnimation(Object object)
包含以下属性:
属性 | 类型 | 默认值 | 必填 | 说明 |
---|---|---|---|---|
duration | number | 400 | 否 | 动画持续时间,单位 ms |
timingFunction | string | ‘linear’ | 否 | 动画的效果 |
delay | number | 0 | 否 | 动画延迟时间,单位 ms |
transformOrigin | string | ‘50% 50% 0’ | 否 |
2.导出动画数据给组件的 animation 属性 ------ animation.export()
export 方法每次调用后会清掉之前的动画操作。
示例代码
.xml
<view class="footer_cart" bind:tap="handleModal" hover-class="footer_cart-hover">
点击显示/隐藏
</view>
<view class="modal" wx:if="{{modalStatus}}">
<view class="mask" bind:tap="hideModal"></view>
<!--弹出框 -->
<view animation="{{animationData}}" class="modal_content">
<view class="modal_content_main">
<view class="content_main_top"></view>
<view class="content_main_delAll">
<view class="main_delAll_right" bind:tap="handleDelAll">
<i class="iconfont delete"></i>
<text>清空</text>
</view>
</view>
<scroll-view scroll-y class="content_main_item_wrap">
<view class="content_main_item">
<view class='main_item' wx:for="{{localCartData}}" wx:for-index="index" wx:for-item="item"
wx:key="cat_id">
<image src="{{item.g_small_logo ? item.g_small_logo : '../../images/home_filter.jpg'}}"
mode="cover">
</image>
<!-- 内容 -->
<view class="main_item_right">
<text class="item_right_title">{{item.g_name}}</text>
<text class="item_right_price">¥{{item.g_price}}</text>
</view>
<view class="main_item_btn">
<text bind:tap="handleOperator" data-operator='{{-1}}' data-index="{{index}}">-</text>
<text>{{item.number}}</text>
<text bind:tap="handleOperator" data-operator='{{1}}' data-index="{{index}}">+</text>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
.js
Page({
/**
* 页面的初始数据
*/
data: {
localCartData: [
{
c_id: 1,
g_id: 2,
g_name: "内容11",
g_price: 60,
g_small_logo: null,
number: 1
},
{
c_id: 2,
g_id: 1,
g_name: "内容21",
g_price: 10,
g_small_logo: null,
number: 2
},
{
c_id: 3,
g_id: 2,
g_name: "内容32",
g_price: 15,
g_small_logo: null,
number: 1
},
],
modalStatus: false
},
//
handleModal: function () {
if(!this.data.modalStatus) {
this.showModal();
} else {
this.hideModal();
}
},
// 显示弹出层 且 本地有添加
showModal: function () {
let animation = wx.createAnimation({
duration: 500,
timingFunction: 'linear',
delay: 0
});
this.animation = animation;
animation.translateY(1000).step();
// 显示遮罩层
this.setData({
animationData: animation.export(),
})
setTimeout(() => {
this.setData({
modalStatus: true
})
}, 20)
setTimeout(() => {
animation.translateY(0).step();
this.setData({
animationData: animation.export()
})
}, 20)
},
//隐藏弹出层
hideModal: function () {
// 隐藏遮罩层
let animation = wx.createAnimation({
duration: 500,
timingFunction: 'ease-out',
delay: 0
});
this.animation = animation;
animation.translateY(1000).step();
// 显示遮罩层
this.setData({
animationData: animation.export(),
})
setTimeout(() => {
animation.translateY(0).step();
this.setData({
animationData: animation.export(),
})
}, 20)
setTimeout(() => {
this.setData({
modalStatus: false
})
}, 20)
}
})
.less
.footer_cart {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 80rpx;
color: #fff;
background-color: #474242;
display: flex;
justify-content: center;
align-items: center;
z-index: 2021;
}
.footer_cart-hover{
box-shadow:0px 0px 10px #eee inset;
}
// 弹窗
.modal {
height: 100%;
.mask {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: #000;
opacity: 0.2;
overflow: hidden;
z-index: 2020;
color: #fff;
}
/*对话框 */
.modal_content {
min-height: 220rpx;
max-height: calc(100vh - 200rpx);
width: 100%;
overflow: hidden;
position: fixed;
bottom: 90rpx;
left: 0;
z-index: 2020;
background: #fff;
border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx;
.modal_content_main {
.content_main_top {
height: 30rpx;
background-color: #f60;
}
.content_main_delAll {
margin: 15rpx 30rpx 0;
padding-bottom: 15rpx;
border-bottom: solid 1rpx #f3f0f3;
.main_delAll_right {
display: flex;
align-items: center;
justify-content: flex-end;
}
}
.content_main_item_wrap {
width: 100%;
overflow: hidden;
min-height: 220rpx;
max-height: calc(90vh - 200rpx);
}
.content_main_item {
padding: 20rpx 30rpx;
.main_item {
&:first-child{
padding-top: 0;
}
padding: 20rpx 0;
display: flex;
border-bottom: solid 1rpx #f3f0f3;
image {
width: 160rpx;
height: 160rpx;
}
.main_item_right {
flex: 1;
margin-left: 15rpx;
display: flex;
flex-direction: column;
padding: 10rpx 0;
.item_right_title {
font-size: 34rpx;
}
.item_right_price {
margin-top: 20rpx;
font-size: 32rpx;
color: var(--themeColor);
}
}
.main_item_btn {
display: flex;
justify-content: center;
align-items: center;
text {
display: flex;
justify-content: center;
align-items: center;
width: 40rpx;
height: 40rpx;
border-radius: 50%;
color: #fff;
background-color: var(--themeColor);
&:nth-child(2) {
background-color: #fff;
color: #000;
margin: 0 8rpx;
}
}
}
}
}
}
}
}