aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-12 01:54:23 -0500
committerCraig Jennings <c@cjennings.net>2026-07-12 01:54:23 -0500
commit52a43ec651cc92c219ef6d2b320b2e77d5b13235 (patch)
tree939ab4eeabe576a97bd3028461dd1479d1ba745d /docs
parent3c54f2f4c4c29d13730f5c47272cf21eb64a2f94 (diff)
downloadarchsetup-52a43ec651cc92c219ef6d2b320b2e77d5b13235.tar.gz
archsetup-52a43ec651cc92c219ef6d2b320b2e77d5b13235.zip
feat(gallery): add R31 radar sweepHEADmain
The rotating scan after a radar PPI scope (reference filed in the catalogue's working directory): a beam circles inside a numbered bearing ring, an afterglow wedge trails it, contacts bloom as the beam passes and fade over the next half turn, and range rings sit under it all. Clicking marks the current bearing. The kit's round CRT draws traces; nothing rotated a scan until this. I verified it in headless Chrome: the sweep rotates, the mark click captures the live bearing, no console exceptions.
Diffstat (limited to 'docs')
-rw-r--r--docs/prototypes/panel-widget-gallery.html50
1 files changed, 50 insertions, 0 deletions
diff --git a/docs/prototypes/panel-widget-gallery.html b/docs/prototypes/panel-widget-gallery.html
index ab69855..f8330bb 100644
--- a/docs/prototypes/panel-widget-gallery.html
+++ b/docs/prototypes/panel-widget-gallery.html
@@ -894,6 +894,9 @@ card(I,'R26','Response graph',
card(I,'R30','Telegraph indicator',
`<svg id="telind" class="rsvg press" viewBox="0 0 110 110" width="110" height="110"></svg>`,
'<b>state on a pie of sectors.</b> The pointer and its little flag name the active state, engine-telegraph style. Click to step the state. After an electric indicator dial.');
+card(I,'R31','Radar sweep',
+ `<svg id="radar" class="rsvg press" viewBox="0 0 130 130" width="130" height="130"></svg>`,
+ '<b>the rotating scan.</b> A sweep beam circles the bearing ring, contacts bloom as it passes and fade after. Click to mark the current bearing. After a radar PPI scope.');
/* ============ CONTROL WIRING ============ */
/* 01 toggle */
@@ -2006,6 +2009,53 @@ function setTelind(i){telI=i;const N=TELIND_STATES.length;
setRd('R30',TELIND_STATES[i]);}
setTelind(0);
+/* R31 radar sweep: rotating beam, blooming contacts, click to mark */
+let radarA=210,radarSweep=null,radarBlips=[],radarMark=null;
+const RADAR_CONTACTS=[[60,.55],[205,.7],[318,.4]];
+(function(){const s=$('radar'),cx=65,cy=65;
+ const defs=svgEl(s,'defs',{});
+ const clip=svgEl(defs,'clipPath',{id:'radarClip'});
+ svgEl(clip,'circle',{cx,cy,r:46});
+ svgEl(s,'circle',{cx,cy,r:62,fill:'#1a1714',stroke:'#060505','stroke-width':2});
+ svgEl(s,'circle',{cx,cy,r:52,fill:'#120b05',stroke:'#3a2a12','stroke-width':1});
+ for(let d=0;d<360;d+=30){const a=d;
+ const [x1,y1]=polar(cx,cy,51,a),[x2,y2]=polar(cx,cy,47,a);
+ svgEl(s,'line',{x1,y1,x2,y2,stroke:'var(--gold)','stroke-width':1,opacity:.8});
+ const g=svgEl(s,'g',{transform:`rotate(${a},${cx},${cy})`});
+ svgEl(g,'text',{x:cx,y:cy-47.5,'text-anchor':'middle','font-size':4.6,'font-family':'var(--mono)',
+ fill:'var(--gold)',opacity:.9}).textContent=String(d).padStart(3,'0');}
+ for(let d=0;d<360;d+=10){if(d%30===0)continue;
+ const [x1,y1]=polar(cx,cy,51,d),[x2,y2]=polar(cx,cy,49,d);
+ svgEl(s,'line',{x1,y1,x2,y2,stroke:'var(--gold)','stroke-width':.6,opacity:.5});}
+ const g=svgEl(s,'g',{'clip-path':'url(#radarClip)'});
+ svgEl(g,'circle',{cx,cy,r:46,fill:'#0d0803'});
+ for(const r of [15,30,45])
+ svgEl(g,'circle',{cx,cy,r,fill:'none',stroke:'rgba(226,160,56,.18)','stroke-width':.7});
+ radarSweep=svgEl(g,'g',{});
+ for(let t=0;t<5;t++){const a0=-14+t*2.8,a1=a0+2.8;
+ const [x1,y1]=polar(cx,cy,46,a0),[x2,y2]=polar(cx,cy,46,a1);
+ svgEl(radarSweep,'path',{d:`M ${cx} ${cy} L ${x1} ${y1} A 46 46 0 0 1 ${x2} ${y2} Z`,
+ fill:`rgba(226,160,56,${(0.04+t*0.045).toFixed(3)})`});}
+ svgEl(radarSweep,'line',{x1:cx,y1:cy,x2:cx,y2:cy-46,stroke:'var(--gold-hi)','stroke-width':1.4,
+ transform:`rotate(0,${cx},${cy})`,opacity:.95});
+ RADAR_CONTACTS.forEach(([bd,rf])=>{const [x,y]=polar(cx,cy,46*rf,bd);
+ radarBlips.push(svgEl(g,'circle',{cx:x,cy:y,r:2.2,fill:'var(--gold-hi)',opacity:0}));});
+ svgEl(s,'circle',{cx,cy,r:3,fill:'var(--gold)',opacity:.8});
+ radarMark=svgEl(s,'text',{x:cx,y:124,'text-anchor':'middle','font-size':6,'letter-spacing':'.12em',
+ 'font-family':'var(--mono)',fill:'var(--steel)'});
+ radarMark.textContent='BEARING —';
+ $('radar').onclick=()=>{radarMark.textContent='MARK '+String(Math.round(radarA)%360).padStart(3,'0');
+ setRd('R31','mark '+String(Math.round(radarA)%360).padStart(3,'0'));};})();
+function tickRadar(){radarA=(radarA+2.6)%360;
+ radarSweep.setAttribute('transform',`rotate(${radarA},65,65)`);
+ RADAR_CONTACTS.forEach(([bd],i)=>{
+ let d=(radarA-bd+360)%360; // degrees since beam passed
+ radarBlips[i].setAttribute('opacity',d<200?Math.max(0,.95-d/200):0);});
+ radarMark.textContent=radarMark.textContent.startsWith('MARK')?radarMark.textContent:
+ 'BEARING '+String(Math.round(radarA)%360).padStart(3,'0');}
+tickRadar();setRd('R31','sweeping');
+if(!matchMedia('(prefers-reduced-motion: reduce)').matches)setInterval(tickRadar,50);
+
/* R25 fourteen-segment display: the starburst that spells */
const SEG14_WORDS=['ZOOM','ECHO','TAPE','MOOD','HALL','COMP'];
const SEG14_MAP={A:['a','b','c','e','f','g1','g2'],C:['a','d','e','f'],