diff --git a/CLAUDE.md b/CLAUDE.md index e73a9a8..fafe055 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -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 ``, 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 `, `set-camera-position.sh `, `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 `, `set-camera-position.sh `, `toggle-camera-rotation.sh` (360° pan in 5 min), `toggle-sky-timelapse.sh` (360× time), `set-sky-time.sh ` (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. diff --git a/plugin/contents/ui/dancer.html b/plugin/contents/ui/dancer.html index 558322c..d37dff4 100644 --- a/plugin/contents/ui/dancer.html +++ b/plugin/contents/ui/dancer.html @@ -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() { diff --git a/set-sky-time.sh b/set-sky-time.sh new file mode 100755 index 0000000..f7f8c0a --- /dev/null +++ b/set-sky-time.sh @@ -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"