如何仅在启动时启动反应弹簧动画

时间:2020-11-05 14:10:26

标签: javascript reactjs react-router react-spring

我试图弄清楚如何在应用启动时仅一次触发动画。

当前,我面临的问题是,如果我切换到另一个视图(另一个组件,使用React-router-dom),然后又切换回Home组件,动画将再次触发。我正在为这个动画使用react-spring。

我只想让该动画在应用程序启动时仅触发一次。并非每次切换到Home之后。 React-spring中是否有任何配置,或者你们知道如何防止这种情况?我真的找不到任何帮助。

设置动画

//State for animation
const [showGameOptions, setShowGameOptions] = useState(true);

//Starting animation
const gameOptionsTransitions = useTransition(showGameOptions, null, {
  from: { opacity: 0, transform: 'translateY(200px)' },
  enter: { opacity: 1, transform: 'translateY(0)' },
  leave: { opacity: 0, transform: 'translateY(200px)' },
});

我将初始状态设置为true,因为我想在开始时触发该动画。对于这一部分,它很好用。

主页组件的return()

<div className="homeScreen">
  <h1>Tic Tac Toe</h1>
  <p>Select game mode</p>
  {gameOptionsTransitions.map(
    ({ item, key, props }) =>
      item && (
        <animated.div key={key} style={props}>
          <Link to="/play" className="setGameMode-btn" onClick={playPlayerVsComputer}>
            Player vs. Computer
          </Link>

          <Link to="/play" className="setGameMode-btn" onClick={playPlayerVsPlayer}>
            Player vs. Player
          </Link>
        </animated.div>
      ),
  )}
</div>

2 个答案:

答案 0 :(得分:0)

如果您的app一直都是SPA,那么您可以使其与以下两种解决方案一起使用:

1。对于fist time个用户访问我们的应用程序(家庭)并且仅一次:

// Without using any server side session
let showAnimation = localStorage.getItem("show_landing_animation");
if(showAnimation === 0) {
  return <Home animate></Home>
  // After that animation has been finished set the flag as 1 in your 
  // nested spring callback
  localStorage.setItem("show_landing_animation", 1)
}
return <Home></Home>


2。对于every time个用户访问我们的应用程序(家庭)并且仅一次:

// Store a flag in "localStorage"

let showAnimation = localStorage.getItem("show_landing_animation");
if(showAnimation === 0) {
  // animate
  return <Home animate></Home>
  // After that animation has been finished set the flag as 1 in your 
  // nested spring component callback
  localStorage.setItem("show_landing_animation", 1)
}
return <Home></Home>
// remove the flag on tab close event
window.onbeforeunload = () => {
  localStorage.removeItem("show_landing_animation");
}

答案 1 :(得分:0)

首先,您需要在Home的父组件中有一个状态,以指示动画已完成。您可以将它作为属性传递给Home组件。

  const [animFinished, setAnimFinished] = React.useState(false);

...

  <Home animFinished={animFinished} setAnimFinished={setAnimFinished} />

现在,在Home组件中,如果animFinished为true,请确保动画不会运行。例如,将from转换设置为to转换。

现在,您要做的就是在动画结束时调用setAnimFinished(true)。您可以在onRest回调中完成此操作。

  const gameOptionsTransitions = useTransition(true, null, {
    from: {
      opacity: 0,
      transform: animFinished ? "translateY(0)" : "translateY(200px)"
    },
    enter: { opacity: 1, transform: "translateY(0)" },
    leave: { opacity: 0, transform: "translateY(200px)" },
    onRest: () => setAnimFinished(true)
  });

这是一个示例: https://codesandbox.io/s/react-spring-animation-on-start-only-3ivw8