React动画

React动画库:react-transition-group(官网

React动画 - Transition

Transition有4个状态

  • 'entering'
  • 'entered'
  • 'exiting'
  • 'exited'

可以通过in来切换状态,timeout决定状态的持续时间

in为true时,为进入状态,,发生:

  1. 为Transition内部的DOM根元素(后续统一称之为DOM元素)添加样式entering类名
  2. 当timeout结束后,去掉之前的样式,Dom元素添加entered类名

in为false时,为退出状态,,发生:

  1. 为Transition内部的DOM根元素添加样式exiting类名
  2. 当timeout结束后,去掉之前的样式,Dom元素添加exited类名
import { Transition } from 'react-transition-group';
import { useRef } 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 },
};

function Fade({ in: inProp }) {
  const nodeRef = useRef(null);
  return (
    <Transition nodeRef={nodeRef} in={inProp} timeout={duration}>
      {state => (
        <div ref={nodeRef} style={{
          ...defaultStyle,
          ...transitionStyles[state]
        }}>
          I'm a fade Transition!
        </div>
      )}
    </Transition>
  );
}

React动画 - CSSTransition

当进入时,发生:

  1. 为CSSTransition内部的DOM根元素(后续统一称之为DOM元素)添加样式enter
  2. 在一下帧(enter样式已经完全应用到了元素),立即为该元素添加样式enter-active
  3. 当timeout结束后,去掉之前的样式,添加样式enter-done

当退出时,发生:

  1. 为CSSTransition内部的DOM根元素(后续统一称之为DOM元素)添加样式exit
  2. 在一下帧(exit样式已经完全应用到了元素),立即为该元素添加样式exit-active
  3. 当timeout结束后,去掉之前的样式,添加样式exit-done

设置classNames属性,可以指定类样式的名称

  1. 字符串:为类样式添加前缀
  2. 对象:为每个类样式指定具体的名称(非前缀)

关于首次渲染时的类样式,appear、apear-active、apear-done,它和enter的唯一区别在于完成时,会同时加入apear-done和enter-done

还可以与Animate.css联用

function App() {
  const [inProp, setInProp] = useState(false);
  const nodeRef = useRef(null);
  return (
    <div>
      <CSSTransition nodeRef={nodeRef} in={inProp} timeout={200} classNames="my-node">
        <div ref={nodeRef}>
          {"I'll receive my-node-* classes"}
        </div>
      </CSSTransition>
      <button type="button" onClick={() => setInProp(true)}>
        Click to Enter
      </button>
    </div>
  );
}

React动画 - SwitchTransition

用于有秩序的切换内部组件

默认情况下:out-in

  1. 当key值改变时,会将之前的DOM根元素添加退出样式(exit,exit-active)
  2. 退出完成后,将该DOM元素移除
  3. 重新渲染内部DOM元素
  4. 为新渲染的DOM根元素添加进入样式(enter, enter-active, enter-done)

in-out:

  1. 重新渲染内部DOM元素,保留之前的元素
  2. 为新渲染的DOM根元素添加进入样式(enter, enter-active, enter-done)
  3. 将之前的DOM根元素添加退出样式(exit,exit-active)
  4. 退出完成后,将该DOM元素移除
function App() {
 const [state, setState] = useState(false);
 const helloRef = useRef(null);
 const goodbyeRef = useRef(null);
 const nodeRef = state ? goodbyeRef : helloRef;
 return (
   <SwitchTransition>
     <CSSTransition
       key={state ? "Goodbye, world!" : "Hello, world!"}
       nodeRef={nodeRef}
       addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
       classNames='fade'
     >
       <button ref={nodeRef} onClick={() => setState(state => !state)}>
         {state ? "Goodbye, world!" : "Hello, world!"}
       </button>
     </CSSTransition>
   </SwitchTransition>
 );
}

.fade-enter{
   opacity: 0;
}
.fade-exit{
   opacity: 1;
}
.fade-enter-active{
   opacity: 1;
}
.fade-exit-active{
   opacity: 0;
}
.fade-enter-active,
.fade-exit-active{
   transition: opacity 500ms;
}

React动画 - TransitionGroup

该组件的children,接收多个Transition或CSSTransition组件,该组件用于根据这些子组件的key值,控制他们的进入和退出状态

import React, { useState } from 'react'
import uuid from "uuid";
import { TransitionGroup, CSSTransition } from "react-transition-group"
import "./App.css"

export default function App() {
    const [tasksList, setTasksList] = useState([
        { id: uuid(), name: "任务1" },
        { id: uuid(), name: "任务2" },
    ]);
    return (
        <div>
            <TransitionGroup appear component="ul" className="abc">
                {
                    tasksList.map(t => (
                        <CSSTransition  timeout={2000} key={t.id}>
                            <li>{t.name} <button
                                onClick={() => {
                                    var newTasks = tasksList.filter(it => it.id !== t.id);
                                    setTasksList(newTasks);
                                }}
                            >删除</button></li>
                        </CSSTransition>
                    ))
                }
            </TransitionGroup>
            <button onClick={() => {
                var name = window.prompt("请输入任务名称");
                setTasksList([...tasksList, { id: uuid(), name }])
            }}>添加一个任务</button>
        </div>

    )
}

.exit{
    transform-origin: left top;
}

.exit-active{
    transform: scale(0);
    transition: 2s;
}

.enter{
    transform-origin: left top;
    transform: scale(0);
}

.enter-active{
    transform: scale(1);
    transition: 2s;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值