React过渡动画react-transition-group

React过渡动画

安装react-transition-group

# npm
npm install react-transition-group --save
# yarn
yarn add react-transition-group

可导入使用的有四个组件对象:

  • Transition(不常用)
  • CSSTransition(它的属性结合css控制组件出现、消失)
  • SwitchTransition(控制两个组件之间状态切换)
  • TransitionGroup(当有一组组件的动画时,需要使用它包裹)

使用CSSTransition

1】首先写css类名样式
  • CSSTransition执行过程中,有三个状态:appear、enter、exit;

  • 它们有三种状态,需要定义对应的CSS样式:

    • 第一类,开始状态:对于的类是-appear、-enter、-exit;
    • 第二类:执行动画:对应的类是-appear-active、-enter-active、-exit-active;
    • 第三类:执行结束:对应的类是-appear-done、-enter-done、-exit-done;
.card-enter, .card-appear {
    opacity: 0;
    transform: scale(.8);
  }
  
  .card-enter-active, .card-appear-active {
    opacity: 1;
    transform: scale(1);
    transition: opacity 300ms, transform 300ms;
  }
  
  .card-exit {
    opacity: 1;
  }
  
  .card-exit-active {
    opacity: 0;
    transform: scale(.8);
    transition: opacity 300ms, transform 300ms;
  }
2】CSSTransition组件属性
  • in:触发进入或者退出状态

    • 如果添加了unmountOnExit={true},那么该组件会在执行退出动画结束后被移除掉;
    • 当in为true时,触发进入状态,会添加-enter、-enter-acitve的class开始执行动画,当动画执行结束后,会移除两个class,并且添加-enter-done的class;
    • 当in为false时,触发退出状态,会添加-exit、-exit-active的class开始执行动画,当动画执行结束后,会移除两个class,并且添加-enter-done的class;
  • classNames:动画class的名称

    • 决定了在编写css时,对应的class名称:比如card-enter、card-enter-active、card-enter-done;
  • timeout:

    • 过渡动画的时间
  • appear:

    • 是否在初次进入添加动画(需要和in同时为true)
  • 其他属性可以参考官网来学习:

    • https://reactcommunity.org/react-transition-group/transition

CSSTransition对应的钩子函数:主要为了检测动画的执行过程,来完成一些JavaScript的操作

  • onEnter:在进入动画之前被触发;
  • onEntering:在应用进入动画时被触发;
  • onEntered:在应用进入动画结束后被触发;
import React, { Component } from 'react'
import { CSSTransition } from 'react-transition-group';
import '../style/ReactTransition.css'

interface IProps { }
interface IState {
    isShowCard: boolean
}
class ReactTransition extends Component<IProps, IState> {
    constructor(props) {
        super(props)
        this.state = {
            isShowCard: true
        }
    }
    render() {
        return (
            <div>
                <button onClick={e => this.setState({ isShowCard: !this.state.isShowCard })}>显示/隐藏</button>
                <CSSTransition
                    in={this.state.isShowCard}//为true进入显示组件(主要通过in属性来控制组件状态)
                    classNames="card"//设置类名的前缀
                    timeout={1000}//设置过渡动画事件
                    unmountOnExit={true}//消失动画结束后 + display:none
                >
                    <div>哈哈哈</div>
                </CSSTransition>
            </div>
        )
    }
}

export default ReactTransition

在这里插入图片描述

使用SwitchTransition

SwitchTransition可以完成两个组件之间切换的炫酷动画:

  • 比如我们有一个按钮需要在on和off之间切换,我们希望看到on先从左侧退出,off再从右侧进入;
  • 这个动画在vue中被称之为 vue transition modes;
  • react-transition-group中使用SwitchTransition来实现该动画;

SwitchTransition中主要有一个属性:mode,有两个值

  • in-out:表示新组件先进入,旧组件再移除;
  • out-in:表示就组件先移除,新组建再进入;

SwitchTransition还是需要通过CSSTransition来进行控制,使用key属性来控制(不能使用in属性)

  • SwitchTransition组件里面要有CSSTransition或者Transition组件,不能直接包裹你想要切换的组件;
  • SwitchTransition里面的CSSTransition或Transition组件不再像以前那样接受in属性来判断元素是何种状态,取而代之的是key属性;
import React, { Component } from 'react'
import { CSSTransition, SwitchTransition } from 'react-transition-group';
import '../style/ReactTransitionSwitch.css'

interface IProps {

}
interface IState {
    isOn: boolean
}
class ReactTransitionSwitch extends Component<IProps, IState> {
    constructor(props: IProps) {
        super(props)
        this.state = {
            isOn: true
        }
    }
    render() {
        const { isOn } = this.state;
        return (
            <div>
                <SwitchTransition mode="out-in">
                    <CSSTransition classNames="btn"
                        timeout={500}
                        key={isOn ? "on" : "off"}>
                        {
                            <button onClick={() => {
                                this.setState({ isOn: !isOn })
                            }}>
                                {isOn ? "on" : "off"}
                            </button>
                        }
                    </CSSTransition>
                </SwitchTransition>
            </div>
        )
    }
}

export default ReactTransitionSwitch

ReactTransitionSwitch.css

.btn-enter {
  transform: translate(100%, 0);
  opacity: 0;
}

.btn-enter-active {
  transform: translate(0, 0);
  opacity: 1;
  transition: all 500ms;
}

.btn-exit {
  transform: translate(0, 0);
  opacity: 1;
}

.btn-exit-active {
  transform: translate(-100%, 0);
  opacity: 0;
  transition: all 500ms;
}

在这里插入图片描述
在这里插入图片描述

使用TransitionGroup

当我们有一组动画时,需要将这些CSSTransition放入到一个TransitionGroup中来完成动画:

import React, { PureComponent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import '../style/ReactTransitionGroup.css';

interface Iprops {

}
interface Istate {
    friends: Array<string>,
    count: number
}
class ReactTransitionGroup extends PureComponent<Iprops, Istate> {
    constructor(props: Iprops) {
        super(props);
        this.state = {
            friends: [],
            count: 0
        }
    }

    render() {
        return (
            <div>
                <TransitionGroup>
                    {
                        this.state.friends.map((item, index) => {
                            return (
                                <CSSTransition classNames="friend" timeout={300} key={index}>
                                    <div>{item}
                                        <button onClick={() => {
                                            let friends = [...this.state.friends]
                                            friends.splice(index, 1)
                                            this.setState({ friends: friends })
                                        }}>&times;</button>
                                    </div>
                                </CSSTransition>
                            )
                        })
                    }
                </TransitionGroup>
                <button className='buttonAdd' onClick={() => {
                    this.setState({
                        friends: [...this.state.friends, (this.state.count + 1).toString()],
                        count: this.state.count + 1
                    })
                }}>+friend</button>
            </div>
        )
    }
}
export default ReactTransitionGroup

ReactTransitionGroup.css

.friend-enter {
    opacity: 0;
}

.friend-enter-active {
    opacity: 1;
    transition: opacity 500ms ease-in;
}

.friend-exit {
    opacity: 1;
}

.friend-exit-active {
    opacity: 0;
    transition: opacity 500ms ease-in;
}

.buttonAdd {
    position: absolute;
    top: 50%;
    left: 55%;
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值