背景
业务需要,游戏中有分组,组和组之间有PK,UI就设计了一个数字翻牌计分的效果图,先看下最终实现:
主要思路是: 将前后两个数字分成上下四个部分,前面的上下部分掌管上下翻动时的动效,后面的主要是显示下一个数字
1,不论是加分还是减分,父元素都要加上 .changing 样式
2,当用户点击加分时:前面数字的下半部分 执行向上翻的动画(给元素加上.up 样式)
2,当用户点击减分时:前面数字的上半部分 执行向下翻的动画(给元素加上.down 样式)
<li class="mini-group-list" v-for="(item,index) in randomGroup" :key="index">
<div class="fraction" :class="{'changing': isReduceFraction || isAddFraction}">
<span class="nextTop">{{item.fraction+ (isReduceFraction?-1: 1)}}</span>
<span class="nextBottom">{{item.fraction+ (isReduceFraction?-1: 1)}}</span>
<span :ref="`currentTop${item.id}`" class="currentTop">{{item.fraction}}</span>
<span :ref="`currentBottom${item.id}`" class="currentBottom">{{item.fraction}}</span>
</div>
<span class="add" @click="addfraction(item)"></span>
<span class="reduce" @click="reducefraction(item)"></span>
</li>
方法:
reducefraction: _debounce(function (item){
if(item.fraction == 0) return // 防止减到负数
this.isReduceFraction = true // 当前状态为减分
let html = this.$refs['currentTop'+item.id][0] // 获取到前面数字的上半部分
html.classList.add('down') // 上半部分执行往下翻的动画
setTimeout(() => {
item.fraction--
this.isReduceFraction = false // 去掉状态,所有卡片恢复初始样式
html.classList.remove('down') // 4毫秒以后移出动画 这个时间卡在动画执行完成的时候
}, 400);
}, 300),
addfraction: _debounce(function (item){
this.isAddFraction = true // 当前状态为加分
let html = this.$refs['currentBottom'+item.id][0] // 获取到前面数字的下半部分
html.classList.add('up') // 下半部分执行往上翻的动画
setTimeout(() => {
item.fraction++
this.isAddFraction = false // 去掉状态,所有卡片恢复初始样式
html.classList.remove('up') // 4毫秒以后移出动画
}, 400);
}, 300),
样式:
.mini-group-list{
width: 130px;
height: 100%;
position: relative;
background: url('../../assets/img/group/fenshujishuBg.png') no-repeat;
background-size: contain;
margin-right: 58px;
color: #2973DA;
.fraction{
font-size: 80px;
height: 100%;
perspective: 180px; // 开启前景
.currentTop, .currentBottom, .nextTop, .nextBottom{
position: absolute;
top: 0;
left: 13px;
height: 50%;
text-align: center;
overflow: hidden;
height: 40px;
width: 105px;
backface-visibility: hidden;
background: #F4C583;
}
.currentTop,.nextTop{
line-height: 1; // 只展示数字的上半部分
top: 7px;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
transform-origin: bottom;
}
.nextTop{
top: 6px;
}
.down{
transform: rotateX(-180deg);
}
.up{
transform: rotateX(180deg);
}
.currentBottom, .nextBottom{
top: unset;
bottom: 20px;
line-height: 0; // 只展示数字的下半部分
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
transform-origin: top;
}
.nextBottom{
bottom: 19px;
}
}
.changing{
.currentTop, .currentBottom{
transition: all 1s;
}
.down{
transform: rotateX(-180deg);
transform-origin: bottom;
}
.up{
transform: rotateX(180deg);
transform-origin: top;
}
}
}