54

React系列十四 - React过渡动画

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=Mzg5MDAzNzkwNA%3D%3D&%3Bmid=2247484083&%3Bidx=1&%3Bsn=badac94836b7908c604b7525b6e21017
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

当然,我们可以通过原生的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"]
    })
  }
}

Recommend

  • 86
    • www.10tiao.com 6 years ago
    • Cache

    React Native中的动画过渡

    最近我在为下一个动画设计试着找新灵感,并在一个网站上看到了一些。我很好奇能否用React Native实现这些过渡。 我们可以看到上图包含了几个动画,工具栏(...

  • 81
    • www.zhangxinxu.com 6 years ago
    • Cache

    canvas中颜色过渡动画效果的实现

    这篇文章发布于 2018年07月22日,星期日,21:14,归类于canvas相关。 阅读 27 次, 今日 27 次 byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=7809...

  • 46
    • www.heeroluo.net 6 years ago
    • Cache

    页面过渡动画优化探索

    对于移动端的Web单页应用来说,为了达到媲美原生应用的效果,页面过渡动画是必不可少的。常用的页面过渡动画包括: 位移——当前页向左侧或右侧水平移出可视区,下一页由反方向移入可视区。 不透明度变化——当前页...

  • 8

    这个问题源自于掘金上的一个留言,一个朋友问到,为什么我下面这段代码的高度过渡动画失效了? 伪代码大概是这样: { height: unset; transition: all 0.3s linear; will-change: height; &.up...

  • 7
    • knightyun.github.io 3 years ago
    • Cache

    CSS3 过渡与动画

    CSS3中出现很多新的特性,下面就讲一下其中比较好玩的3D操作,过渡和动画效果; 过渡(transition) 过渡就是使瞬间的样式变化,按照一定方式变得缓慢平缓; 例如鼠标划过超链接时...

  • 4
    • www.bilibili.com 3 years ago
    • Cache

    你敢信这是十四年前的动画?

    你敢信这是十四年前的动画?_哔哩哔哩_bilibili活动作品你敢信这是十四年前的动画?122.1万播放 · 总弹幕数12452022-02-19 05:50:39  全站排行榜最高第65名

  • 5

    Vue过渡和动画效果展示(案例、GIF动图演示、附源码) 本篇随笔主要写了Vue过渡...

  • 4

    在 android5.0 以上版本中,google 为我们提供了几种 activity 切换的过渡动画,目的是为了让 activity 切换转场更加美观,而在 android5.0 之前的 activity 切换显得生硬。虽然可以自定义给 activity 增添动画效果,但是效果也不尽如意。而 androi5.x 提供的切换动...

  • 5

    V2EX  ›  React React 中怎么快速实现 /t/897332 这种过渡动画?  

  • 3

    微软 Windows 11 虚拟桌面过渡动画回归,并添加切换提示 作者:汪淼 2023-05-04 07:20:56 根据海外网友 PhantomOfEarth 发现的最新测试内容,微软正在为 Windows 11 改进虚拟桌面,在预览版 Build 23440 和 Build...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK