Refactor bunny visibility toggle logic; streamline code and improve readability
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user