How I Built a Cinematic AI Landing Page with GSAP, Canvas API and Next.js
A deep dive into building Digital Rain - a cinematic AI landing page template with falling math symbols, liquid glass UI, and GSAP scroll animations using Next.js 15 and Tailwind CSS.
Most AI landing pages look the same. Hero section. Features grid. Pricing table. Footer. I wanted to build something different - something that makes visitors stop scrolling and say "wow, what is this?" The result is Digital Rain - a cinematic AI landing page with falling mathematical symbols, liquid glass UI, and GSAP-powered scroll animations. Here's exactly how I built it.
π¬ The Vision
The concept came from the Matrix - that iconic falling green code effect. But instead of random characters, I wanted mathematical symbols falling and reacting to a simulated liquid surface. The goal was simple: make your AI product feel like a funded startup from day one.
Live demo: https://og-ai-next.vercel.app/
π Tech Stack
- Next.js 15 - App Router, TypeScript
- Tailwind CSS - styling and glassmorphism
- GSAP - scroll animations and micro-interactions
- Canvas API - custom digital rain animation engine
- SVG Filters - liquid surface simulation
π§ Building the Digital Rain Animation
The heart of the template is the custom rain animation engine. Here's how it works:
Step 1 - Set up the Canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
Step 2 - Define the Symbol Set
Instead of random characters, I used mathematical symbols for a more premium feel:
const symbols = [
'β', 'Ο', 'β', 'β«', 'β', 'Ξ©', 'Ξ»', 'Ο', 'β', 'ΞΈ',
'Ξ±', 'Ξ²', 'Ξ³', 'Ξ΄', 'Ξ΅', 'ΞΆ', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9'
];
Step 3 - Create the Rain Columns
const fontSize = 14;
const columns = Math.floor(canvas.width / fontSize);
const drops: number[] = new Array(columns).fill(1);
function drawRain() {
// Fade effect - creates trail
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw symbols
ctx.fillStyle = '#14b575'; // brand green
ctx.font = `${fontSize}px monospace`;
drops.forEach((drop, i) => {
const symbol = symbols[Math.floor(Math.random() * symbols.length)];
const x = i * fontSize;
const y = drop * fontSize;
ctx.fillStyle = `rgba(20, 181, 117, ${Math.random() * 0.8 + 0.2})`;
ctx.fillText(symbol, x, y);
// Reset drop randomly
if (y > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
});
}
// Animate at 30fps
setInterval(drawRain, 33);
Step 4 - Add the Liquid Surface Reaction
This is the part that makes it feel interactive. When the mouse moves, nearby symbols react:
let mouseX = 0;
let mouseY = 0;
window.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
// In drawRain function - add proximity effect
drops.forEach((drop, i) => {
const x = i * fontSize;
const y = drop * fontSize;
const distance = Math.sqrt(
Math.pow(x - mouseX, 2) + Math.pow(y - mouseY, 2)
);
// Symbols near cursor glow brighter
const opacity = distance < 100 ? 1.0 : Math.random() * 0.8 + 0.2;
ctx.fillStyle = `rgba(20, 181, 117, ${opacity})`;
ctx.fillText(symbol, x, y);
});
β¨ Building the Liquid Glass UI
Glassmorphism is everywhere but most implementations look cheap. Here's how to make it look premium:
.glass-card {
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
}
The key differences from cheap glassmorphism:
- Very low background opacity (0.05 not 0.3)
- Higher blur (20px not 10px)
- Inner top border glow (the inset shadow)
- Dark base background so the blur actually shows
β‘ GSAP Scroll Animations
GSAP makes scroll animations smooth and performant. Here's the pattern I used for every section:
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
// Fade up animation on scroll
gsap.fromTo(
'.feature-card',
{ opacity: 0, y: 60 },
{
opacity: 1,
y: 0,
duration: 0.8,
stagger: 0.15,
ease: 'power3.out',
scrollTrigger: {
trigger: '.features-section',
start: 'top 80%',
end: 'bottom 20%',
}
}
);
The stagger: 0.15 is what makes multiple cards animate in sequence rather than all at once. This small detail makes the whole thing feel much more polished.
π§ The Hero Section Structure
export function Hero() {
return (
<section className="relative min-h-screen flex items-center">
{/* Canvas background */}
<canvas ref={canvasRef} className="absolute inset-0 w-full h-full opacity-40" />
{/* Gradient overlay */}
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-black/20 to-black/80" />
{/* Content */}
<div className="relative z-10 max-w-6xl mx-auto px-6">
<div className="glass-card p-8 rounded-2xl max-w-2xl">
<h1 className="text-5xl font-bold text-white mb-4">
Build Smarter Workflows with AI
</h1>
<p className="text-slate-300 text-lg mb-8">
OG-AI helps teams automate repetitive tasks
</p>
<button className="bg-brand-500 text-black px-8 py-4 rounded-xl font-semibold">
Get Started
</button>
</div>
</div>
</section>
);
}
βοΈ One Config File to Rule Them All
The best decision I made was putting all customization in a single config file:
// src/config.ts
export const config = {
brand: {
name: "Your AI Product",
tagline: "Build Smarter Workflows with AI",
color: "#14b575",
},
hero: {
title: "Build Smarter Workflows with AI",
subtitle: "Automate tasks, generate content, unlock insights",
cta: "Get Started Free",
},
nav: {
links: ["Features", "How It Works", "Pricing", "Testimonials", "FAQ"],
},
pricing: {
monthly: [
{ name: "Starter", price: 9, features: ["100 generations", "API access"] },
{ name: "Pro", price: 29, features: ["Unlimited", "Priority support"] },
]
}
}
No digging through components. Just update this file and everything changes.
π¦ What the Final Template Includes
- Custom digital rain animation engine (Canvas API)
- GSAP scroll animations throughout
- Liquid glass UI components
- Hero, Features, How It Works, Pricing, Testimonials, FAQ, CTA sections
- Both Next.js 15 and React versions
- TypeScript throughout
- Tailwind CSS setup
- Full documentation
π― The Result
The demo speaks for itself: https://og-ai-next.vercel.app/
If you're building an AI product and want your landing page to feel like a funded startup from day one - I turned this into a template you can grab and customize in hours.
Get the template: https://pixelanas.gumroad.com/l/digital-rain
π What I Learned
Building this taught me that the difference between a good landing page and a cinematic one is:
- One unforgettable visual - the rain animation is the hook
- Restraint - not everything needs to animate
- Performance first - Canvas + requestAnimationFrame beats CSS animations for complex effects
- Emotion over information - people buy feelings, not features
If you have questions about any part of the implementation, drop them in the comments. Happy to go deeper on any section.
π Demo β https://og-ai-next.vercel.app/
π Get it β https://pixelanas.gumroad.com/l/digitalrain
Built by Anas - full-stack developer specializing in Next.js, animations, and premium UI. Find me on X: @pixelanas
Comments
No comments yet. Start the discussion.