likes
comments
collection
share

麦当劳扭蛋抽奖小动画

作者站长头像
站长
· 阅读数 3

前言

最近新增抽奖盲盒,就是扭蛋机的形式,由于前端使用GIF图会很大,而且图片会很大,所以扭蛋机中的扭蛋进行分离,前端单独使用css进行。

麦当劳扭蛋机效果

麦当劳扭蛋抽奖小动画

扭蛋机窗口大小

第一步先固定扭蛋机的窗口,我这里使用的大小是 507rpx*507rpx

麦当劳扭蛋抽奖小动画

确定扭蛋数量

首先我们确定我们的扭蛋总数,一共14个扭蛋,之后我们的对这14个扭蛋分别设置对应的动画,我们可以在设计图上先设计好每一个扭蛋的动画轨迹,这样我们在编写css的时候就可以更快的进行了

麦当劳扭蛋抽奖小动画

扭蛋css

接下来是扭蛋动画的css源码

  <template>
  <view :class="['lottery', active ? '' : 'is-disabled']">
    <!-- one -->
    <image class="is-gacha is-one" :src="'./static/gacha/1.png'"></image>
    <!-- two -->
    <image class="is-gacha is-two" :src="'./static/gacha/2.png'"></image>
    <!-- three -->
    <image class="is-gacha is-three" :src="'./static/gacha/3.png'"></image>
    <!-- four -->
    <image class="is-gacha is-four" :src="'./static/gacha/4.png'"></image>
    <!-- five -->
    <image class="is-gacha is-five" :src="'./static/gacha/5.png'"></image>
    <!-- six -->
    <image class="is-gacha is-six" :src="'./static/gacha/6.png'"></image>
    <!-- seven -->
    <image class="is-gacha is-seven" :src="'./static/gacha/7.png'"></image>
    <!-- eight -->
    <image class="is-gacha is-eight" :src="'./static/gacha/8.png'"></image>
    <!-- nine -->
    <image class="is-gacha is-nine" :src="'./static/gacha/9.png'"></image>
    <!-- ten -->
    <image class="is-gacha is-ten" :src="'./static/gacha/10.png'"></image>
    <!-- eleven -->
    <image class="is-gacha is-eleven" :src="'./static/gacha/1.png'"></image>
    <!-- twelve -->
    <image class="is-gacha is-twelve" :src="'./static/gacha/5.png'"></image>
    <!-- thirteen -->
    <image class="is-gacha is-thirteen" :src="'./static/gacha/8.png'"></image>
    <!-- fourteen -->
    <image class="is-gacha is-fourteen" :src="'./static/gacha/10.png'"></image>
  </view>
</template>

<script setup>
import { ref } from 'vue';

// 激活
const active = ref(false);
</script>

