一.React实现动画
1.React通过setState让界面迅速发生变化,但动画的哲学告诉我们,变化要慢,得用一个逐渐变化的过程来过渡,从而帮助用户理解页面.
界面的变化可以分为DOM节点(或组件)的增与减以及DOM节点(或属性)的变化.
其中React提供的ReactCSSTransition能够帮助我们便捷的识别出增加或删除的组件,
从而让我们能够专注于更加简单的属性变化的动画.
2.这里统一将缓动函数通过js实现的动画称作js动画,缓动函数由css提供的动画称作css动画.
3.ReactCSSTransition插件就是利用CSS的Transition和animation来实现组件的出场和入场动画.
二.CSS3 transition
1.css3过渡是元素从一种样式逐渐改变为另一种的效果.
.ani2 {
width: 100px;
height: 100px;
border: 1px solid #ccc;
transition: width 1s, transform 1s;
animation: myfirst 3s infinite;
&:hover {
width: 200px;
transform: rotate(360deg);
}
}
三.css3 animation
1.@keyframes用于创建动画,然后捆绑到某个选择器.
@keyframes myfirst {
0% {
background: #f00;
}
50% {
background: #0f0;
}
100% {
background: #ccc;
}
}
.ani2 {
width: 100px;
height: 100px;
border: 1px solid #ccc;
transition: width 1s, transform 1s;
animation: myfirst 3s infinite;
&:hover {
width: 200px;
transform: rotate(360deg);
}
}
四.react-addons-css-transition-group插件
1.react-addons-transition-group插件,就是在transition和animation两个css属性上实现的.
2.ReactCSSTransition工作原理
当组件出现时,会在组件添加transitionName-appear,然后下一时刻会给组件添加transitionName-appear-active类,
当组件进场时,给组件添加transitionName-enter类,然后下一时刻会给组件添加transitionName-enter-active类;
当组件出场时,会给组件添加transitionName-leave类,然后下一时刻给组件添加transitionName-leave-active类,
我们则可以在css文件中,通过设置transition,设置我们需要执行的动画.
一般情况下,我们主要使用后两种,并且,只有当组件的出场动画完全执行完以后,组件才会被移除.
2.ReactCSSTransitionGroup组件参数
ReactCSSTransitionGroup其实就是一个组件,他规定了特定的参数,我们通过设置这些特定的参数,将这些参数反应到被其包裹的子组件中.
transitionName:设置动态生成类的自定义前缀.
component:字符串,设置ReactCSSTransition生成包裹子组件的标签,默认时span,我们可以通过这个参数自定义,如div,li
transitionEnter:布尔值,设置是否使用出场动画,默认时true.
transitionEnterTimeout:数值,设置入场动画的执行时间,需要在css中和这里同时设置,否则会提示警告.
transitionLeave:布尔值,设置是否使用出场动画,默认时true.
transitionLeaveTimeout:数值,设置出场动画的执行时间,需要在css中和这里同时设置,否则会提示警告.
3.使用步骤
1.引包
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
2.将ReactCSSTransition组件添加到render中
ReactCSSTransitionGroup组件需要添加到已经挂载到页面上的dom元素中.
淡入淡出实例
class TodoList extends Component {
constructor(props) {
super(props);
this.state = {
items: ['1111', '2222', '3333', '4444']
};
}
handleAdd = () => {
var newItems = this.state.items.concat([prompt('enter some text')]);
this.setState({
items: newItems
});
}
handleRemove = (i) => {
var newItems = this.state.items.slice();
newItems.splice(i, 1);
this.setState({
items: newItems
});
}
render() {
return (
<div>
<button onClick={ this.handleAdd }>Add Item</button>
<ReactCSSTransitionGroup
transitionName="example"
transitionEnterTimeout={ 500 }
transitionLeaveTimeout={ 300 }
>
{
this.state.items.map((item, i) => {
return (
<div key={ i } onClick={ this.handleRemove.bind(this, i) }>
{ item }
</div>
)
})
}
</ReactCSSTransitionGroup>
</div>
);
}
}
.example-enter {
opacity: 0.01;
}
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}
轮播图实例
class ImageCarousel extends Component {
constructor(props) {
super(props);
this.state = {
a: [
'https://s1.sonkwo.com/FhXx9C5gqykP4UUJHPKfpS1cexVP',
'http://7fvk4m.com1.z0.glb.clouddn.com/Fjn9lT9RdzW1dpIJ_7vSrxB4UKNB',
'http://7fvk4m.com1.z0.glb.clouddn.com/FsDTCVnB9DYkWF-m0p7zNdVfadTg'
],
current: 0
};
}
componentDidMount() {
setInterval(() => {
let current = this.state.current;
current++;
if (current > this.state.a.length - 1) {
current = 0;
}
this.setState({
current
});
}, 5000);
}
render() {
let { a, current } = this.state;
return (
<div className="react-slide">
<ReactCSSTransitionGroup
component={'li'}
transitionName="carousel"
transitionEnterTimeout={ 1000 }
transitionLeaveTimeout={ 1000 }
>
<img src={ a[current] } key={ a[current] } />
</ReactCSSTransitionGroup>
</div>
);
}
}
.react-slide {
li {
width: 440px;
height: 260px;
overflow: hidden;
}
.carousel-enter {
opacity: 0.01;
}
.carousel-enter.carousel-enter-active {
opacity: 1;
transition: opacity 1s ease-in-out;
}
.carousel-leave {
opacity: 1;
}
.carousel-leave.carousel-leave-active {
opacity: 0.01;
transition: opacity 1s ease-in-out;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。