Add seasonal effects for Pi Day, Pride, Rain, and Storm; enhance existing styles
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 45s
All checks were successful
Auto Release Plugin / build-and-release (push) Successful in 45s
- Introduced new CSS and JS files for Pi Day, Pride, Rain, and Storm effects. - Updated existing seasonal styles (e.g., Halloween, Hearts, Resurrection) to improve performance with 'contain: layout paint'. - Enhanced animations for seasonal effects, including adjustments to keyframes and element creation logic. - Added configuration options for new effects in the main seasonals.js file. - Updated test-site.html to include new seasonal options in the dropdown.
This commit is contained in:
@@ -121,30 +121,80 @@ function createGrass(container) {
|
||||
|
||||
grassContainer.innerHTML = '';
|
||||
|
||||
const bladeCount = window.innerWidth / 3;
|
||||
let pathsBg = '';
|
||||
let pathsFg = '';
|
||||
const w = window.innerWidth;
|
||||
const hSVG = 80;
|
||||
|
||||
// 1. Generate Straight Line HTML-Style Grass (converted to SVG Paths)
|
||||
const bladeCount = w / 5; // Reduced from w/3
|
||||
for (let i = 0; i < bladeCount; i++) {
|
||||
const blade = document.createElement('div');
|
||||
blade.classList.add('spring-grass');
|
||||
|
||||
// MARK: GRASS HEIGHT
|
||||
const height = Math.random() * 40 + 20; // 20-60px height
|
||||
blade.style.height = `${height}px`;
|
||||
blade.style.left = `${i * 3 + Math.random() * 2}px`;
|
||||
|
||||
const duration = Math.random() * 2 + 3;
|
||||
blade.style.animationDuration = `${duration}s`;
|
||||
blade.style.animationDelay = `-${Math.random() * 5}s`;
|
||||
const x = i * 5 + Math.random() * 3;
|
||||
|
||||
const hue = 100 + Math.random() * 40;
|
||||
blade.style.backgroundColor = `hsl(${hue}, 60%, 40%)`;
|
||||
const color = `hsl(${hue}, 60%, 40%)`;
|
||||
|
||||
// Random z-index to interleave with Ladybug (1002)
|
||||
// Values: 1001 (behind) or 1003 (front)
|
||||
const z = Math.random() > 0.5 ? 1001 : 1003;
|
||||
blade.style.zIndex = z;
|
||||
|
||||
grassContainer.appendChild(blade);
|
||||
const line = `<line x1="${x}" y1="${hSVG}" x2="${x}" y2="${hSVG - height}" stroke="${color}" stroke-width="2" />`;
|
||||
// ~66% chance to be in background (1001), 33% foreground (1003)
|
||||
if (Math.random() > 0.33) pathsBg += line; else pathsFg += line;
|
||||
}
|
||||
|
||||
// 2. Generate Curved Earth-Day Style Grass
|
||||
for (let i = 0; i < 200; i++) { // Reduced from 400
|
||||
const x = Math.random() * w;
|
||||
const h = 20 + Math.random() * 50;
|
||||
const cY = hSVG - h;
|
||||
const bend = x + (Math.random() * 40 - 20);
|
||||
const color = Math.random() > 0.5 ? '#4caf50' : '#45a049';
|
||||
const width = 1 + Math.random() * 2;
|
||||
const path = `<path d="M ${x} ${hSVG} Q ${bend} ${cY+20} ${bend} ${cY}" stroke="${color}" stroke-width="${width}" fill="none"/>`;
|
||||
// ~66% chance to be in background (1001), 33% foreground (1003)
|
||||
if (Math.random() > 0.33) pathsBg += path; else pathsFg += path;
|
||||
}
|
||||
|
||||
// 3. Generate SVG Flowers
|
||||
const colors = ['#FF69B4', '#FFD700', '#87CEFA', '#FF4500', '#BA55D3', '#FFA500', '#FF1493', '#FFFFFF'];
|
||||
const flowerCount = Math.floor(w / 40); // Reduced from w/30
|
||||
for (let i = 0; i < flowerCount; i++) {
|
||||
const x = 10 + Math.random() * (w - 20);
|
||||
const y = 10 + Math.random() * 40; // 10-50px from top of SVG
|
||||
const col = colors[Math.floor(Math.random() * colors.length)];
|
||||
|
||||
let flower = '';
|
||||
// Stem
|
||||
flower += `<path d="M ${x} ${hSVG} Q ${x - 5 + Math.random() * 10} ${y+15} ${x} ${y}" stroke="#2e7d32" stroke-width="1.5" fill="none"/>`;
|
||||
|
||||
// Petals
|
||||
const r = 2 + Math.random() * 1.5;
|
||||
flower += `<circle cx="${x-r}" cy="${y-r}" r="${r}" fill="${col}"/>`;
|
||||
flower += `<circle cx="${x+r}" cy="${y-r}" r="${r}" fill="${col}"/>`;
|
||||
flower += `<circle cx="${x-r}" cy="${y+r}" r="${r}" fill="${col}"/>`;
|
||||
flower += `<circle cx="${x+r}" cy="${y+r}" r="${r}" fill="${col}"/>`;
|
||||
// Center
|
||||
flower += `<circle cx="${x}" cy="${y}" r="${r*0.7}" fill="#FFF8DC"/>`;
|
||||
|
||||
// ~66% chance to be in background (1001), 33% foreground (1003)
|
||||
if (Math.random() > 0.33) pathsBg += flower; else pathsFg += flower;
|
||||
}
|
||||
|
||||
// Inject purely SVG based grass container
|
||||
grassContainer.innerHTML = `
|
||||
<div class="spring-meadow-layer" style="z-index: 1001;">
|
||||
<svg class="spring-meadow" viewBox="0 0 ${w} ${hSVG}" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="spring-sway">
|
||||
${pathsBg}
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="spring-meadow-layer" style="z-index: 1003;">
|
||||
<svg class="spring-meadow" viewBox="0 0 ${w} ${hSVG}" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g class="spring-sway" style="animation-delay: -2s;">
|
||||
${pathsFg}
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function initSpringObjects() {
|
||||
@@ -205,6 +255,9 @@ function createBird(container) {
|
||||
wrapper.classList.add('spring-anim-wrapper');
|
||||
wrapper.classList.add('spring-bird-wrapper');
|
||||
|
||||
const alignY = document.createElement('div');
|
||||
alignY.classList.add('spring-align-y');
|
||||
|
||||
const mirror = document.createElement('div');
|
||||
mirror.classList.add('spring-mirror-wrapper');
|
||||
|
||||
@@ -218,19 +271,20 @@ function createBird(container) {
|
||||
// MARK: BIRD SPEED (10-15s)
|
||||
const duration = Math.random() * 5 + 10;
|
||||
|
||||
// MARK: BIRD HEIGHT RANGE (in %)
|
||||
const startY = Math.random() * 55 + 5; // Start 5-60%
|
||||
const endY = Math.random() * 55 + 5; // End 5-60%
|
||||
wrapper.style.setProperty('--start-y', `${startY}%`);
|
||||
wrapper.style.setProperty('--end-y', `${endY}%`);
|
||||
// MARK: BIRD HEIGHT RANGE (in vh)
|
||||
const startY = Math.random() * 55 + 5; // Start 5-60vh
|
||||
const endY = Math.random() * 55 + 5; // End 5-60vh
|
||||
alignY.style.setProperty('--start-y', `${startY}vh`);
|
||||
alignY.style.setProperty('--end-y', `${endY}vh`);
|
||||
|
||||
if (direction === 'right') {
|
||||
wrapper.style.animation = `spring-fly-right-wrapper ${duration}s linear forwards, spring-vertical-drift ${duration}s linear forwards`;
|
||||
wrapper.style.animation = `spring-fly-right-wrapper ${duration}s linear forwards`;
|
||||
mirror.style.transform = 'scaleX(-1)';
|
||||
} else {
|
||||
wrapper.style.animation = `spring-fly-left-wrapper ${duration}s linear forwards, spring-vertical-drift ${duration}s linear forwards`;
|
||||
wrapper.style.animation = `spring-fly-left-wrapper ${duration}s linear forwards`;
|
||||
mirror.style.transform = 'scaleX(1)';
|
||||
}
|
||||
alignY.style.animation = `spring-vertical-drift ${duration}s linear forwards`;
|
||||
|
||||
wrapper.addEventListener('animationend', (e) => {
|
||||
if (e.animationName.includes('fly-')) {
|
||||
@@ -240,11 +294,10 @@ function createBird(container) {
|
||||
});
|
||||
|
||||
bird.style.animation = `spring-bob 2s ease-in-out infinite`;
|
||||
|
||||
wrapper.style.top = `${startY}%`;
|
||||
|
||||
|
||||
mirror.appendChild(bird);
|
||||
wrapper.appendChild(mirror);
|
||||
alignY.appendChild(mirror);
|
||||
wrapper.appendChild(alignY);
|
||||
container.appendChild(wrapper);
|
||||
}
|
||||
|
||||
@@ -253,6 +306,9 @@ function createButterfly(container) {
|
||||
wrapper.classList.add('spring-anim-wrapper');
|
||||
wrapper.classList.add('spring-butterfly-wrapper');
|
||||
|
||||
const alignY = document.createElement('div');
|
||||
alignY.classList.add('spring-align-y');
|
||||
|
||||
const mirror = document.createElement('div');
|
||||
mirror.classList.add('spring-mirror-wrapper');
|
||||
|
||||
@@ -284,12 +340,13 @@ function createButterfly(container) {
|
||||
butterfly.style.animation = `spring-flutter 3s ease-in-out infinite`;
|
||||
butterfly.style.animationDelay = `-${Math.random() * 3}s`;
|
||||
|
||||
// MARK: BUTTERFLY HEIGHT (in %)
|
||||
const top = Math.random() * 35 + 30; // 30-65%
|
||||
wrapper.style.top = `${top}%`;
|
||||
// MARK: BUTTERFLY HEIGHT (in vh)
|
||||
const top = Math.random() * 35 + 30; // 30-65vh
|
||||
alignY.style.transform = `translateY(${top}vh)`;
|
||||
|
||||
mirror.appendChild(butterfly);
|
||||
wrapper.appendChild(mirror);
|
||||
alignY.appendChild(mirror);
|
||||
wrapper.appendChild(alignY);
|
||||
container.appendChild(wrapper);
|
||||
}
|
||||
|
||||
@@ -298,6 +355,9 @@ function createBee(container) {
|
||||
wrapper.classList.add('spring-anim-wrapper');
|
||||
wrapper.classList.add('spring-bee-wrapper');
|
||||
|
||||
const alignY = document.createElement('div');
|
||||
alignY.classList.add('spring-align-y');
|
||||
|
||||
const mirror = document.createElement('div');
|
||||
mirror.classList.add('spring-mirror-wrapper');
|
||||
|
||||
@@ -323,12 +383,13 @@ function createBee(container) {
|
||||
}
|
||||
});
|
||||
|
||||
// MARK: BEE HEIGHT (in %)
|
||||
const top = Math.random() * 60 + 20; // 20-80%
|
||||
wrapper.style.top = `${top}%`;
|
||||
// MARK: BEE HEIGHT (in vh)
|
||||
const top = Math.random() * 60 + 20; // 20-80vh
|
||||
alignY.style.transform = `translateY(${top}vh)`;
|
||||
|
||||
mirror.appendChild(bee);
|
||||
wrapper.appendChild(mirror);
|
||||
alignY.appendChild(mirror);
|
||||
wrapper.appendChild(alignY);
|
||||
container.appendChild(wrapper);
|
||||
}
|
||||
|
||||
@@ -337,6 +398,9 @@ function createLadybugGif(container) {
|
||||
wrapper.classList.add('spring-anim-wrapper');
|
||||
wrapper.classList.add('spring-ladybug-wrapper');
|
||||
|
||||
const alignY = document.createElement('div');
|
||||
alignY.classList.add('spring-align-y');
|
||||
|
||||
const mirror = document.createElement('div');
|
||||
mirror.classList.add('spring-mirror-wrapper');
|
||||
|
||||
@@ -364,11 +428,12 @@ function createLadybugGif(container) {
|
||||
|
||||
bug.style.animation = `spring-crawl 2s ease-in-out infinite`;
|
||||
|
||||
wrapper.style.top = 'auto';
|
||||
wrapper.style.bottom = '5px';
|
||||
// Target the Ladybug to walk on the ground visually (aligning properly with the CSS/SVG grass size)
|
||||
alignY.style.transform = `translateY(calc(100vh - 5px - 30px))`;
|
||||
|
||||
mirror.appendChild(bug);
|
||||
wrapper.appendChild(mirror);
|
||||
alignY.appendChild(mirror);
|
||||
wrapper.appendChild(alignY);
|
||||
container.appendChild(wrapper);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user