Add Oktoberfest feature: implement CSS and JS for Oktoberfest animations and visibility control

This commit is contained in:
CodeDevMLH
2026-02-24 19:22:57 +01:00
parent 97dbc09daa
commit 22d40fb248
2 changed files with 100 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
.oktoberfest-container {
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
contain: strict;
overflow: hidden;
}
.oktoberfest-symbol {
position: absolute;
top: -10%;
font-size: 2.2em;
user-select: none;
animation-name: oktoberfest-fall, oktoberfest-sway;
animation-timing-function: linear, ease-in-out;
animation-iteration-count: infinite, infinite;
}
@keyframes oktoberfest-fall {
0% { transform: translateY(0); opacity: 0; }
10% { opacity: 1; }
100% { transform: translateY(120vh); opacity: 1; }
}
@keyframes oktoberfest-sway {
0%, 100% { margin-left: 0; }
50% { margin-left: 50px; }
}

View File

@@ -0,0 +1,67 @@
const config = window.SeasonalsPluginConfig?.Oktoberfest || {};
const oktoberfest = config.EnableOktoberfest !== undefined ? config.EnableOktoberfest : true;
const oktoberfestSymbols = ['🥨', '🍺', '🍻', '🥨', '🥨'];
let msgPrinted = false;
// function to check and control the oktoberfest
function toggleOktoberfest() {
const oktoberfestContainer = document.querySelector('.oktoberfest-container');
if (!oktoberfestContainer) 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');
// hide oktoberfest if video/trailer player is active or dashboard is visible
if (videoPlayer || trailerPlayer || isDashboard || hasUserMenu) {
oktoberfestContainer.style.display = 'none'; // hide oktoberfest
if (!msgPrinted) {
console.log('Oktoberfest hidden');
msgPrinted = true;
}
} else {
oktoberfestContainer.style.display = 'block'; // show oktoberfest
if (msgPrinted) {
console.log('Oktoberfest visible');
msgPrinted = false;
}
}
}
// observe changes in the DOM
const observer = new MutationObserver(toggleOktoberfest);
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true
});
function createOktoberfest(container) {
for (let i = 0; i < 20; i++) {
const symbol = document.createElement('div');
symbol.className = 'oktoberfest-symbol';
symbol.textContent = oktoberfestSymbols[Math.floor(Math.random() * oktoberfestSymbols.length)];
symbol.style.left = `${Math.random() * 100}%`;
symbol.style.animationDelay = `${Math.random() * 10}s, ${Math.random() * 5}s`;
const duration1 = Math.random() * 5 + 8;
const duration2 = Math.random() * 3 + 3;
symbol.style.animationDuration = `${duration1}s, ${duration2}s`;
container.appendChild(symbol);
}
}
function initializeOktoberfest() {
if (!oktoberfest) return;
const container = document.querySelector('.oktoberfest-container') || document.createElement("div");
if (!document.querySelector('.oktoberfest-container')) {
container.className = "oktoberfest-container";
container.setAttribute("aria-hidden", "true");
document.body.appendChild(container);
}
createOktoberfest(container);
}
initializeOktoberfest();