【问题标题】:How can I do a different animation between the pages with Framer Motion and Next.js?如何使用 Framer Motion 和 Next.js 在页面之间制作不同的动画?
【发布时间】:2021-03-25 20:46:45
【问题描述】:

我使用 Next.js、React、TypeScript 和 Framer Motion。 我不使用反应路由器。 我想在页面之间进行转换。 当我更改页面(在_app.tsx 中)时,我发现了如何从右到左转换。 但是,如果我使用向右箭头和向左箭头的链接,这是相同的过渡。 我想用右箭头从右到左转换,用左箭头从左到右转换。

我的_app.tsx:

import '../public/css/style.scss';
import { animate, AnimateSharedLayout, motion } from 'framer-motion';
import { useRouter } from "next/router";
import App from "next/app";
//import Strategie from './strategie'


export default class MyApp extends App { 
 render(){
        const { Component, pageProps } = this.props;
        const { router } = this.props;
        // const { router } = this.props;
        return <>
            <motion.div key={router.route} initial="pageInitial" animate="pageAnimate" exit="pageExit" variants={{
                pageInitial: {
                    opacity: 0,
                    x: "100%", 
                },
                pageAnimate: {
                    opacity: 1,
                    x: 0,
                    transition: {
                        ease: "easeIn",
                        duration: 0.5,
                    }
                },
                pageExit: {
                    // filter: `invert()`,
                    opacity: 0,
                }
            }}> 
                <Component {...pageProps} />
            </motion.div>
        </> 
    }
} 

我的页面有 2 个箭头(我有几个这样的页面):

import React from "react";
import HomePageBlock, {IdHomePageBlockProps} from '../components/common/home pages/homePage-block';
import ButtonStartProject from "../components/buttons/button-startProject";
import Link from "next/link";
import Sidebar from "../components/common/sidebar/sidebar";



interface IdHomePageSingularityProps {
  title?: string;
}
interface IdHomePageSingularityState{
  homePageInfos: IdHomePageBlockProps[]
}
export default class HomePageSingularity extends React.Component<IdHomePageSingularityProps, IdHomePageSingularityState>{
    constructor(props){
      super(props);
      this.state = {
        homePageInfos: [
          {
            title: <>Révélons <br/> ta singularité</>, 

            subTitle: "notre expertise",

            description: <>Nombreux sont les projets qui émergent aujourd'hui, alors comment se démarquer quand tu as un projet bienveillant sans perdre en efficacité ? <br/> Chez Ben&Jo nous concevons des identités visuelles basés sur une stratégie cohérente. Nous inventerons pour ton projet un univers visuel unique et impactant !</>,
            
            img: { url : "/img/home-pages/singularity.svg"},

            buttonDiscover: <>
              <Link href="/brandingIndex"> 
                <a className="buttonDiscover" >DECOUVRE NOTRE SAVOIR FAIRE !</a>
              </Link></>,

            buttonStartProject: <><ButtonStartProject /></>,

            imgFingersBox: { url : "/img/home-pages/fingersBox.svg"},

            arrowRight: <>
              <Link href="/homePageSucces">
                <img src="/img/home-pages/arrowRight.svg" />
              </Link></>,

            arrowLeft: <>
              <Link href="/homePageStrategie">
                <img src="/img/home-pages/arrowLeft.svg" />
              </Link>
            </>,
          }
        ]
      }
    }
    render(){
      const { homePageInfos } = this.state;
    return <>
        <div className="home__singularity">
          <div><Sidebar /></div>
            { homePageInfos && homePageInfos.map((item, index) => {
                    return <HomePageBlock key={"home__singularity-block_" + index } 
                        {...item} className="home__singularity-block"/>
                })
            }
        </div>
    </>
  }
}

我构建组件的页面:

import React from 'react';
import FingersBox from './fingersBox';


export interface IdHomePageBlockProps {
  title?: {};
  subTitle?: string;
  description?: {};
  img?: {url: string, alt?: string};
  buttonDiscover?: {};
  buttonStartProject?: {};
  arrowRight?: {};
  arrowLeft?: {};
  className?: string;
  imgFingersBox?: {url: string, alt?: string};

}
export interface IdHomePageBlockState{
  
}
export default class HomePageBlock extends React.Component<IdHomePageBlockProps, IdHomePageBlockState>{
  render(){
    const { title, subTitle, description, img, buttonDiscover, buttonStartProject, arrowRight, arrowLeft, className } = this.props;
    return <>
    <div className={className + ' homePage-block'}>
      <header>
        <div className="homePage-block__imageFingers-box"><FingersBox /></div>
        <div className="homePage-block__subTitle">{subTitle}</div>
        <div className="homePage-block__buttonStartProject">{buttonStartProject}</div>
      </header>
      <body>
        <main>
          <div className="homePage-block__title">{title}</div>
          <div className="homePage-block__description">{description}</div>
          <div className="homePage-block__buttonDiscover">{buttonDiscover}</div>
        </main>        
        <aside>
          <div className="homePage-block__image-box">
            <img src={img.url} alt={img.alt} />
          </div>
        </aside> 
      </body>       
      <footer>
        <div className="homePage-block__arrowLeft">{arrowLeft}</div>
        <div className="homePage-block__arrowRight">{arrowRight}</div>
      </footer>
    </div>
    </>
  }
}

