my-homelab-configs/apps/website/cv-theme.js

53 lines
1.6 KiB
JavaScript

const cvThemeButtons = [...document.querySelectorAll('[data-cv-theme]')];
const cvPortrait = document.getElementById('cv-portrait-orbit');
const cvThemeStorageKey = 'cv-theme';
function getStoredCvTheme() {
try {
return localStorage.getItem(cvThemeStorageKey);
} catch (_error) {
return null;
}
}
function storeCvTheme(theme) {
try {
localStorage.setItem(cvThemeStorageKey, theme);
} catch (_error) {
// Theme switching should still work when storage is blocked.
}
}
function setCvTheme(theme) {
const nextTheme = theme === 'fancy' ? 'fancy' : 'elegant';
document.body.classList.toggle('cv-fancy', nextTheme === 'fancy');
document.body.classList.toggle('cv-elegant', nextTheme === 'elegant');
cvThemeButtons.forEach((button) => {
const active = button.dataset.cvTheme === nextTheme;
button.classList.toggle('is-active', active);
button.setAttribute('aria-pressed', active ? 'true' : 'false');
});
storeCvTheme(nextTheme);
}
cvThemeButtons.forEach((button) => {
button.addEventListener('click', () => setCvTheme(button.dataset.cvTheme));
});
document.addEventListener('pointermove', (event) => {
if (!document.body.classList.contains('cv-fancy') || !cvPortrait) return;
const bounds = cvPortrait.getBoundingClientRect();
const centerX = bounds.left + bounds.width / 2;
const centerY = bounds.top + bounds.height / 2;
const radians = Math.atan2(event.clientY - centerY, event.clientX - centerX);
const degrees = radians * 180 / Math.PI;
cvPortrait.style.setProperty('--portrait-rotation', `${degrees + 8}deg`);
});
setCvTheme(getStoredCvTheme() || 'elegant');