Skip to content
This repository was archived by the owner on Apr 4, 2026. It is now read-only.

Commit 285e780

Browse files
committed
Upgrade rocket navigation across all pages
- cryptography: draggable rocket scrollbar (grab & drag to navigate sections), upgraded SVG with gradients/porthole reflections, 5-layer gradient flames, glow pulse, spark particles on drag, track progress fill, enhanced GSAP scroll animations (section headings skew, comparison marks bounce, code blocks slide, glass pop) - index/how-it-works/changelog: unified rocket back-to-top with same crypto-style gradient SVG, 5-layer flames, glow ring pulse, enhanced launch animation with expanding glow trail
1 parent b48bc5c commit 285e780

4 files changed

Lines changed: 669 additions & 5 deletions

File tree

src/pages/changelog.astro

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,81 @@ const base = import.meta.env.BASE_URL.replace(/\/?$/, '/');
113113
</div>
114114
</section>
115115

116+
<!-- Rocket Back to Top -->
117+
<button id="rocket-top" aria-label="Back to top" class="fixed bottom-8 right-8 z-50 w-16 h-16 rounded-full bg-surface/80 backdrop-blur-md border border-phantom/40 flex items-center justify-center cursor-pointer opacity-0 translate-y-8 pointer-events-none transition-all duration-500 hover:scale-110 group">
118+
<div class="rocket-glow absolute -inset-2 rounded-full pointer-events-none"></div>
119+
<svg class="w-9 h-9 transition-transform duration-300 group-hover:-translate-y-1 relative z-10" viewBox="0 0 64 64" fill="none">
120+
<defs>
121+
<linearGradient id="rtBody" x1="32" y1="4" x2="32" y2="48" gradientUnits="userSpaceOnUse">
122+
<stop offset="0%" stop-color="#D68FFF"/>
123+
<stop offset="40%" stop-color="#9C4DCC"/>
124+
<stop offset="100%" stop-color="#6B2FA0"/>
125+
</linearGradient>
126+
<radialGradient id="rtPort" cx="50%" cy="40%" r="55%">
127+
<stop offset="0%" stop-color="#E0B0FF" stop-opacity="0.9"/>
128+
<stop offset="70%" stop-color="#9C4DCC" stop-opacity="0.4"/>
129+
<stop offset="100%" stop-color="#6B2FA0" stop-opacity="0.1"/>
130+
</radialGradient>
131+
</defs>
132+
<path d="M32 4 C32 4 18 18 18 40 L24 47 L40 47 L46 40 C46 18 32 4 32 4Z" fill="url(#rtBody)"/>
133+
<path d="M32 4 C32 4 26 14 25 26 L32 6 L39 26 C38 14 32 4 32 4Z" fill="#D68FFF" opacity="0.25"/>
134+
<circle cx="32" cy="26" r="7" fill="none" stroke="#B44FE0" stroke-width="0.8" opacity="0.4"/>
135+
<circle cx="32" cy="26" r="5.5" fill="#0A0A10" stroke="#B44FE0" stroke-width="1.5"/>
136+
<circle cx="32" cy="26" r="4" fill="url(#rtPort)"/>
137+
<circle cx="30" cy="24" r="1.5" fill="white" opacity="0.35"/>
138+
<circle cx="33.5" cy="28" r="0.7" fill="white" opacity="0.15"/>
139+
<path d="M18 36 L9 52 L18 44Z" fill="#7B2D8E"/>
140+
<path d="M46 36 L55 52 L46 44Z" fill="#7B2D8E"/>
141+
<path d="M18 36 L11 49 L18 42Z" fill="#9C4DCC" opacity="0.3"/>
142+
<path d="M46 36 L53 49 L46 42Z" fill="#9C4DCC" opacity="0.3"/>
143+
<ellipse cx="32" cy="45" rx="8" ry="2.5" fill="#5A1F7A" stroke="#9C4DCC" stroke-width="0.5" opacity="0.7"/>
144+
<line x1="24" y1="38" x2="40" y2="38" stroke="#B44FE0" stroke-width="0.5" opacity="0.25"/>
145+
<line x1="22" y1="42" x2="42" y2="42" stroke="#B44FE0" stroke-width="0.5" opacity="0.15"/>
146+
</svg>
147+
<div class="rocket-flames absolute -bottom-4 left-1/2 -translate-x-1/2 flex gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity z-10">
148+
<div class="w-1 h-3 bg-gradient-to-b from-orange-300 to-orange-600 rounded-full animate-flame1 opacity-90"></div>
149+
<div class="w-1.5 h-5 bg-gradient-to-b from-yellow-200 to-orange-500 rounded-full animate-flame2"></div>
150+
<div class="w-2 h-6 bg-gradient-to-b from-white to-yellow-400 rounded-full animate-flame2" style="animation-delay:-0.1s;"></div>
151+
<div class="w-1.5 h-5 bg-gradient-to-b from-yellow-200 to-orange-500 rounded-full animate-flame2" style="animation-delay:-0.15s;"></div>
152+
<div class="w-1 h-3 bg-gradient-to-b from-orange-300 to-orange-600 rounded-full animate-flame3 opacity-90"></div>
153+
</div>
154+
<div class="absolute -bottom-10 left-1/2 -translate-x-1/2 w-4 h-10 bg-gradient-to-b from-orange-400/20 via-phantom/10 to-transparent rounded-full blur-md opacity-0 group-hover:opacity-100 transition-opacity" id="rocket-top-exhaust"></div>
155+
</button>
156+
<style>
157+
@keyframes flame1 { 0%,100% { height: 10px; opacity: 0.8; } 50% { height: 18px; opacity: 1; } }
158+
@keyframes flame2 { 0%,100% { height: 16px; opacity: 0.9; } 50% { height: 24px; opacity: 1; } }
159+
@keyframes flame3 { 0%,100% { height: 8px; opacity: 0.7; } 50% { height: 16px; opacity: 1; } }
160+
.animate-flame1 { animation: flame1 0.3s ease-in-out infinite; }
161+
.animate-flame2 { animation: flame2 0.25s ease-in-out infinite; }
162+
.animate-flame3 { animation: flame3 0.35s ease-in-out infinite; }
163+
#rocket-top { filter: drop-shadow(0 0 10px rgba(156,77,204,0.3)); }
164+
@keyframes rocketGlow {
165+
0%, 100% { filter: drop-shadow(0 0 10px rgba(156,77,204,0.3)); }
166+
50% { filter: drop-shadow(0 0 22px rgba(156,77,204,0.6)); }
167+
}
168+
#rocket-top.visible { opacity: 1; transform: translateY(0); pointer-events: auto; animation: rocketGlow 3s ease-in-out infinite; }
169+
.rocket-glow {
170+
background: radial-gradient(circle, rgba(156,77,204,0.15) 0%, transparent 70%);
171+
animation: rocketGlowRing 2s ease-in-out infinite;
172+
}
173+
@keyframes rocketGlowRing {
174+
0%, 100% { transform: scale(1); opacity: 0.4; }
175+
50% { transform: scale(1.3); opacity: 0.7; }
176+
}
177+
#rocket-top.launching {
178+
animation: rocketLaunch 0.8s ease-in forwards !important;
179+
}
180+
@keyframes rocketLaunch {
181+
0% { transform: translateY(0) scale(1); filter: drop-shadow(0 0 10px rgba(156,77,204,0.4)); }
182+
20% { transform: translateY(8px) scale(1.15); filter: drop-shadow(0 0 30px rgba(156,77,204,0.8)); }
183+
100% { transform: translateY(-120vh) scale(0.5); opacity: 0; filter: drop-shadow(0 0 40px rgba(156,77,204,1)); }
184+
}
185+
#rocket-top.launching .rocket-flames { opacity: 1 !important; }
186+
#rocket-top.launching .rocket-flames div { height: 1.5rem !important; }
187+
#rocket-top.launching #rocket-top-exhaust { opacity: 1 !important; height: 4rem; }
188+
#rocket-top.launching .rocket-glow { transform: scale(2); opacity: 1; }
189+
</style>
190+
116191
<!-- Footer -->
117192
<footer class="py-12 border-t border-white/5">
118193
<div class="max-w-7xl mx-auto px-6 flex flex-col md:flex-row items-center justify-between gap-6">
@@ -193,6 +268,22 @@ const base = import.meta.env.BASE_URL.replace(/\/?$/, '/');
193268
window.addEventListener('scroll', () => { if (!sp) return; const h = document.documentElement.scrollHeight - window.innerHeight; sp.style.width = h > 0 ? `${(window.scrollY/h*100)}%` : '0%'; });
194269

195270
fetchChangelogs();
271+
272+
// ---- Rocket Back to Top ----
273+
const rocketBtn = document.getElementById('rocket-top');
274+
window.addEventListener('scroll', () => {
275+
if (!rocketBtn) return;
276+
if (window.scrollY > 600) rocketBtn.classList.add('visible');
277+
else rocketBtn.classList.remove('visible');
278+
});
279+
rocketBtn?.addEventListener('click', () => {
280+
rocketBtn.classList.add('launching');
281+
rocketBtn.querySelector('.rocket-flames')?.classList.add('opacity-100');
282+
window.scrollTo({ top: 0, behavior: 'smooth' });
283+
setTimeout(() => {
284+
rocketBtn.classList.remove('launching', 'visible');
285+
}, 1000);
286+
});
196287
</script>
197288

198289
</Layout>

0 commit comments

Comments
 (0)