Skip to main content
Glama
danohn

mcpcap

by danohn
script.js11.6 kB
// Consolidated initialization document.addEventListener('DOMContentLoaded', function() { initMobileNavigation(); initCodeTabSwitching(); initTerminalAnimation(); initCopyButtons(); }); // Mobile navigation toggle function initMobileNavigation() { const navToggle = document.getElementById('navToggle'); const navMenu = document.getElementById('navMenu'); if (!navToggle || !navMenu) return; navToggle.addEventListener('click', function() { const isOpen = navMenu.classList.contains('active'); navMenu.classList.toggle('active'); // Update ARIA attribute navToggle.setAttribute('aria-expanded', !isOpen); // Animate hamburger bars const bars = navToggle.querySelectorAll('.bar'); bars.forEach((bar, index) => { if (!isOpen) { if (index === 0) { bar.style.transform = 'rotate(-45deg) translate(-5px, 6px)'; } else if (index === 1) { bar.style.opacity = '0'; } else { bar.style.transform = 'rotate(45deg) translate(-5px, -6px)'; } } else { bar.style.transform = 'none'; bar.style.opacity = '1'; } }); }); // Close mobile menu when clicking on links const navLinks = document.querySelectorAll('.nav-link'); navLinks.forEach(link => { link.addEventListener('click', () => { navMenu.classList.remove('active'); navToggle.setAttribute('aria-expanded', 'false'); const bars = navToggle.querySelectorAll('.bar'); bars.forEach(bar => { bar.style.transform = 'none'; bar.style.opacity = '1'; }); }); }); } // Smooth scrolling for anchor links document.querySelectorAll('a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { e.preventDefault(); const target = document.querySelector(this.getAttribute('href')); if (target) { const headerOffset = 80; const elementPosition = target.getBoundingClientRect().top; const offsetPosition = elementPosition + window.pageYOffset - headerOffset; window.scrollTo({ top: offsetPosition, behavior: 'smooth' }); } }); }); // Code tab switching function initCodeTabSwitching() { const codeTabs = document.querySelectorAll('.code-tab'); const codeBlocks = document.querySelectorAll('.code-block'); if (!codeTabs.length) return; codeTabs.forEach(tab => { tab.addEventListener('click', function() { const targetTab = this.getAttribute('data-tab'); // Remove active class from all tabs and blocks codeTabs.forEach(t => t.classList.remove('active')); codeBlocks.forEach(block => block.classList.remove('active')); // Add active class to clicked tab and corresponding block this.classList.add('active'); const targetBlock = document.getElementById(targetTab); if (targetBlock) { targetBlock.classList.add('active'); } }); }); } // Navbar scroll effect window.addEventListener('scroll', function() { const navbar = document.querySelector('.navbar'); const scrollPosition = window.scrollY; if (scrollPosition > 50) { navbar.style.backgroundColor = 'rgba(255, 255, 255, 0.98)'; navbar.style.boxShadow = '0 4px 6px -1px rgb(0 0 0 / 0.1)'; } else { navbar.style.backgroundColor = 'rgba(255, 255, 255, 0.95)'; navbar.style.boxShadow = 'none'; } }); // Terminal typing animation function initTerminalAnimation() { const terminalBody = document.querySelector('.terminal-body'); if (!terminalBody) return; const cursor = terminalBody.querySelector('.terminal-cursor'); const commands = [ '$ pip install mcpcap', '$ mcpcap', "Starting MCP server 'mcpcap' with transport 'stdio'" ]; let currentCommand = 0; let currentChar = 0; function createTerminalLine(isOutput = false) { const line = document.createElement('div'); line.className = isOutput ? 'terminal-line output' : 'terminal-line'; if (!isOutput) { line.innerHTML = '<span class="prompt">$</span> '; } terminalBody.insertBefore(line, cursor); return line; } function typeCommand() { if (currentCommand >= commands.length) return; const command = commands[currentCommand]; const isOutput = !command.startsWith('$'); const currentLine = terminalBody.children[terminalBody.children.length - 2]; // Get last line before cursor if (!currentLine || currentChar === 0) { // Create new line for this command const newLine = createTerminalLine(isOutput); if (isOutput) { newLine.textContent = ''; } } const activeLine = terminalBody.children[terminalBody.children.length - 2]; if (currentChar < command.length) { if (isOutput) { activeLine.textContent = command.substring(0, currentChar + 1); } else { activeLine.innerHTML = '<span class="prompt">$</span> ' + command.substring(2, currentChar + 1); } currentChar++; setTimeout(typeCommand, 50); } else { // Command finished, move to next currentCommand++; currentChar = 0; setTimeout(typeCommand, 800); } } // Start typing animation after a short delay setTimeout(typeCommand, 1000); } // Intersection Observer for animations document.addEventListener('DOMContentLoaded', function() { const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' }; const observer = new IntersectionObserver(function(entries) { entries.forEach(entry => { if (entry.isIntersecting) { entry.target.style.animationPlayState = 'running'; entry.target.classList.add('animate-in'); } }); }, observerOptions); // Observe feature cards document.querySelectorAll('.feature-card, .module-card, .step').forEach(el => { el.style.opacity = '0'; el.style.transform = 'translateY(30px)'; el.style.transition = 'all 0.6s ease'; observer.observe(el); }); }); // Add animation styles when elements come into view const style = document.createElement('style'); style.textContent = ` .animate-in { opacity: 1 !important; transform: translateY(0) !important; } .feature-card.animate-in { transition-delay: calc(var(--delay, 0) * 0.1s); } `; document.head.appendChild(style); // Set animation delays for feature cards document.querySelectorAll('.feature-card').forEach((card, index) => { card.style.setProperty('--delay', index); }); // Copy to clipboard functionality for code blocks function initCopyButtons() { // Add copy buttons to code blocks const codeBlocks = document.querySelectorAll('.code-block'); codeBlocks.forEach(block => { const copyButton = document.createElement('button'); copyButton.className = 'copy-button'; copyButton.innerHTML = `<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>Copy`; copyButton.addEventListener('click', function() { const code = block.querySelector('code').textContent; navigator.clipboard.writeText(code).then(() => { copyButton.innerHTML = `<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>Copied!`; copyButton.classList.add('copied'); setTimeout(() => { copyButton.innerHTML = `<svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>Copy`; copyButton.classList.remove('copied'); }, 2000); }); }); block.style.position = 'relative'; block.appendChild(copyButton); }); } // Add copy button styles const copyButtonStyles = document.createElement('style'); copyButtonStyles.textContent = ` .copy-button { position: absolute; top: 1rem; right: 1rem; background-color: #334155; color: #94a3b8; border: 1px solid #475569; border-radius: 6px; padding: 0.5rem; font-size: 0.75rem; cursor: pointer; display: flex; align-items: center; gap: 0.25rem; transition: all 0.3s ease; opacity: 0.7; } .copy-button:hover { background-color: #475569; color: #e2e8f0; opacity: 1; } .copy-button.copied { background-color: #059669; color: white; border-color: #059669; } `; document.head.appendChild(copyButtonStyles); // Parallax effect for hero section window.addEventListener('scroll', function() { const scrolled = window.pageYOffset; const hero = document.querySelector('.hero'); if (hero) { const rate = scrolled * -0.5; hero.style.transform = `translateY(${rate}px)`; } }); // Add loading animation document.addEventListener('DOMContentLoaded', function() { // Remove any loading states and show content document.body.classList.add('loaded'); // Stagger animation for hero stats const stats = document.querySelectorAll('.stat'); stats.forEach((stat, index) => { stat.style.opacity = '0'; stat.style.transform = 'translateY(20px)'; stat.style.transition = `all 0.6s ease ${index * 0.1}s`; setTimeout(() => { stat.style.opacity = '1'; stat.style.transform = 'translateY(0)'; }, 500 + (index * 100)); }); }); // Easter egg: Konami code let konamiCode = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65]; let konamiIndex = 0; document.addEventListener('keydown', function(e) { if (e.keyCode === konamiCode[konamiIndex]) { konamiIndex++; if (konamiIndex === konamiCode.length) { // Add some fun animation document.body.style.animation = 'rainbow 2s infinite'; setTimeout(() => { document.body.style.animation = ''; }, 5000); konamiIndex = 0; } } else { konamiIndex = 0; } }); // Add rainbow animation const rainbowStyles = document.createElement('style'); rainbowStyles.textContent = ` @keyframes rainbow { 0% { filter: hue-rotate(0deg); } 100% { filter: hue-rotate(360deg); } } `; document.head.appendChild(rainbowStyles);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/danohn/mcpcap'

If you have feedback or need assistance with the MCP directory API, please join our Discord server