skeledance/CLAUDE.md
vini 2ceb5df442 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
2026-07-19 21:42:12 -03:00

5.3 KiB
Raw Blame History

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

A KDE Plasma 6 wallpaper plugin — a dancing retrowave robot (DANCEBOT-9000) that reacts to currently playing music via playerctl. No build step, no dependencies to install; the plugin is deployed directly.

Plugin ID: com.vini.dancingcharacter
Install path: ~/.local/share/plasma/wallpapers/com.vini.dancingcharacter

Deploy / test cycle

# Install (or reinstall after edits)
./install.sh

# Remove
./uninstall.sh

After install, activate via: Right-click desktop → Configure Desktop and Wallpaper → Wallpaper Type → Dancing Character.

Plasma hot-reloads QML changes when you reinstall; for HTML/CSS/JS changes you may need to switch away and back to the wallpaper type to force a reload.

Runtime requirement: QtWebEngine QML module must be installed (e.g., qml6-module-qtwebengine on Debian/Ubuntu). playerctl must be running for the music ticker to show track info.

Architecture

plugin/
  metadata.json               # KPackage/KPlugin descriptor for Plasma 6
  contents/ui/
    main.qml                  # Plasma WallpaperItem — hosts everything
    dancer.html               # Self-contained animation (HTML + CSS + JS)
    starcatalog.js            # Generated star data (Yale BSC) — see tools/build_catalog.py
    constellations.js         # Generated zodiac lines — see tools/build_constellations.py
    milkyway.jpg              # Gaia all-sky photo, plate carrée — see tools/build_skymap.py
    astronomy.browser.min.js  # Astronomy Engine (MIT) — Moon/planet ephemerides
tools/
  build_catalog.py            # Regenerates starcatalog.js from the Yale Bright Star Catalog
  build_constellations.py     # Regenerates constellations.js (Stellarium Modern + d3-celestial)
  build_skymap.py             # Reprojects ESA Gaia all-sky map (Hammer → plate carrée)

main.qml — the Plasma host

  • Declares a WallpaperItem with a full-screen WebEngineView pointed at dancer.html.
  • A Plasma5Support.DataSource with engine: "executable" runs playerctl metadata every 2 s and injects the result into the page with webView.runJavaScript("updateMusic(...)").
  • JavaScript is enabled; local file access and local storage are on/off respectively.

dancer.html — the visual layer

Pure HTML/CSS/JS, no external dependencies. All visuals are self-contained:

Layer Technique
Realistic sky (stars) <canvas>; real-time alt-az projection of starcatalog.js (8,404 Yale BSC stars, V ≤ 6.5) for the configured lat/long (default Toledo-PR). Static layer pre-rendered offscreen with triple-buffer + 1.4 s crossfade between reprojections (every 30 s; 4 s during timelapse/camera rotation); bright stars twinkle per frame. Debug: window.__skyTimeOffset (ms) fast-forwards the sky
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)
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: pink vaporwave #daySky with green grass below the horizon, drifting CSS clouds, bright sun disc, golden horizon, stars dimmed to ghosts (0.12), dancer replaced by a grounded gravestone (flattened-ellipse mound/shadow for perspective, no religious symbols). Balada/chuva override day visuals via :not() selectors
Nebula blobs, grid floor, horizon CSS animations
DANCEBOT-9000 robot Pure CSS (divs + @keyframes)
Chest EQ bars & VU meter JS-driven requestAnimationFrame
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), 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.

Dance styles (cycle order): bounce → wave → shuffle → moonwalk → spin. CSS selectors like [data-dance="spin"] .robot { ... } override the default animations via !important.