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();