mirror of
https://github.com/Shik3i/KoalaSync.git
synced 2026-08-28 11:37:16 +00:00
website: Add smooth FAQ accordion spring animation with rotation icon transition
This commit is contained in:
@@ -1248,4 +1248,64 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
updateDynamicVersion();
|
updateDynamicVersion();
|
||||||
localizeHomeLinks();
|
localizeHomeLinks();
|
||||||
initLanguageSelectorValue();
|
initLanguageSelectorValue();
|
||||||
|
// FAQ Accordion Transition (Web Animations API for smooth vertical spring height collapse/expand)
|
||||||
|
try {
|
||||||
|
document.querySelectorAll('.faq-item').forEach(details => {
|
||||||
|
const summary = details.querySelector('summary');
|
||||||
|
let isAnimating = false;
|
||||||
|
|
||||||
|
summary.addEventListener('click', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (isAnimating) return;
|
||||||
|
|
||||||
|
const startHeight = details.offsetHeight;
|
||||||
|
|
||||||
|
if (details.hasAttribute('open')) {
|
||||||
|
isAnimating = true;
|
||||||
|
const computed = window.getComputedStyle(details);
|
||||||
|
const padY = parseInt(computed.paddingTop) + parseInt(computed.paddingBottom);
|
||||||
|
const borderY = parseInt(computed.borderTopWidth) + parseInt(computed.borderBottomWidth);
|
||||||
|
const closedHeight = summary.offsetHeight + padY + (isNaN(borderY) ? 0 : borderY);
|
||||||
|
|
||||||
|
const animation = details.animate([
|
||||||
|
{ height: startHeight + 'px' },
|
||||||
|
{ height: closedHeight + 'px' }
|
||||||
|
], {
|
||||||
|
duration: 250,
|
||||||
|
easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
|
||||||
|
});
|
||||||
|
|
||||||
|
animation.onfinish = () => {
|
||||||
|
details.removeAttribute('open');
|
||||||
|
details.style.height = '';
|
||||||
|
isAnimating = false;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
isAnimating = true;
|
||||||
|
details.setAttribute('open', '');
|
||||||
|
const openHeight = details.offsetHeight;
|
||||||
|
|
||||||
|
const computed = window.getComputedStyle(details);
|
||||||
|
const padY = parseInt(computed.paddingTop) + parseInt(computed.paddingBottom);
|
||||||
|
const borderY = parseInt(computed.borderTopWidth) + parseInt(computed.borderBottomWidth);
|
||||||
|
const closedHeight = summary.offsetHeight + padY + (isNaN(borderY) ? 0 : borderY);
|
||||||
|
|
||||||
|
const animation = details.animate([
|
||||||
|
{ height: closedHeight + 'px' },
|
||||||
|
{ height: openHeight + 'px' }
|
||||||
|
], {
|
||||||
|
duration: 250,
|
||||||
|
easing: 'cubic-bezier(0.16, 1, 0.3, 1)'
|
||||||
|
});
|
||||||
|
|
||||||
|
animation.onfinish = () => {
|
||||||
|
details.style.height = '';
|
||||||
|
isAnimating = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
+4
-3
@@ -2890,6 +2890,7 @@ html:not(.lang-de) [lang="de"] {
|
|||||||
padding: 1.5rem 2rem;
|
padding: 1.5rem 2rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
|
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faq-item:hover {
|
.faq-item:hover {
|
||||||
@@ -2922,13 +2923,13 @@ html:not(.lang-de) [lang="de"] {
|
|||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1);
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
transform-origin: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.faq-item[open] summary::after {
|
.faq-item[open] summary::after {
|
||||||
content: '−';
|
transform: rotate(45deg);
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.faq-item p {
|
.faq-item p {
|
||||||
|
|||||||
Reference in New Issue
Block a user