react实现动画电子倒计时组件

1. 这些天也都在面试,面试的内容呢,也大多千篇一律,无外乎vue、react这些框架的一些原理,和使用方法。但是呢,有一家公司的CTO在国外,没办法对我的技术进行审核,所以他给我发了两套题,第一套题呢,是要使用react实现动画倒计时小时钟组件,父级组件通过传递秒、结束回调方法控制时钟组件。

2. 要求:

(1)倒计时组件调用 :


 

(2)倒计时组件内部简单结构 :


 

3. 思考实现过程:

(1)首先实现简单的数字倒计时更改

(2)最后实现数值更改结合transition运动

4. 具体核心代码实现:

(1)模板结构:

<div>

<section className="timeBox">

<div className="timeBoxLineWrap">

<div className="timeBoxLine" ref="timeBoxLine">

{ this.state.remainingFormattedTime.split('').map((v,index,arr) => (

   (<div className="timeBoxLine-Box" key={index}  >

       <span className="timeBoxLine-Box-item">{this.state.lastTime[index]}</span>

       <span className="timeBoxLine-Box-item">{v}</span>

   </div>)

) 

)}

</div>

</div>

</section>

</div>

(2)生命周期以及执行方法: 

import React from "react";

import './time.css'



export default class Countdown extends React.Component {

    

    constructor(props) {

        super(props);

        this.second = parseInt(this.props.remainingSecond);

        this.timer = null;

        this.state = { remainingFormattedTime: this.formatNumber(this.second-1), lastTime: this.formatNumber(this.second)};

    }



    componentDidMount() {

     //transfer timeTimer

    this.timerTime();

    }





    //change time

    timerTime = ()=>{

     this.timer = setInterval(()=>{

            this.compareTimeList();

            this.second--;

            if( this.second+2 === 0 ){

                this.listenTimeEnd();

            }

     },1000);

    }

    

    //Formatting a second to a time string

    formatNumber = (seconds)=>{

     // max : 99:59:59



     let hour = 0;

     let minute = 0;

     let second = seconds<0 ? 0 : seconds;



     //If it is greater than one second

     if(seconds > 59){

     second = seconds % 60;

     minute = Math.floor(seconds / 60);

    

     if( minute > 59 ){

     hour = Math.floor(minute / 60) > 99 ? 99 : Math.floor(minute / 60);

     minute = minute % 60;

     }

     }



     return (this.addZoom(hour)+':'+this.addZoom(minute)+':'+this.addZoom(second));

    }



    //add zoom

    addZoom = (num)=>{

     if(num*1 > 9){

     return num;

     }else{

     return '0' + num;

     }

    }



    //time end

    listenTimeEnd = ()=>{

     clearInterval(this.timer);

        this.initTimeBox();

        this.setState({ remainingFormattedTime: '00:00:00', lastTime: '00:00:00'});

        this.props.onComplete&&this.props.onComplete();

    }



    initTimeBox(){

        let TimeBoxItems = this.refs.timeBoxLine.children;



        for(var i=0;i

            TimeBoxItems[i].style.cssText = "transition:0s ease;transform:translateY(0);";

        }

    }



    //compare time

    compareTimeList = ()=>{

     let otime = this.state.lastTime;

     let ctime = this.state.remainingFormattedTime;

        let TimeBoxItems = this.refs.timeBoxLine.children;

        let This = this;

        

        //clear transform

        for(var i=0;i

            TimeBoxItems[i].index = i;

            TimeBoxItems[i].addEventListener('transitionend',function(){

                This.setState( {remainingFormattedTime: This.formatNumber(This.second) , lastTime: This.formatNumber(This.second+1) } );

                this.style.cssText = 'transition:0s ease;transform:translateY(0)';

            });

        }

        

        // set animation

     for(var i=0;i

     if(otime[i] != ctime[i]){

                TimeBoxItems[i].style.cssText = "transition:ease 0.5s;transform:translateY(-100%);"

     }else{

                TimeBoxItems[i].style.cssText = "transition:0s ease;transform:translateY(0);";

            }

     }



    }



    // render 

    render() {

        return (

         //模板结构

        );

    } 

}

5. 最需要注意的就是,数据驱动后动画的更改,或者DOM更新后,动画的衔接。

6. 组件开发结束,最终预览效果:

子在川上曰,逝者如斯夫 ~ 

猜你喜欢

转载自blog.csdn.net/WU5229485/article/details/81584373