Enhance theme switching functionality with animation support and improve button interactions. Update CSS for smoother transitions and add spinning effect for icons on button click.

This commit is contained in:
dzakdzaks
2026-06-07 00:57:20 +07:00
parent 6b1e4b3cf3
commit b454579cb8
2 changed files with 49 additions and 7 deletions
+23 -3
View File
@@ -182,6 +182,7 @@ a { color: var(--primary); text-decoration: none; }
border-radius: 20px;
padding: 3px;
margin-left: auto;
transition: background .3s ease, border-color .3s ease;
}
.theme-btn {
border: none;
@@ -195,13 +196,32 @@ a { color: var(--primary); text-decoration: none; }
align-items: center;
justify-content: center;
font-size: .9rem;
transition: background .15s, color .15s;
transition: background .2s ease, color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.theme-btn:hover { background: var(--border); color: var(--text); }
.theme-btn:hover { background: var(--border); color: var(--text); transform: scale(1.1); }
.theme-btn:active { transform: scale(.92); }
.theme-btn.active {
background: var(--surface);
color: var(--primary);
box-shadow: 0 1px 3px rgba(0,0,0,.15);
box-shadow: 0 1px 4px rgba(0,0,0,.18);
}
.theme-btn i {
transition: transform .35s ease;
}
.theme-btn.spinning i {
transform: rotate(360deg);
}
/* ── Theme transition (only when user switches, not on page load) ── */
html.theme-animate,
html.theme-animate *,
html.theme-animate *::before,
html.theme-animate *::after {
transition:
background-color .35s ease,
color .35s ease,
border-color .35s ease,
box-shadow .35s ease !important;
}
.content-area {
+26 -4
View File
@@ -11,19 +11,41 @@ function resolveTheme(mode) {
return (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) ? "dark" : "light";
}
function applyTheme(mode) {
function applyTheme(mode, animate) {
localStorage.setItem(THEME_KEY, mode);
document.documentElement.dataset.theme = resolveTheme(mode);
const html = document.documentElement;
if (animate) {
html.classList.add("theme-animate");
}
html.dataset.theme = resolveTheme(mode);
document.querySelectorAll(".theme-btn").forEach(btn => {
btn.classList.toggle("active", btn.dataset.themeMode === mode);
});
if (animate) {
clearTimeout(applyTheme._timer);
applyTheme._timer = setTimeout(() => html.classList.remove("theme-animate"), 400);
}
}
function initTheme() {
const mode = getStoredTheme();
applyTheme(mode);
applyTheme(mode, false);
document.querySelectorAll(".theme-btn").forEach(btn => {
btn.addEventListener("click", () => applyTheme(btn.dataset.themeMode));
btn.addEventListener("click", () => {
// Spin the icon
const icon = btn.querySelector("i");
if (icon) {
btn.classList.remove("spinning");
void btn.offsetWidth; // force reflow to restart animation
btn.classList.add("spinning");
setTimeout(() => btn.classList.remove("spinning"), 380);
}
applyTheme(btn.dataset.themeMode, true);
});
});
if (window.matchMedia) {
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {