watchful-sun / index.html
ParulPandey's picture
make the speed of earth increase or decrease when slider is used - Follow Up Deployment
9cce9c1 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Celestial Sun Animation</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script>
<style>
/* Custom CSS for the animation canvas */
#animation-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
background-color: #000010;
}
#animation-canvas {
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.control-panel {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
z-index: 10;
background: rgba(0, 0, 20, 0.7);
backdrop-filter: blur(10px);
border-radius: 1rem;
padding: 1rem;
box-shadow: 0 0 20px rgba(255, 223, 186, 0.2);
transition: all 0.3s ease;
}
.info-panel {
position: absolute;
top: 2rem;
right: 2rem;
z-index: 10;
background: rgba(0, 0, 20, 0.7);
backdrop-filter: blur(10px);
border-radius: 1rem;
padding: 1rem;
box-shadow: 0 0 20px rgba(255, 223, 186, 0.2);
max-width: 300px;
transition: all 0.3s ease;
}
@media (max-width: 768px) {
.control-panel {
width: calc(100% - 2rem);
left: 1rem;
transform: none;
}
}
.glow-text {
text-shadow: 0 0 8px rgba(255, 223, 186, 0.8);
}
.slider-thumb {
-webkit-appearance: none;
height: 4px;
border-radius: 2px;
background: linear-gradient(90deg, #ff9a3c, #ff3c3c);
}
.slider-thumb::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 12px;
border-radius: 50%;
background: #fff;
cursor: pointer;
box-shadow: 0 0 5px rgba(255, 223, 186, 0.8);
}
</style>
</head>
<body class="bg-black text-white overflow-hidden">
<div id="animation-container" class="relative">
<canvas id="animation-canvas"></canvas>
<!-- Control Panel -->
<div class="control-panel" style="left: 2rem; transform: none;">
<div class="flex flex-col space-y-2 w-40">
<div>
<label for="earth-speed" class="block text-xs font-medium mb-1">Earth Orbit Speed: <span id="earth-speed-value">0.5</span></label>
<input type="range" id="earth-speed" min="0.1" max="2" step="0.1" value="0.5" class="w-full slider-thumb">
</div>
<div>
<label for="sun-intensity" class="block text-xs font-medium mb-1">Sun Intensity</label>
<input type="range" id="sun-intensity" min="50" max="150" step="5" value="100" class="w-full slider-thumb">
</div>
<button id="reset-btn" class="w-full bg-gray-800 hover:bg-gray-700 text-white py-1 px-2 rounded text-xs transition mt-2">
Reset
</button>
</div>
</div>
</div>
<script>
// Global variables for our celestial objects and stars
let sun;
let earth;
let stars = [];
let animationCanvas;
let earthSpeed = 0.5;
let sunIntensity = 100;
// DOM elements
const earthSpeedSlider = document.getElementById('earth-speed');
const sunIntensitySlider = document.getElementById('sun-intensity');
const earthSpeedValue = document.getElementById('earth-speed-value');
const sunIntensityValue = document.getElementById('sun-intensity-value');
const resetBtn = document.getElementById('reset-btn');
const animationContainer = document.getElementById('animation-container');
// Event listeners for controls
earthSpeedSlider.addEventListener('input', function() {
earthSpeed = parseFloat(this.value);
document.getElementById('earth-speed-value').textContent = earthSpeed.toFixed(1);
if (earth) earth.speed = earthSpeed;
});
sunIntensitySlider.addEventListener('input', function() {
sunIntensity = parseInt(this.value);
sunIntensityValue.textContent = sunIntensity;
});
resetBtn.addEventListener('click', function() {
earthSpeedSlider.value = 0.5;
sunIntensitySlider.value = 100;
earthSpeed = 0.5;
sunIntensity = 100;
document.getElementById('earth-speed-value').textContent = earthSpeed.toFixed(1);
sunIntensityValue.textContent = sunIntensity;
if (earth) earth.speed = earthSpeed;
});
// The main setup function, runs once at the start
function setup() {
animationCanvas = createCanvas(windowWidth, windowHeight);
animationCanvas.id('animation-canvas');
colorMode(HSB, 360, 100, 100, 100);
angleMode(DEGREES);
// Create a new sun instance in the center of the canvas
sun = new Sun(width / 2, height / 2);
// Create an earth instance that orbits the sun
earth = new Earth(sun.pos.x, sun.pos.y, min(width, height) * 0.4); // Center X, Center Y, Orbit Radius
// Create a field of stars for the background
for (let i = 0; i < 300; i++) {
stars.push(createVector(random(width), random(height)));
}
describe('A large, glowing yellow and orange sun with two prominent black eyes and a smile. It follows a small, blue Earth revolving around it. The background is a dark, starry sky.');
}
// The main draw loop, runs continuously
function draw() {
background(245, 90, 10); // Dark space blue
// Draw the stars
drawStars();
// Update the earth's position
earth.update();
// Update and display the sun, telling its eyes to look at the earth
sun.update();
sun.display(earth.pos); // Pass earth's position to the sun
// Display the earth
earth.display();
}
// Function to draw the starfield
function drawStars() {
noStroke();
for (const star of stars) {
// Make some stars twinkle
let alpha = random(50, 100);
if (random() > 0.995) {
alpha = 100; // Bright flash
fill(60, 20, 100, 100);
ellipse(star.x, star.y, 3, 3);
} else {
fill(60, 10, 100, alpha);
ellipse(star.x, star.y, 2, 2);
}
}
}
// Adjust canvas size when the browser window is resized
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
// Re-center the sun and earth's orbit center
if (sun) sun.pos.set(width / 2, height / 2);
if (earth) {
earth.center.set(width / 2, height / 2);
earth.radius = min(width, height) * 0.3;
}
}
// --- Sun Class ---
// Manages the body and eyes of our celestial being
class Sun {
constructor(x, y) {
this.pos = createVector(x, y); // Position vector of the sun's core
this.bodySize = min(width, height) * 0.2; // The size of the main sun body
this.coronaSize = this.bodySize * 2; // The outer size of the corona
// Position the eyes relative to the sun's center - made them larger
this.eyes = [
{ offset: createVector(-this.bodySize * 0.27, -this.bodySize * 0.13), size: this.bodySize * 0.33 },
{ offset: createVector(this.bodySize * 0.27, -this.bodySize * 0.13), size: this.bodySize * 0.33 }
];
}
update() {
// Update body size based on window dimensions
this.bodySize = min(width, height) * 0.2;
this.coronaSize = this.bodySize * 2;
// Update eye positions and sizes
this.eyes[0].offset.set(-this.bodySize * 0.27, -this.bodySize * 0.13);
this.eyes[1].offset.set(this.bodySize * 0.27, -this.bodySize * 0.13);
this.eyes[0].size = this.bodySize * 0.33;
this.eyes[1].size = this.bodySize * 0.33;
}
// Display the entire sun
display(target) { // 'target' is the position the eyes should look at
push();
translate(this.pos.x, this.pos.y);
this.drawCorona();
// --- Draw the Body ---
drawingContext.shadowBlur = 40 * (sunIntensity / 100);
drawingContext.shadowColor = color(45, 90, 100);
noStroke();
fill(45, 80, 100, 20 * (sunIntensity / 100));
ellipse(0, 0, this.bodySize * 1.3, this.bodySize * 1.3);
fill(45, 90, 100, 30 * (sunIntensity / 100));
ellipse(0, 0, this.bodySize * 1.15, this.bodySize * 1.15);
fill(50, 10, 100);
ellipse(0, 0, this.bodySize, this.bodySize);
drawingContext.shadowBlur = 0;
// --- Draw the Eyes ---
this.eyes.forEach(eye => this.drawEye(eye.offset.x, eye.offset.y, eye.size, target));
// --- Draw the Smile ---
push();
noFill();
stroke(30, 80, 40, 80); // A dark, friendly orange/brown
strokeWeight(4);
// arc(x, y, width, height, startAngle, stopAngle)
arc(0, this.bodySize * 0.13, this.bodySize * 0.4, this.bodySize * 0.27, 0, 180);
pop();
pop();
}
drawCorona() {
push();
noFill();
strokeWeight(3);
for (let i = 0; i < 360; i += 2) {
let noiseFactor = noise(i * 0.1, frameCount * 0.01);
let r = map(noiseFactor, 0, 1, this.bodySize * 0.7, this.coronaSize * 0.7 * (sunIntensity / 100));
let x1 = cos(i) * this.bodySize * 0.5;
let y1 = sin(i) * this.bodySize * 0.5;
let x2 = cos(i) * r;
let y2 = sin(i) * r;
let hue = map(r, this.bodySize * 0.7, this.coronaSize * 0.7, 40, 20);
let alpha = map(r, this.bodySize * 0.7, this.coronaSize * 0.7, 100, 20) * (sunIntensity / 100);
stroke(hue, 100, 100, alpha);
line(x1, y1, x2, y2);
}
pop();
}
// Draw a single eye that tracks the target
drawEye(x, y, size, target) {
// Calculate the global position of the eye relative to the canvas
let eyePos = createVector(this.pos.x + x, this.pos.y + y);
// Calculate the angle from the eye to the target (the Earth)
let angle = atan2(target.y - eyePos.y, target.x - eyePos.x);
let dist = p5.Vector.dist(target, eyePos);
// The pupil moves towards the edge, but stops before leaving the eye
let pupilOffset = min(dist, size / 2 - (size / 1.8 / 2));
push();
translate(x, y);
// Add a dark ring around the eye to make it pop from the bright sun surface
stroke(30, 80, 30, 80); // Dark, semi-transparent orange/brown
strokeWeight(2);
fill(50, 15, 100); // Bright, pale yellow for sclera
ellipse(0, 0, size, size);
// Pupil
rotate(angle);
noStroke();
fill(0); // Simple black pupil for high contrast
// The pupil is now centered and does not bulge out.
ellipse(pupilOffset, 0, size / 1.8, size / 1.8);
pop();
}
}
// --- Earth Class ---
// Manages the orbiting Earth
class Earth {
constructor(centerX, centerY, radius) {
this.center = createVector(centerX, centerY);
this.radius = radius;
this.size = min(width, height) * 0.05; // The size for Earth
this.angle = 0;
this.speed = earthSpeed;
this.pos = createVector(); // This will hold the earth's current x, y
}
update() {
// Update size based on window dimensions
this.size = min(width, height) * 0.05;
// Increment the angle to make the earth revolve
this.angle += this.speed;
// Calculate the new x and y position based on the angle and radius
this.pos.x = this.center.x + this.radius * cos(this.angle);
this.pos.y = this.center.y + this.radius * sin(this.angle);
}
display() {
// Draw the orbital path
noFill();
stroke(100, 0, 100, 10); // Faint white line
strokeWeight(1);
ellipse(this.center.x, this.center.y, this.radius * 2, this.radius * 2);
push();
translate(this.pos.x, this.pos.y);
// Add a little glow
drawingContext.shadowBlur = 15;
drawingContext.shadowColor = color(200, 80, 100);
// Draw Earth body (blue)
fill(210, 80, 80); // Blue for water
noStroke();
ellipse(0, 0, this.size, this.size);
// Draw continents (green)
fill(120, 70, 60);
ellipse(-this.size * 0.1, this.size * 0.2, this.size * 0.5, this.size * 0.4);
ellipse(this.size * 0.2, -this.size * 0.2, this.size * 0.6, this.size * 0.3);
pop();
}
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ParulPandey/watchful-sun" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>