aboutsummaryrefslogtreecommitdiff
path: root/docs/prototypes/panel-widget-gallery.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-12 22:09:26 -0500
committerCraig Jennings <c@cjennings.net>2026-07-12 22:09:26 -0500
commitf210e7fce4df8daf69d87f7c8c7d83d4f13673c4 (patch)
tree9f6c84b05a26991cdd265266d173cdfb34ad8e90 /docs/prototypes/panel-widget-gallery.html
parentcace2002494222dcbecf6706ebb29c8d43228edf (diff)
downloadarchsetup-f210e7fce4df8daf69d87f7c8c7d83d4f13673c4.tar.gz
archsetup-f210e7fce4df8daf69d87f7c8c7d83d4f13673c4.zip
refactor(gallery): extract meters N11-N18 into GW builders
Scope, EQ bars, and strip chart take value-driven handles (set samples / push); the eqBands oscillator and the demo signal stay page-side. The N11 screen-family chips now reach the scope through the card handle instead of the retired scopep id.
Diffstat (limited to 'docs/prototypes/panel-widget-gallery.html')
-rw-r--r--docs/prototypes/panel-widget-gallery.html75
1 files changed, 21 insertions, 54 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index beb735b..7862c5e 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -1739,34 +1739,28 @@ card(M,'17','Waveform strip',
(st,rd)=>GW.waveStrip(st,{onChange:(v,t)=>rd(t)}),
'<b>audio waveform / scope.</b> A richer signal view. Live trace; readout shows amplitude. <b>Needs a drawing surface.</b>');
card(M,'N11','Oscilloscope',
- `<span class="scope"><span class="grat"></span><svg viewBox="0 0 176 78" preserveAspectRatio="none"><polyline id="scopep"/></svg></span>`,
+ (st,rd)=>GW.scope(st,{onChange:(v,t)=>rd(t)}),
'<b>a live phosphor trace.</b> A waveform swept over a graticule. Live; readout shows Vpp. <b>Needs a Cairo/GTK area for a smooth trace.</b>');
card(M,'N12','Spectrum / EQ bars',
- `<span class="eq" id="eq"></span>`,
+ (st,rd)=>GW.eqBars(st,{onChange:(v,t)=>rd(t)}),
'<b>level across bands.</b> A live multi-band bar graph — spectrum, per-core CPU. Live; readout shows the peak band.');
card(M,'N13','Crossed-needle meter',
- `<div class="crossm"><div class="face" id="crossm13"><div class="arc"></div><div class="nA" id="cnA"></div><div class="nB" id="cnB"></div></div>
- <div class="lbl"><span>FWD</span><span>RFL</span></div></div>`,
+ (st,rd)=>GW.crossNeedle(st,{value:55,onChange:(v,t)=>rd(t)}),
'<b>two readings, one face.</b> Forward + reflected needles cross. Drag up/down to drive power; readout shows both. <b>Round build wants a drawing surface.</b>');
card(M,'N14','Thermometer column',
- `<div class="thermo" id="thermo14"><div class="scale"><span>90</span><span>60</span><span>30</span></div>
- <div class="wrapcol"><div class="tube"><div class="fill" id="thermf" style="height:58%"></div></div><div class="bulb"></div></div></div>`,
+ (st,rd)=>GW.thermometer(st,{value:58,onChange:(v,t)=>rd(t)}),
'<b>a rising column.</b> The classic mercury tube — temperature, a climbing load. Drag up/down; readout shows the value.');
card(M,'N15','Bourdon pressure gauge',
- `<div class="bourdon" id="bourdon15">
- <svg viewBox="0 0 82 82"><path d="M14 62 A34 34 0 0 1 68 62" fill="none" stroke="#2c2f32" stroke-width="3"/>
- <path d="M52 22 A34 34 0 0 1 68 62" fill="none" stroke="#cb6b4d" stroke-width="3"/></svg>
- <div class="ndl" id="bourd" style="transform:rotate(30deg)"></div><div class="hub"></div><div class="cap">PSI</div></div>`,
+ (st,rd)=>GW.bourdon(st,{value:45,onChange:(v,t)=>rd(t)}),
'<b>a round dial with a red zone.</b> Needle over a printed arc, redline in terracotta. Drag to set PSI; readout tracks. <b>Round sweep is a drawing-area job.</b>');
card(M,'N16','Strip-chart recorder',
- `<span class="strip"><span class="rule"></span><svg viewBox="0 0 176 62" preserveAspectRatio="none"><polyline id="stripp"/></svg><span class="pen" id="strippen" style="top:31px"></span></span>`,
+ (st,rd)=>GW.stripChart(st,{onChange:(v,t)=>rd(t)}),
'<b>a scrolling pen trace.</b> History scrolls left, the pen writes at the right edge. Live; readout shows the current value. <b>Real trace wants a drawing surface.</b>');
card(M,'N17','Correlation meter (±)',
- `<div class="corr" id="corr17"><div class="face"><div class="arc"></div><div class="zero"></div><div class="ndl" id="corrn" style="transform:rotate(8deg)"></div></div>
- <div class="lbl"><span>−1</span><span>0</span><span>+1</span></div></div>`,
+ (st,rd)=>GW.corrMeter(st,{value:58,onChange:(v,t)=>rd(t)}),
'<b>deviation from center.</b> The needle rests at 0 and swings ±. Drag left/right; readout shows the signed value.');
card(M,'N18','Battery-cell gauge',
- `<div class="batt" id="batt18"><div class="cells" id="battc"></div><span class="nub"></span></div>`,
+ (st,rd)=>GW.battCells(st,{value:62,onChange:(v,t)=>rd(t)}),
'<b>charge as discrete cells.</b> Filled cells count up, the last warn in terracotta. Drag left/right to set; readout shows %.');
card(M,'R01','Moving-coil VU meter',
`<svg id="mcvu" class="rsvg" viewBox="0 0 150 96" width="150" height="96"></svg>`,
@@ -1904,28 +1898,7 @@ card(I,'R52','Blinkenlights front panel',
/* 01-09, 24, 25, N01-N10 extracted to widgets.js (GW.*) — wired at their card records */
/* ============ METER WIRING (drag-driven) ============ */
-/* 10-17 extracted to widgets.js (GW.*) — wired at their card records */
-/* N13 crossed-needle */
-let cnPow=55;
-function setCross(v){cnPow=v;const fwd=v,rfl=v*0.68;$('cnA').style.transform=`rotate(${-42+fwd/100*84}deg)`;
- $('cnB').style.transform=`rotate(${42-rfl/100*84}deg)`;setRd('N13','FWD '+Math.round(fwd)+' · RFL '+Math.round(rfl));}
-dragDelta($('crossm13'),()=>cnPow,setCross,{min:0,max:100});setCross(55);
-/* N14 thermometer */
-let thV=58;
-function setThermo(v){thV=v;$('thermf').style.height=v+'%';setRd('N14',Math.round(30+v/100*60)+'°');}
-dragDelta($('thermo14'),()=>thV,setThermo,{min:0,max:100});setThermo(58);
-/* N15 bourdon */
-let bV=45;
-function setBour(v){bV=v;$('bourd').style.transform=`rotate(${-60+v/100*120}deg)`;setRd('N15',Math.round(v/100*160)+' PSI');}
-dragDelta($('bourdon15'),()=>bV,setBour,{min:0,max:100});setBour(45);
-/* N17 correlation */
-function setCorr(p){const v=(p-50)/50;$('corrn').style.transform=`rotate(${v*38}deg)`;setRd('N17',(v>=0?'+':'')+v.toFixed(2));}
-dragX($('corr17'),setCorr);setCorr(58);
-/* N18 battery */
-(function(){const bc=$('battc');for(let i=0;i<8;i++){const c=document.createElement('span');c.className='cell';bc.appendChild(c);}})();
-function setBatt(p){const cells=$('battc').children,lit=Math.round(p/100*cells.length);
- for(let i=0;i<cells.length;i++)cells[i].className='cell'+(i<lit?' on':'')+((p<=25&&i<lit)?' warn':'');setRd('N18',Math.round(p)+'%');}
-dragX($('batt18'),setBatt);setBatt(62);
+/* 10-17, N11-N18 extracted to widgets.js (GW.*) — wired at their card records */
/* ============ INDICATOR WIRING ============ */
/* 18 status lamp */
@@ -2438,9 +2411,8 @@ setRgraph(1200,6.5);
/* ============ LIVE SIGNAL LOOPS ============ */
/* extracted meters: the page keeps the clock + demo signal, drives card handles */
-const MH={vu:$('card-11').gw,mini:$('card-12').gw,spark:$('card-16').gw,wave:$('card-17').gw};
-(function(){const eq=$('eq');for(let b=0;b<11;b++){const band=document.createElement('span');band.className='band';
- for(let s=0;s<9;s++)band.appendChild(document.createElement('i'));eq.appendChild(band);}})();
+const MH={vu:$('card-11').gw,mini:$('card-12').gw,spark:$('card-16').gw,wave:$('card-17').gw,
+ scope:$('card-N11').gw,eq:$('card-N12').gw,strip:$('card-N16').gw};
(function(){const cl=$('clock');for(let i=0;i<12;i++){const t=document.createElement('span');t.className='tk';
t.style.transform=`rotate(${i*30}deg)`;cl.insertBefore(t,cl.firstChild);}})();
const counterDigits=[4,7,1,3,0,0];
@@ -2452,10 +2424,6 @@ function setWheel(w,d){w.querySelector('.col').style.top=(-(d+1)*34)+'px';}
let ph=0;
const eqBands=Array.from({length:11},(_,i)=>({v:0.4,ph:i*0.6}));
-const stripHist=Array.from({length:60},()=>31);
-function paintEq(){const bands=$('eq').children;let peak=0;
- for(let b=0;b<bands.length;b++){const cells=bands[b].children,n=cells.length,val=eqBands[b].v;const lit=Math.round(val*n);peak=Math.max(peak,val);
- for(let k=0;k<n;k++){let c='';if(k<lit)c=(k>=n-1?'clip':k>=n-3?'hot':'on');cells[k].className=c?c:'';}}return peak;}
function lvl(){return Math.max(0,Math.min(1,0.5+0.4*Math.sin(ph*1.3)+(Math.random()<0.15?Math.random()*0.4:0)-Math.random()*0.08));}
function fastTick(){
ph+=0.09;
@@ -2465,14 +2433,12 @@ function fastTick(){
const env=Math.min(1,0.6+0.3*Math.sin(ph*0.4));
const smp=[];for(let x=0;x<=170;x+=3)smp.push(Math.sin(x*0.18+ph*3)*Math.sin(x*0.05));
MH.wave.set(smp,env);
- let sp='';for(let x=0;x<=176;x+=3){const y=39+Math.sin(x*0.16+ph*3.2)*Math.min(1,0.6+0.3*Math.sin(ph*0.4))*22;sp+=`${x},${y.toFixed(1)} `;}
- $('scopep').setAttribute('points',sp.trim());setRd('N11','Vpp '+Math.round((0.6+0.3*Math.sin(ph*0.4))*100));
+ const senv=Math.min(1,0.6+0.3*Math.sin(ph*0.4));
+ const ssmp=[];for(let x=0;x<=176;x+=3)ssmp.push(Math.sin(x*0.16+ph*3.2)*senv);
+ MH.scope.set(ssmp,0.6+0.3*Math.sin(ph*0.4));
eqBands.forEach(bd=>{bd.ph+=0.16;bd.v=Math.max(0.05,Math.min(1,0.5+0.42*Math.sin(bd.ph)+(Math.random()<0.2?Math.random()*0.3:0)-Math.random()*0.06));});
- const peak=paintEq();setRd('N12','peak '+Math.round(peak*100)+'%');
- stripHist.push(31-24*Math.sin(ph*0.7)*(0.6+0.4*Math.sin(ph*0.13))+(Math.random()-0.5)*4);stripHist.shift();
- const last=Math.max(3,Math.min(59,stripHist[stripHist.length-1]));
- $('stripp').setAttribute('points',stripHist.map((v,i)=>`${i/(stripHist.length-1)*176},${Math.max(3,Math.min(59,v)).toFixed(1)}`).join(' '));
- $('strippen').style.top=last+'px';setRd('N16',Math.round((59-last)/56*100));
+ MH.eq.set(eqBands.map(bd=>bd.v));
+ MH.strip.push((28+24*Math.sin(ph*0.7)*(0.6+0.4*Math.sin(ph*0.13))-(Math.random()-0.5)*4)/56);
}
/* clock */
function tickClock(){const d=new Date();const s=d.getSeconds(),m=d.getMinutes(),h=d.getHours()%12;
@@ -2518,9 +2484,10 @@ function paintStatic(){
MH.vu.set(0.55,0.5);MH.mini.set(0.55);
MH.spark.fill(0.5);
MH.wave.set([],0.6);
- eqBands.forEach((bd,i)=>bd.v=0.3+0.5*Math.abs(Math.sin(i*0.9)));setRd('N12','peak '+Math.round(paintEq()*100)+'%');
- $('scopep').setAttribute('points',Array.from({length:60},(_,i)=>`${i*3},${39+Math.sin(i*0.5)*18}`).join(' '));setRd('N11','Vpp 74');
- $('stripp').setAttribute('points',stripHist.map((v,i)=>`${i/(stripHist.length-1)*176},${31-Math.sin(i*0.3)*16}`).join(' '));setRd('N16','50');
+ eqBands.forEach((bd,i)=>bd.v=0.3+0.5*Math.abs(Math.sin(i*0.9)));
+ MH.eq.set(eqBands.map(bd=>bd.v));
+ MH.scope.set(Array.from({length:60},(_,i)=>Math.sin(i*0.5)*18/22),0.74);
+ MH.strip.set(Array.from({length:60},(_,i)=>0.5+Math.sin(i*0.3)*16/56),0.5);
tickClock();renderSeven();setRd('N20','DNS');setRd('N22','scrolling');setRd('N25',String(ctrVal).padStart(6,'0'));
setMcVu(.5);
}
@@ -2954,7 +2921,7 @@ screenChips('R10',$('dmx'),['amber','green','red','blue','vfd'],'amber');
screenChips('R17',$('rcrt'),['green','amber','red','blue','vfd'],'green');
screenChips('R19',$('card-R19').gw.el,['white','green','amber','blue','vfd'],'white');
screenChips('R31',$('radar'),['amber','green','red','blue','vfd'],'amber');
-screenChips('N11',$('scopep').closest('.scope'),['green','amber','red','blue','vfd'],'green');
+screenChips('N11',$('card-N11').gw.el,['green','amber','red','blue','vfd'],'green');
BOOST.forEach(no=>{const rd=document.getElementById('rd-'+no);
if(rd)rd.closest('.card').querySelector('.stagew').classList.add('boost');});