Serengi's picture
Create the following code for me to use in Unreal Engine 5.7:
49b07ed verified
// Celestial Cycles Symphony - Main JavaScript
class CelestialSystem {
constructor() {
this.isPlaying = true;
this.timeScale = 10;
this.currentTime = 6 * 60; // 6:00 AM in minutes
this.dayDuration = 24 * 60; // 24 hours in minutes
this.initializeElements();
this.startSimulation();
this.setupEventListeners();
}
initializeElements() {
this.sun = document.getElementById('sun');
this.moon = document.getElementById('moon');
this.stars = document.getElementById('stars');
this.currentTimeDisplay = document.getElementById('currentTime');
this.timeScaleInput = document.getElementById('timeScale');
this.timeScaleValue = document.getElementById('timeScaleValue');
this.pauseBtn = document.getElementById('pauseBtn');
this.sunPosition = document.getElementById('sunPosition');
this.moonPosition = document.getElementById('moonPosition');
this.timeProgress = document.getElementById('timeProgress');
}
setupEventListeners() {
this.timeScaleInput.addEventListener('input', (e) => {
this.timeScale = parseInt(e.target.value);
this.timeScaleValue.textContent = `${this.timeScale}x`;
this.updateSimulationSpeed();
this.updateCelestialInfo();
this.updateBackground();
this.updateAtmosphericEffects();
this.updateLighting();
this.updateTimeDisplay();
this.updateProgress();
this.updateStars();
this.updateHorizon();
this.updateClouds();
this.updateShadows();
this.updateReflections();
this.updateParticles();
this.updateAudio();
this.updateWeather();
this.updateSeasonalEffects();
});
this.pauseBtn.addEventListener('click', () => {
this.togglePause();
});
// Keyboard controls
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') {
e.preventDefault();
this.togglePause();
}
});
}
togglePause() {
this.isPlaying = !this.isPlaying;
const icon = this.pauseBtn.querySelector('i');
const text = this.pauseBtn.querySelector('span:last-child');
if (this.isPlaying) {
icon.setAttribute('data-feather', 'pause');
text.textContent = 'Pause';
this.pauseBtn.classList.remove('bg-red-600');
this.pauseBtn.classList.add('bg-primary-600');
} else {
icon.setAttribute('data-feather', 'play');
text.textContent = 'Play';
this.pauseBtn.classList.remove('bg-primary-600');
this.pauseBtn.classList.add('bg-red-600');
}
feather.replace();
}
startSimulation() {
const update = () => {
if (this.isPlaying) {
this.currentTime += this.timeScale / 60; // Convert to minutes
if (this.currentTime >= this.dayDuration) {
this.currentTime = 0;
}
this.updateAll();
}
requestAnimationFrame(update);
};
update();
}
updateAll() {
this.updateCelestialPositions();
this.updateBackground();
this.updateAtmosphericEffects();
this.updateLighting();
this.updateTimeDisplay();
this.updateCelestialInfo();
this.updateProgress();
this.updateStars();
this.updateHorizon();
this.updateClouds();
this.updateShadows();
this.updateReflections();
this.updateParticles();
this.updateAudio();
this.updateWeather();
this.updateSeasonalEffects();
}
updateCelestialPositions() {
const timeRatio = this.currentTime / this.dayDuration;
// Sun movement (east to west)
const sunX = 10 + (timeRatio * 80); // 10% to 90% of container width
const sunY = this.calculateSunElevation(timeRatio);
// Moon movement (west to east, opposite of sun)
const moonX = 90 - (timeRatio * 80);
const moonY = this.calculateMoonElevation(timeRatio);
this.sun.style.left = `${sunX}%`;
this.sun.style.bottom = `${sunY}%`;
this.moon.style.left = `${moonX}%`;
this.moon.style.bottom = `${moonY}%`;
// Update sun and moon visibility
const sunOpacity = this.calculateSunOpacity(timeRatio);
const moonOpacity = this.calculateMoonOpacity(timeRatio);
this.sun.style.opacity = sunOpacity;
this.moon.style.opacity = moonOpacity;
}
calculateSunElevation(timeRatio) {
// Parabolic curve for sun elevation
const angle = (timeRatio - 0.5) * Math.PI;
return 5 + (Math.cos(angle) * 25);
}
calculateMoonElevation(timeRatio) {
// Similar to sun but offset
const angle = ((timeRatio + 0.5) % 1 - 0.5) * Math.PI;
return 5 + (Math.cos(angle) * 20);
}
calculateSunOpacity(timeRatio) {
// Sun is visible during daytime
if (timeRatio >= 0.25 && timeRatio <= 0.75) {
return 1;
}
// Gradual fade during sunrise/sunset
if (timeRatio >= 0.2 && timeRatio < 0.25) {
return (timeRatio - 0.2) / 0.05;
}
if (timeRatio > 0.75 && timeRatio <= 0.8) {
return (0.8 - timeRatio) / 0.05;
}
return 0;
}
calculateMoonOpacity(timeRatio) {
// Moon is visible during nighttime
if (timeRatio <= 0.2 || timeRatio >= 0.8) {
return 1;
}
// Gradual fade during moonrise/moonset
if (timeRatio > 0.75 && timeRatio < 0.8) {
return (timeRatio - 0.75) / 0.05;
}
if (timeRatio > 0.2 && timeRatio < 0.25) {
return (0.25 - timeRatio) / 0.05;
}
return 0;
}
updateBackground() {
const timeRatio = this.currentTime / this.dayDuration;
const container = this.sun.parentElement;
// Dynamic sky gradient based on time
let gradient;
if (timeRatio < 0.25) { // Night to morning
gradient = 'from-indigo-900 via-purple-700 to-blue-500';
} else if (timeRatio < 0.35) { // Morning
gradient = 'from-blue-500 via-cyan-400 to-blue-300';
} else if (timeRatio < 0.65) { // Day
gradient = 'from-blue-400 via-cyan-300 to-blue-200';
} else if (timeRatio < 0.75) { // Evening
gradient = 'from-orange-400 via-red-500 to-purple-700';
} else { // Evening to night
gradient = 'from-purple-700 via-indigo-800 to-gray-900';
}
container.className = container.className.replace(/from-\S+ via-\S+ to-\S+/, gradient);
}
updateAtmosphericEffects() {
const timeRatio = this.currentTime / this.dayDuration;
// Update sun glow intensity
const sunGlow = this.sun.querySelector('div');
if (timeRatio >= 0.35 && timeRatio <= 0.65) {
sunGlow.classList.add('animate-pulse');
} else {
sunGlow.classList.remove('animate-pulse');
}
}
updateLighting() {
const timeRatio = this.currentTime / this.dayDuration;
// Simulate lighting changes
document.documentElement.style.setProperty('--light-intensity', this.calculateLightIntensity(timeRatio));
}
calculateLightIntensity(timeRatio) {
// Bell curve for light intensity
const center = 0.5;
const width = 0.25;
const distance = Math.abs(timeRatio - center);
return Math.max(0, 1 - (distance / width) ** 2);
}
updateTimeDisplay() {
const hours = Math.floor(this.currentTime / 60);
const minutes = Math.floor(this.currentTime % 60);
const period = hours >= 12 ? 'PM' : 'AM';
const displayHours = hours % 12 || 12;
this.currentTimeDisplay.textContent =
`${displayHours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')} ${period}`;
}
updateCelestialInfo() {
const timeRatio = this.currentTime / this.dayDuration;
// Sun position info
const sunElevation = Math.round(this.calculateSunElevation(timeRatio) * 3.6);
const sunAzimuth = Math.round(90 + (timeRatio * 180) % 360);
this.sunPosition.textContent = `Elevation: ${sunElevation}° | Azimuth: ${sunAzimuth}°`;
// Moon position info
const moonElevation = Math.round(this.calculateMoonElevation(timeRatio) * 3.6);
const moonAzimuth = Math.round(270 - (timeRatio * 180) % 360);
this.moonPosition.textContent = `Elevation: ${moonElevation}° | Azimuth: ${moonAzimuth}°`;
}
updateProgress() {
const dayProgress = Math.min(1, Math.max(0, (this.currentTime / this.dayDuration - 0.25) / 0.5);
const nightProgress = 1 - dayProgress;
this.timeProgress.textContent =
`Day: ${Math.round(dayProgress * 100)}% | Night: ${Math.round(nightProgress * 100)}%`;
}
updateStars() {
const timeRatio = this.currentTime / this.dayDuration;
const starOpacity = (timeRatio <= 0.2 || timeRatio >= 0.8) ? 1 : 0;
this.stars.style.opacity = starOpacity;
}
updateHorizon() {
// Update horizon line color based on time
const timeRatio = this.currentTime / this.dayDuration;
const horizon = document.querySelector('.absolute.bottom-0');
if (timeRatio < 0.25 || timeRatio > 0.75) {
horizon.className = horizon.className.replace(/from-\S+ to-\S+/, 'from-gray-900 to-gray-700');
} else {
horizon.className = horizon.className.replace(/from-\S+ to-\S+/, 'from-green-900 to-green-700');
}
updateClouds() {
// Cloud movement and lighting simulation
const timeRatio = this.currentTime / this.dayDuration;
document.documentElement.style.setProperty('--cloud-brightness', this.calculateCloudBrightness(timeRatio));
}
calculateCloudBrightness(timeRatio) {
return Math.max(0.3, Math.min(1, this.calculateLightIntensity(timeRatio) + 0.3));
}
updateShadows() {
const timeRatio = this.currentTime / this.dayDuration;
const shadowLength = 50 + (Math.abs(timeRatio - 0.5) * 100);
document.documentElement.style.setProperty('--shadow-length', `${shadowLength}px`);
}
updateReflections() {
// Water reflection intensity
const timeRatio = this.currentTime / this.dayDuration;
const reflectionIntensity = timeRatio >= 0.35 && timeRatio <= 0.65 ? 0.8 : 0.3;
document.documentElement.style.setProperty('--reflection-intensity', reflectionIntensity);
}
updateParticles() {
// Dust particles, fireflies, etc.
const timeRatio = this.currentTime / this.dayDuration;
const particleDensity = timeRatio < 0.25 || timeRatio > 0.75 ? 0.7 : 0.1);
document.documentElement.style.setProperty('--particle-density', particleDensity);
}
updateAudio() {
// Background audio changes
const timeRatio = this.currentTime / this.dayDuration;
const audioVolume = Math.min(1, Math.max(0.1, this.calculateLightIntensity(timeRatio)));
document.documentElement.style.setProperty('--audio-volume', audioVolume);
}
updateWeather() {
// Weather system integration placeholder
const timeRatio = this.currentTime / this.dayDuration;
document.documentElement.style.setProperty('--weather-intensity', Math.random()));
}
updateSeasonalEffects() {
// Seasonal variations placeholder
const timeRatio = this.currentTime / this.dayDuration;
document.documentElement.style.setProperty('--season-factor', 1);
}
updateSimulationSpeed() {
// Adjust animation speeds based on time scale
document.documentElement.style.setProperty('--animation-speed', `${this.timeScale / 10}s`);
}
}
// Initialize the celestial system when the page loads
document.addEventListener('DOMContentLoaded', () => {
new CelestialSystem();
// Add fade-in animations to sections
const sections = document.querySelectorAll('section');
sections.forEach((section, index) => {
section.classList.add('fade-in-up');
section.style.animationDelay = `${index * 0.2}s`;
});
});
// Utility function for smooth transitions
function smoothTransition(element, property, targetValue, duration = 1000) {
element.style.transition = `${property} ${duration}ms cubic-bezier(0.4, 0, 0.2, 1)';
element.style[property] = targetValue;
}
// Export for potential module usage
if (typeof module !== 'undefined' && module.exports) {
module.exports = CelestialSystem;
}