Refactor bunny visibility toggle logic; streamline code and improve readability

This commit is contained in:
CodeDevMLH
2026-02-24 18:32:08 +01:00
parent 599518d627
commit 08b2ae987e
2 changed files with 36 additions and 39 deletions

View File

@@ -53,7 +53,6 @@
left: 0; left: 0;
width: 160px; width: 160px;
height: auto; height: auto;
z-index: 1002;
will-change: transform; will-change: transform;
} }

View File

@@ -2,7 +2,7 @@ const config = window.SeasonalsPluginConfig?.Easter || {};
const easter = config.EnableEaster !== undefined ? config.EnableEaster : true; const easter = config.EnableEaster !== undefined ? config.EnableEaster : true;
const enableBunny = config.EnableBunny !== undefined ? config.EnableBunny : true; const enableBunny = config.EnableBunny !== undefined ? config.EnableBunny : true;
/* MARK: BUNNY LOCOMOTION CONFIGURATION */ /* MARK: Bunny movement config */
const jumpDistanceVw = 5; // Distance in vw the bunny covers per jump const jumpDistanceVw = 5; // Distance in vw the bunny covers per jump
const jumpDurationMs = 770; // Time in ms the bunny spends moving during a jump const jumpDurationMs = 770; // Time in ms the bunny spends moving during a jump
const pauseDurationMs = 116.6666; // Time in ms the bunny pauses between jumps const pauseDurationMs = 116.6666; // Time in ms the bunny pauses between jumps
@@ -29,6 +29,39 @@ const easterEggImages = [
"../Seasonals/Resources/easter_images/eggs.png" "../Seasonals/Resources/easter_images/eggs.png"
]; ];
// Check visibility
function toggleEaster() {
const easterContainer = document.querySelector('.easter-container');
if (!easterContainer) return;
const videoPlayer = document.querySelector('.videoPlayerContainer');
const trailerPlayer = document.querySelector('.youtubePlayerContainer');
const isDashboard = document.body.classList.contains('dashboardDocument');
const hasUserMenu = document.querySelector('#app-user-menu');
if (videoPlayer || trailerPlayer || isDashboard || hasUserMenu) {
easterContainer.style.display = 'none';
if (rabbitTimeout) {
clearTimeout(rabbitTimeout);
isAnimating = false; // Reset to allow restarting later
}
} else {
easterContainer.style.display = 'block';
if (!isAnimating && enableBunny) {
animateRabbit(document.querySelector('#rabbit'));
}
}
}
const observer = new MutationObserver(toggleEaster);
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});
function createEasterGrassAndEggs(container) { function createEasterGrassAndEggs(container) {
let grassContainer = container.querySelector('.easter-grass-container'); let grassContainer = container.querySelector('.easter-grass-container');
if (!grassContainer) { if (!grassContainer) {
@@ -164,16 +197,12 @@ function animateRabbit(rabbit) {
function animationStep(timestamp) { function animationStep(timestamp) {
if (!document.querySelector('.easter-container') || rabbit.style.display === 'none') { if (!document.querySelector('.easter-container') || rabbit.style.display === 'none') {
isAnimating = false; isAnimating = false;
// When hidden, we stop animating. The toggle function will re-init.
return; return;
} }
if (!startTime) { if (!startTime) {
startTime = timestamp; startTime = timestamp;
// FORCE GIF RESTART: // resetting gif, forces the browser to restart the GIF from the first frame (crucial for syncing hops with movement)
// The GIF must restart exactly when the jump loop starts.
// Re-assigning the src without a cache-busting timestamp resets it to frame 0
// while still allowing the browser to serve the cached file immediately.
const currSrc = rabbit.src.split('?')[0]; const currSrc = rabbit.src.split('?')[0];
rabbit.src = ''; rabbit.src = '';
rabbit.src = currSrc; rabbit.src = currSrc;
@@ -181,7 +210,6 @@ function animateRabbit(rabbit) {
const elapsed = timestamp - startTime; const elapsed = timestamp - startTime;
// Calculate how many full loops (jump+pause) have happened
const completedLoops = Math.floor(elapsed / loopDurationMs); const completedLoops = Math.floor(elapsed / loopDurationMs);
const timeInCurrentLoop = elapsed % loopDurationMs; const timeInCurrentLoop = elapsed % loopDurationMs;
@@ -197,14 +225,11 @@ function animateRabbit(rabbit) {
currentX = startX + (completedLoops * jumpDistanceVw + currentLoopDistance) * direction; currentX = startX + (completedLoops * jumpDistanceVw + currentLoopDistance) * direction;
// Update DOM without CSS transitions (since we control it per-frame) // Update DOM without CSS transitions
rabbit.style.transform = `translateX(${currentX}vw) ${transformScale}`; rabbit.style.transform = `translateX(${currentX}vw) ${transformScale}`;
// Check if finished crossing // Check if finished crossing
if ((direction === 1 && currentX >= endX) || (direction === -1 && currentX <= endX)) { if ((direction === 1 && currentX >= endX) || (direction === -1 && currentX <= endX)) {
// Finished crossing! We can rest now.
// Since we explicitly reset the GIF to frame 0 at the start of every loop,
// we no longer have to snap the rest time to the loop duration mathematically.
let restTime = Math.random() * (maxBunnyRestTime - minBunnyRestTime) + minBunnyRestTime; let restTime = Math.random() * (maxBunnyRestTime - minBunnyRestTime) + minBunnyRestTime;
isAnimating = false; isAnimating = false;
@@ -221,33 +246,6 @@ function animateRabbit(rabbit) {
rabbitTimeout = requestAnimationFrame(animationStep); rabbitTimeout = requestAnimationFrame(animationStep);
} }
// Check visibility
function toggleEaster() {
const easterContainer = document.querySelector('.easter-container');
if (!easterContainer) return;
const videoPlayer = document.querySelector('.videoPlayerContainer');
const trailerPlayer = document.querySelector('.youtubePlayerContainer');
const isDashboard = document.body.classList.contains('dashboardDocument');
const hasUserMenu = document.querySelector('#app-user-menu');
if (videoPlayer || trailerPlayer || isDashboard || hasUserMenu) {
easterContainer.style.display = 'none';
if (rabbitTimeout) {
clearTimeout(rabbitTimeout);
isAnimating = false; // Reset to allow restarting later
}
} else {
easterContainer.style.display = 'block';
if (!isAnimating && enableBunny) {
animateRabbit(document.querySelector('#rabbit'));
}
}
}
const observer = new MutationObserver(toggleEaster);
observer.observe(document.body, { childList: true, subtree: true, attributes: true });
function initializeEaster() { function initializeEaster() {
if (!easter) return; if (!easter) return;