如您所见,没有按钮,只有链接。

【问题讨论】:

  • 感谢您的指正,您有办法解决我的问题吗?

标签: reactjs next.js framer-motion


【解决方案1】:

您可以在成帧器运动中使用dynamic variants 来实现此目的。

export default class MyApp extends App { 

constructor(props) {
    super(props)
    this.state = { direction: 'left' }
}

changeDirection(direction: string) {
    this.setState({
      direction
    });
  }

render(){
        const { direction } = this.state
        const { Component, pageProps } = this.props;
        const { router } = this.props;
        // const { router } = this.props;
        return <>
            <motion.div key={router.route} custom={direction} initial="pageInitial" animate="pageAnimate" exit="pageExit" variants={{
                pageInitial: direction => ({
                    opacity: 0,
                    x: direction === 'left' ? "100%" : "-100%", 
                }),
                pageAnimate: {
                    opacity: 1,
                    x: 0,
                    transition: {
                        ease: "easeIn",
                        duration: 0.5,
                    }
                },
                pageExit: {
                    // filter: `invert()`,
                    opacity: 0,
                }
            }}> 
                <Component changeDirection={this.changeDirection} {...pageProps} />
            </motion.div>
        </> 
    }
} 

在实际的页面组件中,您可能需要想办法在导航开始之前根据需要改变方向。

import React from "react";
import { withRouter } from 'next/router'
import HomePageBlock, {IdHomePageBlockProps} from '../components/common/home pages/homePage-block';
import ButtonStartProject from "../components/buttons/button-startProject";
import Link from "next/link";
import Sidebar from "../components/common/sidebar/sidebar";

interface IdHomePageSingularityProps {
  title?: string;
}
interface IdHomePageSingularityState{
  homePageInfos: IdHomePageBlockProps[]
}
class HomePageSingularity extends React.Component<IdHomePageSingularityProps, IdHomePageSingularityState>{
    constructor(props){
      super(props);
      this.state = {
        homePageInfos: [
          {
            title: <>Révélons <br/> ta singularité</>, 

            subTitle: "notre expertise",

            description: <>Nombreux sont les projets qui émergent aujourd'hui, alors comment se démarquer quand tu as un projet bienveillant sans perdre en efficacité ? <br/> Chez Ben&Jo nous concevons des identités visuelles basés sur une stratégie cohérente. Nous inventerons pour ton projet un univers visuel unique et impactant !</>,
            
            img: { url : "/img/home-pages/singularity.svg"},

            buttonDiscover: <>
              <Link href="/brandingIndex"> 
                <a className="buttonDiscover" >DECOUVRE NOTRE SAVOIR FAIRE !</a>
              </Link></>,

            buttonStartProject: <><ButtonStartProject /></>,

            imgFingersBox: { url : "/img/home-pages/fingersBox.svg"},

            arrowRight: <>
              <a onClick={this.handleRightClick} href="/homePageSucces">
                <img src="/img/home-pages/arrowRight.svg" />
              </a></>,

            arrowLeft: <>
              <a onClick={this.handleLeftClick} href="/homePageStrategie">
                <img src="/img/home-pages/arrowLeft.svg" />
              </a>
            </>,
          }
        ]
      }
    }
    const handleRightClick = (e) => {
      e.preventDefault()
      this.changeDirection('right')
      this.props.router.push('/homePageSucces')
    }
const handleLeftClick = (e) => {
      e.preventDefault()
      this.changeDirection('left')
      this.props.router.push('/homePageStrategie')
    }
    render(){
      const { homePageInfos } = this.state;
    return <>
        <div className="home__singularity">
          <div><Sidebar /></div>
            { homePageInfos && homePageInfos.map((item, index) => {
                    return <HomePageBlock key={"home__singularity-block_" + index } 
                        {...item} className="home__singularity-block"/>
                })
            }
        </div>
    </>
  }
}
export default withRouter(HomePageSingularity)

【讨论】:

  • 我明白你想说的,但它不起作用。
  • 也许如果我映射不同的 url 并告诉他们一次要做什么 T 这会起作用,但我不知道如何处理道具、状态等...
  • 它可能不起作用,因为在导航中丢失了道具更改。理想情况下,应该从layout 组件设置方向。尝试创建一个布局组件,作为页面的包装器并在其中设置方向
  • 我有一个 index.tsx 文件,其中有: ``` import FirstPage from "./firstPage";导出默认函数 Index() { return ( > ); }```
  • 你知道是否有一种方法可以定义每条路线及其目的地吗?
猜你喜欢
  • 2022-01-15
  • 1970-01-01
  • 2022-11-21
  • 2022-08-19
  • 2022-12-24
  • 2020-12-28
  • 2023-02-10
  • 2023-01-11
  • 1970-01-01
相关资源
最近更新 更多