-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
114 lines (104 loc) · 4.5 KB
/
script.js
File metadata and controls
114 lines (104 loc) · 4.5 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
(() => {
const prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const animatedElements = document.querySelectorAll(".hero-text, .hero-visual, .section, .service-card");
if ("IntersectionObserver" in window && !prefersReducedMotion) {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry, index) => {
if (!entry.isIntersecting) return;
window.setTimeout(() => entry.target.classList.add("show"), index * 90);
observer.unobserve(entry.target);
});
}, { threshold: 0.18 });
animatedElements.forEach((element) => {
element.classList.add("hidden");
observer.observe(element);
});
} else {
animatedElements.forEach((element) => element.classList.add("show"));
}
window.addEventListener("load", () => {
const loader = document.querySelector(".loader");
const delay = prefersReducedMotion ? 0 : 100;
window.setTimeout(() => {
if (loader) loader.classList.add("hidden");
document.body.classList.add("loaded");
}, delay);
});
const scrollProgress = document.querySelector(".scroll-progress");
const updateScrollProgress = () => {
if (!scrollProgress) return;
const scrollTop = window.scrollY || document.documentElement.scrollTop;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const progress = docHeight > 0 ? (scrollTop / docHeight) * 100 : 0;
scrollProgress.style.width = `${Math.min(100, Math.max(0, progress))}%`;
};
let scrollTicking = false;
window.addEventListener("scroll", () => {
if (scrollTicking) return;
window.requestAnimationFrame(() => {
updateScrollProgress();
scrollTicking = false;
});
scrollTicking = true;
}, { passive: true });
updateScrollProgress();
const cursorGlow = document.querySelector(".cursor-glow");
let mouseTicking = false;
let mouseX = 0;
let mouseY = 0;
if (cursorGlow && !prefersReducedMotion && window.matchMedia("(pointer: fine)").matches) {
document.addEventListener("mousemove", (event) => {
mouseX = event.clientX;
mouseY = event.clientY;
if (mouseTicking) return;
window.requestAnimationFrame(() => {
const x = mouseX / window.innerWidth;
const y = mouseY / window.innerHeight;
document.documentElement.style.setProperty("--mouse-x", `${x * 100}%`);
document.documentElement.style.setProperty("--mouse-y", `${y * 100}%`);
cursorGlow.style.left = `${mouseX}px`;
cursorGlow.style.top = `${mouseY}px`;
mouseTicking = false;
});
mouseTicking = true;
}, { passive: true });
} else if (cursorGlow) {
cursorGlow.style.display = "none";
}
const revealItems = document.querySelectorAll(".section h2, .section > p, .service-card, .portfolio-card, .contact-form, .contact-info");
revealItems.forEach((item, index) => {
item.classList.add("scroll-reveal");
if (index % 3 === 1) item.classList.add("delay-1");
if (index % 3 === 2) item.classList.add("delay-2");
});
if ("IntersectionObserver" in window && !prefersReducedMotion) {
const scrollObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
entry.target.classList.add("active");
scrollObserver.unobserve(entry.target);
});
}, { threshold: 0.18 });
revealItems.forEach((item) => scrollObserver.observe(item));
} else {
revealItems.forEach((item) => item.classList.add("active"));
}
const contactForm = document.querySelector(".contact-form");
const formSuccess = document.querySelector("#formSuccess");
if (contactForm && formSuccess) {
contactForm.addEventListener("submit", () => {
formSuccess.classList.add("show");
window.setTimeout(() => contactForm.reset(), 400);
window.setTimeout(() => formSuccess.classList.remove("show"), 3000);
});
}
})();
const scrollTopBtn = document.getElementById("scrollTopBtn");
if (scrollTopBtn) {
scrollTopBtn.addEventListener("click", () => {
window.scrollTo({
top: 0,
behavior: "smooth",
});
});
}