// script.js
document.addEventListener('DOMContentLoaded', () => {
// Global DOM elements
const modal = document.getElementById('toolModal');
const modalTitleEl = document.getElementById('modalTitle');
const modalBodyEl = document.getElementById('modalBody');
const modalAlertEl = document.getElementById('modalAlert');
const closeModalButton = document.querySelector('.close-button');
const currentYearEl = document.getElementById('currentYear');
if (currentYearEl) {
currentYearEl.textContent = new Date().getFullYear();
}
// --- Helper Functions ---
function openModal(title, toolId) {
modalTitleEl.textContent = title;
modalBodyEl.innerHTML = getToolModalContent(toolId); // Get specific HTML content
modal.style.display = 'block';
document.body.style.overflow = 'hidden'; // Prevent background scrolling
// Initialize tool-specific JS after its HTML is in the DOM
const initializer = toolInitializers[toolId];
if (initializer) {
initializer();
}
clearModalAlert();
}
function closeModal() {
modal.style.display = 'none';
document.body.style.overflow = 'auto';
modalBodyEl.innerHTML = ''; // Clear content to free up event listeners if any
clearModalAlert();
}
function showModalAlert(message, type = 'info') {
modalAlertEl.textContent = message;
modalAlertEl.className = `modal-alert ${type}`; // success, error, info
modalAlertEl.style.display = 'block';
}
function clearModalAlert() {
modalAlertEl.textContent = '';
modalAlertEl.style.display = 'none';
}
function showGlobalAlert(message, duration = 3000) {
const alertBox = document.getElementById('globalAlert');
if (!alertBox) return;
alertBox.textContent = message;
alertBox.style.display = 'block';
alertBox.style.top = '-50px'; // Start off-screen for slide-in
setTimeout(() => {
alertBox.style.opacity = '1';
alertBox.style.top = '20px'; // Slide in
}, 10);
setTimeout(() => {
alertBox.style.opacity = '0';
alertBox.style.top = '-50px'; // Slide out
setTimeout(() => {
alertBox.style.display = 'none';
}, 400); // Match transition duration
}, duration);
}
// --- Tool Card Event Listeners ---
document.querySelectorAll('.tool-card').forEach(card => {
card.addEventListener('click', () => {
const toolId = card.dataset.tool;
const toolTitle = card.querySelector('h3').textContent;
openModal(toolTitle, toolId);
});
});
// --- Event Listeners for Modal ---
if(closeModalButton) closeModalButton.addEventListener('click', closeModal);
window.addEventListener('click', (event) => {
if (event.target === modal) {
closeModal();
}
});
window.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && modal.style.display === 'block') {
closeModal();
}
});
// --- Intersection Observer for Card Animations ---
const cards = document.querySelectorAll('.tool-card');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('fade-in-visible');
observer.unobserve(entry.target);
}
});
}, { threshold: 0.1 });
cards.forEach(card => {
card.classList.add('fade-in-hidden');
observer.observe(card);
});
// --- Tool HTML Content and Initializers ---
// This object will store functions that return HTML strings for each tool's modal body
const toolModalContents = {
ageCalculator: () => `
`,
bmiCalculator: () => `
`,
emiCalculator: () => `
`,
percentageCalculator: () => `
`,
lengthConverter: () => `
`,
weightConverter: () => `
`,
temperatureConverter: () => `
`,
textAnalyzer: () => `
`,
caseConverter: () => `
`,
passwordGenerator: () => `
`,
randomNumberGenerator: () => `
`,
colorConverter: () => `
`,
stopwatch: () => `
00:00:00.000
`,
countdownTimer: () => `
00:05:00
`,
dateCalculator: () => `
Calculate Duration Between Dates
Add/Subtract Time
`,
tipCalculator: () => `
`,
notesApp: () => `