Replace CSS robot with animated character switcher
Swaps DANCEBOT-9000 CSS robot for a pool of APNG characters that cycle randomly every 8s and on track change: 4 skeleton GIFs, a dancing baby (YouTube clip), and Pepe. Background removal done with ffmpeg colorkey. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5378772d8a
commit
9fbfb0592d
7 changed files with 30 additions and 79 deletions
|
|
@ -208,11 +208,15 @@ html, body {
|
|||
.robot-wrap {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 40%;
|
||||
bottom: 32%;
|
||||
transform: translateX(-50%);
|
||||
filter:
|
||||
drop-shadow(0 0 35px rgba(0,200,255,0.25))
|
||||
drop-shadow(0 20px 15px rgba(0,0,80,0.6));
|
||||
}
|
||||
|
||||
.skeleton-gif {
|
||||
display: block;
|
||||
height: 40vh;
|
||||
width: auto;
|
||||
filter: drop-shadow(0 0 20px rgba(0,200,255,0.4));
|
||||
}
|
||||
|
||||
/* Entire robot bounces on the beat (0.5s = 1 beat at 120 BPM) */
|
||||
|
|
@ -694,81 +698,7 @@ html, body {
|
|||
|
||||
<!-- ===================== ROBOT ===================== -->
|
||||
<div class="robot-wrap">
|
||||
<div class="robot">
|
||||
|
||||
<!-- Antenna -->
|
||||
<div class="antenna-wrap">
|
||||
<div class="antenna-stick">
|
||||
<div class="antenna-ball"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Head -->
|
||||
<div class="head">
|
||||
<div class="eyes">
|
||||
<div class="eye"></div>
|
||||
<div class="eye"></div>
|
||||
</div>
|
||||
<div class="mouth-panel">
|
||||
<div class="mouth-seg"></div>
|
||||
<div class="mouth-seg"></div>
|
||||
<div class="mouth-seg"></div>
|
||||
<div class="mouth-seg"></div>
|
||||
<div class="mouth-seg"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Neck -->
|
||||
<div class="neck"></div>
|
||||
|
||||
<!-- Middle row: left arm, torso, right arm -->
|
||||
<div class="middle">
|
||||
<div class="shoulder"></div>
|
||||
<div class="arm left">
|
||||
<div class="hand"></div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;flex-direction:column;align-items:center;">
|
||||
<div class="torso">
|
||||
<div class="chest-screen" id="chestScreen">
|
||||
<div class="eq-row" id="eqTop"></div>
|
||||
<div class="chest-logo">♪ ♫ ♪</div>
|
||||
<div class="eq-row" id="eqBot"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hip">
|
||||
<div class="rivet"></div>
|
||||
<div class="rivet"></div>
|
||||
<div class="rivet"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="arm right">
|
||||
<div class="hand"></div>
|
||||
</div>
|
||||
<div class="shoulder"></div>
|
||||
</div>
|
||||
|
||||
<!-- Legs -->
|
||||
<div class="legs">
|
||||
<div class="leg-grp">
|
||||
<div class="upper-leg left"></div>
|
||||
<div class="knee"></div>
|
||||
<div class="lower-leg left">
|
||||
<div class="foot"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="leg-grp">
|
||||
<div class="upper-leg right"></div>
|
||||
<div class="knee"></div>
|
||||
<div class="lower-leg right">
|
||||
<div class="foot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div><!-- .robot -->
|
||||
|
||||
<img src="skeleton6.apng" class="skeleton-gif" alt="skeleton">
|
||||
<div class="robot-shadow"></div>
|
||||
</div><!-- .robot-wrap -->
|
||||
|
||||
|
|
@ -1038,6 +968,7 @@ function updateMusic(artist, title) {
|
|||
: (title || artist || '— —');
|
||||
if (el.textContent === text) return;
|
||||
el.textContent = text;
|
||||
pickSkeleton();
|
||||
// scroll only if text is long
|
||||
const wrap = el.parentElement;
|
||||
el.classList.toggle('short', el.scrollWidth <= wrap.clientWidth + 10);
|
||||
|
|
@ -1061,6 +992,26 @@ function nextDanceStyle() {
|
|||
document.body.setAttribute('data-dance', 'bounce');
|
||||
setInterval(nextDanceStyle, 8000);
|
||||
|
||||
/* ============================================================
|
||||
SKELETON SWITCHER
|
||||
Add new files to SKELETONS to include them in the rotation.
|
||||
Switches on music change and randomly every 16 beats (8s).
|
||||
============================================================ */
|
||||
const SKELETONS = ['skeleton.apng', 'skeleton2.apng', 'skeleton3.apng', 'skeleton4.apng', 'skeleton5.apng', 'skeleton6.apng'];
|
||||
const skeletonImg = document.querySelector('.skeleton-gif');
|
||||
let currentSkel = 5;
|
||||
|
||||
function pickSkeleton() {
|
||||
if (SKELETONS.length < 2) return;
|
||||
let next;
|
||||
do { next = Math.floor(Math.random() * SKELETONS.length); }
|
||||
while (next === currentSkel);
|
||||
currentSkel = next;
|
||||
skeletonImg.src = SKELETONS[currentSkel];
|
||||
}
|
||||
|
||||
setInterval(pickSkeleton, 8000);
|
||||
|
||||
/* ============================================================
|
||||
DEV SHIM — only active when served via HTTP (not from QML)
|
||||
Simulates playerctl updates so the music ticker works in-browser.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue