Spaces:
Running
Running
Download src/VisualControls.tsx from fffiloni/Sand3D-assets-explorer: direct link, hf CLI and curl.
- Browser
- Download file 2.17 kB
-
https://huggingface.co/spaces/fffiloni/Sand3D-assets-explorer/resolve/main/src/VisualControls.tsx
- Command line
-
hf download hf://spaces/fffiloni/Sand3D-assets-explorer/src/VisualControls.tsx
-
curl -L -o VisualControls.tsx https://huggingface.co/spaces/fffiloni/Sand3D-assets-explorer/resolve/main/src/VisualControls.tsx
2.17 kB
| import {RotateCcw} from 'lucide-react'; | |
| export type ViewMode='parts'|'materials'|'meshes'; | |
| export type InspectionPart={id:string;name:string;jointId?:string|null}; | |
| export type InspectionInfo={parts:InspectionPart[];triangles:number;meshDetail:'edges'|'wireframe'}; | |
| type Props={mode:ViewMode;amount:number;part:string;busy:boolean;info:InspectionInfo; | |
| onMode:(mode:ViewMode)=>void;onExplode:(value:number)=>void;onPart:(id:string)=>void;onReset:()=>void}; | |
| export default function VisualControls({mode,amount,part,busy,info,onMode,onExplode,onPart,onReset}:Props){ | |
| const modes:ViewMode[]=['parts','materials','meshes']; | |
| return <section className="visual-controls" aria-label="3D appearance"> | |
| <div className="visual-toolbar"> | |
| <div className="view-modes" role="group" aria-label="Rendering mode"> | |
| {modes.map(value=><button key={value} disabled={busy} aria-pressed={mode===value} onClick={()=>onMode(value)}>{value[0].toUpperCase()+value.slice(1)}</button>)} | |
| </div> | |
| <button className="icon-button" aria-label="Reset appearance" title="Reset view, materials and separation" onClick={onReset} disabled={busy}><RotateCcw size={15}/></button> | |
| </div> | |
| <div className="explode-control"> | |
| <label htmlFor="object-explode">Explode</label> | |
| <input id="object-explode" aria-label="Separate parts" type="range" min="0" max="1" step="0.01" value={amount} onChange={e=>onExplode(+e.target.value)} disabled={info.parts.length<2||busy}/> | |
| <output htmlFor="object-explode">{Math.round(amount*100)}%</output> | |
| </div> | |
| <div className="visual-detail"> | |
| <label className="part-picker"><span className="sr-only">Inspect a part</span><select title="Select a part, or tap it on the object" aria-label="Inspect a part" value={part} onChange={e=>onPart(e.target.value)} disabled={busy}> | |
| <option value="">All parts · {info.parts.length.toLocaleString()}</option> | |
| {info.parts.map(p=><option key={p.id} value={p.id}>{p.name}</option>)} | |
| </select></label> | |
| <span className="mesh-count">{busy?'Preparing view…':mode==='meshes'?`${info.triangles.toLocaleString()} triangles${info.meshDetail==='wireframe'?' · wireframe':''}`:''}</span> | |
| </div> | |
| </section>; | |
| } | |