This repository has been archived by the owner on Apr 20, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
Is it possible to crossfade? #53
Comments
@j2is I managed to do this with https://github.com/reactjs/react-transition-group instead |
@mattjis Do you have an example by chance? |
import React, { useRef, useState, useEffect } from 'react';
import { CSSTransition } from 'react-transition-group';
import { useRouter } from 'next/router';
import './app.css';
function PageTransition(props) {
const { c: PageComponent, lc: lastPageComponent } = props;
const componentsDiffer = lastPageComponent &&
PageComponent.key !== lastPageComponent.key;
const [transitioning, setTransitioning] = useState(componentsDiffer); // Transition if components differ
const [transitioningFor, setTransitioningFor] = useState(PageComponent.key); // Keep track of which we just transitioned in
// If the components differ and PageComponent.key is new, we need to start
// a new transition
if (componentsDiffer &&
transitioningFor !== PageComponent.key) {
setTransitioningFor(PageComponent.key);
setTransitioning(true);
}
function onFinishTransition() {
console.log('FINISHED', PageComponent.key);
setTransitioning(false);
}
function fixScroll() {
// Scroll left to 0 every frame, firefox will fuck this up if not
document.querySelector('.concerning').scrollLeft = 0;
}
console.log(PageComponent?.key, lastPageComponent?.key, transitioning, transitioningFor);
return (
<div className='concerning'>
<CSSTransition in={!transitioning} appear={true} timeout={600} classNames="page-transition" exit={false} onExited={onFinishTransition}>
<div>
{PageComponent}
</div>
</CSSTransition>
<CSSTransition in={transitioning} timeout={600} classNames="page-transition" enter={false} onExiting={fixScroll} onExited={onFinishTransition}>
<div className="outgoing">
{lastPageComponent}
</div>
</CSSTransition>
</div>
);
}
export default function MyApp(params) {
const router = useRouter();
const key = router.route;
const { Component: PageComponent, pageProps } = params;
// Needs to be in MyApp, otherwise it will get recreated with a new page when the page changes and then we lose the last component
// If you useState, react throws lots of out of order hook errors, cant store JSX inside state
const lastPageComponentRef = useRef(undefined);
const getLayoutAndPage = (PageComponent, pageProps) => {
// TODO: Convert this into just one function
// Use the layout defined at the page level, if available
const getLayout = PageComponent.getLayout || ((page) => page);
// Use the layout builder defined (which takes pageComponent and pageProps and builds the
// pageComponent too
const getLayoutBuilder = PageComponent.getLayoutBuilder || ((PageComponent, pageProps) => getLayout(<PageComponent {...pageProps} />));
return (
<div key={key}>
{getLayoutBuilder(PageComponent, pageProps)}
</div>
);
};
const c = getLayoutAndPage(PageComponent, pageProps);
const lc = lastPageComponentRef.current || getLayoutAndPage(PageComponent, pageProps);
const ret = (
<PageTransition lc={lastPageComponentRef.current} c={getLayoutAndPage(PageComponent, pageProps)} />
);
lastPageComponentRef.current = c;
return ret;
} .concerning {
position: relative;
width: 100%;
overflow: hidden;
}
.page-transition-enter-done,
.page-transition-appear-done,
.page-transition-exit-done {
}
.page-transition-enter {
transform: translateX(-100%);
}
.page-transition-enter-active {
transform: translate(0);
transition: transform 600ms;
transition-timing-function: cubic-bezier(.26,1,.25,1);
}
.page-transition-exit {
display: block !important;
transform: translate(0);
}
.page-transition-exit-active {
display: block !important;
transform: translateX(100%);
transition: transform 600ms;
transition-timing-function: cubic-bezier(.26,1,.25,1);
}
.page-transition-exit-done {
display: none;
}
.outgoing {
position: absolute;
top: 0;
left: 0;
width: 100%;
pointer-events: none;
} Rough code for anyone who needs it. This implements sliding pages in Next at the _app.js level. Things that I learned:
|
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
All examples have one page shown at a time, is it possible to have the previous page visible while the new one transitions in? (Like the Instagram app)
The text was updated successfully, but these errors were encountered: