From a00b777d2b939d057a4ed43786c6c0072c2552d9 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 12 Jul 2026 00:56:00 -0500 Subject: feat(gallery): add R22 three-position slide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A detented slide switch after a drum machine's variation control (reference filed in the catalogue's working directory): a chrome pill parks at A, AB, or B, the active legend lights, and the LED pair below reports honestly — A or B lights its own dot, AB lights both. Clicking a position moves the pill with a short settle. The kit had toggles, segmented buttons, and continuous sliders, but no detented multi-position slide. I verified all three positions in headless Chrome: the pill parks, legends relight, and the LED count matches the position (2 for AB, 1 otherwise), no console exceptions. --- docs/prototypes/panel-widget-gallery.html | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'docs/prototypes/panel-widget-gallery.html') diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html index fa9d536..70b92d2 100644 --- a/docs/prototypes/panel-widget-gallery.html +++ b/docs/prototypes/panel-widget-gallery.html @@ -727,6 +727,9 @@ card(C,'R20','Drum roller selector', card(C,'R21','LED program row', ``, 'identical keys, one lit dot. The LED above the button carries the selection, not the key itself — the classic program-select row. Click a key; readout names the program. After a digital reverb’s program bank.'); +card(C,'R22','Three-position slide', + ``, + 'a detented pill, three stops. The chrome pill parks at A, AB, or B, and the LED pair below tells the truth — both light on AB. Click a position. After a drum machine variation switch.'); /* ============ METERS & GAUGES ============ */ const M=$('meters'); @@ -1791,6 +1794,33 @@ function setLedrow(i){ledrowI=i; setRd('R21',`${ledrowI+1} · ${LEDROW_PROGS[ledrowI]}`);} setLedrow(5); +/* R22 three-position slide: chrome pill, detents, honest LED pair */ +const VARSL_POS=['A','AB','B']; +let varslI=1,varslPill=null,varslLbls=[],varslLeds=[]; +(function(){const s=$('varslide');const detX=[34,55,76]; + svgEl(s,'text',{x:55,y:10,'text-anchor':'middle','font-size':5.5,'letter-spacing':'.16em', + 'font-family':'var(--mono)',fill:'var(--steel)'}).textContent='BASIC · VARIATION'; + svgEl(s,'rect',{x:20,y:16,width:70,height:14,rx:7,fill:'#0b0a09',stroke:'#000','stroke-width':1}); + svgEl(s,'rect',{x:21,y:17,width:68,height:5,rx:2.5,fill:'rgba(255,255,255,.04)'}); + varslPill=svgEl(s,'rect',{x:-13,y:18.5,width:26,height:9,rx:4.5,fill:'url(#sfChrome)',stroke:'#4e4a42','stroke-width':.6}); + varslPill.style.transition='transform .12s'; + VARSL_POS.forEach((lbl,i)=>{ + varslLbls.push(svgEl(s,'text',{x:detX[i],y:40,'text-anchor':'middle','font-size':6.5, + 'font-family':'var(--mono)',fill:'var(--dim)'})); + varslLbls[i].textContent=lbl;}); + svgEl(s,'rect',{x:32,y:45,width:46,height:11,rx:2,fill:'#141210',stroke:'#060505'}); + [44,66].forEach(x=>varslLeds.push(svgEl(s,'circle',{cx:x,cy:50.5,r:2.4,fill:'#3a0f0a'}))); + s.addEventListener('click',e=>{const r=s.getBoundingClientRect(); + const x=(e.clientX-r.left)/r.width*110; + setVarsl(x<45?0:x<66?1:2);});})(); +function setVarsl(i){varslI=i;const detX=[34,55,76]; + varslPill.setAttribute('transform',`translate(${detX[i]},0)`); + varslLbls.forEach((t,k)=>t.setAttribute('fill',k===i?'var(--gold-hi)':'var(--dim)')); + const lit=[i===0||i===1,i===2||i===1]; + varslLeds.forEach((l,k)=>l.setAttribute('fill',lit[k]?'var(--jewel-r)':'#3a0f0a')); + setRd('R22',VARSL_POS[i]);} +setVarsl(1); + /* ============ LIVE SIGNAL LOOPS ============ */ buildBars($('vuL'),16);buildBars($('vuR'),16);$('mini').innerHTML=''; (function(){const eq=$('eq');for(let b=0;b<11;b++){const band=document.createElement('span');band.className='band'; -- cgit v1.2.3