vue倒计时无缝循环上下切换(1秒切换一次带动画)

vue倒计时无缝循环上下切换(1秒切换一次带动画)

之前也在网上找了倒计时切换的不少文章,大同小异,干脆还是自己写得了。

1.代码比较简单,也不多做介绍了,直接新建一个组件,将代码拉进去就行。
2. 给组件传一个参数:rangeTime=86600,作为剩余时间,单位:秒。


<template>
  <div class="item-time-box">
    <div class="time-cell">
      <div class="time-cell-box">
        <div class="time-list" :style="{top:getScrollTop.day+'px'}">
          <div>30</div>
          <div v-for="(item,index) of 31" :key="index">
            {{index>=10?index:'0'+index}}
          </div>
        </div>
      </div>
      <span></span>
    </div>
    <div class="time-cell">
      <div class="time-cell-box">
        <div class="time-list" :class="{'clear-transtion':downReset.hour}" :style="{top:getScrollTop.hour+'px'}">
          <div>23</div>
          <div v-for="(item,index) of 24" :key="index">
            {{index>=10?index:'0'+index}}
          </div>
        </div>
      </div>
      <span></span>
    </div>
    <div class="time-cell">
      <div class="time-cell-box">
        <div class="time-list" :class="{'clear-transtion':downReset.minute}" :style="{top:getScrollTop.minute+'px'}">
          <div>59</div>
          <div v-for="(item,index) of 60" :key="index">
            {{index>=10?index:'0'+index}}
          </div>
        </div>
      </div>
      <span></span>
    </div>
  </div>
</template>

<script>
export default {
  props:{
    rangeTime:{ // 剩余时间,单位秒
      type:Number,
      default:0
    }
  },
  computed:{
    getScrollTop(){
      // -36: 因为给0上面加了最后一个数,用于无缝滚动
      let day = this.timeData.day*-36-36; 
      // 如果是23时,并且没有执行重回,就滚动到第一个(第一个就是复制的最后一个)
      let hour = (this.timeData.hour==23 && !this.downReset.hour)?0:this.timeData.hour*-36-36;
      // 如果是59分,并且没有执行重回,就滚动到第一个(第一个就是复制的最后一个) 
      let minute = (this.timeData.minute==59 && !this.downReset.minute)?0:this.timeData.minute*-36-36;
      return {day,hour,minute}
    },
  },
  data(){
    return {
      timeData:{ // 面板上显示的时间 (天时分)
        day:0,
        hour:0,
        minute:0,
      },
      downReset:{ // (时分)是否重回到最后一个
        hour:false,
        minute:false,
      }
    }
  },
  mounted(){
    if(this.rangeTime>0){
      // 显示初始化时间
      this.getSurplusTime(this.rangeTime);
      // 进入倒计时
      this.downTime();
    }
  },
  methods:{
    downTime(){ // 倒计时
      let second = this.rangeTime;
      let times = setInterval(()=>{
        if(second<=0){
          clearInterval(times);
          times=null;
          setTimeout(()=>{
            // this.$message.success('奖金通知已发送');
            this.$emit('runTimer'); // 倒计时结束,触发方法
          },500)
          return false;
        }
        second-=60; // 我是以分为单位,为了更好的看效果,每秒定时器 - 1分钟
        this.getSurplusTime(second);
      },1000)
    },
    getSurplusTime(second){ // 获取剩余时间
      let minute=0;                    
      let hour=0;                    
      let day=0;                    
      minute = parseInt(second/60);
      if(minute>=60) { 
        hour = parseInt(minute/60);
        minute%=60;
      }
      if(hour>=24){
        day = parseInt(hour/24);
        hour%=24;
      }
      this.timeData={day,hour,minute};
      if((hour==23 && !this.downReset.hour) || (minute==59 && !this.downReset.minute)){ 
        // 先将位置移到第一个
        this.downReset={
          hour:false,
          minute:false
        }
        // 如果有时/分,到了最大值,320毫秒后,定位到最后一个
        // 为什么要定位:如果没有重定位,最大值显示的位置是复制的第一个的位置。需要定时器取消动画,定位到最后,实现无缝环形效果
        setTimeout(()=>{
          this.downReset={
            hour:hour==23,
            minute:minute==59
          }
        },320)
      }else{
        this.downReset={
          hour:hour==23,
          minute:minute==59
        }
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.item-time-box{
  height: 90px;
  border-radius: 4px;
  background: #F1F1F1;
  box-shadow: 0 0 5px 0 #ccc inset;
  margin-bottom: 5px;
  padding: 10px 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  .time-cell{
    text-align: center;
    .time-cell-box{  
      position: relative;
      overflow: hidden;
      width: 36px;
      height: 36px;
      line-height: 36px;
      border-radius: 3px;
      background: #0089D1;
      box-shadow: 0 0 10px 0 rgb(20, 20, 20,0.2) inset;
      color:#fff;
      font-size: 20px;
      margin-bottom: 5px;
      .time-list{
        position: absolute;
        transition:all 0.3s;
        top: 0;
        left: 0;
        width: 100%;
        &.clear-transtion{
          transition:none;
        }
      }
    }
  }
}
</style>

实际效果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值