-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
113 lines (89 loc) · 3.58 KB
/
script.js
File metadata and controls
113 lines (89 loc) · 3.58 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
document.querySelectorAll(".read-more").forEach(button => {
let lastScrollPos = 0;
button.addEventListener("click", () => {
const container = button.closest(".project");
if (!container) return;
const description = container.querySelector(".description");
if (container.classList.contains("expanded")) {
// --- SMOOTH COLLAPSE ---
// 1. Lock to current height so it doesn't 'snap' to 0
description.style.maxHeight = description.scrollHeight + 'px';
// 2. Trigger a reflow (The 'Secret Sauce' for smoothness)
description.offsetHeight;
// 3. Animate to 0
description.style.maxHeight = '0';
setTimeout(() => {
description.style.display = 'none';
window.scrollTo({ top: lastScrollPos, behavior: 'smooth' });
}, 400);
container.classList.remove('expanded');
button.childNodes[0].textContent = 'Read more ';
} else {
// --- SMOOTH EXPAND ---
lastScrollPos = window.scrollY;
// 1. Show it but keep it invisible/collapsed
description.style.display = 'block';
description.style.maxHeight = '0';
// 2. Wait for the browser to register 'display: block'
requestAnimationFrame(() => {
requestAnimationFrame(() => {
const fullHeight = description.scrollHeight;
description.style.maxHeight = fullHeight + 'px';
});
});
// 3. Remove the cap after animation
setTimeout(() => {
if (container.classList.contains("expanded")) {
description.style.maxHeight = 'none';
}
}, 450);
container.classList.add('expanded');
button.childNodes[0].textContent = 'Read less ';
}
});
});
document.querySelectorAll(".read-more").forEach(button => {
let lastScrollPos = 0;
button.addEventListener("click", () => {
const container = button.closest(".notes");
if (!container) return;
const description = container.querySelector(".description");
if (container.classList.contains("expanded")) {
// --- COLLAPSE (CLOSING) ---
// 1. Start scrolling back IMMEDIATELY (Removes the 'reset' delay)
window.scrollTo({ top: lastScrollPos, behavior: 'smooth' });
// 2. Set height to current pixels so it has a starting point to animate from
description.style.maxHeight = description.scrollHeight + 'px';
description.offsetHeight; // Force reflow so the browser 'feels' the height
// 3. Shrink to 0
description.style.maxHeight = '0';
// 4. Reset UI text and class right away
container.classList.remove('expanded');
button.childNodes[0].textContent = 'Read more ';
// 5. Cleanup: Hide element only AFTER the fast 0.2s animation
setTimeout(() => {
if (!container.classList.contains("expanded")) {
description.style.display = 'none';
}
}, 0);
} else {
// --- EXPAND (OPENING) ---
lastScrollPos = window.scrollY;
description.style.display = 'block';
// Double frame wait ensures the 'display: block' is rendered before animating
requestAnimationFrame(() => {
requestAnimationFrame(() => {
description.style.maxHeight = description.scrollHeight + 'px';
});
});
// 6. Remove the 'cap' after opening (The 'None' cleanup)
setTimeout(() => {
if (container.classList.contains("expanded")) {
description.style.maxHeight = 'none';
}
}, 450);
container.classList.add('expanded');
button.childNodes[0].textContent = 'Read less ';
}
});
});