|
|
@ -1,4 +1,60 @@
|
|
|
|
|
|
|
|
const disk = document.getElementById('profile');
|
|
|
|
|
|
|
|
const audio = document.getElementById('disk-audio');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let hovering = false;
|
|
|
|
|
|
|
|
let startTime = 0;
|
|
|
|
|
|
|
|
let speedInterval = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// On page load, try to prime the audio.
|
|
|
|
|
|
|
|
window.addEventListener('load', () => {
|
|
|
|
|
|
|
|
// Start playing the audio muted to force loading and decoding.
|
|
|
|
|
|
|
|
audio.muted = true;
|
|
|
|
|
|
|
|
audio.play().then(() => {
|
|
|
|
|
|
|
|
// Immediately pause so it doesn't actually play muted.
|
|
|
|
|
|
|
|
audio.pause();
|
|
|
|
|
|
|
|
audio.muted = false;
|
|
|
|
|
|
|
|
audio.currentTime = 0; // Reset to start if desired.
|
|
|
|
|
|
|
|
console.log("Audio primed and ready.");
|
|
|
|
|
|
|
|
}).catch(err => {
|
|
|
|
|
|
|
|
// If this fails (due to browser policies), we'll still try on hover.
|
|
|
|
|
|
|
|
console.log("Could not prime audio:", err);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
disk.addEventListener('mouseenter', () => {
|
|
|
|
|
|
|
|
hovering = true;
|
|
|
|
|
|
|
|
startTime = Date.now();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Play the audio if not already playing
|
|
|
|
|
|
|
|
if (audio.paused) {
|
|
|
|
|
|
|
|
audio.currentTime = 0; // Start from beginning if desired
|
|
|
|
|
|
|
|
audio.play().catch(err => {
|
|
|
|
|
|
|
|
console.log('Playback blocked:', err);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
speedInterval = setInterval(() => {
|
|
|
|
|
|
|
|
if (!hovering) return;
|
|
|
|
|
|
|
|
const elapsedSeconds = (Date.now() - startTime) / 1000;
|
|
|
|
|
|
|
|
const newDuration = Math.max(0.2, 2 - 0.2 * elapsedSeconds);
|
|
|
|
|
|
|
|
disk.style.animationDuration = newDuration + 's';
|
|
|
|
|
|
|
|
}, 100);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
disk.addEventListener('mouseleave', () => {
|
|
|
|
|
|
|
|
hovering = false;
|
|
|
|
|
|
|
|
clearInterval(speedInterval);
|
|
|
|
|
|
|
|
disk.style.animationDuration = '2s';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Pause the audio when the mouse leaves
|
|
|
|
|
|
|
|
audio.pause();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get the theme switch checkbox
|
|
|
|
// Get the theme switch checkbox
|
|
|
|
|
|
|
|
|
|
|
|
const themeSwitch = document.getElementById('theme-switch');
|
|
|
|
const themeSwitch = document.getElementById('theme-switch');
|
|
|
|
|
|
|
|
|
|
|
|
// Function to set the theme
|
|
|
|
// Function to set the theme
|
|
|
@ -27,4 +83,8 @@ themeSwitch.addEventListener('change', (e) => {
|
|
|
|
const isDark = !e.target.checked; // Light mode when checked
|
|
|
|
const isDark = !e.target.checked; // Light mode when checked
|
|
|
|
setTheme(isDark);
|
|
|
|
setTheme(isDark);
|
|
|
|
localStorage.setItem('theme', isDark ? 'dark' : 'light'); // Save preference
|
|
|
|
localStorage.setItem('theme', isDark ? 'dark' : 'light'); // Save preference
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|