175 lines
5.8 KiB
JavaScript
175 lines
5.8 KiB
JavaScript
const config = window.SeasonalsPluginConfig?.Carnival || {};
|
|
|
|
const carnival = config.EnableCarnival !== undefined ? config.EnableCarnival : true;
|
|
const randomCarnival = config.EnableRandomCarnival !== undefined ? config.EnableRandomCarnival : true;
|
|
const randomCarnivalMobile = config.EnableRandomCarnivalMobile !== undefined ? config.EnableRandomCarnivalMobile : false;
|
|
const enableDifferentDuration = config.EnableDifferentDuration !== undefined ? config.EnableDifferentDuration : true;
|
|
const enableSway = config.EnableCarnivalSway !== undefined ? config.EnableCarnivalSway : true;
|
|
const carnivalCount = config.ObjectCount || 80;
|
|
|
|
let msgPrinted = false;
|
|
|
|
// function to check and control the carnival animation
|
|
function toggleCarnival() {
|
|
const carnivalContainer = document.querySelector('.carnival-container');
|
|
if (!carnivalContainer) 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 carnival if video/trailer player is active or dashboard is visible
|
|
if (videoPlayer || trailerPlayer || isDashboard || hasUserMenu) {
|
|
carnivalContainer.style.display = 'none'; // hide carnival
|
|
if (!msgPrinted) {
|
|
console.log('Carnival hidden');
|
|
msgPrinted = true;
|
|
}
|
|
} else {
|
|
carnivalContainer.style.display = 'block'; // show carnival
|
|
if (msgPrinted) {
|
|
console.log('Carnival visible');
|
|
msgPrinted = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// observe changes in the DOM
|
|
const observer = new MutationObserver(toggleCarnival);
|
|
|
|
// start observation
|
|
observer.observe(document.body, {
|
|
childList: true, // observe adding/removing of child elements
|
|
subtree: true, // observe all levels of the DOM tree
|
|
attributes: true // observe changes to attributes (e.g. class changes)
|
|
});
|
|
|
|
const confettiColors = [
|
|
'#fce18a', '#ff726d', '#b48def', '#f4306d',
|
|
'#36c5f0', '#2ccc5d', '#e9b31d', '#9b59b6',
|
|
'#3498db', '#e74c3c', '#1abc9c', '#f1c40f'
|
|
];
|
|
|
|
function createConfettiPiece(container, isInitial = false) {
|
|
const wrapper = document.createElement('div');
|
|
wrapper.classList.add('carnival-wrapper');
|
|
|
|
let swayWrapper = wrapper;
|
|
|
|
if (enableSway) {
|
|
swayWrapper = document.createElement('div');
|
|
swayWrapper.classList.add('carnival-sway-wrapper');
|
|
wrapper.appendChild(swayWrapper);
|
|
}
|
|
|
|
const confetti = document.createElement('div');
|
|
confetti.classList.add('carnival-confetti');
|
|
|
|
// Random color
|
|
const color = confettiColors[Math.floor(Math.random() * confettiColors.length)];
|
|
confetti.style.backgroundColor = color;
|
|
|
|
// Random shape
|
|
const shape = Math.random();
|
|
if (shape > 0.8) {
|
|
confetti.classList.add('circle');
|
|
} else if (shape > 0.6) {
|
|
confetti.classList.add('square');
|
|
} else if (shape > 0.4) {
|
|
confetti.classList.add('triangle');
|
|
} else {
|
|
confetti.classList.add('rect');
|
|
}
|
|
|
|
// Random position
|
|
wrapper.style.left = `${Math.random() * 100}%`;
|
|
|
|
// Random dimensions
|
|
if (!confetti.classList.contains('circle') && !confetti.classList.contains('square') && !confetti.classList.contains('triangle')) {
|
|
const width = Math.random() * 5 + 4;
|
|
const height = Math.random() * 6 + 8;
|
|
confetti.style.width = `${width}px`;
|
|
confetti.style.height = `${height}px`;
|
|
}
|
|
|
|
// Animation settings
|
|
const duration = Math.random() * 5 + 5;
|
|
|
|
let delay = 0;
|
|
if (isInitial) {
|
|
delay = -Math.random() * duration;
|
|
} else {
|
|
delay = Math.random() * 10;
|
|
}
|
|
|
|
wrapper.style.animationDelay = `${delay}s`;
|
|
wrapper.style.animationDuration = `${duration}s`;
|
|
|
|
if (enableSway) {
|
|
// Random sway duration
|
|
const swayDuration = Math.random() * 2 + 3; // 3-5s per cycle
|
|
swayWrapper.style.animationDuration = `${swayDuration}s`;
|
|
swayWrapper.style.animationDelay = `-${Math.random() * 5}s`;
|
|
|
|
// Random sway amplitude (using CSS variable for dynamic keyframe)
|
|
// Sway between 30px and 100px
|
|
const swayAmount = Math.random() * 70 + 30;
|
|
const direction = Math.random() > 0.5 ? 1 : -1;
|
|
swayWrapper.style.setProperty('--sway-amount', `${swayAmount * direction}px`);
|
|
}
|
|
|
|
// Flutter speed variation
|
|
confetti.style.animationDuration = `${Math.random() * 2 + 1}s`;
|
|
|
|
if (enableSway) {
|
|
swayWrapper.appendChild(confetti);
|
|
wrapper.appendChild(swayWrapper);
|
|
} else {
|
|
wrapper.appendChild(confetti);
|
|
}
|
|
|
|
container.appendChild(wrapper);
|
|
}
|
|
|
|
function addRandomCarnivalObjects(count) {
|
|
const carnivalContainer = document.querySelector('.carnival-container');
|
|
if (!carnivalContainer) return;
|
|
|
|
console.log('Adding random carnival confetti');
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
createConfettiPiece(carnivalContainer, true);
|
|
}
|
|
}
|
|
|
|
// initialize standard carnival objects
|
|
function initCarnivalObjects() {
|
|
let container = document.querySelector('.carnival-container');
|
|
if (!container) {
|
|
container = document.createElement("div");
|
|
container.className = "carnival-container";
|
|
container.setAttribute("aria-hidden", "true");
|
|
document.body.appendChild(container);
|
|
}
|
|
|
|
// Initial confetti
|
|
for (let i = 0; i < 30; i++) {
|
|
createConfettiPiece(container, true);
|
|
}
|
|
}
|
|
|
|
// initialize carnival
|
|
function initializeCarnival() {
|
|
if (!carnival) return; // exit if carnival is disabled
|
|
initCarnivalObjects();
|
|
toggleCarnival();
|
|
|
|
const screenWidth = window.innerWidth;
|
|
if (randomCarnival && (screenWidth > 768 || randomCarnivalMobile)) {
|
|
addRandomCarnivalObjects(carnivalCount);
|
|
}
|
|
}
|
|
|
|
initializeCarnival();
|