React 動畫 Animation


文章源自: https://facebook.github.io/react/docs/animation.html

ReactCSSTransitionGroup 基於 ReactTransitionGroup ,當一個React組件enter或者leave時可以方便的用來執行CSS transitions和animations。

導入ReactCSSTransitionGroup

import ReactCSSTransitionGroup from 'react-addons-css-transition-group' // ES6
var ReactCSSTransitionGroup = require('react-addons-css-transition-group') // ES5 with npm
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup; // ES5 with react-with-addons.js

定義組件

var React = require('react');
var ReactDOM = require('react-dom');
var CSSTransitionGroup = require('react-addons-css-transition-group');
var INTERVAL = 2000;

var AnimateDemo = React.createClass({
    getInitialState: function() {
        return {current: 0};
    },

    componentDidMount: function() {
        this.interval = setInterval(this.tick, INTERVAL);
    },

    componentWillUnmount: function() {
        clearInterval(this.interval);
    },

    tick: function() {
        this.setState({current: this.state.current + 1});
    },

    render: function() {
        var children = [];
        var pos = 0;
        var colors = ['red', 'gray', 'blue'];
        for (var i = this.state.current; i < this.state.current + colors.length; i++) {
            var style = {
                left: pos * 128,
                background: colors[i % colors.length]
            };
            pos++;
            children.push(<div key={i} className="animateItem" style={style}>{i}</div>);
        }
        return (
            <CSSTransitionGroup
            className="animateExample"
            transitionEnterTimeout={1500}
            transitionLeaveTimeout={1500}
            transitionName="example">
            {children}
            </CSSTransitionGroup>
        );
    }
});

注意: 必須給 ReactCSSTransitionGroup 中的每一個child設置一個key屬性,即使只渲染一個element

在這個組件中,當添加一個元素到 ReactCSSTransitionGroup 中時,這個元素將會自動添加上 example-enter 和 example-enter-active 樣式。添加上的樣式基於 transitionName 這個屬性來設置。我們需要做的就是定義example-xxx等樣式;

.example-enter,
.example-leave {
    -webkit-transition: all 2s;
    transition: all 2s;
}

.example-enter { /* begin **/
    opacity: 0.01;
    margin-left: 128px;
}

.example-enter.example-enter-active { /* finish **/
    opacity: 1;
    margin-left: 0;
}

.example-leave {
    opacity: 1;
    margin-left: 0;
}

.example-leave.example-leave-active {
    opacity: 0.01;
    margin-left: -128px;
}

.animateExample {
    display: block;
    height: 128px;
    position: relative;
    width: 384px;
}

.animateItem {
    color: white;
    font-size: 36px;
    font-weight: bold;
    height: 128px;
    line-height: 128px;
    position: absolute;
    text-align: center;
    -webkit-transition: all 1s; /* TODO: make this a move animation */
    transition: all 1s; /* TODO: make this a move animation */
    width: 128px;
}

example-enter和example-enter-active分別表示動畫開始和動畫結束時的樣式定義;

動畫時間在css樣式表中和render方法中,都必須指定,時間用來告訴React什么時候去移除animation樣式以及什么時候從DOM中移除元素。

初始加載動畫

ReactCSSTransitionGroup 提供了可選的屬性 transitionAppear ,用來指定組件初始加載時的動畫,該屬性默認值是false,所以在組件加載的時候默認是沒有動畫的; 

return (
     <CSSTransitionGroup
            className="animateExample"
            transitionAppear={true}
            transitionAppearTimeout={1500}
            transitionEnterTimeout={1500}
            transitionLeaveTimeout={1500}
            transitionName="example">
             {children}
     </CSSTransitionGroup>
);

修改組件的render方法,並且在css中定義example-appear, example-appear-active樣式;

.example-appear {
    opacity: 0.01;
    margin-left: 128px;
}

.example-appear.example-appear-active {
    opacity: 1;
    margin-left: 0;
}

這樣在組件初始加載的時候,也會有動畫了!

組件第一次加載的時候,執行的動畫是appear,之后再有element動態添加到CSSTransitionGroup,將會執行enter動畫,而不會是appear動畫;

transitionEnter和transitionLeave默認值是true,所以如果不把它們指定為false的話得指定transitionEnterTimeout和transitionLeaveTimeout。

自定義Classes

除了通過transitionName指定樣式,還可以指定每一步的動畫樣式,其中,active樣式名可以不用指定;

// ...
<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    enterActive: 'enterActive',
    leave: 'leave',
    leaveActive: 'leaveActive',
    appear: 'appear',
    appearActive: 'appearActive'
  } }>
  {item}
</ReactCSSTransitionGroup>

<ReactCSSTransitionGroup
  transitionName={ {
    enter: 'enter',
    leave: 'leave',
    appear: 'appear'
  } }>
  {item2}
</ReactCSSTransitionGroup>
// ...

Animating One or Zero Items

上面所實現的動畫,都是整個Group中的元素都將被設置動畫,實際上還可以指定只需要某一/零個元素執行動畫;

import ReactCSSTransitionGroup from 'react-addons-css-transition-group';

function ImageCarousel(props) {
  return (
    <div>
      <ReactCSSTransitionGroup
        transitionName="carousel"
        transitionEnterTimeout={300}
        transitionLeaveTimeout={300}>
        <img src={props.imageSrc} key={props.imageSrc} />
      </ReactCSSTransitionGroup>
    </div>
  );
}

Animation Group Must Be Mounted To Work

為了組child添加動畫屬性,ReactCSSTransitionGroup 必須已經被加載到DOM中,或者將 transitionAppear 設置成true。

render() {
  const items = this.state.items.map((item, i) => (
    <div key={item} onClick={() => this.handleRemove(i)}>
      <ReactCSSTransitionGroup transitionName="example">
        {item}
      </ReactCSSTransitionGroup>
    </div>
  ));

  return (
    <div>
      <button onClick={this.handleAdd}>Add Item</button>
      {items}
    </div>
  );
}

上面這個例子將不會起作用,因為ReactCSSTransitionGroup被加載到新的div中,而不是已經加載好的元素當中,且沒有設置transitionAppear。

Disabling Animations 

還可以禁止掉enter或者是leave動畫,比如希望有enter動畫而不想要leave動畫,但是ReactCSSTransitionGroup需要等待動畫完成后才從dom中remove元素,此時可以通過設置transitionEnter={false}或者transitionLeave={false}來禁止相應的動畫;

在ReactCSSTransitionGroup中,沒有動畫完成的監聽,所以如果想要獲取到動畫的執行進度並且添加其它操作是不可行的,如果確實有需要,可以使用ReactTransitionGroup

 


免責聲明!

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



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