React 过渡组动态改变滑动方向

React Transition Group Dynamically Change Slide Direction

我正在创建一个移动导航菜单,并使用 React Transition Group 中的 CSSTransition 组件来处理不同级别导航中的动画。

我能够在不同的层次上成功地制作动画,但只能在一个方向上。例如,内容将从右侧进入,从左侧退出。让我感到困惑的部分是当我需要更改内容动画进出的方向时。

对于我的示例,假设我有 3 张幻灯片

最初幻灯片 #2 将从右侧进入如果我们转到幻灯片 #3 它将从左侧退出。

如果我们在幻灯片 #3 上并且想返回到幻灯片 #2 那么我希望幻灯片 #2 从右边进入。

import { useState } from 'react';
import { CSSTransition } from 'react-transition-group';
import './App.css';

const App = () => {
    const [page, setPage] = useState(1);
    return (
        <>
            Page: {page}
            <nav>
                <button onClick={() => page !== 1 && setPage(page - 1)}>Prev</button>
                <button onClick={() => page >= 1 && page <= 2 && setPage(page + 1)}>
                    Next
                </button>
            </nav>
            <div className='content'>
                <CSSTransition
                    in={page === 1}
                    classNames='slide'
                    timeout={500}
                    unmountOnExit
                >
                    <SlideOne />
                </CSSTransition>
                <CSSTransition
                    in={page === 2}
                    classNames='slide'
                    timeout={500}
                    unmountOnExit
                >
                    <SlideTwo />
                </CSSTransition>
                <CSSTransition
                    in={page === 3}
                    classNames='slide'
                    timeout={500}
                    unmountOnExit
                >
                    <SlideThree />
                </CSSTransition>
            </div>
        </>
    );
};

const SlideOne = () => {
    return <h3>Hello From Slide One</h3>;
};

const SlideTwo = () => {
    return <h3>Hello From Slide Two</h3>;
};

const SlideThree = () => {
    return <h3>Hello From Slide Three</h3>;
};

export default App;
.content {
    width: 200px;
    height: 100px;
    overflow: hidden;
    box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
    padding: 1rem;
    position: relative;
}

h3 {
    position: absolute;
}

.slide-enter {
    opacity: 0;
    transform: translateX(100%);
}
.slide-enter-active {
    opacity: 1;
    transform: translateX(0%);
    transition: all 0.5s;
}
.slide-exit {
    opacity: 1;
    transform: translateX(0%);
}
.slide-exit-active {
    opacity: 0;
    transform: translateX(-100%);
    transition: all 0.5s;
}

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

const App = () => {
  const [page, setPage] = useState(1);
  const [direction, setDirection] = useState("left");
  return (
    <>
      Page: {page}
      <nav>
        <button
          onClick={() => {
            page !== 1 && setPage(page - 1);
            direction !== "right" && setDirection("right");
          }}
        >
          {" "}
          Prev
        </button>
        <button
          onClick={() => {
            page >= 1 && page <= 2 && setPage(page + 1);
            direction !== "left" && setDirection("left");
          }}
        >
          Next
        </button>
      </nav>
      <div className="content">
        {/* <TransitionGroup> */}
        <CSSTransition
          in={page === 1}
          classNames={`slide-${direction}`}
          timeout={500}
          unmountOnExit
        >
          <SlideOne />
        </CSSTransition>
        <CSSTransition
          in={page === 2}
          classNames={`slide-${direction}`}
          timeout={500}
          unmountOnExit
        >
          <SlideTwo />
        </CSSTransition>
        <CSSTransition
          in={page === 3}
          classNames={`slide-${direction}`}
          timeout={500}
          unmountOnExit
        >
          <SlideThree />
        </CSSTransition>
        {/* </TransitionGroup> */}
      </div>
    </>
  );
};

const SlideOne = () => {
  return <h3>Hello From Slide One</h3>;
};

const SlideTwo = () => {
  return <h3>Hello From Slide Two</h3>;
};

const SlideThree = () => {
  return <h3>Hello From Slide Three</h3>;
};

export default App;

.content {
  width: 200px;
  height: 100px;
  overflow: hidden;
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
  padding: 1rem;
  position: relative;
}

h3 {
  position: absolute;
}

.slide-left-enter {
  opacity: 0;
  transform: translateX(100%);
}
.slide-left-enter-active {
  opacity: 1;
  transform: translateX(0%);
  transition: all 2000ms;
}
.slide-left-exit {
  opacity: 1;
  transform: translateX(0%);
}
.slide-left-exit-active {
  opacity: 0;
  transform: translateX(-100%);
  transition: all 2000ms;
}

.slide-right-enter {
  opacity: 0;
  transform: translateX(-100%);
}
.slide-right-enter-active {
  opacity: 1;
  transform: translateX(0%);
  transition: all 2000ms;
}
.slide-right-exit {
  opacity: 1;
  transform: translateX(0%);
}
.slide-right-exit-active {
  opacity: 0;
  transform: translateX(100%);
  transition: all 2000ms;
}

诀窍是反转每个按键按钮的翻译