Inertia Zoom Parallax

A zoom parallax hero section with sliding titles.

Preview

Code

Code

app/page.tsx

1import ZoomParallaxHero from "@/components/zoom-parallax-hero"; 2 3const HomePage = () => { 4 return ( 5 <ZoomParallaxHero /> 6 ); 7} 8 9export default HomePage;

Installation

Initialized a project and installed the necessary dependencies to use this component.

1. Initialize a new Next.js project:

Code
npx create-next-app@latest my-app

2. Install Framer Motion

Code
npm install framer-motion

Add Parallax Zoom Component

Code

src/components/zoom-parallax-hero.tsx

1"use client" 2 3import { motion, useScroll, useTransform } from 'framer-motion'; 4import { fadeSlideRight, fadeSlideLeft, fadeUp, fadeIn } from '@/anim'; 5import { useRef } from 'react'; 6 7 8const ZoomParallaxHero = () => { 9 const container = useRef(null); 10 const { scrollYProgress } = useScroll({ 11 target: container, 12 offset: ['start start', 'end end'] 13 }) 14 15 const moveRight = useTransform(scrollYProgress, [0, 1], [0, 300]); 16 const moveLeft = useTransform(scrollYProgress, [0, 1], [0, -300]); 17 18 return ( 19 <div ref={container} className="h-[300vh] relative bg-white text-black"> 20 <div className="sticky overflow-hidden top-0 h-screen flex flex-col items-center justify-center"> 21 <div className=' lg:px-10 2xl:px-20 pt-16 md:pt-20 md:pb-16 w-full flex flex-col justify-between h-[68%] md:h-full'> 22 <motion.div 23 style={{ x: moveRight }} 24 className=' w-full flex items-center justify-center md:justify-start md:px-20' 25 variants={fadeSlideRight} 26 initial="hidden" 27 animate="visible" 28 > 29 <motion.h1 30 className=' font-cabinetGrotesk text-7xl md:text-9xl xl:text-[12rem] font-bold uppercase' 31 variants={fadeIn} 32 initial="hidden" 33 animate="visible" 34 transition={{ delay: 0.2 }} 35 >Astrae</motion.h1> 36 </motion.div> 37 <motion.div 38 className=' hidden xl:flex w-full items-center justify-between' 39 variants={fadeUp} 40 initial="hidden" 41 animate="visible" 42 transition={{ delay: 0.4 }} 43 > 44 <span className='uppercase font-medium md:text-base 2xl:text-lg'> 45 A Creative 46 <span className=' font-semibold'> 47 Ecommerce Studio 48 </span> 49 </span> 50 <span className='uppercase font-medium md:text-base 2xl:text-lg'> 51 Setting Brands 52 <span className='font-semibold'> 53 In Motion 54 </span> 55 </span> 56 </motion.div> 57 <span> 58 59 <motion.div 60 style={{ x: moveLeft }} 61 className=' w-full flex items-center justify-center md:justify-end md:px-20' 62 variants={fadeSlideLeft} 63 initial="hidden" 64 animate="visible" 65 transition={{ delay: 0.6 }} 66 > 67 <motion.h1 68 className=' font-cabinetGrotesk text-7xl md:text-9xl xl:text-[12rem] font-bold uppercase' 69 variants={fadeIn} 70 initial="hidden" 71 animate="visible" 72 transition={{ delay: 0.8 }} 73 >Studios</motion.h1> 74 </motion.div> 75 76 <motion.div 77 className=' md:hidden flex flex-col w-full items-center' 78 variants={fadeUp} 79 initial="hidden" 80 animate="visible" 81 transition={{ delay: 0.4 }} 82 > 83 <span className=' uppercase font-medium md:text-base 2xl:text-lg'> 84 A Creative <span className=' font-semibold'>Ecommerce Studio</span> 85 </span> 86 <span className=' uppercase font-medium md:text-base 2xl:text-lg'> 87 Setting Brands <span className=' font-semibold'>In Motion</span> 88 </span> 89 </motion.div> 90 </span> 91 92 </div> 93 <motion.div 94 style={{ scale: useTransform(scrollYProgress, [0, 1], [1, 3]) }} 95 className="w-full h-full top-0 absolute flex items-center justify-center" 96 variants={fadeIn} 97 initial="hidden" 98 animate="visible" 99 transition={{ delay: 1 }} 100 > 101 <div 102 className={` 103 relative object-cover w-[90vw] xl:w-[40rem] 104 2xl:w-[52rem] h-auto aspect-square sm:aspect-video md:aspect-video` 105 }> 106 <video 107 autoPlay 108 loop 109 muted 110 playsInline 111 preload="auto" 112 className="object-cover w-full h-full" 113 > 114 <source src="/assets/showcase-2.mp4" type="video/mp4" /> 115 Your browser does not support the video tag. 116 </video> 117 </div> 118 </motion.div> 119 </div> 120 </div> 121 ) 122} 123 124export default ZoomParallaxHero;

Add Animations

Code

src/anim/index.ts

1import { Variants } from "framer-motion"; 2 3export const fadeSlideRight: Variants = { 4 hidden: { opacity: 0, x: -80 }, 5 visible: { opacity: 1, x: 0, transition: { duration: 0.8, ease: "easeOut" } }, 6}; 7 8export const fadeSlideLeft: Variants = { 9 hidden: { opacity: 0, x: 80 }, 10 visible: { opacity: 1, x: 0, transition: { duration: 0.8, ease: "easeOut" } }, 11}; 12 13export const fadeUp: Variants = { 14 hidden: { opacity: 0, y: 40 }, 15 visible: { opacity: 1, y: 0, transition: { duration: 0.8, ease: "easeOut" } }, 16}; 17 18export const fadeIn: Variants = { 19 hidden: { opacity: 0 }, 20 visible: { opacity: 1, transition: { duration: 1, ease: "easeOut" } }, 21};

Add Global Styles

Code

src/globals.css

1@import "tailwindcss"; 2 3:root { 4 --background: #ffffff; 5 --foreground: #000000; 6} 7 8@theme inline { 9 --color-background: var(--background); 10 --color-foreground: var(--foreground); 11 --font-inter: var(--font-inter); 12 --font-cabinetGrotesk: var(--font-cabinetGrotesk); 13} 14 15@media (prefers-color-scheme: dark) { 16 :root { 17 --background: #000000; 18 --foreground: #ededed; 19 } 20} 21 22body { 23 background: var(--background); 24 color: var(--foreground); 25 font-family: Arial, Helvetica, sans-serif; 26} 27 28 29/* Scrollbar */ 30 31/* Firefox */ 32* { 33 scrollbar-width: none; 34} 35/* Chrome, Edge, and Safari */ 36*::-webkit-scrollbar { 37 display: none; 38} 39/* End Scrollbar */

Become an Astrae
Affiliate Today

Make referrals, and bring in clients. Keep 50% of your earnings paid out weekly.

Description