A beautiful vanilla JavaScript library for rendering dynamic sky backgrounds with realistic atmospheric scattering, animated starfields, and seamless time control.
Transform your web projects with stunning, physically-accurate sky renders that respond to time and location. Watch the sky transition from brilliant blue day to star-filled night, complete with atmospheric scattering and animated celestial bodies.
- π Realistic Atmospheric Scattering - Physically-based sky rendering using single-scattering approximation
- β Animated Starfield - Multi-layer parallax starfield with breathing animation that appears at night
- π Star Rotation - Stars rotate throughout the day/night cycle based on time (360Β° rotation over 24 hours)
- π Dynamic Twilight - Stars fade in gradually during twilight and fade out at dawn
- π Custom Slider Support - Connect any slider (linear, circular, or custom) to control time
- π Auto Location Detection - Automatically detects user location via IP geolocation
- π Manual Location - Set custom latitude/longitude coordinates
- π± Mobile Responsive - Optimized for mobile devices
- π¨ Zero Configuration - Works out of the box with sensible defaults
- β‘ Lightweight - Minimal overhead, maximum visual impact
Simply include the DynamicSky library:
<script src="https://cdn.jsdelivr.net/gh/aakaashjois/dynamic-sky@main/dynamic-sky.js"></script>π‘ Note: The CSS styles are automatically injected into the page when the library loads, so you don't need to include a separate CSS file.
- Download
dynamic-sky.jsfrom the repository - Include it in your HTML:
<script src="path/to/dynamic-sky.js"></script>The CSS is bundled into the JavaScript file and will be automatically injected when the library loads.
Dependencies: This library uses SunCalc for sun position calculations.
Get up and running in minutes! Dynamic Sky is designed to be simple and intuitive.
<!DOCTYPE html>
<html>
<head>
<!-- No CSS file needed - styles are injected automatically -->
</head>
<body>
<!-- Required containers -->
<div id="background-sky"></div>
<div id="stars-container"></div>
<!-- Your content here -->
<div id="page-container">
<h1>Hello World</h1>
</div>
<script src="dynamic-sky.js"></script>
<script>
const sky = new DynamicSky();
sky.init();
</script>
</body>
</html>DynamicSky can automatically create the containers if they don't exist:
<!DOCTYPE html>
<html>
<head>
<!-- No CSS file needed - styles are injected automatically -->
</head>
<body>
<!-- Your content here - no containers needed! -->
<div id="page-container">
<h1>Hello World</h1>
</div>
<script src="dynamic-sky.js"></script>
<script>
// Containers will be created automatically
const sky = new DynamicSky({
skyContainer: '#background-sky',
starsContainer: '#stars-container'
});
sky.init(); // Creates containers if they don't exist
</script>
</body>
</html>const sky = new DynamicSky({
skyContainer: '#background-sky',
starsContainer: '#stars-container',
latitude: 37.7749, // San Francisco
longitude: -122.4194,
starLayers: 3,
starDensity: 5,
onUpdate: function(data) {
console.log('Sky updated:', data);
}
});
sky.init();DynamicSky doesn't provide sliders - you create your own! Here's how to connect any slider:
<!-- Your custom slider (linear, circular, or any type) -->
<input type="range" id="my-slider" min="0" max="1440">
<script>
const sky = new DynamicSky();
sky.init();
const slider = document.getElementById('my-slider');
slider.addEventListener('input', function() {
// Convert slider value (minutes) to a date and update sky
const minutes = parseInt(slider.value);
const date = sky.minutesToDate(minutes);
sky.updateSky(date);
});
// Initialize with current time
slider.value = sky.dateToMinutes();
sky.updateSky(sky.minutesToDate(sky.dateToMinutes()));
</script>See example.html for complete examples of linear and circular sliders.
Customize Dynamic Sky to fit your needs with these configuration options:
| Option | Type | Default | Description |
|---|---|---|---|
skyContainer |
string |
'#background-sky' |
CSS selector for sky background container |
starsContainer |
string |
'#stars-container' |
CSS selector for stars container |
latitude |
number |
null |
Latitude coordinate (auto-detected if not provided) |
longitude |
number |
null |
Longitude coordinate (auto-detected if not provided) |
autoDetectLocation |
boolean |
true |
Automatically detect location via IP |
starLayers |
number |
3 |
Number of starfield layers |
starDensity |
number |
5 |
Star density multiplier |
locationApiUrl |
string |
'https://ipwho.is/' |
URL for IP geolocation API |
onUpdate |
function |
null |
Callback fired when sky updates |
onLocationDetected |
function |
null |
Callback fired when location is detected |
Initialize the DynamicSky instance. Must be called after creating an instance.
const sky = new DynamicSky();
sky.init();Update the sky background for a specific date/time. This is the main method that sliders should call.
// Update to current time
sky.updateSky();
// Update to a specific date/time
const futureDate = new Date('2024-12-25T12:00:00');
sky.updateSky(futureDate);Manually set the location coordinates.
sky.setLocation(40.7128, -74.0060); // New YorkThese methods help you convert between different slider value formats and dates:
Convert minutes of day (0-1440) to a Date object for today.
const date = sky.minutesToDate(720); // 12:00 PM
sky.updateSky(date);Convert a percentage (0-1) to a Date object for today.
const date = sky.percentToDate(0.5); // 12:00 PM (50% through the day)
sky.updateSky(date);Convert hours (0-24) to a Date object for today.
const date = sky.hoursToDate(14.5); // 2:30 PM
sky.updateSky(date);Convert a Date object to minutes of day (0-1440).
const now = new Date();
const minutes = sky.dateToMinutes(now); // Current time in minutesConvert a Date object to percentage of day (0-1).
const now = new Date();
const percent = sky.dateToPercent(now); // Current time as percentageClean up and destroy the instance.
sky.destroy();DynamicSky is designed to work with any slider implementation. Here are examples:
const slider = document.getElementById('linear-slider');
slider.addEventListener('input', function() {
const minutes = parseInt(slider.value);
sky.updateSky(sky.minutesToDate(minutes));
});// In your circular slider's drag handler:
function onDrag(values) {
const minutes = values.totalMinutes; // Your slider's value
sky.updateSky(sky.minutesToDate(minutes));
}const slider = document.getElementById('percent-slider');
slider.addEventListener('input', function() {
const percent = parseFloat(slider.value) / 100; // 0-1
sky.updateSky(sky.percentToDate(percent));
});As long as you can convert your slider's value to a Date object, you can connect it:
// Your slider's value handler
function onSliderChange(value) {
// Convert your slider's value format to a Date however you need
const date = convertYourValueToDate(value);
sky.updateSky(date);
}The library dispatches a custom event when initialized:
document.addEventListener('dynamic-sky-initialized', function(event) {
console.log('Location:', event.detail.latitude, event.detail.longitude);
});The starfield is an integral part of DynamicSky and includes:
- Multi-layer Parallax - Stars are rendered in multiple layers with different depths for a 3D effect
- Breathing Animation - Stars have a subtle breathing/pulsing animation effect
- Dynamic Visibility - Stars automatically fade in during twilight (when sun is below horizon) and fade out at dawn
- Time-based Rotation - Stars rotate 360Β° over 24 hours, matching the Earth's rotation. The rotation updates whenever
updateSky()is called with a new time - Mobile Optimized - Reduced star density on mobile devices for better performance
Stars are created automatically when updateSky() is first called. They:
- Appear gradually as the sun sets (fade in during twilight)
- Are fully visible at night (when sun altitude < -6Β°)
- Rotate based on the time of day (0Β° at midnight, 180Β° at noon, 360Β° at next midnight)
- Fade out gradually as the sun rises
To see stars, set your slider to nighttime hours (typically 6 PM - 6 AM depending on location and season).
The library uses the following CSS classes for the starfield (you can style these):
.dynamic-sky-layer- Starfield layer containers.dynamic-sky-star- Individual star elements
Note: Slider styling is entirely up to you - DynamicSky doesn't provide any slider styles.
- β Chrome (latest)
- β Firefox (latest)
- β Safari (latest)
- β Edge (latest)
β οΈ Requires ES5+ support (no IE11).
Copyright 2025 Aakaash Jois
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
This library was inspired by and builds upon the following amazing projects:
- Horizon by dnlzro - The original inspiration for this library. Horizon renders the current sky at your location as a CSS gradient, showcasing beautiful atmospheric rendering techniques.
- SunCalc by mourner - SunCalc calculations for accurate sun position and astronomical data.
Made with π by aakaashjois
β Star this repo if you find it useful!