react過渡動畫效果的實現,react-transition-group


本文介紹react相關的過渡動畫效果的實現

有點類似vue的transition組件,主要用於組件mount和unmount之前切換時應用動畫效果

  1. 安裝

    cnpm install react-transition-group --save
    
  2. transition動畫

    import React from 'react'
    import ReactDOM from 'react-dom'
    import Transition from 'react-transition-group/Transition';
    const duration = 300;
    const defaultStyle = {
        transition: `opacity ${duration}ms ease-in-out`,
        opacity: 0,
        width: "100px",
        height: "100px",
        background: "red"
    }
    const transitionStyles = {
        entering: { opacity: 0 },
        entered:  { opacity: 1 },
    };
    class MyComponent extends React.Component {
        constructor() {
            super();
                this.state = {
                in: false
            }
        }
        toggleEnterState = () => {
            this.setState({in: !this.state.in})
        }
        render() {
            return (
            <div>
                <Transition in={this.state.in} timeout={1000} mountOnEnter={true} unmountOnExit={true}>
                    {(state) => (
                        <div style={{
                        ...defaultStyle,
                        ...transitionStyles[state]
                        }}>
                        I'm A fade Transition!
                        </div>
                    )}
                </Transition>
                <button onClick={this.toggleEnterState}>Click to Enter</button>
            </div>
            )
        }
    }
    ReactDOM.render(
        <MyComponent/>,
        document.getElementById('root')
    ) 
    
  3. transition動畫配套api

    ** children 
        指的是Transition標簽包含的待應用動畫的元素,可以使用react的元素,也可以直接用函數,函數可以接受state參數
        state的代表動畫的4個狀態
            entering
            entered
            exiting
            exited
    ** in
        應用於Transition標簽上面,切換enter和exit,從而出現動畫效果,布爾值
    ** mountOnEnter
        在元素enter的時候才掛載,布爾值
    ** unmountOnExit
        在元素exit的時候銷毀,布爾值
    ** appear
        默認情況下Transition初次掛載的時候不應用動畫
        設置為apear之后,會自動應用一次enter動畫
        布爾值
    ** enter
        是否啟用enter時候的動畫,布爾值
        作用和設置timeout為0一樣
    ** exit
        是否啟用exit時候的動畫,布爾值
        作用和設置timeout為0一樣
    ** timeout
        過渡的持續時間,必須設置此值,除非addEventListener提供了
        timeout = {500}或者
        timeout = {{
            enter: 300,
            exit: 500
        }}
    ** addEndListener
        用來監聽dom節點的transition結束事件
        addEndListener = {
            (node,done) => {
                node.addEventListener('transitionend', function(){
                    alert(111);
                });
                done();
            }
        }
        node是dom元素節點,done是切換狀態的回調函數
    ** onEnter
        用來監聽 enter 狀態的鈎子函數
        onEnter={ 
            (node,isAppearing) => {console.log(node,isAppearing)
        }
        node是dom節點
        isAppearing是appear屬性值
        另外 onEntering 和 onEntered用法類似
    ** onExit   
        用來監聽 exit 狀態開始觸發的鈎子函數
        onExit={ 
            (node) => {console.log(node)
        }
        另外 onExiting 和 onExited 用法類似
    
  4. animate動畫

    ** index.js
        import React from 'react'
        import ReactDOM from 'react-dom'
        import { CSSTransition } from 'react-transition-group';
        import './index.css';
        const defaultStyle = {
            width: "100px",
            height: "100px",
            background: "red"
        }
        class MyComponent extends React.Component {
            constructor() {
                super();
                this.state = {
                    in: true
                }
            }
            toggleEnterState = () => {
                this.setState({in: !this.state.in})
            }
            render() {
                return (
                    <div>
                        <CSSTransition in={this.state.in} timeout={500} classNames='bounceInLeft'>
                            {(state) => (
                                <div style={{
                                ...defaultStyle
                                }}>
                                I'm A fade Transition!
                                </div>
                            )}
                        </CSSTransition>
                        <button onClick={this.toggleEnterState}>Click to Enter</button>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <MyComponent/>,
            document.getElementById('root')
        )
    ** index.css
        @keyframes bounceInLeft {
            from, 60%, 75%, 90%, to {
                animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            }
            0% {
                opacity: 0;
                transform: translate3d(-3000px, 0, 0);
            }
            60% {
                opacity: 1;
                transform: translate3d(25px, 0, 0);
            }
            75% {
                transform: translate3d(-10px, 0, 0);
            }
            90% {
                transform: translate3d(5px, 0, 0);
            }
            to {
                transform: none;
            }
        }
        @keyframes bounceOutRight {
            20% {
                opacity: 1;
                transform: translate3d(-20px, 0, 0);
            }
            to {
                opacity: 0;
                transform: translate3d(2000px, 0, 0);
            }
        }
        .bounceInLeft-enter{
            animation: bounceInLeft 1s 1;
        }
        .bounceInLeft-exit{
            animation: bounceOutRight 1s 1;
        }
    
  5. animate動畫配套api

    ** classNames 
        用在CSSTransition標簽上面,自動添加狀態后綴名
        classNames = "demo";
        會依次應用 demo-enter,demo-enter-active,demo-exit,demo-exit-active,demo-appear,demo-appear-active
        如果單獨制定class的name的話可以使用如下
        classNames = {{
            appear: 'demo1',
            appearActive: 'demo2',
            enter: 'demo3',
            enterActive: 'demo4',
            exit: 'demo5',
            exitActive: 'demo6'
        }}
    ** onEnter
        在enter或者appear類應用完成后立馬調用回調函數
            onEnter={ 
                (node,isAppearing) => {console.log(node,isAppearing)}
            }
    ** onEntering
        在enter-active或者appear-active應用完成后立馬調用回調函數
            onEntering={ 
                (node,isAppearing) => {console.log(node,isAppearing)}
            }
    ** onEntered
        在enter或者appear移除完成后立馬調用回調函數
            onEntered={ 
                (node,isAppearing) => {console.log(node,isAppearing)}
            }
    ** onExit
        在exit類應用完成后立即調用回調函數
            onEntered={ 
                (node) => {console.log(node)}
            }
    ** onExiting
        在exit-active類應用完成后立即調用回調函數
            onExiting={ 
                (node) => {console.log(node)}
            }
    ** onExited
        在exit類移除后立即調用
            onExited={ 
                (node) => {console.log(node)}
            }
    
  6. TransitionGroup

    專門處理列表動畫而誕生的組件,只要在TransitionGroup中的元素減少或者增加,自動為Transition或者CSSTransition應用in屬性
    import React from 'react'
    import ReactDOM from 'react-dom'
    import Transition from 'react-transition-group/Transition';
    import {TransitionGroup} from 'react-transition-group'
    const duration = 300;
    const defaultStyle = {
        transition: `opacity ${duration}ms ease-in-out`,
        opacity: 0,
        width: "100px",
        height: "100px",
        background: "red"
    }
    const transitionStyles = {
        entering: { opacity: 0 },
        entered:  { opacity: 1 },
    };
    class MyComponent extends React.Component {
        constructor() {
            super();
            this.state = {
                arr: ['a','c','d','e']
            }
        }
        addItem = () => {
        this.setState({
            arr: this.state.arr.concat(['f'])
        });
        }
        render() {
            return (
            <div>
                <TransitionGroup component="span" appear>
                    {this.state.arr.map( (item,index) => (
                        <Transition key={index} timeout={0}>
                            {(state) => (
                                <div style={{
                                ...defaultStyle,
                                ...transitionStyles[state]
                                }}>
                                {item}
                                </div>
                            )}
                        </Transition>
                    ) )}
                </TransitionGroup>
                <button onClick={this.addItem}>添加元素</button>
            </div>
            )
        }
    }
    ReactDOM.render(
        <MyComponent/>,
        document.getElementById('root')
    )
    
  7. TransitionGroup配套api

    ** component
        默認TransitionGroup是渲染成div,可以通過指定component改變這一默認行為
    ** appear
        是否執行初次渲染enter動畫
    ** enter
        是否開啟enter動畫
    ** exit
        是否開啟exit動畫
    ** childFactory
        此函數是TransitionGroup將要展示子元素的攔截器
        childFactory={(el) => {console.log(el);return el}}
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM