1、转场动画(入场、离场)
使用 react-transition-group.
注意点:
-
CSSTransitionGroup
默认在 DOM 树中生成一个span
标签包裹其子节点,如果想要使用其他 html 标签,可设定CSSTransitionGroup
的component
属性; -
CSSTransitionGroup
的子元素必须添加key
值才会在节点发生变化时,准确地计算出哪些节点需要添加入场动画,哪些节点需要添加离场动画; -
CSSTransitionGroup
的动画效果只作用于直接子节点,不作用于其孙子节点; - 动画的结束时间不以 css 中 transition-duration 为准,而是以
transitionEnterTimeout
,transitionLeaveTimeout
,TransitionAppearTimeout
为准,因为某些情况下 transitionend 事件不会被触发,详见MDN transitionend。
import React, { Component } from 'react';
import { CSSTransitionGroup } from 'react-transition-group';
export default class Tabs extends Component {
constructor(props) {
super(props);
this.state = {
activeId: 1,
tabData: [{
id: 1,
panel: '选项1'
}, {
id: 2,
panel: '选项2'
}]
};
}
addTab = () => {
// 添加tab代码
...
}
deleteTab = (id) => {
// 删除tab代码
...
}
render() {
const { tabData, activeId } = this.state;
const renderTabs = () => {
return tabData.map((item, index) => {
return (
<div
className={`tab-item${item.id === activeId ? ' tab-item-active' : ''}`}
key={`tab${item.id}`}
>
{item.panel}
<span className="btns btn-delete" onClick={() => this.deleteTab(item.id)}>✕</span>
</div>
);
})
}
return (
<div>
<div className="tabs" >
<CSSTransitionGroup
transitionName="tabs-wrap"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
{renderTabs()}
</CSSTransitionGroup>
<span className="btns btn-add" onClick={this.addTab}>+</span>
</div>
<div className="tab-cont">
cont
</div>
</div>
);
}
}
/* tab动态增加动画 */
.tabs-wrap-enter {
opacity: 0.01;
}
.tabs-wrap-enter.tabs-wrap-enter-active {
opacity: 1;
transition: all 500ms ease-in;
}
.tabs-wrap-leave {
opacity: 1;
}
.tabs-wrap-leave.tabs-wrap-leave-active {
opacity: 0.01;
transition: all 500ms ease-in;
}
2、单元素简单动画
使用 CSS3 transition || animation。
关键点:css做动画的属性值由state来控制
import React, { Component } from 'react';
export default class Progress extends Component {
constructor(props) {
super(props);
this.state = {
percent: 10
};
}
increase = () => {
const percent = this.state.percent + 10;
this.setState({
percent: percent > 100 ? 100 : percent,
})
}
decrease = () => {
const percent = this.state.percent - 10;
this.setState({
percent: percent < 0 ? 0 : percent,
})
}
render() {
const { percent } = this.state;
return (
<div>
<div className="progress">
<div className="progress-wrapper" >
<div className="progress-inner" style = {{width: `${percent}%`}} ></div>
</div>
<div className="progress-info" >{percent}%</div>
</div>
<div className="btns">
<button onClick={this.decrease}>-</button>
<button onClick={this.increase}>+</button>
</div>
</div>
);
}
}
.progress-inner {
transition: width 400ms cubic-bezier(0.08, 0.82, 0.17, 1);
}
3、react-motion
提供缓动函数,动画效果更逼真
用react-motion实现react动画
网友评论