React系列十四 - React过渡动画

栏目: IT技术 · 发布时间: 3年前

内容简介:在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,可以很好的增加用户体验。当然,我们可以通过原生的CSS来实现这些过渡动画,但是React社区为我们提供了react-transition-group用来完成过渡动画。React曾为开发者提供过动画插件

在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,可以很好的增加用户体验。

当然,我们可以通过原生的CSS来实现这些过渡动画,但是React社区为我们提供了react-transition-group用来完成过渡动画。

一. react-transition-group介绍

React曾为开发者提供过动画插件 react-addons-css-transition-group ,后由社区维护,形成了现在的 react-transition-group

这个库可以帮助我们方便的实现组件的 入场离场 动画,使用时需要进行额外的安装:

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

# yarn
yarn add react-transition-group

react-transition-group本身非常小,不会为我们应用程序增加过多的负担。

react-transition-group主要包含四个组件:

  • Transition

    • 该组件是一个和平台无关的组件(不一定要结合CSS);

    • 在前端开发中,我们一般是结合CSS来完成样式,所以比较常用的是CSSTransition;

  • CSSTransition

    • 在前端开发中,通常使用CSSTransition来完成过渡动画效果

  • SwitchTransition

    • 两个组件显示和隐藏切换时,使用该组件

  • TransitionGroup

    • 将多个动画组件包裹在其中,一般用于列表中元素的动画;

二. react-transition-group使用

2.1. CSSTransition

CSSTransition是基于Transition组件构建的:

  • CSSTransition执行过程中,有三个状态:appear、enter、exit;

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

    • 第一类,开始状态:对于的类是-appear、-enter、exit;

    • 第二类:执行动画:对应的类是-appear-active、-enter-active、-exit-active;

    • 第三类:执行结束:对应的类是-appear-done、-enter-done、-exit-done;

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 './App.css'

import { CSSTransition } from 'react-transition-group';

import { Card, Avatar, Button } from 'antd';
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';

const { Meta } = Card;

export default class App extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      isShowCard: true
    }
  }

  render() {
    return (
      <div>
        <Button type="primary" onClick={e => this.setState({isShowCard: !this.state.isShowCard})}>显示/隐藏</Button>
        <CSSTransition in={this.state.isShowCard}
                       classNames="card"
                       timeout={1000}
                       unmountOnExit={true}
                       onEnter={el => console.log("进入动画前")}
                       onEntering={el => console.log("进入动画")}
                       onEntered={el => console.log("进入动画后")}
                       onExit={el => console.log("退出动画前")}
                       onExiting={el => console.log("退出动画")}
                       onExited={el => console.log("退出动画后")}
                      >
          <Card
            style={{ width: 300 }}
            cover={
              <img
                alt="example"
                src="https://gw.alipayobjects.com/zos/rmsportal/JiqGstEfoWAOHiTxclqi.png"
              />
            }
            actions={[
              <SettingOutlined key="setting" />,
              <EditOutlined key="edit" />,
              <EllipsisOutlined key="ellipsis" />,
            ]}
          >
            <Meta
              avatar={<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />}
              title="Card title"
              description="This is the description"
            />
          </Card>
        </CSSTransition>
      </div>
    )
  }
}

对应的css样式如下:

.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.2. SwitchTransition

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

  • 比如我们有一个按钮需要在on和off之间切换,我们希望看到on先从左侧退出,off再从右侧进入;

  • 这个动画在vue中被称之为 vue transition modes;

  • react-transition-group中使用SwitchTransition来实现该动画;

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

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

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

如何使用SwitchTransition呢?

  • SwitchTransition组件里面要有CSSTransition或者Transition组件,不能直接包裹你想要切换的组件;

  • SwitchTransition里面的CSSTransition或Transition组件不再像以前那样接受in属性来判断元素是何种状态,取而代之的是key属性;

我们来演练一个按钮的入场和出场效果:

import { SwitchTransition, CSSTransition } from "react-transition-group";

export default class SwitchAnimation extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      isOn: true
    }
  }

  render() {
    const {isOn} = this.state;

    return (
      <SwitchTransition mode="out-in">
        <CSSTransition classNames="btn"
                       timeout={500}
                       key={isOn ? "on" : "off"}>
          {
          <button onClick={this.btnClick.bind(this)}>
            {isOn ? "on": "off"}
          </button>
        }
        </CSSTransition>
      </SwitchTransition>
    )
  }

  btnClick() {
    this.setState({isOn: !this.state.isOn})
  }
}

对应的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;
}

2.3. TransitionGroup

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

import React, { PureComponent } from 'react'
import { CSSTransition, TransitionGroup } from 'react-transition-group';

export default class GroupAnimation extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      friends: []
    }
  }

  render() {
    return (
      <div>
        <TransitionGroup>
          {
            this.state.friends.map((item, index) => {
              return (
                <CSSTransition classNames="friend" timeout={300} key={index}>
                  <div>{item}</div>
                </CSSTransition>
              )
            })
          }
        </TransitionGroup>
        <button onClick={e => this.addFriend()}>+friend</button>
      </div>
    )
  }

  addFriend() {
    this.setState({
      friends: [...this.state.friends, "coderwhy"]
    })
  }
}

以上所述就是小编给大家介绍的《React系列十四 - React过渡动画》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP for the World Wide Web, Second Edition (Visual QuickStart Gu

PHP for the World Wide Web, Second Edition (Visual QuickStart Gu

Larry Ullman / Peachpit Press / 2004-02-02 / USD 29.99

So you know HTML, even JavaScript, but the idea of learning an actual programming language like PHP terrifies you? Well, stop quaking and get going with this easy task-based guide! Aimed at beginning ......一起来看看 《PHP for the World Wide Web, Second Edition (Visual QuickStart Gu》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具