参考答案:
在日常开发中,页面切换时的转场动画是比较基础的一个场景
当一个组件在显示与消失过程中存在过渡动画,可以很好的增加用户的体验
在react
中实现过渡动画效果会有很多种选择,如react-transition-group
,react-motion
,Animated
,以及原生的CSS
都能完成切换动画
在react
中,react-transition-group
是一种很好的解决方案,其为元素添加enter
,enter-active
,exit
,exit-active
这一系列勾子
可以帮助我们方便的实现组件的入场和离场动画
其主要提供了三个主要的组件:
其实现动画的原理在于,当CSSTransition
的in
属性置为true
时,CSSTransition
首先会给其子组件加上xxx-enter
、xxx-enter-active
的class
执行动画
当动画执行结束后,会移除两个class
,并且添加-enter-done
的class
所以可以利用这一点,通过css
的transition
属性,让元素在两个状态之间平滑过渡,从而得到相应的动画效果
当in
属性置为false
时,CSSTransition
会给子组件加上xxx-exit
和xxx-exit-active
的class
,然后开始执行动画,当动画结束后,移除两个class
,然后添加-enter-done
的class
如下例子:
1export default class App2 extends React.PureComponent { 2 3 state = {show: true}; 4 5 onToggle = () => this.setState({show: !this.state.show}); 6 7 render() { 8 const {show} = this.state; 9 return ( 10 <div className={'container'}> 11 <div className={'square-wrapper'}> 12 <CSSTransition 13 in={show} 14 timeout={500} 15 classNames={'fade'} 16 unmountOnExit={true} 17 > 18 <div className={'square'} /> 19 </CSSTransition> 20 </div> 21 <Button onClick={this.onToggle}>toggle</Button> 22 </div> 23 ); 24 } 25}
对应css
样式如下:
1.fade-enter { 2 opacity: 0; 3 transform: translateX(100%); 4} 5 6.fade-enter-active { 7 opacity: 1; 8 transform: translateX(0); 9 transition: all 500ms; 10} 11 12.fade-exit { 13 opacity: 1; 14 transform: translateX(0); 15} 16 17.fade-exit-active { 18 opacity: 0; 19 transform: translateX(-100%); 20 transition: all 500ms; 21}
SwitchTransition
可以完成两个组件之间切换的炫酷动画
比如有一个按钮需要在on
和off
之间切换,我们希望看到on
先从左侧退出,off
再从右侧进入
SwitchTransition
中主要有一个属性mode
,对应两个值:
SwitchTransition
组件里面要有CSSTransition
,不能直接包裹你想要切换的组件
里面的CSSTransition
组件不再像以前那样接受in
属性来判断元素是何种状态,取而代之的是key
属性
下面给出一个按钮入场和出场的示例,如下:
1import { SwitchTransition, CSSTransition } from "react-transition-group"; 2 3export default class SwitchAnimation extends PureComponent { 4 constructor(props) { 5 super(props); 6 7 this.state = { 8 isOn: true 9 } 10 } 11 12 render() { 13 const {isOn} = this.state; 14 15 return ( 16 <SwitchTransition mode="out-in"> 17 <CSSTransition classNames="btn" 18 timeout={500} 19 key={isOn ? "on" : "off"}> 20 { 21 <button onClick={this.btnClick.bind(this)}> 22 {isOn ? "on": "off"} 23 </button> 24 } 25 </CSSTransition> 26 </SwitchTransition> 27 ) 28 } 29 30 btnClick() { 31 this.setState({isOn: !this.state.isOn}) 32 } 33}
css
文件对应如下:
1.btn-enter { 2 transform: translate(100%, 0); 3 opacity: 0; 4} 5 6.btn-enter-active { 7 transform: translate(0, 0); 8 opacity: 1; 9 transition: all 500ms; 10} 11 12.btn-exit { 13 transform: translate(0, 0); 14 opacity: 1; 15} 16 17.btn-exit-active { 18 transform: translate(-100%, 0); 19 opacity: 0; 20 transition: all 500ms; 21}
当有一组动画的时候,就可将这些CSSTransition
放入到一个TransitionGroup
中来完成动画
同样CSSTransition
里面没有in
属性,用到了key
属性
TransitionGroup
在感知children
发生变化的时候,先保存移除的节点,当动画结束后才真正移除
其处理方式如下:
插入的节点,先渲染dom,然后再做动画
删除的节点,先做动画,然后再删除dom
如下:
1import React, { PureComponent } from 'react' 2import { CSSTransition, TransitionGroup } from 'react-transition-group'; 3 4export default class GroupAnimation extends PureComponent { 5 constructor(props) { 6 super(props); 7 8 this.state = { 9 friends: [] 10 } 11 } 12 13 render() { 14 return ( 15 <div> 16 <TransitionGroup> 17 { 18 this.state.friends.map((item, index) => { 19 return ( 20 <CSSTransition classNames="friend" timeout={300} key={index}> 21 <div>{item}</div> 22 </CSSTransition> 23 ) 24 }) 25 } 26 </TransitionGroup> 27 <button onClick={e => this.addFriend()}>+friend</button> 28 </div> 29 ) 30 } 31 32 addFriend() { 33 this.setState({ 34 friends: [...this.state.friends, "coderwhy"] 35 }) 36 } 37}
对应css
如下:
1.friend-enter { 2 transform: translate(100%, 0); 3 opacity: 0; 4} 5 6.friend-enter-active { 7 transform: translate(0, 0); 8 opacity: 1; 9 transition: all 500ms; 10} 11 12.friend-exit { 13 transform: translate(0, 0); 14 opacity: 1; 15} 16 17.friend-exit-active { 18 transform: translate(-100%, 0); 19 opacity: 0; 20 transition: all 500ms; 21}
最近更新时间:2024-08-10