场景描述:
打开抽卡界面,卡牌出现并发牌至固定的位置,此时展示的是卡牌的背面;用户点击卡牌时,卡牌进行翻转,并展示卡牌内容,或者发牌后自动进行翻转和展示。
本实例在页面挂载后自动播放动画,若需点击后再播放,只需将事件写入click事件当中即可
卡牌样式可根据具体需求设置
实现思路:
html结构:
动态设置class属性,即可实现动态的css样式及动画
<template>
<div class="cardContent">
<div class="cardBox">
<div
:class="['card-item', `card-item-${index + 1}`]"
v-for="(item, index) in drawList"
:key="index"
>
<!-- 数组中存入index值时,将写有动画的class属性赋给标签,即开始播放动画 -->
<div
:class="['card', selectArr.includes(index) ? 'cardAnimate' : '']"
>卡牌背面</div>
<div
:class="['contxt', selectArr.includes(index) ? 'contxtAnimate' : '']"
>卡牌{{index+1}}正面
</div>
</div>
</div>
</div>
</template>
翻牌动画在挂载后自动执行,
//数组中存入index值时,将写有动画的class属性赋给标签,即开始播放动画
//自动播放翻牌动画,1500ms后播放第一张翻牌动画,然后每200ms播放一张
for (let i = 0; i < 6; i++) {
setTimeout(() => {
this.selectArr.push(i);
}, 1500 + (i - 1) * 200);
}
给每个卡牌进行定位,页面加载后执行相应的发牌和翻牌动画,
若翻牌动画欲设置为点击后翻牌,在methods中定义方法,并给包含卡牌正面和反面的标签父元素设置@click事件:@click=rotateCard(index)
methods: {
rotateCard(index) {
this.selectArr.push(index);
},
},
完整代码如下:
<template>
<div class="cardContent">
<div class="cardBox">
<div
:class="['card-item', `card-item-${index + 1}`]"
v-for="(item, index) in drawList"
:key="index"
>
<!-- 数组中存入index值时,将写有动画的class属性赋给标签,即开始播放动画 -->
<div
:class="['card', selectArr.includes(index) ? 'cardAnimate' : '']"
>卡牌背面</div>
<div
:class="['contxt', selectArr.includes(index) ? 'contxtAnimate' : '']"
>卡牌{{index+1}}正面
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
drawList:5,
selectArr: [],
};
},
mounted() {
//数组中存入index值时,将写有动画的class属性赋给标签,即开始播放动画
//自动播放翻牌动画,1500ms后播放第一张翻牌动画,然后每200ms播放一张
for (let i = 0; i < 6; i++) {
setTimeout(() => {
this.selectArr.push(i);
}, 1500 + (i - 1) * 200);
}
},
};
</script>
<style>
/* 每张卡牌属性 */
.card-item {
width: 212rpx;
height: 252rpx;
margin: 10rpx;
border-radius: 10px;
/* 文字居中 */
line-height:252rpx;
text-align: center;
}
/* 翻转前 */
.card-item .card {
width: 212rpx;
height: 252rpx;
border-radius: 10px;
backface-visibility: hidden;
background-color: aliceblue;
}
/* 翻转后 */
.card-item .contxt {
width: 212rpx;
height: 252rpx;
border-radius: 10px;
backface-visibility: hidden;
/* 定位于和翻转前相同的位置 */
position: relative;
top: -252rpx;
left: 0;
/* Y轴翻转180°,成卡牌效果*/
transform: rotateY(180deg);
opacity: 0;
background-color: bisque;
}
/*将每个卡牌进行定位*/
.card-item-1 {
position: absolute;
left: 20rpx;
top: 200rpx;
animation: issueCard1 1.5s;
}
.card-item-2 {
position: absolute;
left: 252rpx;
top: 200rpx;
animation: issueCard2 1.5s;
}
.card-item-3 {
position: absolute;
left: 484rpx;
top: 200rpx;
animation: issueCard3 1.5s;
}
.card-item-4 {
position: absolute;
left: 136rpx;
top: 472rpx;
animation: issueCard4 1.5s;
}
.card-item-5 {
position: absolute;
left: 368rpx;
top: 472rpx;
animation: issueCard5 1.5s;
}
/* 卡片翻牌 */
/* 背面 */
.cardAnimate {
animation: rotetaCard 0.5s ease-in;
animation-fill-mode: forwards;
}
/* 正面 */
.contxtAnimate {
animation: contxtRotate 0.5s ease-in;
animation-fill-mode: forwards;
}
/* 正面卡牌翻牌动画 */
@keyframes contxtRotate {
from {
transform: rotateY(180deg);
opacity: 1;
}
to {
transform: rotateY(0deg);
opacity: 1;
}
}
/* 背面卡牌翻牌动画 */
@keyframes rotetaCard {
from {
transform: rotateY(0);
}
to {
transform: rotateY(180deg);
}
}
/* 每张卡牌发牌动画 */
@keyframes issueCard1 {
0% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(0);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1);
}
50% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
60% {
position: fixed;
left: 20rpx;
top: 200rpx;
}
100% {
}
}
@keyframes issueCard2 {
0% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(0);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1);
}
50% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
60% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
70% {
position: absolute;
left: 252rpx;
top: 200rpx;
}
100% {
}
}
@keyframes issueCard3 {
0% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(0);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1);
}
50% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
70% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
80% {
position: absolute;
left: 484rpx;
top: 200rpx;
}
100% {
}
}
@keyframes issueCard4 {
0% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(0);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1);
}
50% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
80% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
90% {
position: absolute;
left: 136rpx;
top: 472rpx;
}
100% {
}
}
@keyframes issueCard5 {
0% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(0);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1);
}
50% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
90% {
position: fixed;
top: 750rpx;
left: 269rpx;
transform: scale(1);
}
100% {
position: absolute;
left: 368rpx;
top: 472rpx;
}
}
</style>