当前位置: 首页> 教育> 大学 > React@16.x(33)动画(上)

React@16.x(33)动画(上)

时间:2025/7/11 17:56:51来源:https://blog.csdn.net/qq_40147756/article/details/139638456 浏览次数:0次

目录

  • 1,Transition
    • 一些常用 props
      • 1,mountOnEnter
      • 2,unmountOnExit
      • 3,appear
  • 2,CSSTransition
    • 2.1,和 Transition 组件的区别
    • 2.2,举例
    • 2.3,常用 props
      • 2.3.1,classNames
      • 2.3.2,appear
    • 2.4,结合 animate.css

使用 react-transition-group 来实现动画。总共有4个动画组件,覆盖大多应用场景。

1,Transition

官方文档

过渡动画的原理,和 Vue的过渡动画 类似。分为2个阶段:

  1. 进入(enter)过渡动画,对应的状态有3个,
    1. 进入前的初始状态 default
    2. 动画进行中的状态 entering
    3. 进入后的结束状态 entered
  2. 退出(exit / leave)过渡动画,对应的状态也是3个,
    1. 退出前的初始状态 entered
    2. exiting
    3. exited

注意
进入前的初始状态和 exited 是一个状态。
退出前的初始状态和 entered 也是一个状态。

以一个渐入渐出动画举例,

.default {transition: opacity 2s ease-in-out;
}
.default, .exiting, .exited{opacity: 0;
}
.entering, .entered {opacity: 1;
}

官方文档的例子:

