css-实现卡牌的发牌和翻转动画

场景描述:

打开抽卡界面,卡牌出现并发牌至固定的位置,此时展示的是卡牌的背面;用户点击卡牌时,卡牌进行翻转,并展示卡牌内容,或者发牌后自动进行翻转和展示。

本实例在页面挂载后自动播放动画,若需点击后再播放,只需将事件写入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>

猜你喜欢

转载自blog.csdn.net/m0_53206841/article/details/128019045