Skip to content

Commit 4293399

Browse files
authored
Add files via upload
1 parent c748af0 commit 4293399

File tree

6 files changed

+3355
-0
lines changed

6 files changed

+3355
-0
lines changed

index.html

+959
Large diffs are not rendered by default.

poster1.jpg

382 KB
Loading

poster2.jpg

352 KB
Loading

poster3.jpg

615 KB
Loading

script.js

+222
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
/*--================================================
2+
/ Name: Zuid - Creative Portfolio
3+
/ Developer: JohnDev19
4+
/ GitHub: https://github.com/JohnDev19/
5+
/ License: MIT
6+
/ Last Update: December 2024
7+
=====================================================
8+
/ Description:
9+
/ Zuid is a creative portfolio website designed to showcase the work of a digital designer and developer
10+
=====================================================
11+
/ Technologies Used:
12+
/ - HTML5
13+
/ - CSS3
14+
/ - JavaScript
15+
/ - AOS (Animate On Scroll)
16+
/ - Swiper.js for sliders
17+
/ - Font Awesome for icons
18+
/ - Google Fonts for typography
19+
=================================================== */
20+
document.addEventListener('DOMContentLoaded', () => {
21+
const hamburger = document.querySelector('.hamburger');
22+
const navMenu = document.querySelector('.nav-menu');
23+
const navbar = document.querySelector('.navbar');
24+
25+
hamburger.addEventListener('click', () => {
26+
hamburger.classList.toggle('active');
27+
navMenu.classList.toggle('active');
28+
29+
if (navMenu.classList.contains('active')) {
30+
document.body.style.overflow = 'hidden';
31+
} else {
32+
document.body.style.overflow = 'auto';
33+
}
34+
});
35+
36+
navMenu.querySelectorAll('a').forEach(link => {
37+
link.addEventListener('click', () => {
38+
hamburger.classList.remove('active');
39+
navMenu.classList.remove('active');
40+
document.body.style.overflow = 'auto';
41+
});
42+
});
43+
44+
window.addEventListener('scroll',
45+
() => {
46+
if (window.scrollY > 100) {
47+
navbar.classList.add('scrolled');
48+
} else {
49+
navbar.classList.remove('scrolled');
50+
}
51+
});
52+
53+
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
54+
anchor.addEventListener('click', function (e) {
55+
e.preventDefault();
56+
57+
const targetId = this.getAttribute('href');
58+
const targetElement = document.querySelector(targetId);
59+
60+
if (targetElement) {
61+
targetElement.scrollIntoView({
62+
behavior: 'smooth',
63+
block: 'start'
64+
});
65+
}
66+
});
67+
});
68+
69+
const observerOptions = {
70+
root: null,
71+
rootMargin: '0px',
72+
threshold: 0.1
73+
};
74+
75+
const fadeInObserver = new IntersectionObserver((entries) => {
76+
entries.forEach(entry => {
77+
if (entry.isIntersecting) {
78+
entry.target.classList.add('fade-in');
79+
}
80+
});
81+
}, observerOptions);
82+
83+
document.querySelectorAll('.section').forEach(section => {
84+
fadeInObserver.observe(section);
85+
});
86+
87+
const subscribeForm = document.querySelector('.subscribe-form');
88+
if (subscribeForm) {
89+
subscribeForm.addEventListener('submit', (e) => {
90+
e.preventDefault();
91+
const emailInput = subscribeForm.querySelector('input[type="email"]');
92+
93+
if (emailInput.value && emailInput.value.includes('@')) {
94+
alert('Thank you for subscribing!');
95+
emailInput.value = '';
96+
} else {
97+
alert('Please enter a valid email address.');
98+
}
99+
});
100+
}
101+
});
102+
103+
const styleSheet = document.createElement('style');
104+
styleSheet.textContent = `
105+
.section {
106+
opacity: 0;
107+
transform: translateY(20px);
108+
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
109+
}
110+
.section.fade-in {
111+
opacity: 1;
112+
transform: translateY(0);
113+
}
114+
`;
115+
document.head.appendChild(styleSheet);
116+
117+
document.addEventListener('DOMContentLoaded', () => {
118+
const filterBtns = document.querySelectorAll('.filter-btn');
119+
const portfolioItems = document.querySelectorAll('.portfolio-item');
120+
121+
filterBtns.forEach(btn => {
122+
btn.addEventListener('click', () => {
123+
124+
filterBtns.forEach(b => b.classList.remove('active'));
125+
btn.classList.add('active');
126+
127+
const filter = btn.getAttribute('data-filter');
128+
129+
portfolioItems.forEach(item => {
130+
const category = item.getAttribute('data-category');
131+
132+
if (filter === 'all' || category === filter) {
133+
item.style.display = 'block';
134+
item.style.opacity = 0;
135+
item.style.transform = 'scale(0.9)';
136+
setTimeout(() => {
137+
item.style.opacity = 1;
138+
item.style.transform = 'scale(1)';
139+
}, 50);
140+
} else {
141+
item.style.display = 'none';
142+
}
143+
});
144+
});
145+
});
146+
});
147+
148+
document.addEventListener('DOMContentLoaded', () => {
149+
const scrollArrow = document.querySelector('.scroll-arrow');
150+
151+
scrollArrow.addEventListener('click', (e) => {
152+
e.preventDefault();
153+
const aboutSection = document.getElementById('about');
154+
155+
aboutSection.scrollIntoView({
156+
behavior: 'smooth',
157+
block: 'start'
158+
});
159+
});
160+
});
161+
162+
document.addEventListener('DOMContentLoaded', () => {
163+
const goToTopBtn = document.getElementById('goToTopBtn');
164+
165+
function debounce(func, wait = 10, immediate = true) {
166+
let timeout;
167+
return function() {
168+
const context = this, args = arguments;
169+
const later = function() {
170+
timeout = null;
171+
if (!immediate) func.apply(context, args);
172+
};
173+
const callNow = immediate && !timeout;
174+
clearTimeout(timeout);
175+
timeout = setTimeout(later, wait);
176+
if (callNow) func.apply(context, args);
177+
};
178+
}
179+
180+
window.addEventListener('scroll', debounce(() => {
181+
if (window.pageYOffset > 300) {
182+
goToTopBtn.classList.add('show');
183+
} else {
184+
goToTopBtn.classList.remove('show');
185+
}
186+
}));
187+
188+
goToTopBtn.addEventListener('click', () => {
189+
const startPosition = window.pageYOffset;
190+
const startTime = performance.now();
191+
const duration = 1000;
192+
193+
function animation(currentTime) {
194+
const elapsed = currentTime - startTime;
195+
const progress = Math.min(elapsed / duration,
196+
1);
197+
const easeInOutCubic = progress < 0.5
198+
? 4 * progress ** 3: 1 - ((-2 * progress + 2) ** 3) / 2;
199+
200+
window.scrollTo(0,
201+
startPosition * (1 - progress));
202+
if (elapsed < duration) requestAnimationFrame(animation);
203+
}
204+
205+
requestAnimationFrame(animation);
206+
});
207+
});
208+
209+
document.addEventListener('DOMContentLoaded', () => {
210+
const progressBar = document.createElement('div');
211+
progressBar.id = 'scroll-progress';
212+
document.body.appendChild(progressBar);
213+
214+
window.addEventListener('scroll',
215+
() => {
216+
const winScroll = document.body.scrollTop || document.documentElement.scrollTop;
217+
const height = document.documentElement.scrollHeight - document.documentElement.clientHeight;
218+
const scrolled = (winScroll / height) * 100;
219+
220+
progressBar.style.width = `${scrolled}%`;
221+
});
222+
});

0 commit comments

Comments
 (0)