import { Transition } from "react-transition-group";
import { useRef, useState } from "react";// 过渡时间
const duration = 300;// 默认样式
const defaultStyle = {transition: `opacity ${duration}ms ease-in-out`,opacity: 0,
};// 过渡样式
const transitionStyles = {entering: { opacity: 1 },entered: { opacity: 1 },exiting: { opacity: 0 },exited: { opacity: 0 },
};/*** Transition.children 是一个函数,函数的返回值是要进行动画的元素。* 函数会随着过渡动画的进行而调用(进入动画会调用3次,对应3种状态),参数 state 就是当前过渡状态。* @param {in} boolean,动画开关。从 false-> true,开启进入动画,反之退出动画。* @returns*/
function Fade({ in: inProp }) {const nodeRef = useRef(null);return (<TransitionnodeRef={nodeRef}in={inProp}timeout={duration}addEndListener={() => {nodeRef.current.addEventListener("transitionend",() => {console.log("过渡结束");},{ once: true });}}>{(state) => (<divref={nodeRef}style={{...defaultStyle,...transitionStyles[state],}}>I'm a fade Transition!</div>)}</Transition>);
}export default function App() {const [visible, setVisible] = useState(true);return (<><buttononClick={() => {setVisible(!visible);}}>切换动画</button><Fade in={visible} /></>);
}

效果:

在这里插入图片描述

也可以不用内联样式,而用 class 来添加更多的样式:

<div className={state}>I'm a fade Transition!</div>

一些常用 props

1,mountOnEnter

延迟挂载。顾名思义,在进入动画开始前再加载要进行动画的元素。默认 false 立即加载。

比如,对渐入渐出动画来说,如果初始值 in={false},也就是说元素一开始是隐藏的。

  • 默认情况下 mountOnEnter={false} 元素依然会被挂载到 DOM 中,等待动画开始。
  • 如果设置 mountOnEntermountOnEnter={true} 则元素延迟挂载,一开始并不会挂载到DOM中,直到动画开始才挂载并进行动画。

2,unmountOnExit

顾名思义,在退出动画结果后,是否在DOM中直接卸载动画元素。默认 false 不卸载。

3,appear

默认情况下,在元素挂载阶段,如果 in={true} 则直接进入动画的最终状态,整个过程 Transition.children 只会调用一次,参数 state=entered

此时设置 appearappear={true},则进入动画会经历完整3个阶段,函数也会运行 3 次。

注意,Transition 组件中并没有提供 appear 这个状态,所以也无法设置改状态下的样式。所以只是函数会运行3次而已
如果想一开始就执行一次进入的过渡动画,得使用下面这个组件 CSSTransition

还有其他的一些属性不多介绍了,比如设置过渡动画结束后的回调函数等。用到时参考官方文档即可。

2,CSSTransition

官方文档

2.1,和 Transition 组件的区别

  1. CSSTransition 是在 Transition 的基础上实现的,可以理解为是它的增强版,同时继承了它的所有属性 props。
  2. Transition 只是提供了基础的进入和退出动画,并将过渡状态 state 暴露出来,通过它来设置样式。更复杂的动画需要用到 onEnter 等回调函数来实现。
    CSSTransition 是基于 CSS 的过渡动画组件,只需要为不同的过渡状态指定相应的类名(classNames),CSSTransition 会自动在适当的时机添加或删除这些类。
  3. CSSTransition* 能够实现加载动画

2.2,举例

import { CSSTransition } from "react-transition-group";
import { useState } from "react";
import "./App.css";export default function App() {const [inProp, setInProp] = useState(true);return (<div><CSSTransition in={inProp} timeout={200} classNames="crane"><div>classNames 是自定义类名前缀</div></CSSTransition><button type="button" onClick={() => setInProp(!inProp)}>进入/退出</button></div>);
}
.crane-enter {opacity: 0;
}
.crane-enter-active {opacity: 1;transition: opacity 200ms;
}
.crane-enter-done {opacity: 1;
}
.crane-exit {opacity: 1;
}
.crane-exit-active {opacity: 0;transition: opacity 200ms;
}.crane-exit-done {opacity: 0;
}

逻辑,动画效果和 Transition 组件差不多。同样的,进入和退出动画分别有3种状态,不过直接对应到类名上了:

  • 进入动画
    1. enter,动画开始前的初始化类名。
    2. enter-active,动画进行中的类名。
    3. enter-done,动画结束后的类名。
  • 退出动画
    1. exit
    2. exit-active
    3. exit-done
  • 还多了加载动画
    1. appear
    2. appear-active
    3. appear-done

2.3,常用 props

2.3.1,classNames

有2种情况:

  • 字符串,表示动画类名前缀(上面的例子已经演示了)。
  • 对象,设置状态对应的动画类名(所以可结合 animate.css 使用,下文有举例)。
classNames={{appear: 'my-appear',appearActive: 'my-active-appear',appearDone: 'my-done-appear',enter: 'my-enter',enterActive: 'my-active-enter',enterDone: 'my-done-enter',exit: 'my-exit',exitActive: 'my-active-exit',exitDone: 'my-done-exit',
}}

2.3.2,appear

Transition 组件的 appear 属性中,介绍了它没有对应的状态来设置样式。而 CSSTransition 组件是有的。

举例:(只包含关键代码)

<CSSTransition in={true} appear classNames="crane"></CSSTransition>
.crane-appear {transform: translateX(200px);
}
.crane-appear-active {transform: translateX(0);transition: transform 200ms;
}
.crane-appear-done {transform: translateX(0);
}

这样,在页面加载完成时(刷新页面后),就会执行上面的动画了。

2.4,结合 animate.css

animate 样式举例1,animate 样式举例2

安装:

npm install animate.css -S

样例完整代码:

import { CSSTransition } from "react-transition-group";
import { useRef, useState } from "react";
import "./App.css";
import "animate.css";function MyCSSTransition({ in: inProp, children }) {return (<div><CSSTransitionin={inProp}appearmountOnEntertimeout={1000}classNames={{appearActive: "animate__fadeInRight",enterActive: "animate__fadeInRight",exitActive: "animate__fadeOutLeft",exitDone: "exit-done",}}><div className="animate__animated common">{children}</div></CSSTransition></div>);
}export default function App() {const [inProp, setInProp] = useState(true);return (<div className="app-box"><MyCSSTransition in={inProp}><h1>组件1</h1></MyCSSTransition><MyCSSTransition in={!inProp}><h1>组件2</h1></MyCSSTransition><button type="button" onClick={() => setInProp(!inProp)}>进入/退出</button></div>);
}
/* App.css */
.app-box {position: relative;margin-left: 80px;padding-top: 100px;width: 200px;
}
.common {position: absolute;top: 0;
}.exit-done {display: none;
}

效果:

在这里插入图片描述

注意点:

1,在引入 animate.css 后,对要进行动画的元素的添加基础类名animate__animated,其他过渡动画添加 animate__动画类名即可。比如:

<h1 class="animate__animated animate__bounce">An animated element</h1>

2,classNames 属性的类名最终会添加到 ref={nodeRef} 的元素上。

3,因为 animate.css 中的类名都是过渡动画的类名,所以只需要设置 appearActiveenterActiveexitActive这3个进行中的状态类名+最终态类名即可。

4,注意也设置了 mountOnEnter 属性,这是为了让没有进行动画的元素先不加载,以免影响到进行加载动画 appearActive 的元素。

接下篇文章 React 动画(下)


以上。

关键字:React@16.x(33)动画(上)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: