-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathscript.js
More file actions
129 lines (97 loc) · 3.94 KB
/
Copy pathscript.js
File metadata and controls
129 lines (97 loc) · 3.94 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
// Infinite Horizontal Scroll Animation
window.addEventListener("load", () => {
const wrapper = document.querySelector(".scroll-wrapper");
const inner = document.getElementById("scrollInner");
const track = document.getElementById("track");
const gap = 15;
const pxPerSec = 50;
function buildMarquee() {
while (inner.children.length > 1) {
inner.removeChild(inner.lastChild);
}
const loopWidth = track.getBoundingClientRect().width + gap;
while (inner.getBoundingClientRect().width < wrapper.offsetWidth + loopWidth) {
const clone = track.cloneNode(true);
clone.removeAttribute("id");
inner.appendChild(clone);
}
inner.style.setProperty("--loop-width", loopWidth + "px");
inner.style.setProperty("--duration", loopWidth / pxPerSec + "s");
}
buildMarquee();
let resizeTimer;
window.addEventListener("resize", () => {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(buildMarquee, 200);
});
});
// Navbar Live Time
function updateTime() {
const now = new Date();
const time = now.toLocaleTimeString([], {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
document.getElementById('time').textContent = time;
}
updateTime();
setInterval(updateTime, 1000);
// Footer Heart Animation
const heart = document.querySelector(".heart");
if (heart) {
const heartInner = heart.querySelector(".heart-inner");
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
heart.addEventListener("click", () => {
if (heartInner) {
heartInner.classList.remove("beat");
void heartInner.offsetWidth;
heartInner.classList.add("beat");
}
if (reduceMotion) return;
const rect = heart.getBoundingClientRect();
const cx = rect.left + rect.width / 2 + window.scrollX;
const cy = rect.top + rect.height / 2 + window.scrollY;
const count = 8;
for (let i = 0; i < count; i++) {
const p = document.createElement("span");
p.className = "heart-particle";
p.textContent = "❤️";
const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.6;
const dist = 55 + Math.random() * 55;
const tx = Math.cos(angle) * dist;
const ty = Math.sin(angle) * dist - 25;
p.style.left = cx + "px";
p.style.top = cy + "px";
p.style.setProperty("--tx", tx.toFixed(1) + "px");
p.style.setProperty("--ty", ty.toFixed(1) + "px");
p.style.setProperty("--rot", (Math.random() * 120 - 60).toFixed(0) + "deg");
p.style.setProperty("--scale", (0.5 + Math.random() * 0.7).toFixed(2));
p.style.fontSize = (10 + Math.random() * 8).toFixed(0) + "px";
p.style.animationDuration = (650 + Math.random() * 250).toFixed(0) + "ms";
document.body.appendChild(p);
p.addEventListener("animationend", () => p.remove());
}
});
if (heartInner) {
heartInner.addEventListener("animationend", () => heartInner.classList.remove("beat"));
}
}
// Theme Toggle
const themeToggle = document.getElementById("themeToggle");
if (themeToggle) {
const root = document.documentElement;
const themeMeta = document.querySelector('meta[name="theme-color"]');
themeToggle.addEventListener("click", () => {
const next = root.getAttribute("data-theme") === "light" ? "dark" : "light";
root.classList.add("theme-transition");
root.setAttribute("data-theme", next);
if (themeMeta) {
themeMeta.setAttribute("content", next === "light" ? "#F2ECE4" : "#141414");
}
try {
localStorage.setItem("theme", next);
} catch (e) { }
window.setTimeout(() => root.classList.remove("theme-transition"), 400);
});
}