logo

Animação de página à esquerda

Uma animação de transição imersiva de uma página para outra

Animações de transições no Next ainda são um tópico delicado nas versões mais recentes. Apesar do next-view-transitions ser uma mão na roda, para as versões do Next 15, foi necessário fazer um fork alternativo para consertar um bug de build que provavelmente vão consertar nas próximas versões.

Também se fez necessário adicionar algumas linhas de CSS no globals.css

Código:

// @/components/layout/pageAnimation.tsx
	interface pageAnimationProps {
	direction: 'vertical' | 'horizontal';
}

const directionMap = {
	vertical: 'translateY',
	horizontal: 'translateX',
};

export const pageAnimation = ({ direction = 'vertical' }: pageAnimationProps) => {
	document.documentElement.animate(
		[
			{
				opacity: 1,
				scale: 1,
				transform: `${directionMap[direction]}(0)`,			},
			{
				opacity: 0.5,
				scale: 0.9,
				transform: `${directionMap[direction]}(-100px)`,
			},
		],
		{
			duration: 1000,
			easing: 'cubic-bezier(0.76, 0, 0.24, 1)',
			fill: 'forwards',
			pseudoElement: '::view-transition-old(root)',
		}
	);

	document.documentElement.animate(
		[
			{
				transform: `${directionMap[direction]}(100%)`,
			},
			{
				transform: `${directionMap[direction]}(0)`,
			},
		],
		{
			duration: 1000,
			easing: 'cubic-bezier(0.76, 0, 0.24, 1)',
			fill: 'forwards',
			pseudoElement: '::view-transition-new(root)',
		}
	);
};
yarn add motion clsx tailwind-merge
//@/components/layout/transitionWrapper.tsx
'use client';

import { HTMLMotionProps, motion } from 'motion/react';

const TransitionWrapper = (props: HTMLMotionProps<'div'>) => {
	return (
		<div>
			<motion.div initial={{ opacity: 1 }} animate={{ opacity: 1 }} transition={{ delay: 0.8 }} {...props} />
		</div>
	);
};

export default TransitionWrapper;
yarn add motion clsx tailwind-merge

/* ViewTransitions */
::view-transition-group(root) {
	z-index: auto !important;
}

::view-transition-image-pair(root) {
	isolation: isolate;
	will-change: transform, opacity, scale;
	z-index: 1;
}

::view-transition-new(root) {
	z-index: 2;
	animation: none !important;
}

::view-transition-old(root) {
	z-index: 1;
	animation: none !important;
}
Inclua no globals.css

Prévia: