Files
ZanePersonal/assets/js/modules/animations.js
copilot-swe-agent[bot] 542d80802e feat: Implement comprehensive repository improvements
- Set up ESLint and Prettier for code quality
- Split large script.js into modular architecture (DOM, animations, effects, easter-eggs, sound, interactions)
- Organize assets into proper directory structure (assets/css, assets/js/modules, assets/images)
- Add semantic HTML5 landmarks (header, main, nav, footer)
- Implement ARIA labels and keyboard navigation for accessibility
- Set up Vite build system with minification and optimization
- Add CSS custom properties for design tokens
- Create sitemap.xml and robots.txt for SEO
- Add MIT LICENSE
- Expand README with comprehensive documentation
- Set up GitHub Actions CI/CD workflow
- Optimize build output: ~59KB total (30KB image + 13KB CSS + 16KB JS gzipped)

Co-authored-by: ZaneThePython <102631678+ZaneThePython@users.noreply.github.com>
2025-11-09 00:09:48 +00:00

123 lines
2.9 KiB
JavaScript

// Animation utilities and functions
import { DOM, getMainElements } from './dom.js';
// Animate elements on page load
export function animateOnLoad() {
const { avatar, brandName, disclaimer } = getMainElements();
const navButtons = DOM.getAll('.nav-button');
// Set initial states
if (avatar) {
avatar.style.opacity = '0';
avatar.style.transform = 'translateY(30px)';
}
if (brandName) {
brandName.style.opacity = '0';
brandName.style.transform = 'translateY(30px)';
}
navButtons.forEach((button, index) => {
button.style.opacity = '0';
button.style.transform = 'translateX(30px)';
button.style.transitionDelay = `${index * 0.1}s`;
});
if (disclaimer) {
disclaimer.style.opacity = '0';
}
// Animate in sequence
setTimeout(() => {
if (avatar) {
avatar.style.transition = 'all 0.8s ease';
avatar.style.opacity = '1';
avatar.style.transform = 'translateY(0)';
}
}, 200);
setTimeout(() => {
if (brandName) {
brandName.style.transition = 'all 0.8s ease';
brandName.style.opacity = '1';
brandName.style.transform = 'translateY(0)';
}
}, 400);
setTimeout(() => {
navButtons.forEach((button) => {
button.style.transition = 'all 0.6s ease';
button.style.opacity = '1';
button.style.transform = 'translateX(0)';
});
}, 600);
setTimeout(() => {
if (disclaimer) {
disclaimer.style.transition = 'all 0.8s ease';
disclaimer.style.opacity = '1';
}
}, 800);
}
// Typing animation
export function typeWriter(element, text, speed = 100) {
if (!element) return;
let i = 0;
element.innerHTML = '';
function type() {
if (i < text.length) {
element.innerHTML += text.charAt(i);
i++;
setTimeout(type, speed);
}
}
type();
}
// Animate skill tags with stagger effect
export function animateSkillTags() {
const skillTags = DOM.getAll('.skill-tag');
skillTags.forEach((tag, index) => {
tag.style.opacity = '0';
tag.style.transform = 'translateY(20px)';
setTimeout(() => {
tag.style.transition = 'all 0.5s ease';
tag.style.opacity = '1';
tag.style.transform = 'translateY(0)';
}, index * 100);
});
}
// Animate project cards with stagger effect
export function animateProjectCards() {
const projectCards = DOM.getAll('.project-card');
projectCards.forEach((card, index) => {
card.style.opacity = '0';
card.style.transform = 'translateY(30px)';
setTimeout(() => {
card.style.transition = 'all 0.6s ease';
card.style.opacity = '1';
card.style.transform = 'translateY(0)';
}, index * 150);
});
}
// Add typing animation for tagline
export function addTypingAnimation() {
const { tagline } = getMainElements();
if (tagline) {
const originalText = tagline.textContent;
tagline.textContent = '';
setTimeout(() => {
typeWriter(tagline, originalText, 100);
}, 2000);
}
}