aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/prototypes/panel-widget-gallery.html41
1 files changed, 41 insertions, 0 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index be79a0a..252a368 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -715,6 +715,9 @@ card(C,'R15','Multi-band dial',
card(C,'R16','Entry keypad',
`<svg id="keypad" class="rsvg" viewBox="0 0 150 190" width="150" height="190"></svg>`,
'<b>a composed entry instrument.</b> Worn keycaps feed the amber display; the lamp watches the buffer; the amber keys confirm and clear. Click the keys. After an industrial keypad prop.');
+card(C,'R18','Thumb-slide attenuator pair',
+ `<svg id="thumbsl" class="rsvg" viewBox="0 0 130 150" width="130" height="150"></svg>`,
+ '<b>a lit column of numbers, a thumb tab.</b> The scale glows inside the rail; the cream tab rides beside it and the nearest figure lights. Drag either channel. After a compressor blend/mix pair.');
/* ============ METERS & GAUGES ============ */
const M=$('meters');
@@ -1631,6 +1634,44 @@ function tickRcrt(){rcrtPh+=0.12;const amp=8+3*Math.sin(rcrtPh*0.35);let pts='';
tickRcrt();
if(!matchMedia('(prefers-reduced-motion: reduce)').matches)setInterval(tickRcrt,80);
+/* R18 thumb-slide attenuator pair: lit numeral strip, side thumb tab */
+const THSL=[{name:'BLEND',v:74},{name:'MIX',v:92}];
+const thslParts=[];
+(function(){const s=$('thumbsl'),y0=22,y1=122;
+ const defs=svgEl(s,'defs',{});
+ const rg=svgEl(defs,'linearGradient',{id:'thRail',x1:0,y1:0,x2:1,y2:0});
+ svgEl(rg,'stop',{offset:'0','stop-color':'#3a3733'});
+ svgEl(rg,'stop',{offset:'.5','stop-color':'#211f1c'});
+ svgEl(rg,'stop',{offset:'1','stop-color':'#161412'});
+ const tg=svgEl(defs,'linearGradient',{id:'thTab',x1:0,y1:0,x2:0,y2:1});
+ svgEl(tg,'stop',{offset:'0','stop-color':'#f2efe6'});
+ svgEl(tg,'stop',{offset:'1','stop-color':'#c6c1b3'});
+ THSL.forEach((ch,i)=>{const x=40+i*50;
+ svgEl(s,'rect',{x:x-9,y:y0-10,width:18,height:y1-y0+20,rx:3,fill:'url(#thRail)',stroke:'#0a0908','stroke-width':1.2});
+ for(const sy of [y0-6,y1+6]){svgEl(s,'circle',{cx:x,cy:sy,r:2.4,fill:'url(#sfScrew)',stroke:'#0a0908','stroke-width':.5});
+ svgEl(s,'line',{x1:x-1.8,y1:sy-1,x2:x+1.8,y2:sy+1,stroke:'#14110e','stroke-width':.8});}
+ svgEl(s,'rect',{x:x-5,y:y0,width:10,height:y1-y0,fill:'#0d0a08',stroke:'#050404'});
+ for(let n=0;n<=10;n++){const val=100-n*10,y=y0+6+n*(y1-y0-12)/10;
+ svgEl(s,'text',{x,y:y+2,'text-anchor':'middle','font-size':5.5,'font-family':'var(--mono)',
+ fill:'var(--gold)',opacity:.55}).textContent=val;}
+ const tab=svgEl(s,'g',{});
+ svgEl(tab,'rect',{x:x+7,y:-6,width:8,height:12,rx:2,fill:'url(#thTab)',stroke:'#7a766a','stroke-width':.6});
+ svgEl(tab,'rect',{x:x+8.2,y:-1,width:5.6,height:1.6,fill:'rgba(0,0,0,.25)'});
+ svgEl(s,'text',{x,y:145,'text-anchor':'middle','font-size':6,'letter-spacing':'.14em',
+ 'font-family':'var(--mono)',fill:'var(--steel)'}).textContent=ch.name;
+ const hit=svgEl(s,'rect',{x:x-12,y:y0-10,width:30,height:y1-y0+20,fill:'transparent'});
+ hit.style.cursor='ns-resize';
+ thslParts.push({tab,nums:[...s.querySelectorAll('text')].filter(t=>t.getAttribute('x')==String(x)&&t.textContent!==ch.name)});
+ dragY(hit,pct=>setThsl(i,pct));});
+ })();
+function setThsl(i,v){v=Math.max(0,Math.min(100,Math.round(v)));THSL[i].v=v;
+ const p=thslParts[i];
+ p.tab.setAttribute('transform',`translate(0,${28+(100-v)*0.88})`);
+ p.nums.forEach(t=>{const on=Math.abs(parseInt(t.textContent)-v)<=5;
+ t.setAttribute('fill',on?'var(--gold-hi)':'var(--gold)');t.setAttribute('opacity',on?'1':'.55');});
+ setRd('R18',`${THSL[0].name} ${THSL[0].v} ยท ${THSL[1].name} ${THSL[1].v}`);}
+setThsl(0,74);setThsl(1,92);
+
/* ============ 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';