【问题标题】:Get the Gatsby Link destination and conditionally render exit animation with Framer Motion获取 Gatsby Link 目标并使用 Framer Motion 有条件地渲染退出动画
【发布时间】:2021-10-20 08:35:21
【问题描述】:

我建立了一个小型网站,以了解有关使用 Gatsby 和 Framer Motion 和 Styled Components 进行页面转换的更多信息。

[SPOILER]:我要解决的问题在代码块的末尾

目前的工作方式很简单:

带有项目列表的主页

export default function Home() {
  return (
    <Layout>
      <Welcome />
      <WorkList />
      <Footer />
    </Layout>
  )
}

通过createPages 生成每个项目的项目页面模板(这里是简化版)

import React, { useState, useRef, useContext, useEffect } from "react"
import { Link } from "gatsby"

// Components
...

// Data
import Projects from "../data/works.json"

// Styles
...

// Variants
...

const Project = ({ pageContext }) => {
  const project = Projects.find(({ id }) => id === pageContext.id)
  
  // lots of functions here

  return (
    <Layout>
      <ProjectWrapper>
        <Container>
          <ProjectContent>
            <BackgroundLines />
            <ProjectContentInner>
              <ProjectHeader>
                <!-- here the header logic -->
              </ProjectHeader>
              <ProjectBlocks>
                <!-- here the content logic -->
              </ProjectBlocks>
            </ProjectContentInner>
            <ProjectFooter>
              <!-- here the footer logic -->
            </ProjectFooter>
          </ProjectContent>
        </Container>
      </ProjectWrapper>
    </Layout>
  )
}

export default Project

布局组件持有导航

// Components
import Header from "./header"

// Styles
import { GlobalStyle } from "../styles/globalStyles"

const Layout = ({ children }) => {
  return (
    <div className="app">
      <GlobalStyle />
      <Header />
      <main>{children}</main>
    </div>
  )
}

export default Layout

最后但同样重要的是,gatsby.browser.jsAnimatePresenceContext Provider 包装在一起

import React from "react"
import { AnimatePresence } from "framer-motion"
import { LocationProvider } from "./src/context/locationContext"

export const wrapPageElement = ({ element }) => (
  <LocationProvider>
    <AnimatePresence exitBeforeEnter>{element}</AnimatePresence>
  </LocationProvider>
)

export const shouldUpdateScroll = () => {
  return false
}

所以我想做的事情看起来很容易,但事实证明并非如此(至少对我来说)。 我目前在 2 个项目之间进行了完美的过渡,类似于您可以看到的 in here

如果您滚动到页面底部,您可以看到下一个项目的标题显示为预览,一旦您点击它,它将平滑过渡到下一个项目页面。

太棒了。

但是,但是当用户单击导航中的链接将他带到主页或另一个页面时,这种转换是一个问题。

我不希望有相同的退出过渡,其中一些元素消失而另一些重叠,我不希望相同的时间。我想做一些完全不同的事情,这取决于我要去的地方。

我认为的解决方案是有条件地在帧运动中渲染exit transition,以根据某些变量具有不同的退出动画。

我希望能够在组件卸载之前跟踪Link Destination,以便能够有条件地在 Framer Motion 中渲染退出过渡

因为,正如您所见,导航不在 project.jsLink 拥有destination 状态。这实际上不起作用,因为一切似乎都得到了重新渲染。

我只提供了对理解整体结构至关重要的代码片段,但我可以更深入地了解我构建 variants 或当前 exit 动画的方式。

【问题讨论】:

    标签: reactjs react-hooks gatsby use-context framer-motion


    【解决方案1】:

    我不确定它是否会有所帮助,但您可以将 props 作为 wrapPageElement 中的任何 React 组件:

    export const wrapPageElement = ({ element, props }) => {
      console.log("props", props)
      if(props.location.pathname==='/'){
        //return some other animation stuff
      }
    
      return <LocationProvider {...props}>
        <AnimatePresence exitBeforeEnter>{element}</AnimatePresence>
      </LocationProvider>
    }
    

    【讨论】:

    • 我知道这一点,但实际上,我需要目的地而不是页面的来源,因为我想根据我要去的地方改变行为。例如。如果我在做这个项目,我要去家里,做这个过渡。否则,进行其他转换。
    • 我缺少您的实现上下文,但您可以从许多 Gatsby 浏览器 API (gatsbyjs.com/docs/reference/config-files/gatsby-browser/…) 获取数据(来源和目标)。在那里,您可以尝试根据目的地设置一些逻辑
    • 我认为 onRouteUpdate 可能是一个很好的起点。谢谢!而不是我应该弄清楚如何在组件卸载之前传递此信息以便能够设置条件退出动画。
    猜你喜欢
    • 1970-01-01
    • 2023-02-13
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2021-05-29
    相关资源
    最近更新 更多