Skip to content
This repository has been archived by the owner on Mar 29, 2023. It is now read-only.

make page transition easier for next.js | 让next.js的页面切换动画更简单

Notifications You must be signed in to change notification settings

postor/next-page-transition

Repository files navigation

next-page-transition

make page transition easier for next.js | 让next.js的页面切换动画更简单

screenshot.gif

quick glance https://www.youtube.com/watch?v=zpzbNA0J9CM&list=PLM1v95K5B1ntVsYvNJIxgRPppngrO_X4s

usage | 使用方法

components/wrapper.js

import w from 'next-page-transition'
import { zoomfade } from 'next-page-transition/dist/presets'

export const wrapper = w(zoomfade())

pages/index.js

import Link from 'next/link'
import wrapper from '../components/wrapper'

const Index = () => (<div>
  <p>home page</p>
  <Link href="/about"><a>about</a></Link>
</div>)

export default wrapper(Index)

note Do not use Router.onRouteChangeStart=xxx in your code, use routerEvents.on('routeChangeStart', xxx) refer next-router-events | 不要在你的代码中使用 Router.onRouteChangeStart=xxx 这样的代码,如果需要绑定next.js的路由事件请使用routerEvents.on('routeChangeStart', xxx),详情参考 next-router-events

note To clean the hook created by this package (most cases you do not need to), you can use wrapper.destory() to unregister | 要清理前面提到的router事件绑定(大部分时候应该是不需要清理的),你可以使用 wrapper.destory() 来清理

try it out | 体验一下

params | 参数说明

import w from 'next-page-transition'
const wrapper = w({
    duration: 600,           //transition duration | 动画时长
    containerProps: {        //props for container | 容器元素的属性
      style: {                
        position: 'relative'  
      }
    },
    frameProps: {            //props for frame | 页面外框元素的属性
      style: {
        position: 'absolute',
        width: '100%',
        opacity: 0,
        transition: `${duration}ms ease-in-out`,
      }
    },
    transitionStyles: {      //transition styles | 各个状态的style
      inital: { opacity: 0 }, // before come into view
      entering: { opacity: 1, }, // entering view
      entered: { opacity: 1 }, // stay in view
      exiting: { opacity: 0, }, // leaving view, while next page entering
      exited: { opacity: 0 }, // left view, right before removed
    },
  })

with _app.js | 使用 _app.js

import React from 'react'
import App from 'next/app'
import w from 'next-page-transition'
import { zoomfade } from 'next-page-transition/dist/presets'

const wrapper = w(zoomfade())

const transMap = new Map()

class MyApp extends App {
  render() {
    const { Component, pageProps } = this.props
    if (!transMap[Component]) transMap[Component] = wrapper(Component)
    const Trans = transMap[Component]
    return (<Trans {...pageProps} />)
  }
}

export default MyApp

custom transition for single page | 不同页面使用不同的动画

use getTransitionConfig function | 给组件添加 getTransitionConfig 方法

import wrapper from '../components/wrapper'
import { fade } from 'next-page-transition/dist/presets'

const transitionConfig = fade(1000)
transitionConfig.frameProps.style.transform = 'none'

const About = () => (<div>
  <p>about page</p>
</div>)

About.getTransitionConfig = () => transitionConfig

export default wrapper(About)

getTransitionConfig will get called with two params(from page component and to page component) when navigation happen

当导航发生时getTransitionConfig 会被调用并且传入两个参数(上一个页面组件和新的页面组件)

About.getTransitionConfig = (Last,Current) => {
  if(Last && Last === About){
    console.log('leaving about and entering',Current)
  }else if(Current === About){
    console.log('entering about and leaving',Last)
  }
}

custom container | 自定义的容器

you may need something do not animate with page, or something like template, for example side-nav-bar

你可能会需要一些不跟着页面做动画的东西,或者像是类似模板概念的东西,比如说 侧边导航条

import w from 'next-page-transition'
import { zoomfade } from 'next-page-transition/dist/presets'
import SideBar from './SideBar'

const wrapper = w({
  ...zoomfade(),
  Container: (props) => {
    const { children } = props
    return (<div style={{
      position: 'absolute',
      width: '100vw',
      height: '100vh',
      overflow: 'hidden',
    }}>
      {children}
      <SideBar />
    </div>)
  },
})

Container by default is a div, where props come from containerProps in config

(props) => (<div {...props} />)

you can refer wrapper.js and run example for real code and result

you can refer wrapper.js and run example for real code and result

presets | 预定义动画

import { zoomfade } from 'next-page-transition/dist/presets'

  • fade
  • zoom
  • zoomfade
  • zoomrotate
  • flipVertical
  • flipHorizontal
  • slideUp
  • slideDown
  • slideLeft
  • slideRight

About

make page transition easier for next.js | 让next.js的页面切换动画更简单

Topics

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published