文章源自: https://facebook.github.io/react/docs/animation.htmlcss
ReactCSSTransitionGroup
基于 ReactTransitionGroup
,当一个React组件enter或者leave时能够方便的用来执行CSS transitions和animations。html
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
!react
在这个组件中,当添加一个元素到 ReactCSSTransitionGroup 中时,这个元素将会自动添加上
example-enter
和 example-enter-active
样式。添加上的样式基于 transitionName 这个属性来设置。
咱们须要作的就是定义example-xxx等样式;git
.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分别表示动画开始和动画结束时的样式定义;github
动画时间在css样式表中和render方法中,都必须指定,时间用来告诉React何时去移除animation样式以及何时从DOM中移除元素。web
ReactCSSTransitionGroup 提供了可选的属性 transitionAppear ,用来指定组件初始加载时的动画,该属性默认值是false,因此在组件加载的时候默认是没有动画的; npm
return ( <CSSTransitionGroup className="animateExample" transitionAppear={true} transitionAppearTimeout={1500} transitionEnterTimeout={1500} transitionLeaveTimeout={1500} transitionName="example"> {children} </CSSTransitionGroup> );
修改组件的render方法,而且在css中定义example-appear, example-appear-active样式;api
.example-appear { opacity: 0.01; margin-left: 128px; } .example-appear.example-appear-active { opacity: 1; margin-left: 0; }
这样在组件初始加载的时候,也会有动画了!app
组件第一次加载的时候,执行的动画是appear,以后再有element动态添加到CSSTransitionGroup,将会执行enter动画,而不会是appear动画;dom
transitionEnter和transitionLeave默认值是true,因此若是不把它们指定为false的话得指定transitionEnterTimeout和transitionLeaveTimeout。
除了经过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> // ...
上面所实现的动画,都是整个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> ); }
为了组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。
还能够禁止掉enter或者是leave动画,好比但愿有enter动画而不想要leave动画,可是ReactCSSTransitionGroup须要等待动画完成后才从dom中remove元素,此时能够经过设置transitionEnter={false}或者transitionLeave={false}来禁止相应的动画;
在ReactCSSTransitionGroup中,没有动画完成的监听,因此若是想要获取到动画的执行进度而且添加其它操做是不可行的,若是确实有须要,可使用ReactTransitionGroup;