關鍵幀動畫,摺疊面板(parseFloat,requestAnimationFrame,cancelAnimationFrame)

當前項目是在react項目中的,所以本案例代碼改變數據申明和數據更改都是react的方式

 效果圖如下:

 首先聲明幾個變量

 

constructor(props) {  // 變量申明
        super(props);
        this.state = {
            todayList: {}
        }
        this.view = null;          //摺疊內容變量
        this.animation1 = null;    //動畫(收起)
        this.animation2 = null;    //動畫(展開)
        this.heightList = {};      //摺疊內容高度(用於存儲)

        this.stepDeHeight = this.stepDeHeight.bind(this);      //動畫收起函數
        this.stepGainHeight = this.stepGainHeight.bind(this);  //動畫展開函數
    }

 然後,定義三個函數分別爲:動畫收起函數動畫展開函數面板的點擊事件

函數和api說明:

parseFloat():函數可解析一個字符串,並返回一個浮點數

https://www.runoob.com/jsref/jsref-parsefloat.html

requestAnimationFrame():執行關鍵幀動畫的方法

https://www.jianshu.com/p/f6d933670617

cancelAnimationFrame():消除關鍵幀動畫的方法

https://www.w3cschool.cn/fetch_api/fetch_api-5rzn2uyv.html

 一下爲動畫效果的全部行數,你可以仔細按照流程走下去。代碼沒有一一做註釋。

//動畫收起函數
stepDeHeight(height) {
        // cancelAnimationFrame(this.animation2)
        if (parseFloat(this.view.style.height) > 0) {
            this.view.style.height =
                parseFloat(this.view.style.height) - height * 5 / 100 + "px";
            this.animation1 = requestAnimationFrame(() => { this.stepDeHeight(height) });
        } else {
            this.view.style.height = 0;
            cancelAnimationFrame(this.animation1)
            // this.view.style.display='none'
            return;
        }
    }
//動畫展開函數
    stepGainHeight(height) {
        // cancelAnimationFrame(this.animation1)
        // this.view.style.display='block'
        if (parseFloat(this.view.style.height) < height) {
            this.view.style.height =
                parseFloat(this.view.style.height) + height * 5 / 100 + "px";
            this.animation2 = requestAnimationFrame(() => { this.stepGainHeight(height) });
        } else {
            this.view.style.height = height;
            cancelAnimationFrame(this.animation2)
            return;

        }
    }
//點擊事件
    hiddenShow(index) {
        this.view = document.getElementsByClassName('league-table')[index];
        console.log(this.view.getBoundingClientRect().height)
      
        if (this.view.getBoundingClientRect().height > 0) {
            if (!this.heightList[index]) {
                this.heightList[index] = this.view.getBoundingClientRect().height;
            }
            if (this.view.getBoundingClientRect().height == this.heightList[index]) {
                this.view.style.height = this.view.getBoundingClientRect().height + 'px';
                cancelAnimationFrame(this.animation2)
                this.stepDeHeight(this.heightList[index])
            }
        } else {
            cancelAnimationFrame(this.animation1)
            console.log(this.heightList[index])
            this.stepGainHeight(this.heightList[index])
        }
    }

 最後,本案例是後臺返回一個數組,然後我通過map()遍歷出來,然後在return()裏面的面板內容中添加點擊事件。

// 面板顯示點擊view,如下所有內容都放到map遍歷div內
<div className="league-name" 
    onClick={() => { this.hiddenShow(index); }}>點我</div>
<div className="league-table" style={{ display: 'block' }}>
    {..........存放面板內容..............}
</div>

實際代理在問價中很多,希望讀者可以看懂,不做全部呈現了。但是根據代碼走,邏輯還是比較清晰的,不懂請留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章