代码之家  ›  专栏  ›  技术社区  ›  Darren

反应过渡组中的退出延迟动画

  •  8
  • Darren  · 技术社区  · 6 年前

    我在用 反应过渡组 在一个 反应 盖茨比耶斯 (V2)项目。

    我有我的页面转换与动画,但当 Link 退出 exiting 动画被缩短,因为下一页已经准备好进入。

    我试过推迟 链接 但当页面更改被延迟时 exit 直到 delay 结束了 链接 被起诉了。

    我怎么能 延迟 页面更改,同时启动 退出的 动画 onClick ? 或者,有更好的方法或者 props 有空吗?

    这是我的密码

    布局.js

    class Layout extends React.Component {
      ...
      return (
        <Transition>{children}</Transition>
      );
    }
    

    过渡.js

    class Transition extends React.Component {
    constructor(props) {
        super(props);
        this.state = { exiting: false };
        this.listenerHandler = this.listenerHandler.bind(this);
      }
    
      listenerHandler() {
        this.setState({ exiting: true });
      }
    
      componentDidMount() {
        window.addEventListener(historyExitingEventType, this.listenerHandler);
      }
    
      componentWillUnmount() {
        window.removeEventListener(historyExitingEventType, this.listenerHandler);
      }
    
      static getDerivedStateFromProps({ exiting }) {
        if (exiting) {
          return { exiting: false };
        }
        return null;
      }
    
      render() {
        const transitionProps = {
          timeout: {
            enter: 0,
            exit: timeout
          },
          appear: true,
          in: !this.state.exiting
        };
    
        return (
          <ReactTransition {...transitionProps}>
            {status => (
              <div
                style={{
                  ...getTransitionStyle({ status, timeout })
                }}
              >
                {this.props.children}
              </div>
            )}
          </ReactTransition>
        );
      }
    }
    
    export default Transition;
    

    盖茨比-config.js

    import createHistory from 'history/createBrowserHistory';
    
    const timeout = 1500;
    const historyExitingEventType = `history::exiting`;
    
    const getUserConfirmation = (pathname, callback) => {
      const event = new CustomEvent(historyExitingEventType, {
        detail: { pathname }
      });
      window.dispatchEvent(event);
      setTimeout(() => {
        callback(true);
      }, timeout);
    };
    
    let history;
    if (typeof document !== 'undefined') {
      history = createHistory({ getUserConfirmation });
      history.block(location => location.pathname);
    }
    
    export const replaceHistory = () => history;
    
    export { historyExitingEventType, timeout };
    

    getTransitionStyle.js版本

    const getTransitionStyles = timeout => {
    
    return {
        entering: {
          transform: `scale(1.05) translateZ(0)`,
          opacity: 0
        },
        entered: {
          transition: `transform 750ms ease, opacity ${timeout}ms ease`,
          transitionDelay: `750ms`,
          transform: `scale(1) translateZ(0)`,
          opacity: 1
        },
        exiting: {
          transition: `transform 750ms ease, opacity ${timeout}ms ease`,
          transform: `scale(0.98) translateZ(0)`,
          opacity: 0
        }
      };
    };
    
    const getTransitionStyle = ({ timeout, status }) =>
      getTransitionStyles(timeout)[status];
    
    export default getTransitionStyle;
    
    1 回复  |  直到 6 年前
        1
  •  4
  •   Fabian Schultz    6 年前

    Gatsby v2使用的是Reach路由器而不是React路由器,因此使用 getUserConfirmation 具有 replaceHistory 不会再工作了。在盖茨比v2 RC中你可以使用 react-pose 要更直接地创建页面转换,请执行以下操作:

    盖茨比浏览器.js 盖茨比-ssr.js :

    import React from "react"
    import Transition from "./src/components/transition"
     export const wrapPageElement = ({ element, props }) => {
      return <Transition {...props}>{element}</Transition>
    }
    

    过渡.js 组成部分:

    import React from "react"
    import posed, { PoseGroup } from "react-pose"
    
    const timeout = 250
    
    class Transition extends React.PureComponent {
      render() {
        const { children, location } = this.props
    
        const RoutesContainer = posed.div({
          enter: { delay: timeout, delayChildren: timeout },
        })
    
        // To enable page transitions on mount / initial load,
        // use the prop `animateOnMount={true}` on `PoseGroup`.
        return (
          <PoseGroup>
            <RoutesContainer key={location.pathname}>{children}</RoutesContainer>
          </PoseGroup>
        )
      }
    }
    
    export default Transition
    

    在你的内心 :

    // Use `posed.div` elements anywhere on the pages.
    
    const Transition = posed.div({
      enter: {
        opacity: 1,
      },
      exit: {
        opacity: 0,
      },
    })
    
    // ...
    
    <Transition>Hello World!</Transition>
    

    检查 official example 一个工作演示。