vue.js实现收能量

其他活动实现:

抽奖转盘: vue.js实现抽奖转盘
红包雨: vue.js实现红包雨

1.实现的放大的同时上下移动 (先将代码部分抽出现实现)

能量4.gif

 <!-- <div class="father">
    <div class="test"></div>
    <div class="test"></div>
    <div class="test"></div>
    <div class="test"></div>
  </div> -->
  <div class="father">
    <div class="test"></div>
  </div>
  <div class="father">
    <div class="test"></div>
  </div>
  <div class="father">
    <div class="test"></div>
  </div>
  <div class="father">
    <div class="test"></div>
  </div>
  <style>
     @keyframes father{
      0%   {
        transform: translate(0, 0)
      }
      50%  {
        transform: translate(0, -15px)
      }
      100% {
        transform: translate(0, 0px)
      }
    }
    .father{
      animation: father 1.5s ease-in-out 1s forwards infinite
    }
    .test {
      width: 50px;
      height: 50px;
      background-color: burlywood;
      border-radius: 50%;
      animation: star-stone 1s ease-in-out 0s forwards alternate;
    }
    @keyframes star-stone{
      from{
        transform: scale(0, 0);
      }
      to{
        transform: scale(1, 1);
      }
    }
  </style>
复制代码

因为泡泡的出现是随机出现的,那么必须保证上下移动的步调是一致的,所以必须将上下移动的css动画放在子元素的父级

2.实现能量的排版与自动出现

能量5.gif

2.1先定义是否显示的option参数,因为import进来的数据,存在引用,所以这里使用工厂函数

/indexOption.js

export function imgArrFun () {
  return [
    {
      id: 1,
      isShow: false,
    },
    {
      id: 2,
      isShow: false,
    },
    {
      id: 3,
      isShow: false,
    },
    {
      id: 4,
      isShow: false,
    },
    {
      id: 5,
      isShow: false,
    },
    {
      id: 6,
      isShow: false,
    },
    {
      id: 7,
      isShow: false,
    },
    {
      id: 8,
      isShow: false,
    },
    {
      id: 9,
      isShow: false,
    },
    {
      id: 10,
      isShow: false,
    },
  ]
}
export function idArrFun () {
  return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
复制代码
2.2实现

index.vue

html:

<!-- 能量分布 -->
 <span :class="['father', centerVisible ? 'star-energy-center' : 
 `position${index + 1}`]"  v-for="(item, index) in imgList" :key="index">
     <img v-show="item.isShow" :class="[item.isShow ? 'star-stone': '' ]" 
     src="@/assets/image/starEnergy/starStone.png">
 </span>
 
 <!-- 可领取 -->
 <div v-show="!pushVisible && bubbleShow" class="star-energy-button" @click="combine"></div>
复制代码

css:

   .star-stone {
      width: 100%;
      animation: star-stone 1s ease-in-out 0s forwards alternate;
    }
    @keyframes star-stone{
      from{
        transform: scale(0, 0);
      }
      to{
        transform: scale(1, 1);
      }
    }
    @keyframes father{
      0%   {
        transform: translate(0, 0)
      }
      50%  {
        transform: translate(0, -15px)
      }
      100% {
        transform: translate(0, 0px)
      }
    }
    .position1 {
      top: 48px;
    }
    .position2 {
      top: 178px;
      left: 180px;
    }
    .position3 {
      top: 178px;
    }
    .position4 {
      top: 178px;
      left: 440px;
    }
    .position5 {
      top: 244px;
      left: 570px;
    }
    .position6 {
      top: 244px;
      left: 50px;
    }
    .position7 {
      top: 308px;
      left: 180px;
    }
    .position8 {
      top: 308px;
    }
    .position9 {
      top: 308px;
      left: 440px;
    }
    .position10 {
      top: 438px;
    }
    
    .father{
      @include position(absolute, 130px, 130px);
      left: 310px;
      right: 310px;
      top: 243px;
      animation: father 1.5s ease-in-out 1s forwards infinite
    }
   .star-energy-center{
      position: absolute;
      transition: all 1s linear;
      animation: star-energy-center 2s linear forwards alternate;
    }
    @keyframes star-energy-center {
      0%   {
        transform: translate(0, 0);
        opacity: 1;
      }
      50%   {
        transform: translate(0, 0);
        opacity: 1;
      }
      100% {
        transform: translateY(-200px);
        transition: all .1s;
        opacity: 0;
      }
    }
