aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/panel-widget-gallery.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-12 00:50:20 -0500
committerCraig Jennings <c@cjennings.net>2026-07-12 00:50:20 -0500
commit96f3b0c071d267c266b2ad2315a97568b50cc046 (patch)
tree7c5d1df67c180ed6ab08f4fa3eb5628337fbf751 /docs/prototypes/panel-widget-gallery.html
parentfe6df41b287bc45a8f65853bf59f6f9297978d9a (diff)
downloadarchsetup-96f3b0c071d267c266b2ad2315a97568b50cc046.tar.gz
archsetup-96f3b0c071d267c266b2ad2315a97568b50cc046.zip
feat(gallery): add R20 drum roller selector
An equalizer-style tone selector pair as inline SVG (reference filed in the catalogue's working directory): each numbered drum shows through a tall window with curvature shading, and the center value sits on an inverted chip. The drums drag independently with a short roll transition. This differs from the thumbwheel, which shows one number in a separate window. Here the visible number strip is itself the control face, like the source hardware. I verified both drums in headless Chrome: independent drags roll the strips and update the chips, no console exceptions.
Diffstat (limited to 'docs/prototypes/panel-widget-gallery.html')
-rw-r--r--docs/prototypes/panel-widget-gallery.html49
1 files changed, 49 insertions, 0 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index 30478bc..6e22c05 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -721,6 +721,9 @@ card(C,'R18','Thumb-slide attenuator pair',
card(C,'R19','Waveform region editor',
`<svg id="wregion" class="rsvg" viewBox="0 0 190 100" width="190" height="100"></svg>`,
'<b>pick a region on the wave.</b> The monochrome LCD shows the sample; drag near either flag to move START or END, and the selection draws bright. After a sampler edit screen.');
+card(C,'R20','Drum roller selector',
+ `<svg id="drumr" class="rsvg" viewBox="0 0 130 140" width="130" height="140"></svg>`,
+ '<b>roll to the number.</b> The numbered drum shows through a tall window and the center value sits on an inverted chip. Drag either drum. After an equalizer tone selector.');
/* ============ METERS & GAUGES ============ */
const M=$('meters');
@@ -1713,6 +1716,52 @@ function setWregion(sv,ev){wrS=Math.max(0,Math.min(96,sv));wrE=Math.max(4,Math.m
setRd('R19',`S ${Math.round(wrS)}% · E ${Math.round(wrE)}%`);}
setWregion(22,76);
+/* R20 drum roller selector: numbered drum in a window, center chip reads it */
+const DRUMR=[{name:'HIGH',v:6},{name:'LOW',v:8}];
+const drumrGrps=[];
+(function(){const s=$('drumr'),cy=76,step=17;
+ const defs=svgEl(s,'defs',{});
+ const paper=svgEl(defs,'linearGradient',{id:'drPaper',x1:0,y1:0,x2:1,y2:0});
+ svgEl(paper,'stop',{offset:'0','stop-color':'#cfc6a8'});
+ svgEl(paper,'stop',{offset:'.5','stop-color':'#ece4c8'});
+ svgEl(paper,'stop',{offset:'1','stop-color':'#c6bd9e'});
+ const curve=svgEl(defs,'linearGradient',{id:'drCurve',x1:0,y1:0,x2:0,y2:1});
+ svgEl(curve,'stop',{offset:'0','stop-color':'rgba(0,0,0,.4)'});
+ svgEl(curve,'stop',{offset:'.28','stop-color':'rgba(0,0,0,0)'});
+ svgEl(curve,'stop',{offset:'.72','stop-color':'rgba(0,0,0,0)'});
+ svgEl(curve,'stop',{offset:'1','stop-color':'rgba(0,0,0,.4)'});
+ svgEl(s,'text',{x:65,y:12,'text-anchor':'middle','font-size':7,'letter-spacing':'.18em',
+ 'font-family':'var(--mono)',fill:'var(--steel)'}).textContent='EQUALIZER';
+ DRUMR.forEach((ch,i)=>{const x=45+i*50;
+ svgEl(s,'text',{x:x+18,y:34,'text-anchor':'middle','font-size':8,fill:'var(--steel)'}).textContent='+';
+ svgEl(s,'text',{x:x+18,y:124,'text-anchor':'middle','font-size':8,fill:'var(--steel)'}).textContent='−';
+ svgEl(s,'rect',{x:x-12,y:24,width:24,height:104,rx:4,fill:'url(#thRail)',stroke:'#0a0908','stroke-width':1.2});
+ const clip=svgEl(defs,'clipPath',{id:'drClip'+i});
+ svgEl(clip,'rect',{x:x-9,y:28,width:18,height:96});
+ svgEl(s,'rect',{x:x-9,y:28,width:18,height:96,fill:'url(#drPaper)'});
+ const g=svgEl(s,'g',{'clip-path':`url(#drClip${i})`});
+ const nums=svgEl(g,'g',{});nums.style.transition='transform .12s';
+ for(let n=1;n<=10;n++)
+ svgEl(nums,'text',{x,y:cy+3+(ch.v-n)*step,'text-anchor':'middle','font-size':9,'font-weight':700,
+ 'font-family':'var(--mono)',fill:'#2b2418'}).textContent=n;
+ svgEl(g,'rect',{x:x-9,y:28,width:18,height:96,fill:'url(#drCurve)','pointer-events':'none'});
+ svgEl(s,'rect',{x:x-8,y:cy-6.5,width:16,height:13,rx:1.5,fill:'#1a1613',opacity:.92});
+ const chip=svgEl(s,'text',{x,y:cy+3,'text-anchor':'middle','font-size':9,'font-weight':700,
+ 'font-family':'var(--mono)',fill:'var(--cream)'});
+ svgEl(s,'text',{x,y:136,'text-anchor':'middle','font-size':6,'letter-spacing':'.12em',
+ 'font-family':'var(--mono)',fill:'var(--steel)'}).textContent=ch.name;
+ const hit=svgEl(s,'rect',{x:x-14,y:24,width:28,height:104,fill:'transparent'});
+ hit.style.cursor='ns-resize';
+ drumrGrps.push({nums,chip,base:ch.v});
+ dragDelta(hit,()=>DRUMR[i].v,v=>setDrumr(i,v),{min:1,max:10,sens:.08});});
+ })();
+function setDrumr(i,v){v=Math.max(1,Math.min(10,v));DRUMR[i].v=v;
+ const p=drumrGrps[i];
+ p.nums.style.transform=`translateY(${(v-p.base)*17}px)`;
+ p.chip.textContent=Math.round(v);
+ setRd('R20',`${DRUMR[0].name} ${Math.round(DRUMR[0].v)} · ${DRUMR[1].name} ${Math.round(DRUMR[1].v)}`);}
+setDrumr(0,6);setDrumr(1,8);
+
/* ============ LIVE SIGNAL LOOPS ============ */
buildBars($('vuL'),16);buildBars($('vuR'),16);$('mini').innerHTML='<i></i><i></i><i></i><i></i>';
(function(){const eq=$('eq');for(let b=0;b<11;b++){const band=document.createElement('span');band.className='band';