Add day mode driven by the real sun
The Sun's true altitude (Astronomy Engine, on the timelapse clock) raises the desktop sun from the horizon up to ~78% of the screen at culmination and back down at sunset; at night it rests on the horizon as before. Above -3° the body gains a 'dia' class: light blue sky with a pink horizon band (#daySky), bright warm sun disc without retro stripes, golden horizon line, stars/nebulae/meteors washed out, and the dancing skeleton swaps for a wooden coffin with a golden cross. Balada and chuva keep priority via :not() selectors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015HtPHsTnDcLVSCiF5FGHZj
This commit is contained in:
parent
444d46a4db
commit
a80b22bdcc
2 changed files with 157 additions and 1 deletions
|
|
@ -59,6 +59,7 @@ Pure HTML/CSS/JS, no external dependencies. All visuals are self-contained:
|
||||||
| Milky Way | Per-pixel sampling of `milkyway.jpg` (Gaia photo, full res): `buildMwGrid` caches viewport unit vectors + extinction/glare, `renderMilkyWay` applies only the sidereal rotation (camera azimuth folded into the equatorial→galactic matrix) and stylized "development" (deep blacks, saturation, cool shadows). Decoded texture stays resident (~75 MB) |
|
| Milky Way | Per-pixel sampling of `milkyway.jpg` (Gaia photo, full res): `buildMwGrid` caches viewport unit vectors + extinction/glare, `renderMilkyWay` applies only the sidereal rotation (camera azimuth folded into the equatorial→galactic matrix) and stylized "development" (deep blacks, saturation, cool shadows). Decoded texture stays resident (~75 MB) |
|
||||||
| Moon & planets | Astronomy Engine topocentric ephemerides: Moon with real phase texture + bright-limb angle, 7 planets with magnitude-scaled dots (labels only in constellation mode) |
|
| Moon & planets | Astronomy Engine topocentric ephemerides: Moon with real phase texture + bright-limb angle, 7 planets with magnitude-scaled dots (labels only in constellation mode) |
|
||||||
| Zodiac constellations | Stellarium Modern lines (traces only, no artwork); toggled via `/tmp` file or `C` key |
|
| Zodiac constellations | Stellarium Modern lines (traces only, no artwork); toggled via `/tmp` file or `C` key |
|
||||||
|
| Day mode | Real sun altitude (Astronomy Engine, follows the timelapse clock) drives `--sun-bottom` (horizon → ~78% at culmination) and a `dia` body class: light blue/pink `#daySky`, bright sun disc, golden horizon, stars/nebulae fade out, dancer replaced by a CSS coffin. Balada/chuva override day visuals via `:not()` selectors |
|
||||||
| Nebula blobs, grid floor, horizon | CSS animations |
|
| Nebula blobs, grid floor, horizon | CSS animations |
|
||||||
| DANCEBOT-9000 robot | Pure CSS (divs + `@keyframes`) |
|
| DANCEBOT-9000 robot | Pure CSS (divs + `@keyframes`) |
|
||||||
| Chest EQ bars & VU meter | JS-driven `requestAnimationFrame` |
|
| Chest EQ bars & VU meter | JS-driven `requestAnimationFrame` |
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ html, body {
|
||||||
filter: blur(80px);
|
filter: blur(80px);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
animation: nebulaFloat ease-in-out infinite;
|
animation: nebulaFloat ease-in-out infinite;
|
||||||
|
transition: opacity 12s ease;
|
||||||
}
|
}
|
||||||
.nebula::after {
|
.nebula::after {
|
||||||
content: '';
|
content: '';
|
||||||
|
|
@ -796,7 +797,8 @@ body.balada .music-ticker {
|
||||||
height: 280px;
|
height: 280px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
bottom: 41.5%;
|
/* --sun-bottom segue o sol real (modo dia); 41.5% = pousado no horizonte */
|
||||||
|
bottom: var(--sun-bottom, 41.5%);
|
||||||
transform: translateX(-50%) translateY(50%);
|
transform: translateX(-50%) translateY(50%);
|
||||||
transition:
|
transition:
|
||||||
bottom 2.8s cubic-bezier(0.16, 1, 0.3, 1),
|
bottom 2.8s cubic-bezier(0.16, 1, 0.3, 1),
|
||||||
|
|
@ -1124,12 +1126,135 @@ body.chuva .horizon {
|
||||||
}
|
}
|
||||||
body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; }
|
body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; }
|
||||||
|
|
||||||
|
/* ============================================================
|
||||||
|
MODO DIA — o sol real levanta o sol do desktop; céu clareia,
|
||||||
|
estrelas se ofuscam e o esqueleto descansa no caixão.
|
||||||
|
Balada e chuva têm prioridade sobre o visual diurno.
|
||||||
|
============================================================ */
|
||||||
|
|
||||||
|
/* Céu diurno: azul lá em cima, rosa no horizonte, lilás sob a grade */
|
||||||
|
#daySky {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 12s ease;
|
||||||
|
background: linear-gradient(to bottom,
|
||||||
|
#5fb2ef 0%,
|
||||||
|
#8fd0f7 32%,
|
||||||
|
#cfeaff 50%,
|
||||||
|
#ffd9ec 58.5%,
|
||||||
|
#f2e2ff 58.6%,
|
||||||
|
#d9c8f0 100%);
|
||||||
|
}
|
||||||
|
body.dia:not(.balada):not(.chuva) #daySky { opacity: 1; }
|
||||||
|
|
||||||
|
/* Estrelas, nebulosas e meteoros ofuscados pela luz do dia */
|
||||||
|
body.dia:not(.balada):not(.chuva) #starfield { opacity: 0; transition: opacity 12s ease; }
|
||||||
|
body.dia:not(.balada):not(.chuva) .nebula { opacity: 0; }
|
||||||
|
body.dia:not(.balada):not(.chuva) #meteorLayer { opacity: 0; }
|
||||||
|
|
||||||
|
/* O sol vira sol de verdade: disco quente, sem listras retrô */
|
||||||
|
#sunDiaBg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 9s ease;
|
||||||
|
background: radial-gradient(circle at 50% 40%,
|
||||||
|
#fffce0 0%,
|
||||||
|
#ffe866 42%,
|
||||||
|
#ffc247 72%,
|
||||||
|
#ff9e33 100%);
|
||||||
|
}
|
||||||
|
body.dia:not(.balada):not(.chuva) #sunDiaBg { opacity: 1; }
|
||||||
|
body.dia:not(.balada):not(.chuva) #sunStripes { opacity: 0; }
|
||||||
|
body.dia:not(.balada):not(.chuva) .synthwave-sun {
|
||||||
|
box-shadow:
|
||||||
|
0 0 60px rgba(255,225,130, 0.85),
|
||||||
|
0 0 160px rgba(255,205, 90, 0.45),
|
||||||
|
0 0 320px rgba(255,185, 70, 0.22);
|
||||||
|
}
|
||||||
|
body.dia:not(.balada):not(.chuva) .synthwave-sun::after {
|
||||||
|
background: radial-gradient(ellipse at 50% 50%,
|
||||||
|
rgba(255,235,160, 0.32) 0%,
|
||||||
|
rgba(255,210,110, 0.16) 45%,
|
||||||
|
transparent 72%);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizonte dourado no lugar do neon rosa/ciano */
|
||||||
|
body.dia:not(.balada):not(.chuva) .horizon {
|
||||||
|
background: linear-gradient(
|
||||||
|
to right,
|
||||||
|
transparent 0%,
|
||||||
|
rgba(255,190,110,0.85) 20%,
|
||||||
|
rgba(255,235,170,1) 50%,
|
||||||
|
rgba(255,190,110,0.85) 80%,
|
||||||
|
transparent 100%
|
||||||
|
);
|
||||||
|
box-shadow: 0 0 25px rgba(255,210,130,0.7), 0 0 80px rgba(255,190,110,0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* De dia o esqueleto dorme: some o dançarino, aparece o caixão */
|
||||||
|
body.dia:not(.balada):not(.chuva) .robot-wrap { opacity: 0 !important; }
|
||||||
|
.coffin-wrap {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 28%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 4s ease;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
body.dia:not(.balada):not(.chuva) .coffin-wrap { opacity: 1; }
|
||||||
|
.coffin-shade {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1.6vh;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 22vh;
|
||||||
|
height: 3.2vh;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: radial-gradient(ellipse, rgba(40,20,40,0.38), transparent 70%);
|
||||||
|
}
|
||||||
|
.coffin {
|
||||||
|
position: relative;
|
||||||
|
width: 15vh;
|
||||||
|
height: 34vh;
|
||||||
|
clip-path: polygon(32% 0%, 68% 0%, 100% 26%, 73% 100%, 27% 100%, 0% 26%);
|
||||||
|
background:
|
||||||
|
linear-gradient(105deg, rgba(255,255,255,0.10), rgba(0,0,0,0.24) 62%),
|
||||||
|
linear-gradient(to bottom, #7a4a28 0%, #5c3620 46%, #452716 100%);
|
||||||
|
filter: drop-shadow(0 6px 18px rgba(60,30,20,0.45));
|
||||||
|
}
|
||||||
|
.coffin::before { /* costura da tampa */
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 6%; right: 6%;
|
||||||
|
top: 26%;
|
||||||
|
height: 3px;
|
||||||
|
background: rgba(0,0,0,0.45);
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.coffin-cross-v, .coffin-cross-h {
|
||||||
|
position: absolute;
|
||||||
|
background: linear-gradient(to bottom, #e8c87e, #c9a250);
|
||||||
|
border-radius: 2px;
|
||||||
|
box-shadow: 0 0 10px rgba(255,225,150,0.55);
|
||||||
|
}
|
||||||
|
.coffin-cross-v { left: 50%; top: 36%; width: 0.9vh; height: 24%; transform: translateX(-50%); }
|
||||||
|
.coffin-cross-h { left: 50%; top: 42%; width: 34%; height: 0.9vh; transform: translateX(-50%); }
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="scene">
|
<div class="scene">
|
||||||
|
|
||||||
|
<!-- Céu diurno (fade conforme o sol real sobe) -->
|
||||||
|
<div id="daySky"></div>
|
||||||
|
|
||||||
<!-- Nebula blobs -->
|
<!-- Nebula blobs -->
|
||||||
<div class="nebula nebula-a"></div>
|
<div class="nebula nebula-a"></div>
|
||||||
<div class="nebula nebula-b"></div>
|
<div class="nebula nebula-b"></div>
|
||||||
|
|
@ -1141,6 +1266,7 @@ body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; }
|
||||||
<!-- Synthwave sun — sits behind floor grid and horizon; becomes disco ball in balada mode -->
|
<!-- Synthwave sun — sits behind floor grid and horizon; becomes disco ball in balada mode -->
|
||||||
<div class="synthwave-sun">
|
<div class="synthwave-sun">
|
||||||
<div id="sunBaladaBg"></div>
|
<div id="sunBaladaBg"></div>
|
||||||
|
<div id="sunDiaBg"></div>
|
||||||
<div id="sunStripes"></div>
|
<div id="sunStripes"></div>
|
||||||
<div id="sunChuvaFace"></div>
|
<div id="sunChuvaFace"></div>
|
||||||
<div class="sun-rays-wrap" id="sunRaysWrap"></div>
|
<div class="sun-rays-wrap" id="sunRaysWrap"></div>
|
||||||
|
|
@ -1169,6 +1295,15 @@ body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; }
|
||||||
</div>
|
</div>
|
||||||
</div><!-- .robot-wrap -->
|
</div><!-- .robot-wrap -->
|
||||||
|
|
||||||
|
<!-- Caixão do esqueleto (modo dia) -->
|
||||||
|
<div class="coffin-wrap">
|
||||||
|
<div class="coffin-shade"></div>
|
||||||
|
<div class="coffin">
|
||||||
|
<div class="coffin-cross-v"></div>
|
||||||
|
<div class="coffin-cross-h"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- VU Meter -->
|
<!-- VU Meter -->
|
||||||
<div class="vu-meter" id="vuMeter"></div>
|
<div class="vu-meter" id="vuMeter"></div>
|
||||||
|
|
||||||
|
|
@ -1705,6 +1840,25 @@ function buildMoonPhaseTexture(phase) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Modo dia: a altitude real do Sol comanda o sol do desktop.
|
||||||
|
Nasce -> sobe até ~78% da tela na culminação -> desce no pôr; à noite
|
||||||
|
fica pousado no horizonte (41.5%), como sempre foi. O timelapse
|
||||||
|
acelera o ciclo junto, já que tudo deriva de skyNowMs(). ── */
|
||||||
|
let sunNoonAlt = 60, sunNoonKey = -1;
|
||||||
|
function updateDayMode(date, observer, sunAlt) {
|
||||||
|
const dayKey = Math.floor(date.getTime() / 86400000);
|
||||||
|
if (dayKey !== sunNoonKey) {
|
||||||
|
const transit = Astronomy.SearchHourAngle(Astronomy.Body.Sun, observer, 0, date);
|
||||||
|
sunNoonAlt = Math.max(5, transit.hor.altitude);
|
||||||
|
sunNoonKey = dayKey;
|
||||||
|
}
|
||||||
|
const climb = Math.max(0, Math.min(1, sunAlt / sunNoonAlt));
|
||||||
|
document.documentElement.style.setProperty(
|
||||||
|
'--sun-bottom', (41.5 + 36.5 * climb).toFixed(2) + '%');
|
||||||
|
/* -3°: meio do crepúsculo civil — troca com as transições longas do CSS */
|
||||||
|
document.body.classList.toggle('dia', sunAlt > -3);
|
||||||
|
}
|
||||||
|
|
||||||
function updateSolarSystem(date, lst, W, H, horizonPx) {
|
function updateSolarSystem(date, lst, W, H, horizonPx) {
|
||||||
if (typeof Astronomy === 'undefined') return;
|
if (typeof Astronomy === 'undefined') return;
|
||||||
try {
|
try {
|
||||||
|
|
@ -1717,6 +1871,7 @@ function updateSolarSystem(date, lst, W, H, horizonPx) {
|
||||||
};
|
};
|
||||||
const moonCoords = bodyCoordinates(Astronomy.Body.Moon, false);
|
const moonCoords = bodyCoordinates(Astronomy.Body.Moon, false);
|
||||||
const sunCoords = bodyCoordinates(Astronomy.Body.Sun, false);
|
const sunCoords = bodyCoordinates(Astronomy.Body.Sun, false);
|
||||||
|
updateDayMode(date, observer, sunCoords.aa.alt);
|
||||||
const moonScreen = moonCoords.sc
|
const moonScreen = moonCoords.sc
|
||||||
? { ...moonCoords.sc, alt: moonCoords.aa.alt, az: moonCoords.aa.az }
|
? { ...moonCoords.sc, alt: moonCoords.aa.alt, az: moonCoords.aa.az }
|
||||||
: null;
|
: null;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue