Add Oktoberfest feature: implement CSS and JS for Oktoberfest animations and visibility control
This commit is contained in:
33
Jellyfin.Plugin.Seasonals/Web/oktoberfest.css
Normal file
33
Jellyfin.Plugin.Seasonals/Web/oktoberfest.css
Normal 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; }
|
||||||
|
}
|
||||||
67
Jellyfin.Plugin.Seasonals/Web/oktoberfest.js
Normal file
67
Jellyfin.Plugin.Seasonals/Web/oktoberfest.js
Normal 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();
|
||||||
Reference in New Issue
Block a user