Hero prompt: <!DOCTYPE html> <html lang="en"> <head> <meta ...
7views
0favorites
Model used
Hero1.0Generation parameters
Image1008x100811299jpg
Prompt
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CHRISTABEL | Cinematic Blueprint Experience</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/EffectComposer.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/RenderPass.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/postprocessing/UnrealBloomPass.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600&family=Playfair+Display:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--primary: #d4a574;
--secondary: #8b6f4e;
--accent: #e8d5c4;
--dark: #1a1a1a;
--light: #f5f3f0;
--gradient-1: linear-gradient(135deg, #f5f3f0 0%, #ebe6df 50%, #f0ebe5 100%);
--gradient-2: linear-gradient(135deg, #1a1a1a 0%, #2a2520 50%, #1a1a1a 100%);
--glass: rgba(255, 255, 255, 0.08);
--glass-border: rgba(212, 165, 116, 0.3);
}
body {
font-family: 'Inter', sans-serif;
background: var(--light);
overflow-x: hidden;
cursor: none;
color: var(--dark);
scroll-behavior: smooth;
}
.font-display { font-family: 'Space Grotesk', sans-serif; }
.font-serif { font-family: 'Playfair Display', serif; }
/* ===== CUSTOM CURSOR ===== */
.cursor-dot, .cursor-outline {
position: fixed;
top: 0; left: 0;
transform: translate(-50%, -50%);
border-radius: 50%;
z-index: 9999;
pointer-events: none;
transition: transform 0.15s ease-out;
}
.cursor-dot {
width: 8px; height: 8px;
background: var(--primary);
box-shadow: 0 0 20px rgba(212, 165, 116, 0.6);
}
.cursor-outline {
width: 44px; height: 44px;
border: 1.5px solid rgba(212, 165, 116, 0.4);
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}
body.cursor-hover .cursor-outline {
width: 70px; height: 70px;
border-color: var(--primary);
background: rgba(212, 165, 116, 0.08);
backdrop-filter: blur(4px);
}
/* ===== BLUEPRINT GRID BACKGROUND ===== */
.blueprint-grid {
position: fixed; inset: 0;
background-image:
linear-gradient(rgba(139, 111, 78, 0.08) 1px, transparent 1px),
linear-gradient(90deg, rgba(139, 111, 78, 0.08) 1px, transparent 1px);
background-size: 60px 60px;
pointer-events: none;
z-index: 1;
opacity: 0.7;
}
.blueprint-grid::before {
content: ''; position: absolute; inset: 0;
background-image:
radial-gradient(circle at 25% 25%, rgba(212, 165, 116, 0.06) 0%, transparent 50%),
radial-gradient(circle at 75% 75%, rgba(139, 111, 78, 0.04) 0%, transparent 50%);
animation: pulseGrid 15s infinite alternate;
}
@keyframes pulseGrid {
0%, 100% { opacity: 0.7; }
50% { opacity: 1; }
}
/* ===== CINEMATIC SECTIONS ===== */
section {
position: relative;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 4rem 2rem;
overflow: hidden;
}
/* ===== HERO SECTION ===== */
.hero-section {
background: var(--gradient-1);
perspective: 1000px;
}
#canvas-container {
position: absolute; inset: 0;
z-index: 2;
opacity: 0;
transform: scale(0.95);
transition: opacity 1.2s ease, transform 1.2s cubic-bezier(0.16, 1, 0.3, 1);
}
#canvas-container.active {
opacity: 1;
transform: scale(1);
}
.hero-content {
position: relative;
z-index: 10;
text-align: center;
max-width: 900px;
padding: 2rem;
}
.hero-title {
font-family: 'Playfair Display', serif;
font-size: clamp(3rem, 8vw, 6rem);
font-weight: 700;
line-height: 1.05;
background: linear-gradient(135deg, var(--dark) 0%, var(--secondary) 50%, var(--primary) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: titleReveal 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
opacity: 0;
transform: translateY(30px);
}
@keyframes titleReveal {
to { opacity: 1; transform: translateY(0); }
}
.hero-subtitle {
font-size: clamp(1.1rem, 2.5vw, 1.4rem);
color: var(--secondary);
margin: 1.5rem 0 2.5rem;
opacity: 0;
transform: translateY(20px);
animation: fadeInUp 1s 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes fadeInUp {
to { opacity: 1; transform: translateY(0); }
}
/* ===== GLASSMORPHISM CARDS ===== */
.glass-card {
background: var(--glass);
border: 1px solid var(--glass-border);
backdrop-filter: blur(12px);
border-radius: 24px;
padding: 2.5rem;
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.glass-card:hover {
transform: translateY(-8px) scale(1.02);
border-color: var(--primary);
box-shadow:
0 20px 40px rgba(139, 111, 78, 0.15),
0 0 60px rgba(212, 165, 116, 0.1);
}
/* ===== SCROLL INDICATOR ===== */
.scroll-indicator {
position: absolute;
bottom: 3rem;
left: 50%;
transform: translateX(-50%);
z-index: 20;
display: flex;
flex-direction: column;
align-items: center;
gap: 0.75rem;
opacity: 0.8;
animation: bounce 2s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(10px); }
}
.scroll-line {
width: 1px;
height: 60px;
background: linear-gradient(to bottom, var(--primary), transparent);
position: relative;
}
.scroll-line::after {
content: '';
position: absolute;
bottom: 0;
left: -3px;
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--primary);
box-shadow: 0 0 15px rgba(212, 165, 116, 0.8);
animation: scrollDot 2s infinite;
}
@keyframes scrollDot {
0% { opacity: 1; transform: translateY(0); }
100% { opacity: 0; transform: translateY(-40px); }
}
/* ===== PARALLAX ELEMENTS ===== */
.parallax-element {
position: absolute;
will-change: transform;
pointer-events: none;
opacity: 0.6;
}
.orb {
border-radius: 50%;
filter: blur(40px);
animation: floatOrb 25s infinite ease-in-out;
}
@keyframes floatOrb {
0%, 100% { transform: translate(0, 0) scale(1); }
25% { transform: translate(30px, -20px) scale(1.05); }
50% { transform: translate(-20px, 30px) scale(0.95); }
75% { transform: translate(15px, 15px) scale(1.02); }
}
/* ===== SECTION TRANSITIONS ===== */
.section-divider {
height: 1px;
background: linear-gradient(90deg, transparent, var(--primary), transparent);
margin: 4rem auto;
max-width: 600px;
position: relative;
}
.section-divider::after {
content: '';
position: absolute;
top: -4px;
left: 50%;
transform: translateX(-50%);
width: 10px;
height: 10px;
border-radius: 50%;
background: var(--primary);
box-shadow: 0 0 20px rgba(212, 165, 116, 0.8);
}
/* ===== LOADING SCREEN ===== */
.loader {
position: fixed;
inset: 0;
background: var(--dark);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
transition: opacity 0.8s ease, visibility 0.8s ease;
}
.loader.hidden {
opacity: 0;
visibility: hidden;
}
.loader-content {
text-align: center;
}
.loader-logo {
font-family: 'Playfair Display', serif;
font-size: 3rem;
color: var(--primary);
margin-bottom: 2rem;
letter-spacing: 4px;
animation: pulseLogo 2s infinite;
}
@keyframes pulseLogo {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.8; transform: scale(0.98); }
}
.loader-bar {
width: 200px;
height: 3px;
background: rgba(255,255,255,0.1);
border-radius: 3px;
overflow: hidden;
position: relative;
}
.loader-progress {
position: absolute;
top: 0; left: 0;
height: 100%;
width: 0%;
background: var(--primary);
box-shadow: 0 0 15px rgba(212, 165, 116, 0.8);
animation: loadProgress 2.5s ease-in-out forwards;
}
@keyframes loadProgress {
to { width: 100%; }
}
/* ===== RESPONSIVE ===== */
@media (max-width: 768px) {
.hero-title { font-size: clamp(2.5rem, 10vw, 4rem); }
.glass-card { padding: 1.8rem; }
section { padding: 3rem 1.5rem; }
}
</style>
</head>
<body class="antialiased">
<!-- Loading Screen -->
<div class="loader" id="loader">
<div class="loader-content">
<div class="loader-logo font-serif">CHRISTABEL</div>
<div class="loader-bar">
<div class="loader-progress"></div>
</div>
</div>
</div>
<!-- Custom Cursor -->
<div class="cursor-dot"></div>
<div class="cursor-outline"></div>
<!-- Blueprint Grid Background -->
<div class="blueprint-grid"></div>
<!-- Floating Orbs -->
<div class="parallax-element orb" style="width: 300px; height: 300px; background: rgba(212, 165, 116, 0.15); top: 10%; left: 5%; animation-delay: 0s;"></div>
<div class="parallax-element orb" style="width: 200px; height: 200px; background: rgba(139, 111, 78, 0.12); bottom: 15%; right: 8%; animation-delay: -8s;"></div>
<div class="parallax-element orb" style="width: 150px; height: 150px; background: rgba(212, 165, 116, 0.1); top: 60%; left: 15%; animation-delay: -15s;"></div>
<!-- Hero Section -->
<section class="hero-section" id="hero">
<div id="canvas-container"></div>
<div class="hero-content">
<h1 class="hero-title font-serif">CHRISTABEL</h1>
<p class="hero-subtitle font-display">An immersive cinematic journey through architectural poetry and digital artistry</p>
<button class="glass-card font-display font-medium px-8 py-4 cursor-pointer hover-trigger inline-flex items-center gap-3 group">
<span>Begin Experience</span>
<svg class="w-5 h-5 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
</svg>
</button>
</div>
<div class="scroll-indicator">
<span class="text-xs font-display uppercase tracking-widest text-gray-600">Scroll</span>
<div class="scroll-line"></div>
</div>
</section>
<!-- Story Section -->
<section id="story" class="bg-gradient-to-b from-[#f5f3f0] to-[#ebe6df]">
<div class="max-w-5xl mx-auto text-center px-4">
<div class="glass-card inline-block mb-8">
<span class="font-display text-sm uppercase tracking-widest text-gray-600">The Vision</span>
</div>
<h2 class="font-serif text-4xl md:text-5xl font-bold mb-6 leading-tight">
Where <span class="text-[var(--primary)]">Architecture</span> Meets <span class="text-[var(--secondary)]">Imagination</span>
</h2>
<p class="font-display text-lg text-gray-700 max-w-3xl mx-auto leading-relaxed">
CHRISTABEL redefines digital storytelling through cinematic 3D environments,
scroll-driven narratives, and meticulously crafted interactions that transform
every scroll into a moment of discovery.
</p>
</div>
</section>
<!-- Features Section -->
<section id="features" class="bg-[var(--dark)] text-[var(--light)]">
<div class="max-w-6xl mx-auto px-4">
<div class="grid md:grid-cols-3 gap-8">
<!-- Feature 1 -->
<div class="glass-card hover-trigger">
<div class="w-16 h-16 rounded-2xl bg-gradient-to-br from-[var(--primary)] to-[var(--secondary)] flex items-center justify-center mb-6">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M14 10l-2 1m0 0l-2-1m2 1v2.5M20 7l-2 1m2-1l-2-1m2 1v2.5M14 4l-2-1-2 1M4 7l2-1M4 7l2 1M4 7v2.5M12 21l-2-1m2 1l2-1m-2 1v-2.5M6 18l-2-1v-2.5M18 18l2-1v-2.5"/>
</svg>
</div>
<h3 class="font-serif text-2xl font-bold mb-3">Cinematic 3D Worlds</h3>
<p class="font-display text-gray-300 leading-relaxed">
Procedurally generated environments that respond to your scroll,
creating a living, breathing narrative space.
</p>
</div>
<!-- Feature 2 -->
<div class="glass-card hover-trigger">
<div class="w-16 h-16 rounded-2xl bg-gradient-to-br from-[var(--secondary)] to-[var(--primary)] flex items-center justify-center mb-6">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
</div>
<h3 class="font-serif text-2xl font-bold mb-3">Scroll-Driven Magic</h3>
<p class="font-display text-gray-300 leading-relaxed">
Every scroll triggers precise animations, camera movements, and
environmental shifts that tell your story frame by frame.
</p>
</div>
<!-- Feature 3 -->
<div class="glass-card hover-trigger">
<div class="w-16 h-16 rounded-2xl bg-gradient-to-br from-[var(--primary)] to-[var(--accent)] flex items-center justify-center mb-6">
<svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
</svg>
</div>
<h3 class="font-serif text-2xl font-bold mb-3">Premium Aesthetics</h3>
<p class="font-display text-gray-300 leading-relaxed">
Glassmorphism, dynamic lighting, and curated typography create
a luxurious visual language that elevates every interaction.
</p>
</div>
</div>
</div>
</section>
<!-- CTA Section -->
<section id="cta" class="relative overflow-hidden">
<div class="absolute inset-0 bg-gradient-to-br from-[var(--primary)]/10 via-transparent to-[var(--secondary)]/10"></div>
<div class="max-w-4xl mx-auto text-center px-4 relative z-10">
<h2 class="font-serif text-4xl md:text-5xl font-bold mb-6">
Ready to Transform Your Digital Presence?
</h2>
<p class="font-display text-xl text-gray-700 mb-10 max-w-2xl mx-auto">
Let's craft an unforgettable cinematic experience that captivates your audience
and elevates your brand to new heights.
</p>
<button class="glass-card font-display font-semibold px-10 py-5 cursor-pointer hover-trigger inline-flex items-center gap-3 group text-lg">
<span>Start Your Journey</span>
<svg class="w-6 h-6 group-hover:translate-x-1 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
</svg>
</button>
</div>
</section>
<!-- Footer -->
<footer class="py-12 text-center text-gray-600 font-display text-sm border-t border-gray-200">
<p>© 2024 CHRISTABEL Experience. Crafted with precision and passion.</p>
</footer>
<script>
// ===== CUSTOM CURSOR =====
const cursorDot = document.querySelector('.cursor-dot');
const cursorOutline = document.querySelector('.cursor-outline');
window.addEventListener('mousemove', (e) => {
const posX = e.clientX;
const posY = e.clientY;
// Dot follows instantly
cursorDot.style.left = `${posX}px`;
cursorDot.style.top = `${posY}px`;
// Outline follows with slight delay for smooth effect
cursorOutline.animate({
left: `${posX}px`,
top: `${posY}px`
}, { duration: 500, fill: "forwards" });
});
// Hover effects for interactive elements
const hoverTriggers = document.querySelectorAll('.hover-trigger, a, button');
hoverTriggers.forEach(el => {
el.addEventListener('mouseenter', () => {
document.body.classList.add('cursor-hover');
});
el.addEventListener('mouseleave', () => {
document.body.classList.remove('cursor-hover');
});
});
// ===== LOADER =====
window.addEventListener('load', () => {
setTimeout(() => {
document.getElementById('loader').classList.add('hidden');
initCinematicExperience();
}, 2600);
});
// ===== CINEMATIC EXPERIENCE INIT =====
function initCinematicExperience() {
// Activate canvas after load
document.getElementById('canvas-container').classList.add('active');
// Initialize Three.js scene
initThreeJS();
// Initialize GSAP ScrollTrigger
initScrollAnimations();
// Parallax effects for orbs
initParallax();
}
// ===== THREE.JS CINEMATIC SCENE =====
function initThreeJS() {
const container = document.getElementById('canvas-container');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.2;
container.appendChild(renderer.domElement);
// Create cinematic particle system
const particlesGeometry = new THREE.BufferGeometry();
const particlesCount = 2000;
const posArray = new Float32Array(particlesCount * 3);
for(let i = 0; i < particlesCount * 3; i++) {
posArray[i] = (Math.random() - 0.5) * 15;
}
particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3));
const particlesMaterial = new THREE.PointsMaterial({
size: 0.03,
color: 0xd4a574,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending
});
const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particlesMesh);
// Add floating geometric shapes
const shapes = [];
const geometries = [
new THREE.IcosahedronGeometry(0.8, 0),
new THREE.OctahedronGeometry(0.7, 0),
new THREE.TetrahedronGeometry(0.9, 0)
];
for(let i = 0; i < 8; i++) {
const geometry = geometries[Math.floor(Math.random() * geometries.length)];
const material = new THREE.MeshPhongMaterial({
color: i % 2 === 0 ? 0xd4a574 : 0x8b6f4e,
transparent: true,
opacity: 0.15,
wireframe: true
});
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10,
(Math.random() - 0.5) * 10
);
mesh.rotation.set(Math.random() * Math.PI, Math.random() * Math.PI, 0);
scene.add(mesh);
shapes.push({
mesh,
speed: 0.001 + Math.random() * 0.003,
rotationSpeed: 0.002 + Math.random() * 0.005
});
}
// Lighting
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const pointLight1 = new THREE.PointLight(0xd4a574, 1.2, 20);
pointLight1.position.set(5, 5, 5);
scene.add(pointLight1);
const pointLight2 = new THREE.PointLight(0x8b6f4e, 0.8, 15);
pointLight2.position.set(-5, -3, 4);
scene.add(pointLight2);
camera.position.z = 5;
// Animation loop
let time = 0;
function animate() {
requestAnimationFrame(animate);
time += 0.005;
// Animate particles
particlesMesh.rotation.y = time * 0.1;
particlesMesh.rotation.x = time * 0.05;
// Animate shapes
shapes.forEach(shape => {
shape.mesh.rotation.x += shape.rotationSpeed;
shape.mesh.rotation.y += shape.rotationSpeed * 0.7;
shape.mesh.position.y += Math.sin(time + shape.mesh.id) * 0.002;
});
// Subtle camera movement
camera.position.x = Math.sin(time * 0.3) * 0.3;
camera.position.y = Math.cos(time * 0.2) * 0.2;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
animate();
// Handle resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Scroll-based camera movement
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
camera.position.z = 5 + scrollY * 0.002;
particlesMesh.rotation.y = scrollY * 0.0005;
});
}
// ===== GSAP SCROLL ANIMATIONS =====
function initScrollAnimations() {
gsap.registerPlugin(ScrollTrigger);
// Hero title stagger reveal
gsap.from('.hero-title', {
scrollTrigger: {
trigger: '#hero',
start: 'top top',
end: 'bottom top',
scrub: 1
},
scale: 1.05,
opacity: 0.9
});
// Story section entrance
gsap.from('#story .glass-card', {
scrollTrigger: {
trigger: '#story',
start: 'top 80%',
toggleActions: 'play none none reverse'
},
y: 40,
opacity: 0,
duration: 1,
ease: 'power3.out'
});
// Features cards stagger
gsap.utils.toArray('#features .glass-card').forEach((card, i) => {
gsap.from(card, {
scrollTrigger: {
trigger: card,
start: 'top 85%',
toggleActions: 'play none none reverse'
},
y: 60,
opacity: 0,
duration: 0.8,
delay: i * 0.15,
ease: 'back.out(1.7)'
});
});
// CTA section parallax
gsap.to('#cta', {
scrollTrigger: {
trigger: '#cta',
start: 'top 70%',
end: 'bottom top',
scrub: 1
},
backgroundPosition: '50% 150%',
ease: 'none'
});
}
// ===== PARALLAX EFFECTS =====
function initParallax() {
const parallaxElements = document.querySelectorAll('.parallax-element');
window.addEventListener('scroll', () => {
const scrolled = window.scrollY;
parallaxElements.forEach((el, index) => {
const speed = 0.02 + (index * 0.015);
const yPos = -(scrolled * speed);
el.style.transform = `translateY(${yPos}px)`;
});
});
// Mouse-based parallax for hero
const hero = document.getElementById('hero');
hero.addEventListener('mousemove', (e) => {
const xAxis = (window.innerWidth / 2 - e.pageX) / 25;
const yAxis = (window.innerHeight / 2 - e.pageY) / 25;
document.querySelectorAll('.orb').forEach((orb, i) => {
const factor = 0.5 + (i * 0.3);
orb.style.transform = `translate(${xAxis * factor}px, ${yAxis * factor}px)`;
});
});
}
// ===== SMOOTH SCROLL FOR ANCHOR LINKS =====
document.querySelectorAll('a[href^="#"], button').forEach(anchor => {
anchor.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if(target) {
gsap.to(window, {
duration: 1.2,
scrollTo: { y: target, offsetY: 80 },
ease: 'power3.inOut'
});
}
});
});
// ===== PREVENT SCROLL JUMP ON LOAD =====
window.addEventListener('load', () => {
document.body.style.overflowY = 'auto';
});
</script>
<!-- GSAP ScrollToPlugin for smooth anchor scrolling -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollToPlugin.min.js"></script>
</body>
</html>
More by @sphamandla
Comments (0)
Please sign in to comment