← back to Scarlet Riverboat Masquerade
Replace emoji motifs with original DRAWN animated song-items: flickering flames, spinning flowers, twinkling stars, rotating snowflakes, water drops, spinning wheels, flapping birds, + musical notes default — keyed to the current track title, floating up through the scene
546a5e7ce467506f816c3b9560f210ce75831858 · 2026-09-01 22:30:12 -0700 · Steve Abrams
Files touched
Diff
commit 546a5e7ce467506f816c3b9560f210ce75831858
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Sep 1 22:30:12 2026 -0700
Replace emoji motifs with original DRAWN animated song-items: flickering flames, spinning flowers, twinkling stars, rotating snowflakes, water drops, spinning wheels, flapping birds, + musical notes default — keyed to the current track title, floating up through the scene
---
index.html | 89 ++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 55 insertions(+), 34 deletions(-)
diff --git a/index.html b/index.html
index b9dda3c..986ee3e 100644
--- a/index.html
+++ b/index.html
@@ -422,52 +422,73 @@ const VENUES=[
];
let venueOn=true;
-// ---- Song-motif layer: floats items drawn from the current track's title ----
-const MOTIFS=[
- [/fire|flame|mountain|burn/, ['🔥','⛰️','✨']],
- [/sugar|magnolia|sugaree|begonia|rose|flower|daffodil|lily|garden/, ['🌺','🌸','🌼']],
- [/rain|snow|cold|storm|hail|winter/, ['❄️','🌧️','☁️']],
- [/sun|sunshine|sunflower|shine|summer/,['🌞','🌻','☀️']],
- [/moon|dark star|midnight|star/, ['🌙','⭐','✨']],
- [/water|river|ripple|ocean|wave|sea|rowing/, ['💧','🌊']],
- [/bird|eagle|dove|sparrow|crow/, ['🐦','🕊️']],
- [/cat|china cat|tiger|lion/, ['🐱','🐾']],
- [/train|casey|railroad|jones|engine/, ['🚂','🛤️']],
- [/truck|road|highway|ramble|wheel|turnin/, ['🚚','🛣️','🎡']],
- [/devil|hell|deal|gambl|dice|card/, ['🃏','🎲']],
- [/eyes|world/, ['👁️','🌍']],
- [/wine|whiskey|beer|jug|drink/, ['🍷','🥃']],
- [/love|heart|sweet|darling|honey/, ['💗','💘']],
- [/gold|silver|diamond|jewel/, ['✨','💎']],
- [/rat|mouse|wharf/, ['🐀']],
- [/candy|man/, ['🍬']]
+// ---- Song-motif layer: original DRAWN animated items keyed to the current track title ----
+const MOTIF_MAP=[
+ [/fire|flame|mountain|burn/, 'flame'],
+ [/sugar|magnolia|sugaree|begonia|rose|flower|lily|garden|daffodil|scarlet/, 'flower'],
+ [/rain|snow|cold|storm|winter|hail/, 'snow'],
+ [/star|moon|dark star|midnight|shine|sunshine|sun/, 'star'],
+ [/water|river|ripple|ocean|wave|sea|row|creek/, 'water'],
+ [/wheel|turnin|truck|road|ramble|train|casey|railroad|jones/, 'wheel'],
+ [/bird|eagle|dove|sparrow|crow|wing/, 'bird']
];
-let motifParticles=[], motifClock=0, motifSet=null, motifKey=null;
-function currentMotifs(){
+let motifParticles=[], motifClock=0, motifType=null, motifKey=null;
+function currentMotifType(){
const tr=((window.SRM&&window.SRM.track)||'').toLowerCase();
- if(tr===motifKey) return motifSet;
- motifKey=tr; motifSet=null;
- for(const m of MOTIFS){ if(m[0].test(tr)){ motifSet=m[1]; break; } }
- return motifSet;
+ if(tr===motifKey) return motifType;
+ motifKey=tr; motifType='note'; // default: musical notes for every song
+ for(const m of MOTIF_MAP){ if(m[0].test(tr)){ motifType=m[1]; break; } }
+ return motifType;
+}
+function drawMotif(type,s,life,tt,col){
+ const al=Math.max(0,Math.min(0.9,life));
+ if(type==='flame'){
+ const f=Math.sin(tt*12+s)*0.18;
+ ctx.globalAlpha=al; ctx.fillStyle='#ff8a3a';
+ ctx.beginPath(); ctx.moveTo(0,s*0.6); ctx.quadraticCurveTo(-s*0.5,0,0,-s*0.75-f*s); ctx.quadraticCurveTo(s*0.5,0,0,s*0.6); ctx.fill();
+ ctx.fillStyle='#ffd24a'; ctx.beginPath(); ctx.moveTo(0,s*0.4); ctx.quadraticCurveTo(-s*0.25,0,0,-s*0.42-f*s); ctx.quadraticCurveTo(s*0.25,0,0,s*0.4); ctx.fill();
+ } else if(type==='flower'){
+ ctx.globalAlpha=al; ctx.rotate(tt*0.6+s); ctx.fillStyle=col||'#ff6aa0';
+ for(let i=0;i<5;i++){ ctx.rotate(Math.PI*2/5); ctx.beginPath(); ctx.ellipse(0,-s*0.5,s*0.28,s*0.5,0,0,7); ctx.fill(); }
+ ctx.fillStyle='#ffd24a'; ctx.beginPath(); ctx.arc(0,0,s*0.22,0,7); ctx.fill();
+ } else if(type==='snow'){
+ ctx.globalAlpha=al; ctx.strokeStyle='#dff0ff'; ctx.lineWidth=1.6; ctx.lineCap='round'; ctx.rotate(tt*0.8);
+ for(let i=0;i<6;i++){ ctx.rotate(Math.PI/3); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(0,-s*0.6); ctx.stroke(); }
+ } else if(type==='star'){
+ const tw=0.6+0.4*Math.sin(tt*6+s); ctx.globalAlpha=al*tw; ctx.fillStyle='#ffe89a';
+ ctx.beginPath(); for(let i=0;i<10;i++){ const a=i*Math.PI/5-Math.PI/2, r=(i%2?s*0.22:s*0.6); ctx.lineTo(Math.cos(a)*r,Math.sin(a)*r); } ctx.closePath(); ctx.fill();
+ } else if(type==='water'){
+ ctx.globalAlpha=al; ctx.fillStyle='#7ac0ff';
+ ctx.beginPath(); ctx.moveTo(0,-s*0.55); ctx.quadraticCurveTo(s*0.5,s*0.2,0,s*0.5); ctx.quadraticCurveTo(-s*0.5,s*0.2,0,-s*0.55); ctx.fill();
+ } else if(type==='wheel'){
+ ctx.globalAlpha=al; ctx.rotate(tt*3); ctx.strokeStyle='#f2b64a'; ctx.lineWidth=2;
+ ctx.beginPath(); ctx.arc(0,0,s*0.5,0,7); ctx.stroke();
+ for(let i=0;i<6;i++){ ctx.rotate(Math.PI/3); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(0,-s*0.5); ctx.stroke(); }
+ } else if(type==='bird'){
+ const flap=Math.sin(tt*8+s)*0.4; ctx.globalAlpha=al; ctx.strokeStyle='#241010'; ctx.lineWidth=2.2; ctx.lineCap='round';
+ ctx.beginPath(); ctx.moveTo(-s*0.5,0); ctx.quadraticCurveTo(-s*0.2,-s*0.45-flap*s,0,0); ctx.quadraticCurveTo(s*0.2,-s*0.45-flap*s,s*0.5,0); ctx.stroke();
+ } else { // musical note
+ ctx.globalAlpha=al; ctx.fillStyle=col||'#f2b64a';
+ ctx.beginPath(); ctx.ellipse(-s*0.18,s*0.35,s*0.28,s*0.2,-0.3,0,7); ctx.fill();
+ ctx.fillRect(s*0.06,-s*0.55,s*0.09,s*0.95);
+ ctx.beginPath(); ctx.moveTo(s*0.15,-s*0.55); ctx.quadraticCurveTo(s*0.5,-s*0.5,s*0.42,-s*0.18); ctx.lineTo(s*0.15,-s*0.28); ctx.closePath(); ctx.fill();
+ }
+ ctx.globalAlpha=1;
}
function drawSongMotifs(dt){
- const set=currentMotifs();
- if(set && S.playing && !S.reduced){
+ const type=currentMotifType();
+ if(type && S.playing && !S.reduced){
motifClock+=dt;
- if(motifClock>0.75 && motifParticles.length<40){ motifClock=0;
- motifParticles.push({x:S.W*(0.08+Math.random()*0.84), y:S.H*0.9, vy:-(18+Math.random()*26), drift:(Math.random()-0.5)*14, life:1, size:20+Math.random()*20, g:set[(Math.random()*set.length)|0]});
+ if(motifClock>0.55 && motifParticles.length<48){ motifClock=0;
+ motifParticles.push({x:S.W*(0.06+Math.random()*0.88), y:S.H*0.9, vy:-(18+Math.random()*26), drift:(Math.random()-0.5)*14, life:1, size:16+Math.random()*16, type, col:pal('accent',0)});
}
}
if(!motifParticles.length) return;
- ctx.save(); ctx.textAlign='center'; ctx.textBaseline='middle';
for(let i=motifParticles.length-1;i>=0;i--){ const p=motifParticles[i];
p.y+=p.vy*dt; p.x+=p.drift*dt; p.life-=dt*0.16;
if(p.life<=0 || p.y<S.H*0.14){ motifParticles.splice(i,1); continue; }
- ctx.globalAlpha=Math.max(0,Math.min(0.9,p.life));
- ctx.font=`${p.size}px "Apple Color Emoji","Segoe UI Emoji",serif`;
- ctx.fillText(p.g, p.x, p.y);
+ ctx.save(); ctx.translate(p.x,p.y); drawMotif(p.type,p.size,p.life,S.t,p.col); ctx.restore();
}
- ctx.restore(); ctx.globalAlpha=1;
}
function drawVenue(){
← c67e4f5 Concert venue backdrops (per-show stage-light beams + venue
·
back to Scarlet Riverboat Masquerade
·
Riverboat room: searchable full Grateful Dead archive — type 88dc7e0 →