Preview
Live interactive preview.
Installation
Add this component to your project using the CLI:
terminal
npx -y vui-registry-cli-v1@latest add parallax-glass-footerSource Code
parallax-glass-footer.tsx
"use client";
import React, { useRef } from "react";
import { motion, useScroll, useTransform } from "framer-motion";
import { ArrowRight, Instagram, Twitter, Linkedin, Github } from "lucide-react";
import { VelocityLogo } from "@/components/velocity-logo";
export default function ParallaxGlassFooter() {
const containerRef = useRef<HTMLDivElement>(null);
const { scrollYProgress } = useScroll({
target: containerRef,
offset: ["start end", "end end"]
});
// Unique scroll effects instead of basic parallax
const scale = useTransform(scrollYProgress, [0, 1], [0.8, 1]);
const rotateX = useTransform(scrollYProgress, [0, 1], [15, 0]);
const opacity = useTransform(scrollYProgress, [0, 0.5, 1], [0, 0.8, 1]);
const textScale = useTransform(scrollYProgress, [0, 1], [0.9, 1]);
const formY = useTransform(scrollYProgress, [0, 1], ["20%", "0%"]);
const linksY = useTransform(scrollYProgress, [0, 1], ["40%", "0%"]);
return (
<div className="w-full relative bg-zinc-50 dark:bg-zinc-950 font-satoshi">
{/* DUMMY CONTENT */}
<div className="w-full h-[100vh] flex flex-col items-center justify-center bg-zinc-50 dark:bg-zinc-950 border-b border-black/5 dark:border-white/5 z-20 relative shadow-[0_20px_80px_rgba(0,0,0,0.1)]">
<h2 className="text-3xl md:text-5xl lg:text-7xl font-bold tracking-tight text-zinc-800 dark:text-zinc-200 text-center max-w-4xl px-6 leading-[1.1] font-satoshi" style={{ fontFamily: 'Satoshi, sans-serif' }}>
Keep scrolling to experience the reveal.
</h2>
<p className="text-zinc-400 mt-8 font-medium text-sm tracking-widest uppercase">
Scroll Down
</p>
</div>
{/* ACTUAL FOOTER COMPONENT */}
<div className="relative w-full overflow-hidden bg-zinc-950 perspective-[1000px]">
<motion.div
ref={containerRef}
style={{ scale, rotateX, opacity, transformOrigin: "top center" }}
className="relative w-full h-[800px] md:h-[600px] bg-gradient-to-b from-indigo-950/20 to-zinc-950 selection:bg-white/30 border-t border-white/10 rounded-t-3xl md:rounded-t-[3rem] overflow-hidden shadow-[0_-20px_80px_rgba(79,70,229,0.15)] mt-[-2rem] z-10"
>
{/* Background Elements */}
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20 mix-blend-overlay pointer-events-none" />
{/* Glowing Orbs */}
<motion.div
style={{ opacity }}
className="absolute -top-[20%] -left-[10%] w-[50%] h-[50%] bg-indigo-500/20 rounded-full blur-[120px] pointer-events-none"
/>
<motion.div
style={{ opacity }}
className="absolute -bottom-[20%] -right-[10%] w-[50%] h-[50%] bg-rose-500/20 rounded-full blur-[120px] pointer-events-none"
/>
<div className="absolute inset-0 w-full h-full flex flex-col justify-between p-8 md:p-16 lg:p-24 z-10">
{/* Top Section */}
<div className="flex flex-col md:flex-row justify-between items-start md:items-end gap-12 w-full">
<motion.div style={{ scale: textScale, opacity }} className="max-w-xl">
<h3 className="text-white text-4xl md:text-5xl lg:text-6xl font-satoshi font-bold tracking-tight leading-[1.1]" style={{ fontFamily: 'Satoshi, sans-serif' }}>
Ready to build something <span className="text-transparent bg-clip-text bg-gradient-to-r from-indigo-400 to-rose-400">extraordinary?</span>
</h3>
</motion.div>
<motion.div style={{ opacity, y: formY }} className="flex flex-col gap-6 w-full md:w-auto">
<div className="relative group max-w-sm w-full">
<div className="absolute -inset-0.5 bg-gradient-to-r from-indigo-500 to-rose-500 rounded-full blur opacity-30 group-hover:opacity-60 transition duration-500"></div>
<div className="relative flex items-center bg-black/50 backdrop-blur-xl border border-white/10 rounded-full p-2">
<input
type="email"
placeholder="Enter your email"
className="w-full bg-transparent px-4 outline-none text-sm text-white placeholder:text-white/40 font-satoshi"
/>
<button className="bg-white text-black px-6 py-2.5 rounded-full text-sm font-semibold hover:scale-105 transition-transform flex items-center gap-2 font-satoshi">
Subscribe <ArrowRight className="w-4 h-4" />
</button>
</div>
</div>
</motion.div>
</div>
{/* Divider */}
<motion.div
style={{ scaleX: opacity }}
className="w-full h-px bg-gradient-to-r from-transparent via-white/20 to-transparent my-12 md:my-0 origin-center"
/>
{/* Bottom Section */}
<motion.div style={{ opacity, y: linksY }} className="flex flex-col md:flex-row justify-between items-start md:items-end gap-12 w-full text-white/70 text-sm font-satoshi">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-16 lg:gap-24 w-full md:w-auto">
<div className="flex flex-col gap-4">
<h4 className="text-white font-semibold uppercase tracking-widest text-xs">Product</h4>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Features</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Integrations</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Pricing</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Changelog</a>
</div>
<div className="flex flex-col gap-4">
<h4 className="text-white font-semibold uppercase tracking-widest text-xs">Company</h4>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">About Us</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Careers</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Blog</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Contact</a>
</div>
<div className="flex flex-col gap-4">
<h4 className="text-white font-semibold uppercase tracking-widest text-xs">Legal</h4>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Privacy Policy</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Terms of Service</a>
<a href="#" className="hover:text-white hover:translate-x-1 transition-all duration-300">Cookie Policy</a>
</div>
<div className="flex flex-col gap-4">
<h4 className="text-white font-semibold uppercase tracking-widest text-xs">Social</h4>
<div className="flex gap-4">
<a href="#" className="hover:text-white hover:-translate-y-1 transition-all bg-white/5 hover:bg-white/10 p-2 rounded-full"><Instagram className="w-4 h-4" /></a>
<a href="#" className="hover:text-white hover:-translate-y-1 transition-all bg-white/5 hover:bg-white/10 p-2 rounded-full"><Twitter className="w-4 h-4" /></a>
<a href="#" className="hover:text-white hover:-translate-y-1 transition-all bg-white/5 hover:bg-white/10 p-2 rounded-full"><Github className="w-4 h-4" /></a>
</div>
</div>
</div>
<div className="flex flex-col md:items-end gap-4 shrink-0">
<VelocityLogo height={28} />
<p className="text-xs uppercase tracking-widest mt-2 text-white/50">© {new Date().getFullYear()} Velocity UI</p>
</div>
</motion.div>
</div>
</motion.div>
</div>
</div>
);
}
Dependencies
framer-motion: latestlucide-react: latest