Grayish day sky, stronger fog clouds, sky clock jump control

Day sky desaturates to warm gray tones (matching the currently playing
album's cover), clouds get denser and larger so they actually read on
screen. New set-sky-time.sh + /tmp/skeledance-sky-offset poller jumps
the simulated sky clock to any time of today, composing with the
timelapse for previews.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015HtPHsTnDcLVSCiF5FGHZj
This commit is contained in:
vini 2026-07-19 21:42:12 -03:00
parent 13f71289a6
commit 2ceb5df442
3 changed files with 50 additions and 12 deletions

View file

@ -66,7 +66,7 @@ Pure HTML/CSS/JS, no external dependencies. All visuals are self-contained:
| Music ticker / album art / karaoke lyrics | DOM text set by `updateMusic(artist, title)` (called from QML); lyrics left, album art right, ticker centered — all with dark veils/shadows for contrast over the Milky Way |
| Dance style cycling | `data-dance` attribute on `<body>`, toggled by JS every 8 s |
**Runtime controls** (state files in `/tmp/skeledance-*`, polled every 800 ms by dancer.html; each has a root-level helper script): `toggle-balada.sh`, `toggle-chuva.sh` (mutually exclusive modes), `toggle-constellations.sh`, `preview-constellation.sh <Vir|off>`, `set-camera-position.sh <norte|leste|sul|oeste|graus>`, `toggle-camera-rotation.sh` (360° pan in 5 min), `toggle-sky-timelapse.sh` (360× time). `test-modes.sh` reloads the plugin and cycles modes.
**Runtime controls** (state files in `/tmp/skeledance-*`, polled every 800 ms by dancer.html; each has a root-level helper script): `toggle-balada.sh`, `toggle-chuva.sh` (mutually exclusive modes), `toggle-constellations.sh`, `preview-constellation.sh <Vir|off>`, `set-camera-position.sh <norte|leste|sul|oeste|graus>`, `toggle-camera-rotation.sh` (360° pan in 5 min), `toggle-sky-timelapse.sh` (360× time), `set-sky-time.sh <HH:MM|off>` (jump the sky clock to a time of day; combines with the timelapse). `test-modes.sh` reloads the plugin and cycles modes.
**Tempo anchor**: everything is keyed to 120 BPM (`BEAT_MS = 500 ms`). CSS animation durations for the robot parts use multiples/fractions of 0.5 s, 1 s, or 2 s.

View file

@ -1141,11 +1141,11 @@ body.chuva #sunChuvaFace { opacity: 1; transition: opacity 5s ease; }
opacity: 0;
transition: opacity 12s ease;
background: linear-gradient(to bottom,
#7d4f94 0%,
#b0619f 26%,
#d183b3 44%,
#e3a3b8 60%,
#edc19e 66%,
#676074 0%,
#837a88 26%,
#a3939f 44%,
#bfaeb0 60%,
#d3c0ab 66%,
#5a7d4a 66.1%,
#3e5c35 82%,
#2a4126 100%);
@ -1165,17 +1165,17 @@ body.dia:not(.balada):not(.chuva) #meteorLayer { opacity: 0; }
pointer-events: none;
opacity: 0;
transition: opacity 12s ease;
filter: blur(42px);
filter: blur(26px);
background: radial-gradient(ellipse,
rgba(238,205,228,0.60) 0%, rgba(216,168,205,0.30) 55%, transparent 75%);
rgba(232,226,232,0.95) 0%, rgba(198,186,200,0.55) 55%, transparent 78%);
will-change: transform, opacity;
}
.cloud-a { width: 46vh; height: 11vh; top: 10%; left: 8%;
.cloud-a { width: 62vh; height: 14vh; top: 10%; left: 8%;
animation: dayCloudDrift1 26s ease-in-out infinite alternate; }
.cloud-b { width: 38vh; height: 9vh; top: 22%; right: 10%;
.cloud-b { width: 52vh; height: 12vh; top: 22%; right: 8%;
animation: dayCloudDrift2 34s ease-in-out infinite alternate;
animation-delay: -12s; }
.cloud-c { width: 30vh; height: 7vh; top: 36%; left: 32%;
.cloud-c { width: 42vh; height: 9vh; top: 36%; left: 30%;
animation: dayCloudDrift3 22s ease-in-out infinite alternate;
animation-delay: -7s; }
@keyframes dayCloudDrift1 {
@ -1190,7 +1190,7 @@ body.dia:not(.balada):not(.chuva) #meteorLayer { opacity: 0; }
from { transform: translateX(-1.5vw) scaleX(1.05); }
to { transform: translateX(2vw) scaleX(0.90); }
}
body.dia:not(.balada):not(.chuva) .day-cloud { opacity: 0.8; }
body.dia:not(.balada):not(.chuva) .day-cloud { opacity: 1; }
/* O sol vira sol de verdade: disco quente, sem listras retrô */
#sunDiaBg {
@ -2260,6 +2260,26 @@ let skyTimeScaleFileVal = null;
.finally(() => setTimeout(pollSkyTimeScaleFile, 800));
})();
/* Deslocamento do relógio do céu em horas, controlado por set-sky-time.sh
(pula p/ um horário de hoje; combina com o timelapse). */
let skyOffsetFileVal = null;
(function pollSkyOffsetFile() {
fetch('file:///tmp/skeledance-sky-offset?t=' + Date.now())
.then(r => r.text())
.then(t => {
const v = t.trim();
if (v === skyOffsetFileVal) return;
skyOffsetFileVal = v;
const hours = Number(v);
if (!Number.isFinite(hours)) return;
window.__skyTimeOffset = hours * 3600 * 1000;
lastProjMs = -Infinity;
projectSky();
})
.catch(() => {})
.finally(() => setTimeout(pollSkyOffsetFile, 800));
})();
/* Posição fixa controlada por set-camera-position.sh. */
let cameraAzimuthFileVal = null;
(function pollCameraAzimuthFile() {

18
set-sky-time.sh Executable file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Pula o relógio do céu para hoje às HH:MM (ex.: ./set-sky-time.sh 06:15).
# "off" (ou sem argumento) volta ao tempo real. Combina com o timelapse.
STATE_FILE=/tmp/skeledance-sky-offset
TARGET=${1:-off}
if [ "$TARGET" = "off" ]; then
printf '0\n' > "$STATE_FILE"
printf 'Relógio do céu em tempo real\n'
exit 0
fi
target_epoch=$(date -d "today $TARGET" +%s) || exit 2
now_epoch=$(date +%s)
offset_h=$(awk "BEGIN { printf \"%.4f\", ($target_epoch - $now_epoch) / 3600 }")
printf '%s\n' "$offset_h" > "$STATE_FILE"
printf 'Relógio do céu em %s de hoje (offset %sh)\n' "$TARGET" "$offset_h"