【问题标题】:How to start react-spring animation only on startup如何仅在启动时启动 react-spring 动画
【发布时间】:2020-11-06 04:07:56
【问题描述】:

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

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

我只想让该动画在应用启动时触发一次。不是每次切换到主页后。 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,因为我想在开始时触发该动画。这部分效果很好。

Home 组件的 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>

【问题讨论】:

  • 您可以使用浏览器历史记录来确保您已经访问过主页。你试过了吗?你已经在使用 react-router-dom 了。
  • 不,我没试过。我对此有点陌生,所以这就是我在这里寻求帮助的原因。浏览器历史记录很难吗?
  • 您可以使用useEffect 在渲染组件时触发动画。但问题是当您访问该组件时,您的动画会一次又一次地触发。这就是现在发生的事情。我说的对吗?
  • 是的。你说的对 。我在发布这个问题之前尝试过这种 useEffect 方法:/

标签: javascript reactjs react-router react-spring


【解决方案1】:

如果您的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");
}

【讨论】:

    【解决方案2】:

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

      const [animFinished, setAnimFinished] = React.useState(false);
    
    ...
    
      <Home animFinished={animFinished} setAnimFinished={setAnimFinished} />
    

    现在在 Home 组件中确保如果 animFinished 为真,动画将不会运行。例如将 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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-23
      • 1970-01-01
      • 2020-07-11
      相关资源
      最近更新 更多