argobox-portfolio/script.js

222 lines
8.4 KiB
JavaScript

/**
* Main JavaScript file for argobox.com
* Handles navigation, animations, and interactivity
*/
document.addEventListener('DOMContentLoaded', function() {
// Update current year in footer
const yearElement = document.getElementById('current-year');
if (yearElement) {
yearElement.textContent = new Date().getFullYear();
}
// Mobile menu toggle
const menuToggle = document.querySelector('.mobile-menu-btn');
const navLinks = document.querySelector('.nav-links');
if (menuToggle && navLinks) {
menuToggle.addEventListener('click', function() {
navLinks.classList.toggle('active');
});
}
// Set active navigation links based on scroll position
const sections = document.querySelectorAll('section');
const navItems = document.querySelectorAll('.nav-link');
function updateActiveLink() {
let currentSection = '';
sections.forEach(section => {
const sectionTop = section.offsetTop - 100;
const sectionHeight = section.offsetHeight;
if (window.scrollY >= sectionTop && window.scrollY < sectionTop + sectionHeight) {
currentSection = section.getAttribute('id');
}
});
navItems.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${currentSection}`) {
link.classList.add('active');
}
});
}
window.addEventListener('scroll', updateActiveLink);
updateActiveLink();
// Handle navbar style change on scroll
const navbar = document.querySelector('.navbar');
function updateNavbarStyle() {
if (window.scrollY > 50) {
navbar?.classList.add('scrolled');
} else {
navbar?.classList.remove('scrolled');
}
}
window.addEventListener('scroll', updateNavbarStyle);
updateNavbarStyle();
// Form submission handling
const contactForm = document.getElementById('contact-form');
if (contactForm) {
contactForm.addEventListener('submit', function(e) {
e.preventDefault();
// In a real implementation, you would send the form data to a backend service
// For now, we'll just simulate a successful submission
const formData = new FormData(contactForm);
const formValues = Object.fromEntries(formData.entries());
console.log('Form submission:', formValues);
// Show success message
alert('Thank you for your message! I will get back to you soon.');
// Reset form
contactForm.reset();
});
}
// Initialize and animate the hero terminal
const typingElement = document.querySelector('.typing-effect');
if (typingElement) {
// The animation is handled by CSS, nothing to do here
console.log('Terminal typing animation initialized');
}
// Create animated data streams in the dashboard
function createDataStreamAnimation() {
// Look for either class name that might be in the HTML
const dataStreamContainer = document.querySelector('.data-stream') ||
document.querySelector('.hero-visual .tech-dashboard .data-stream');
console.log('Data stream container found:', !!dataStreamContainer);
if (!dataStreamContainer) return;
// Clear existing lines
const existingLines = dataStreamContainer.querySelectorAll('.data-line');
existingLines.forEach(line => line.remove());
// Create new random lines
for (let i = 0; i < 10; i++) {
const line = document.createElement('div');
line.classList.add('data-line');
// Random positioning and animation
const left = Math.random() * 90 + 5; // 5-95%
const width = Math.random() * 40 + 10; // 10-50%
const duration = Math.random() * 3 + 2; // 2-5s
line.style.left = `${left}%`;
line.style.width = `${width}%`;
line.style.animationDuration = `${duration}s`;
dataStreamContainer.appendChild(line);
console.log('Added data line:', i);
}
}
// Try to initialize the data stream animation (with retry for race conditions)
setTimeout(createDataStreamAnimation, 100);
// Refresh data streams periodically
setInterval(createDataStreamAnimation, 8000);
// Update terminal output with random status messages
function updateTerminalOutput() {
const terminalOutput = document.querySelector('.terminal-output');
if (!terminalOutput) return;
const statusMessages = [
{ text: 'All systems operational', type: '' },
{ text: 'Backup completed successfully', type: 'terminal-success' },
{ text: 'Security scan in progress', type: 'terminal-info' },
{ text: 'New updates available', type: 'terminal-warning' },
{ text: 'Optimizing database performance', type: 'terminal-info' }
];
// Randomly update one of the lines
const lineIndex = Math.floor(Math.random() * 2) + 4; // Only update the last few lines
const lineToUpdate = terminalOutput.children[lineIndex];
if (lineToUpdate) {
const randomMessage = statusMessages[Math.floor(Math.random() * statusMessages.length)];
lineToUpdate.textContent = `> ${randomMessage.text}`;
lineToUpdate.className = 'terminal-line';
if (randomMessage.type) {
lineToUpdate.classList.add(randomMessage.type);
}
}
}
// Periodically update the terminal with new messages
setInterval(updateTerminalOutput, 5000);
// Simulated live metrics - randomly update values periodically
function updateMetrics() {
function updateMetricIfExists(selector, minValue, maxValue) {
const valueElement = document.querySelector(selector + ' .metric-value') ||
document.querySelector(selector + ' .metric-header .metric-value');
const barElement = document.querySelector(selector + ' .metric-progress');
if (valueElement && barElement) {
const newValue = Math.floor(Math.random() * (maxValue - minValue)) + minValue;
valueElement.textContent = `${newValue}%`;
barElement.style.width = `${newValue}%`;
return true;
}
return false;
}
// Try different selectors to find the metrics
// First attempt with nth-child
let found = updateMetricIfExists('.metric:nth-child(1)', 20, 50);
if (!found) {
// Alternative approach - try by unique class or attribute
updateMetricIfExists('[data-metric="cpu"]', 20, 50);
}
updateMetricIfExists('.metric:nth-child(2)', 45, 65) ||
updateMetricIfExists('[data-metric="memory"]', 45, 65);
updateMetricIfExists('.metric:nth-child(3)', 60, 65) ||
updateMetricIfExists('[data-metric="storage"]', 60, 65);
updateMetricIfExists('.metric:nth-child(4)', 15, 45) ||
updateMetricIfExists('[data-metric="network"]', 15, 45);
}
// Update metrics every 5 seconds
setInterval(updateMetrics, 5000);
// Trigger an initial metrics update
setTimeout(updateMetrics, 500);
// Debug info - help determine if there are any issues
console.log('Script loaded successfully');
console.log('Sections found:', sections.length);
console.log('Nav links found:', navItems.length);
// Check if dashboard elements exist
console.log('Data stream container exists:',
!!document.querySelector('.data-stream') ||
!!document.querySelector('.tech-dashboard .data-stream'));
console.log('Metrics containers exist:',
!!document.querySelector('.metric'));
// Add some diagnostic info in case we're having issues
if (!document.querySelector('.data-stream') &&
!document.querySelector('.tech-dashboard .data-stream')) {
console.warn('Data stream container not found - visualizations may not appear');
}
});