diff --git a/Jellyfin.Plugin.Seasonals/Web/underwater.js b/Jellyfin.Plugin.Seasonals/Web/underwater.js index ca2d2bd..6d99be8 100644 --- a/Jellyfin.Plugin.Seasonals/Web/underwater.js +++ b/Jellyfin.Plugin.Seasonals/Web/underwater.js @@ -1,9 +1,7 @@ const config = window.SeasonalsPluginConfig?.Underwater || {}; const underwater = config.EnableUnderwater !== undefined ? config.EnableUnderwater : true; -const symbolCount = config.SymbolCount || 15; -const useRandomSymbols = config.EnableRandomSymbols !== undefined ? config.EnableRandomSymbols : true; -const enableRandomMobile = config.EnableRandomSymbolsMobile !== undefined ? config.EnableRandomSymbolsMobile : false; +const symbolCountMobile = config.SymbolCountMobile !== undefined ? config.SymbolCountMobile : 2; // Devisor to reduce number of objects on mobile const enableDifferentDuration = config.EnableDifferentDuration !== undefined ? config.EnableDifferentDuration : true; const enableLightRays = config.EnableLightRays !== undefined ? config.EnableLightRays : true; const seaweedCount = config.SeaweedCount !== undefined ? config.SeaweedCount : 50; @@ -17,27 +15,49 @@ const crabCount = config.CrabCount !== undefined ? config.CrabCount : 2; const starfishCount = config.StarfishCount !== undefined ? config.StarfishCount : 2; const shellCount = config.ShellCount !== undefined ? config.ShellCount : 2; +// credits: https://lottiefiles.com/free-animation/seaweed-E6Go0HdkqY const seaweeds = [ "../Seasonals/Resources/underwater_assets/seaweed_1.gif", "../Seasonals/Resources/underwater_assets/seaweed_2.gif" ]; -// Statics for bottom +/** + * Credits: + * https://www.animierte-gifs.net/img-animiertes-krebs-bild-0041-59970.htm + * https://www.animierte-gifs.net/img-animiertes-krebs-bild-0002-59931.htm + * + */ const crabImages = [ "../Seasonals/Resources/underwater_assets/crab_1.gif", "../Seasonals/Resources/underwater_assets/crab_2.gif", "../Seasonals/Resources/underwater_assets/crab_3.gif" ]; +/** + * Credits: + * https://lottiefiles.com/free-animation/dancing-starfish-tJ9ZFu9Zq0 + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0003-50003.htm + */ const starfishImages = [ "../Seasonals/Resources/underwater_assets/starfish_1.gif", "../Seasonals/Resources/underwater_assets/starfish_2.gif" ]; +// Credit: https://www.animierte-gifs.net/img-animiertes-muschel-bild-0021-108539.htm const shellImages = [ "../Seasonals/Resources/underwater_assets/shell_1.gif" ]; +/** + * Credits: + * https://lottiefiles.com/free-animation/0101uwt-tt-01-4fA4Lm9gtN + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0473-50473.htm + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0290-50290.htm + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0049-50049.htm + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0403-50403.htm + * + * https://flaticon.com + */ const fishImages = [ "../Seasonals/Resources/underwater_assets/fish_1.gif", "../Seasonals/Resources/underwater_assets/fish_2.gif", @@ -55,15 +75,22 @@ const fishImages = [ "../Seasonals/Resources/underwater_assets/fish_15.png" ]; +/** + * Credits: + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0221-50221.htm + * https://www.animierte-gifs.net/img-animiertes-fische-bild-0217-50217.htm + */ const seahorsesImages = [ "../Seasonals/Resources/underwater_assets/seahorse_1.gif", "../Seasonals/Resources/underwater_assets/seahorse_2.gif" ]; +// credit: https://lottiefiles.com/free-animation/sea-turtle-s0sbHIWS2F const turtleImages = [ "../Seasonals/Resources/underwater_assets/turtle.gif" ]; +// credits: https://lottiefiles.com/free-animation/jellyfish-wPwyF8EeSQ const jellyfishImages = [ "../Seasonals/Resources/underwater_assets/jellyfish_1.gif", "../Seasonals/Resources/underwater_assets/jellyfish_2.gif" @@ -137,16 +164,15 @@ function createUnderwater() { const useRandomDuration = enableDifferentDuration !== false; let isMobile = window.matchMedia("only screen and (max-width: 768px)").matches; - // Seaweed swaying at the bottom (evenly distributed based on count) - const activeSeaweedCount = Math.max(1, seaweedCount); + const activeSeaweedCount = isMobile ? Math.max(1, Math.floor(seaweedCount / Math.max(1, symbolCountMobile))) : Math.max(1, seaweedCount); const seaweedSpacing = 95 / activeSeaweedCount; - for (let i = 0; i < seaweedCount; i++) { + for (let i = 0; i < activeSeaweedCount; i++) { let seaweed = document.createElement('div'); seaweed.className = 'underwater-seaweed'; seaweed.style.position = 'absolute'; - // MARK: Distance from the bottom edge for the seaweed + // Distance from the bottom edge for the seaweed seaweed.style.bottom = '-18px'; let offset = (Math.random() * seaweedSpacing) - (seaweedSpacing / 2); @@ -163,7 +189,7 @@ function createUnderwater() { seaweed.style.transform = `scale(${scale}) ${flip}`; seaweed.style.zIndex = depth < 0.5 ? '15' : '30'; - // Mix Emojis and GIFs + // Mix Emojis and GIFs for seaweed if (Math.random() > 0.4) { let img = document.createElement('img'); img.src = seaweeds[Math.floor(Math.random() * seaweeds.length)]; @@ -182,9 +208,8 @@ function createUnderwater() { // Static Bottom Creatures logic function spawnStatic(imageArray, maxCount, baseSize) { - // Evaluate an actual count between 1 and maxCount if random symbols are enabled - const actualCount = (useRandomSymbols && maxCount > 0) ? Math.floor(Math.random() * maxCount) + 1 : maxCount; - for (let i = 0; i < actualCount; i++) { + let spawnLimit = isMobile ? Math.floor(maxCount / Math.max(1, symbolCountMobile)) : maxCount; + for (let i = 0; i < spawnLimit; i++) { let creature = document.createElement('div'); creature.className = 'underwater-static-bottom'; creature.style.position = 'absolute'; @@ -216,13 +241,9 @@ function createUnderwater() { // Swimmers logic function spawnSwimmerLoop(imageArray, maxCount, baseSize, typeName) { if (maxCount <= 0) return; - let spawnLimit = isMobile ? (enableRandomMobile ? maxCount : Math.floor(maxCount / 2)) : maxCount; + let spawnLimit = isMobile ? Math.floor(maxCount / Math.max(1, symbolCountMobile)) : maxCount; - // Randomize the actual amount spawned up to the limit - const actualCount = (useRandomSymbols && spawnLimit > 0) ? Math.floor(Math.random() * spawnLimit) + 1 : spawnLimit; - - for (let i = 0; i < actualCount; i++) { - // Spawn immediately but use negative delay to distribute them across the screen! + for (let i = 0; i < spawnLimit; i++) { spawnSingleSwimmer(imageArray, baseSize, typeName); } }