<style lang="scss" scoped>
.lottery {
  position: absolute;
  top: 206rpx;
  margin: 0 auto;
  left: 0;
  right: 0;
  z-index: 1;
  width: 507rpx;
  height: 527rpx;
  overflow: hidden;
  border: 10rpx solid transparent;
  border-radius: 30rpx;

  &.is-disabled {
    .is-gacha {
      animation: none;
      will-change: transform;
    }
  }

  .is-gacha {
    width: 140rpx;
    height: 140rpx;
    position: absolute;
    bottom: 0;
    left: 0;
    animation-duration: 1s;
    animation-timing-function: linear;
  }

  .is-one {
    z-index: 11;
    left: -36rpx;
    bottom: -21rpx;
    animation-name: gachaOne;
  }

  .is-two {
    z-index: 10;
    left: 50rpx;
    bottom: -56rpx;
    animation-name: gachaTwo;
  }

  .is-three {
    z-index: 7;
    left: 160rpx;
    bottom: -60rpx;
    animation-name: gachaThree;
    transform: translate(0, 0) rotate(33deg);
  }

  .is-four {
    z-index: 5;
    left: 280rpx;
    bottom: -30rpx;
    animation-name: gachaFour;
    transform: translate(0, 0) rotate(45deg);
  }

  .is-five {
    z-index: 4;
    left: initial;
    bottom: -40rpx;
    right: -20rpx;
    animation-name: gachaFive;
    transform: translate(0, 0) rotate(-30deg);
  }

  .is-six {
    z-index: 9;
    bottom: 50rpx;
    left: 50rpx;
    animation-name: gachaSix;
    transform: translate(0, 0) rotate(25deg);
  }

  .is-seven {
    z-index: 8;
    left: -30rpx;
    bottom: 110rpx;
    animation-name: gachaSeven;
    transform: translate(0, 0) rotate(-36deg);
  }

  .is-eight {
    z-index: 8;
    left: 50rpx;
    bottom: 110rpx;
    animation-name: gachaEight;
    transform: translate(0, 0) rotate(6deg);
  }

  .is-nine {
    left: 170rpx;
    bottom: 50rpx;
    z-index: 3;
    animation-name: gachaNine;
    transform: translate(0, 0) rotate(15deg);
  }

  .is-ten {
    left: 280rpx;
    z-index: 3;
    bottom: 70rpx;
    animation-name: gachaTen;
    transform: translate(0, 0) rotate(0);
  }

  .is-eleven {
    left: 380rpx;
    bottom: 50rpx;
    z-index: 3;
    animation-name: gachaEleven;
    transform: translate(0, 0) rotate(15deg);
  }

  .is-twelve {
    left: 130rpx;
    bottom: 130rpx;
    z-index: 8;
    animation-name: gachaTwelve;
    transform: translate(0, 0) rotate(10deg);
  }

  .is-thirteen {
    left: 260rpx;
    z-index: 2;
    bottom: 140rpx;
    animation-name: gachaThirteen;
    transform: translate(0, 0) rotate(75deg);
  }

  .is-fourteen {
    left: 380rpx;
    bottom: 150rpx;
    z-index: 2;
    animation-name: gachaFourteen;
    transform: translate(0, 0) rotate(35deg);
  }

  @keyframes gachaOne {
    0% {
      transform: translate(0, 0) rotate(0deg);
    }
    20% {
      transform: translate(176rpx, -224rpx) rotate(-23deg);
    }
    40% {
      transform: translate(411rpx, -86rpx) rotate(-70deg);
    }
    60% {
      transform: translate(223rpx, 43rpx) rotate(-140deg);
    }
    80% {
      transform: translate(80rpx, -80rpx) rotate(30deg);
    }
    100% {
      transform: translate(0, 0) rotate(0deg);
    }
  }

  @keyframes gachaTwo {
    0% {
      transform: translate(0, 0) rotate(0);
    }
    20% {
      transform: translate(-50rpx, -176rpx) rotate(20deg);
    }
    40% {
      transform: translate(96rpx, -250rpx) rotate(66deg);
    }
    60% {
      transform: translate(320rpx, -90rpx) rotate(110deg);
    }
    80% {
      transform: translate(150rpx, 0) rotate(200deg);
    }
    100% {
      transform: translate(0, 0) rotate(360deg);
    }
  }

  @keyframes gachaThree {
    0% {
      transform: translate(0, 0) rotate(33deg);
    }
    20% {
      transform: translate(-180rpx, -100rpx) rotate(120deg);
    }
    40% {
      transform: translate(-92rpx, -200rpx) rotate(170deg);
    }
    60% {
      transform: translate(100rpx, -130rpx) rotate(260deg);
    }
    80% {
      transform: translate(210rpx, -50rpx) rotate(300deg);
    }
    100% {
      transform: translate(0, 0) rotate(393deg);
    }
  }

  @keyframes gachaFour {
    0% {
      transform: translate(0, 0) rotate(45deg);
    }
    20% {
      transform: translate(-120rpx, -130rpx) rotate(90deg);
    }
    40% {
      transform: translate(-20rpx, -250rpx) rotate(150deg);
    }
    60% {
      transform: translate(90rpx, -140rpx) rotate(270deg);
    }
    80% {
      transform: translate(90rpx, -30rpx) rotate(320deg);
    }
    100% {
      transform: translate(0, 0) rotate(405deg);
    }
  }

  @keyframes gachaFive {
    0% {
      transform: translate(0, 0) rotate(-30deg);
    }
    20% {
      transform: translate(-330rpx, -70rpx) rotate(10deg);
    }
    40% {
      transform: translate(-280rpx, -180rpx) rotate(110deg);
    }
    60% {
      transform: translate(-180rpx, -160rpx) rotate(150deg);
    }
    80% {
      transform: translate(-20rpx, -80rpx) rotate(280deg);
    }
    100% {
      transform: translate(0, 0) rotate(310deg);
    }
  }

  @keyframes gachaSix {
    0% {
      transform: translate(0, 0) rotate(25deg);
    }
    20% {
      transform: translate(-20rpx, 60rpx) rotate(0);
    }
    40% {
      transform: translate(100rpx, -150rpx) rotate(70deg);
    }
    60% {
      transform: translate(320rpx, -60rpx) rotate(160deg);
    }
    80% {
      transform: translate(200rpx, 80rpx) rotate(300deg);
    }
    100% {
      transform: translate(0, 0) rotate(385deg);
    }
  }

  @keyframes gachaSeven {
    0% {
      transform: translate(0, 0) rotate(-36deg);
    }
    20% {
      transform: translate(154rpx, -120rpx) rotate(16deg);
    }
    40% {
      transform: translate(284rpx, -40rpx) rotate(160deg);
    }
    60% {
      transform: translate(240rpx, 120rpx) rotate(230deg);
    }
    80% {
      transform: translate(100rpx, 57rpx) rotate(280deg);
    }
    100% {
      transform: translate(0, 0) rotate(330deg);
    }
  }

  @keyframes gachaEight {
    0% {
      transform: translate(0, 0) rotate(-36deg);
    }
    25% {
      transform: translate(150rpx, -70rpx) rotate(110deg);
    }
    50% {
      transform: translate(320rpx, -70rpx) rotate(230deg);
    }
    75% {
      transform: translate(200rpx, -30rpx) rotate(300deg);
    }
    100% {
      transform: translate(0, 0) rotate(366deg);
    }
  }

  @keyframes gachaNine {
    0% {
      transform: translate(0, 0) rotate(15deg);
    }
    25% {
      transform: translate(-200rpx, -30rpx) rotate(70deg);
    }
    50% {
      transform: translate(100rpx, -80rpx) rotate(180deg);
    }
    75% {
      transform: translate(200rpx, -50rpx) rotate(270deg);
    }
    100% {
      transform: translate(0, 0) rotate(375deg);
    }
  }

  @keyframes gachaTen {
    0% {
      transform: translate(0, 0) rotate(0);
    }
    25% {
      transform: translate(-280rpx, 70rpx) rotate(-120deg);
    }
    50% {
      transform: translate(-250rpx, -70rpx) rotate(-220deg);
    }
    75% {
      transform: translate(-100rpx, -50rpx) rotate(-280deg);
    }
    100% {
      transform: translate(0, 0) rotate(-360deg);
    }
  }

  @keyframes gachaEleven {
    0% {
      transform: translate(0, 0) rotate(15deg);
    }
    25% {
      transform: translate(-100rpx, 80rpx) rotate(90deg);
    }
    50% {
      transform: translate(-300rpx, -60rpx) rotate(150deg);
    }
    75% {
      transform: translate(-100rpx, -100rpx) rotate(250deg);
    }
    100% {
      transform: translate(0, 0) rotate(375deg);
    }
  }

  @keyframes gachaTwelve {
    0% {
      transform: translate(0, 0) rotate(10deg);
    }
    25% {
      transform: translate(100rpx, 140rpx) rotate(50deg);
    }
    50% {
      transform: translate(250rpx, -20rpx) rotate(120deg);
    }
    75% {
      transform: translate(150rpx, -70rpx) rotate(260deg);
    }
    100% {
      transform: translate(0, 0) rotate(370deg);
    }
  }

  @keyframes gachaThirteen {
    0% {
      transform: translate(0, 0) rotate(75deg);
    }
    25% {
      transform: translate(120rpx, 50rpx) rotate(180deg);
    }
    50% {
      transform: translate(-50rpx, 160rpx) rotate(250deg);
    }
    75% {
      transform: translate(-150rpx, 80rpx) rotate(360deg);
    }
    100% {
      transform: translate(0, 0) rotate(435deg);
    }
  }

  @keyframes gachaFourteen {
    0% {
      transform: translate(0, 0) rotate(35deg);
    }
    25% {
      transform: translate(-50rpx, 160rpx) rotate(100deg);
    }
    50% {
      transform: translate(-200rpx, 100rpx) rotate(220deg);
    }
    75% {
      transform: translate(-100rpx, -70rpx) rotate(300deg);
    }
    100% {
      transform: translate(0, 0) rotate(395deg);
    }
  }
}
</style>

最终实现效果

以下就是扭蛋最终的滚动效果

麦当劳扭蛋抽奖小动画