/** * The Dance of Life's Seasons * * A representation of how I view life's transitions as a series of seasons, * each with its own beauty and purpose. The UI animations mirror the natural * flow between periods of growth, abundance, reflection, and rest. */ class LifeSeason { constructor(name, color, mood, activities, lessons) { this.name = name; this.color = color; this.mood = mood; this.activities = activities; this.lessons = lessons; this.transitionDuration = 1200; // ms } // Each season has its own animation style getTransitionStyle() { const styles = { 'Spring': 'cubic-bezier(0.2, 0.8, 0.2, 1)', // Bouncy, energetic 'Summer': 'cubic-bezier(0, 0, 0.58, 1)', // Quick start, slow finish 'Autumn': 'cubic-bezier(0.25, 0.1, 0.25, 1)', // Steady, contemplative 'Winter': 'cubic-bezier(0.42, 0, 0.58, 1)' // Symmetric, balanced }; return styles[this.name] || 'ease'; } // How we visually represent this season renderVisual(container) { container.style.backgroundColor = this.color; container.style.transition = `all ${this.transitionDuration}ms ${this.getTransitionStyle()}`; // Clear previous content container.innerHTML = ''; // Create season title with mood emoji const title = document.createElement('h2'); title.textContent = `${this.name} ${this.mood}`; title.classList.add('season-title'); container.appendChild(title); // Add floating elements that represent activities this.activities.forEach(activity => { const element = document.createElement('div'); element.textContent = activity; element.classList.add('activity-bubble'); element.style.animationDuration = `${5 + Math.random() * 7}s`; container.appendChild(element); }); // Add the lesson as a footer const lesson = document.createElement('p'); lesson.textContent = this.lessons[Math.floor(Math.random() * this.lessons.length)]; lesson.classList.add('season-lesson'); container.appendChild(lesson); } } class LifeJourney { constructor() { this.seasons = [ new LifeSeason( 'Spring', '#a6e3b7', '🌱', ['Learning', 'Starting', 'Growing', 'Dreaming'], ['Beginnings require courage', 'Growth is uncomfortable but necessary', 'Plant intentions with care'] ), new LifeSeason( 'Summer', '#ffd166', '☀️', ['Creating', 'Sharing', 'Building', 'Connecting'], ['Celebrate your achievements', 'Abundance comes from consistent effort', 'Share your light with others'] ), new LifeSeason( 'Autumn', '#e07a5f', '🍂', ['Reflecting', 'Evaluating', 'Releasing', 'Transforming'], ['Let go of what no longer serves you', 'Beauty exists in transition', 'Harvest what you've learned'] ), new LifeSeason( 'Winter', '#8ecae6', '❄️', ['Resting', 'Planning', 'Healing', 'Contemplating'], ['Stillness brings clarity', 'Rest is productive', 'In silence, wisdom grows'] ) ]; this.currentSeasonIndex = 0; this.container = null; this.isTransitioning = false; } initialize(containerId) { this.container = document.getElementById(containerId); if (!this.container) { console.error('Container element not found'); return; } // Add navigation controls const controls = document.createElement('div'); controls.classList.add('season-controls'); const prevBtn = document.createElement('button'); prevBtn.textContent = '← Previous Season'; prevBtn.addEventListener('click', () => this.previousSeason()); const nextBtn = document.createElement('button'); nextBtn.textContent = 'Next Season →'; nextBtn.addEventListener('click', () => this.nextSeason()); controls.appendChild(prevBtn); controls.appendChild(nextBtn); document.body.appendChild(controls); // Display initial season this.displayCurrentSeason(); } displayCurrentSeason() { if (this.isTransitioning) return; const season = this.seasons[this.currentSeasonIndex]; season.renderVisual(this.container); } nextSeason() { if (this.isTransitioning) return; this.isTransitioning = true; this.currentSeasonIndex = (this.currentSeasonIndex + 1) % this.seasons.length; // Add transition-out class this.container.classList.add('transition-out'); setTimeout(() => { this.displayCurrentSeason(); this.container.classList.remove('transition-out'); this.isTransitioning = false; }, 600); } previousSeason() { if (this.isTransitioning) return; this.isTransitioning = true; this.currentSeasonIndex = (this.currentSeasonIndex - 1 + this.seasons.length) % this.seasons.length; // Add transition-out class but in reverse this.container.classList.add('transition-out-reverse'); setTimeout(() => { this.displayCurrentSeason(); this.container.classList.remove('transition-out-reverse'); this.isTransitioning = false; }, 600); } } // Initialize the journey when the DOM is ready document.addEventListener('DOMContentLoaded', () => { const journey = new LifeJourney(); journey.initialize('life-container'); // Add a reflection prompt that changes periodically const reflectionPrompts = [ "What season of life are you in right now?", "Which season challenges you the most?", "What are you growing in this season?", "What needs to be released before your next season?" ]; const reflectionElement = document.createElement('div'); reflectionElement.classList.add('reflection-prompt'); document.body.appendChild(reflectionElement); let promptIndex = 0; const updatePrompt = () => { reflectionElement.textContent = reflectionPrompts[promptIndex]; promptIndex = (promptIndex + 1) % reflectionPrompts.length; }; updatePrompt(); setInterval(updatePrompt, 10000); });