-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
137 lines (118 loc) · 4.57 KB
/
script.js
File metadata and controls
137 lines (118 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Mobile Navigation Toggle
const hamburger = document.querySelector('.hamburger');
const navMenu = document.querySelector('.nav-menu');
hamburger.addEventListener('click', () => {
navMenu.classList.toggle('active');
hamburger.classList.toggle('active');
});
// Close mobile menu when clicking on a link
document.querySelectorAll('.nav-menu a').forEach(link => {
link.addEventListener('click', () => {
navMenu.classList.remove('active');
hamburger.classList.remove('active');
});
});
// Smooth scrolling for navigation links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Navbar background change on scroll
const navbar = document.querySelector('.navbar');
window.addEventListener('scroll', () => {
if (window.scrollY > 100) {
navbar.style.background = 'rgba(255, 255, 255, 0.98)';
navbar.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)';
} else {
navbar.style.background = 'rgba(255, 255, 255, 0.98)';
}
});
// Intersection Observer for fade-in animations
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// Add fade-in animation to sections
document.querySelectorAll('section').forEach(section => {
section.style.opacity = '0';
section.style.transform = 'translateY(20px)';
section.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
observer.observe(section);
});
// Add animation to project cards
document.querySelectorAll('.project-card').forEach((card, index) => {
card.style.opacity = '0';
card.style.transform = 'translateY(30px)';
card.style.transition = `opacity 0.5s ease ${index * 0.1}s, transform 0.5s ease ${index * 0.1}s`;
observer.observe(card);
});
// Add animation to timeline items
document.querySelectorAll('.timeline-item').forEach((item, index) => {
item.style.opacity = '0';
item.style.transform = 'translateX(-30px)';
item.style.transition = `opacity 0.5s ease ${index * 0.2}s, transform 0.5s ease ${index * 0.2}s`;
observer.observe(item);
});
// Add animation to skill categories
document.querySelectorAll('.skill-category').forEach((category, index) => {
category.style.opacity = '0';
category.style.transform = 'scale(0.9)';
category.style.transition = `opacity 0.5s ease ${index * 0.1}s, transform 0.5s ease ${index * 0.1}s`;
observer.observe(category);
});
// Typing effect for hero section (optional - you can customize or remove)
const heroText = document.querySelector('.hero h1');
if (heroText) {
const originalText = heroText.innerHTML;
heroText.innerHTML = '';
let i = 0;
function typeWriter() {
if (i < originalText.length) {
heroText.innerHTML += originalText.charAt(i);
i++;
setTimeout(typeWriter, 50);
}
}
// Uncomment the line below to enable typing effect
// typeWriter();
}
// Active navigation link on scroll
const sections = document.querySelectorAll('section[id]');
window.addEventListener('scroll', () => {
const scrollY = window.pageYOffset;
sections.forEach(section => {
const sectionHeight = section.offsetHeight;
const sectionTop = section.offsetTop - 100;
const sectionId = section.getAttribute('id');
if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
document.querySelectorAll('.nav-menu a').forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${sectionId}`) {
link.classList.add('active');
}
});
}
});
});
// Form validation (if you add a contact form later)
// Add your form validation logic here
// Console message for recruiters
console.log('%cHey there! 👋', 'font-size: 20px; font-weight: bold; color: #B31B1B;');
console.log('%cThanks for checking out my portfolio! Feel free to reach out if you\'d like to connect.', 'font-size: 14px; color: #333;');
console.log('%c- Danny McCance', 'font-size: 14px; font-style: italic; color: #666;');