Add Cherry Blossom feature with configuration options and animations [skip ci]
This commit is contained in:
@@ -582,9 +582,9 @@
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label class="emby-checkbox-label">
|
||||
<input id="EnableSpring" name="EnableSpring" type="checkbox" is="emby-checkbox" />
|
||||
<span>Enable Spring Seasonal</span>
|
||||
<span class="checkboxLabel">Enable Spring</span>
|
||||
</label>
|
||||
<div class="fieldDescription">Enable the Spring theme in general (e.g. for automation).</div>
|
||||
<div class="fieldDescription">Enables the Spring theme (grass, pollen).</div>
|
||||
</div>
|
||||
<div class="checkboxContainer checkboxContainer-withDescription">
|
||||
<label class="emby-checkbox-label">
|
||||
@@ -610,11 +610,6 @@
|
||||
<input is="emby-input" type="number" id="SpringPollenCount" name="SpringPollenCount" />
|
||||
<div class="fieldDescription">Number of pollen particles (if enabled).</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel" for="SpringLadybugCount">Ladybug Count</label>
|
||||
<input is="emby-input" type="number" id="SpringLadybugCount" name="SpringLadybugCount" />
|
||||
<div class="fieldDescription">Number of ladybugs.</div>
|
||||
</div>
|
||||
<div class="inputContainer">
|
||||
<label class="inputLabel" for="SpringSunbeamCount">Sunbeam Count</label>
|
||||
<input is="emby-input" type="number" id="SpringSunbeamCount" name="SpringSunbeamCount" />
|
||||
@@ -889,6 +884,7 @@
|
||||
' <option value="easter">Easter</option>' +
|
||||
' <option value="resurrection">Resurrection</option>' +
|
||||
' <option value="spring">Spring</option>' +
|
||||
' <option value="cherryblossom">Cherry Blossom</option>' +
|
||||
' <option value="summer">Summer</option>' +
|
||||
' <option value="carnival">Carnival</option>' +
|
||||
' </select>' +
|
||||
@@ -1065,9 +1061,7 @@
|
||||
|
||||
// Spring
|
||||
document.querySelector('#EnableSpring').checked = config.Spring.EnableSpring;
|
||||
document.querySelector('#SpringPetalCount').value = config.Spring.PetalCount;
|
||||
document.querySelector('#SpringPollenCount').value = config.Spring.PollenCount;
|
||||
document.querySelector('#SpringLadybugCount').value = config.Spring.LadybugCount;
|
||||
document.querySelector('#SpringSunbeamCount').value = config.Spring.SunbeamCount;
|
||||
document.querySelector('#EnableRandomSpring').checked = config.Spring.EnableRandomSpring;
|
||||
document.querySelector('#EnableRandomSpringMobile').checked = config.Spring.EnableRandomSpringMobile;
|
||||
@@ -1088,6 +1082,13 @@
|
||||
document.querySelector('#EnableRandomCarnivalMobile').checked = config.Carnival.EnableRandomCarnivalMobile;
|
||||
document.querySelector('#EnableDifferentDurationCarnival').checked = config.Carnival.EnableDifferentDuration;
|
||||
|
||||
// Cherry Blossom
|
||||
document.querySelector('#EnableCherryBlossom').checked = config.CherryBlossom.EnableCherryBlossom;
|
||||
document.querySelector('#CherryBlossomPetalCount').value = config.CherryBlossom.PetalCount;
|
||||
document.querySelector('#EnableRandomCherryBlossom').checked = config.CherryBlossom.EnableRandomCherryBlossom;
|
||||
document.querySelector('#EnableRandomCherryBlossomMobile').checked = config.CherryBlossom.EnableRandomCherryBlossomMobile;
|
||||
document.querySelector('#EnableDifferentDurationCherryBlossom').checked = config.CherryBlossom.EnableDifferentDuration;
|
||||
|
||||
Dashboard.hideLoadingMsg();
|
||||
});
|
||||
});
|
||||
@@ -1197,9 +1198,7 @@
|
||||
|
||||
// Spring
|
||||
config.Spring.EnableSpring = document.querySelector('#EnableSpring').checked;
|
||||
config.Spring.PetalCount = parseInt(document.querySelector('#SpringPetalCount').value);
|
||||
config.Spring.PollenCount = parseInt(document.querySelector('#SpringPollenCount').value);
|
||||
config.Spring.LadybugCount = parseInt(document.querySelector('#SpringLadybugCount').value);
|
||||
config.Spring.SunbeamCount = parseInt(document.querySelector('#SpringSunbeamCount').value);
|
||||
config.Spring.EnableRandomSpring = document.querySelector('#EnableRandomSpring').checked;
|
||||
config.Spring.EnableRandomSpringMobile = document.querySelector('#EnableRandomSpringMobile').checked;
|
||||
@@ -1220,6 +1219,13 @@
|
||||
config.Carnival.EnableRandomCarnivalMobile = document.querySelector('#EnableRandomCarnivalMobile').checked;
|
||||
config.Carnival.EnableDifferentDuration = document.querySelector('#EnableDifferentDurationCarnival').checked;
|
||||
|
||||
// Cherry Blossom
|
||||
config.CherryBlossom.EnableCherryBlossom = document.querySelector('#EnableCherryBlossom').checked;
|
||||
config.CherryBlossom.PetalCount = parseInt(document.querySelector('#CherryBlossomPetalCount').value);
|
||||
config.CherryBlossom.EnableRandomCherryBlossom = document.querySelector('#EnableRandomCherryBlossom').checked;
|
||||
config.CherryBlossom.EnableRandomCherryBlossomMobile = document.querySelector('#EnableRandomCherryBlossomMobile').checked;
|
||||
config.CherryBlossom.EnableDifferentDuration = document.querySelector('#EnableDifferentDurationCherryBlossom').checked;
|
||||
|
||||
ApiClient.updatePluginConfiguration(SeasonalsConfigPage.pluginUniqueId, config).then(function (result) {
|
||||
Dashboard.processPluginConfigurationUpdateResult(result);
|
||||
});
|
||||
|
||||
58
Jellyfin.Plugin.Seasonals/Web/cherryblossom.css
Normal file
58
Jellyfin.Plugin.Seasonals/Web/cherryblossom.css
Normal file
@@ -0,0 +1,58 @@
|
||||
.cherryblossom-container {
|
||||
display: block;
|
||||
position: fixed;
|
||||
overflow: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Petals */
|
||||
.cherryblossom-petal {
|
||||
position: fixed;
|
||||
top: -20px;
|
||||
z-index: 1005;
|
||||
width: 15px;
|
||||
height: 10px;
|
||||
background-color: #ffc0cb;
|
||||
border-radius: 15px 0px 15px 0px;
|
||||
|
||||
will-change: transform, top;
|
||||
animation-name: cherryblossom-fall, cherryblossom-sway;
|
||||
animation-timing-function: linear, ease-in-out;
|
||||
animation-iteration-count: infinite, infinite;
|
||||
animation-duration: 10s, 3s;
|
||||
}
|
||||
|
||||
.cherryblossom-petal.lighter {
|
||||
background-color: #ffd1dc;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.cherryblossom-petal.darker {
|
||||
background-color: #ffb7c5;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.cherryblossom-petal.type2 {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 10px 0px 10px 5px;
|
||||
}
|
||||
|
||||
@keyframes cherryblossom-fall {
|
||||
0% { top: -10%; }
|
||||
100% { top: 100%; }
|
||||
}
|
||||
|
||||
@keyframes cherryblossom-sway {
|
||||
0%, 100% {
|
||||
transform: translateX(0) rotate(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(30px) rotate(45deg);
|
||||
}
|
||||
}
|
||||
101
Jellyfin.Plugin.Seasonals/Web/cherryblossom.js
Normal file
101
Jellyfin.Plugin.Seasonals/Web/cherryblossom.js
Normal file
@@ -0,0 +1,101 @@
|
||||
const config = window.SeasonalsPluginConfig?.CherryBlossom || {};
|
||||
|
||||
const cherryBlossom = config.EnableCherryBlossom !== undefined ? config.EnableCherryBlossom : true;
|
||||
const petalCount = config.PetalCount || 25;
|
||||
const randomCherryBlossom = config.EnableRandomCherryBlossom !== undefined ? config.EnableRandomCherryBlossom : true;
|
||||
const randomCherryBlossomMobile = config.EnableRandomCherryBlossomMobile !== undefined ? config.EnableRandomCherryBlossomMobile : false;
|
||||
const enableDifferentDuration = config.EnableDifferentDuration !== undefined ? config.EnableDifferentDuration : true;
|
||||
|
||||
let msgPrinted = false;
|
||||
|
||||
function toggleCherryBlossom() {
|
||||
const container = document.querySelector('.cherryblossom-container');
|
||||
if (!container) 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');
|
||||
|
||||
if (videoPlayer || trailerPlayer || isDashboard || hasUserMenu) {
|
||||
container.style.display = 'none';
|
||||
if (!msgPrinted) {
|
||||
console.log('CherryBlossom hidden');
|
||||
msgPrinted = true;
|
||||
}
|
||||
} else {
|
||||
container.style.display = 'block';
|
||||
if (msgPrinted) {
|
||||
console.log('CherryBlossom visible');
|
||||
msgPrinted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(toggleCherryBlossom);
|
||||
observer.observe(document.body, { childList: true, subtree: true, attributes: true });
|
||||
|
||||
function createPetal(container) {
|
||||
const petal = document.createElement('div');
|
||||
petal.classList.add('cherryblossom-petal');
|
||||
|
||||
const type = Math.random() > 0.5 ? 'type1' : 'type2';
|
||||
petal.classList.add(type);
|
||||
|
||||
const color = Math.random() > 0.7 ? 'darker' : 'lighter';
|
||||
petal.classList.add(color);
|
||||
|
||||
const randomLeft = Math.random() * 100;
|
||||
petal.style.left = `${randomLeft}%`;
|
||||
|
||||
const size = Math.random() * 0.5 + 0.5;
|
||||
petal.style.transform = `scale(${size})`;
|
||||
|
||||
const duration = Math.random() * 5 + 8;
|
||||
const delay = Math.random() * 10;
|
||||
const swayDuration = Math.random() * 2 + 2;
|
||||
|
||||
if (enableDifferentDuration) {
|
||||
petal.style.animationDuration = `${duration}s, ${swayDuration}s`;
|
||||
}
|
||||
petal.style.animationDelay = `${delay}s, ${Math.random() * 3}s`;
|
||||
|
||||
container.appendChild(petal);
|
||||
}
|
||||
|
||||
function addRandomObjects() {
|
||||
const container = document.querySelector('.cherryblossom-container');
|
||||
if (!container) return;
|
||||
|
||||
for (let i = 0; i < petalCount; i++) {
|
||||
createPetal(container);
|
||||
}
|
||||
}
|
||||
|
||||
function initObjects() {
|
||||
let container = document.querySelector('.cherryblossom-container');
|
||||
if (!container) {
|
||||
container = document.createElement("div");
|
||||
container.className = "cherryblossom-container";
|
||||
container.setAttribute("aria-hidden", "true");
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
// Initial batch
|
||||
for (let i = 0; i < 15; i++) {
|
||||
createPetal(container);
|
||||
}
|
||||
}
|
||||
|
||||
function initializeCherryBlossom() {
|
||||
if (!cherryBlossom) return;
|
||||
initObjects();
|
||||
toggleCherryBlossom();
|
||||
|
||||
const screenWidth = window.innerWidth;
|
||||
if (randomCherryBlossom && (screenWidth > 768 || randomCherryBlossomMobile)) {
|
||||
addRandomObjects();
|
||||
}
|
||||
}
|
||||
|
||||
initializeCherryBlossom();
|
||||
Reference in New Issue
Block a user