复制代码

js部分

  computed: {
    // 没有泡泡就让按钮显示不可以按
    'bubbleShow' () {
      const list = this.imgList.filter(item => item.isShow) || []
      return list.length > 0
    },
  },
  async created () {
    this.imgList = imgArrFun()
    // 首次加载先让能量随机出现
    this.getStarEnergyData()
  },
  
  methods: {
    // 获取星能量倒计时和可领取奖励数
    async getStarEnergyData () {
      this.$loading.show()
      const data = await xxxx接口(this.token)
      this.isCombineVisible = true
      this.starEnergyData = data.info
      // 拿到后台返回的数据
      const energyBouns = 10 * +this.ruleData.wealthBonus
      this.showEnergyNum = this.starEnergyData.accumulateWealthNum >= energyBouns ?
      10 : (+this.starEnergyData.accumulateWealthNum % energyBouns) / 
      this.ruleData.wealthBonus
      this.showStarEnergy(this.showEnergyNum)
      this.surplusTime = +this.starEnergyData.surplusTime
    },
    // 点击合成
    async combine () {
      if (this.isCombineVisible) { // 设置isCombineVisible防止重复点击
        this.pushVisible = true // 因为按下去是其他样式,所以设定一个状态
        setTimeout(async () => {
          this.pushVisible = false
          await getStarEnergyApi(this.token) // 合成的时候需要进行一次上报
          this.isCombineVisible = false
          this.centerVisible = true // 主要是做收能量的动效
          document.getElementsByClassName('father')[0].addEventListener(
          'animationend', this.animationendFunc)
        }, 100)
      }
    },
    // 消失之后,将数据初始化
    animationendFunc () {
      if (!this.centerVisible) {
        return
      }
      this.imgList = imgArrFun()
      this.showBouns = true
      // 2s之后将显示弹框隐藏,居中class隐藏,重新调接口
      setTimeout(() => {
        this.showBouns = false
        this.centerVisible = false
        this.getStarEnergyData()
      }, 2000)
    },
    // 显示能量球以及开始倒计时
    async showStarEnergy (num) {
      clearInterval(this.timer)
      this.countDown(this.surplusTime)
      this.ids = idArrFun()
      this.imgList = imgArrFun()
      const res = this.getRandom(num, this.ids)
      this.imgList.forEach((img) => {
        res.forEach(item => {
          if (img.id === item) {
            img.isShow = true
          }
        })
      })
    },
     // 获取随机数
    getRandom (num, ids) {
      // 输出数组
      const out = []
      // 输出个数
      while (out.length < num) {
        const temp = (Math.random() * ids.length) >> 0
        out.push(ids.splice(temp, 1)[0])
      }
      return out
    },
    // 倒计时
    countDown (seconds = 60) {
      // 定时器
      this.timeObj = dateTransform(seconds)
      this.timer = setInterval(() => {
        // 把转换后的结果显示出来
        this.timeObj = dateTransform(seconds)
        if (seconds < 0) {
          this.zeroHandle()
        }
        seconds--
      }, 1000)
    },
    // 生成泡泡逻辑
    zeroHandle () {
      clearInterval(this.timer)
      this.activeStarNum = this.activeStarNum + this.ruleData.wealthBonus
      this.countDown(this.ruleData.onlineTime)
      // 如果已经有了10个泡泡,就不往下执行了
      const imgHiddenList = this.imgList.filter(item => !item.isShow) || []
      if (imgHiddenList.length !== 0) {
        this.showBubble()
      }
    },
     // 显示泡泡
    showBubble () {
      // 如果泡泡数存在,下次就随机出现得范围就是isShow不为true得
      const resArr = this.imgList.filter(item => !item.isShow).map(i => i.id)
      if (resArr.length === 0) return
      this.ids = [...resArr]
      // 将出现的设置为true
      const res = this.getRandom(1, this.ids)
      this.imgList.forEach((img) => {
        res.forEach(item => {
          if (img.id === item) {
            img.isShow = true
          }
        })
      })
    },
  }
复制代码

注意:
从动画上来说,最重要的是在没有点击居中的时候,应该是按照UI图的样式进行10个球固定位置的分布,等点击收能量的时候,进行一个整体的动画,给一个过渡的效果,让每个球,做同样的操作,而不是针对单个球不同的位置做相应的操作

从逻辑上来说,随机出现小球,一定要注意去排除已经出现过的小球.

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享