Spaces:
Running
Running
Download src/MotionControls.tsx from fffiloni/openusd-explorer: direct link, hf CLI and curl.
- Browser
- Download file 2.51 kB
-
https://huggingface.co/spaces/fffiloni/openusd-explorer/resolve/main/src/MotionControls.tsx
- Command line
-
hf download hf://spaces/fffiloni/openusd-explorer/src/MotionControls.tsx
-
curl -L -o MotionControls.tsx https://huggingface.co/spaces/fffiloni/openusd-explorer/resolve/main/src/MotionControls.tsx
2.51 kB
| import {Play,Pause,ChevronLeft,ChevronRight,Eye,RotateCcw} from 'lucide-react'; | |
| import {motionTitle,motionValue,type MotionJoint} from './motion'; | |
| type Props={joints:MotionJoint[];index:number;progress:number;playing:boolean;highlighted:boolean; | |
| onSelect:(index:number)=>void;onProgress:(value:number)=>void;onPlay:()=>void;onReset:()=>void;onHighlight:()=>void}; | |
| export default function MotionControls({joints,index,progress,playing,highlighted,onSelect,onProgress,onPlay,onReset,onHighlight}:Props){ | |
| const joint=joints[index],title=motionTitle(joint,index); | |
| return <div className="motion-controls" aria-label="Movement controls"> | |
| <div className="motion-heading"> | |
| {joints.length>1&&<button className="icon-button" aria-label="Previous movement" onClick={()=>onSelect((index-1+joints.length)%joints.length)}><ChevronLeft size={16}/></button>} | |
| <div className="motion-name" aria-live="polite"><strong>{title}</strong><small>{joint.type==='prismatic'?'Sliding':'Rotation'}{joints.length>1?` · ${index+1} of ${joints.length}`:''}</small></div> | |
| {joints.length>1&&<button className="icon-button" aria-label="Next movement" onClick={()=>onSelect((index+1)%joints.length)}><ChevronRight size={16}/></button>} | |
| <span className="dock-spacer"/> | |
| <button className={`icon-button ${highlighted?'active':''}`} aria-label="Highlight moving part" aria-pressed={highlighted} title="Highlight moving part" onClick={onHighlight}><Eye size={16}/></button> | |
| <button className="icon-button" aria-label="Reset this movement" title="Reset this movement" onClick={onReset}><RotateCcw size={15}/></button> | |
| </div> | |
| <div className="motion-slider-row"> | |
| <button className="icon-button play-button" aria-label={playing?'Pause this movement':'Play this movement'} title={playing?'Pause this movement':'Play this movement'} onClick={onPlay}>{playing?<Pause size={18}/>:<Play size={18}/>}</button> | |
| <span className="motion-limit">{motionValue(joint,0)}</span> | |
| <input className="joint-slider" aria-label={`${title} position`} aria-valuetext={motionValue(joint,progress)} type="range" min="0" max="1" step="0.001" value={progress} onChange={event=>onProgress(+event.target.value)}/> | |
| <span className="motion-limit">{motionValue(joint,1)}</span> | |
| </div> | |
| <p className="motion-hint">{highlighted?'Highlighted part':'Selected part'} {joint.type==='prismatic'?'slides':'rotates'} · {motionValue(joint,progress)}{joint.partial?' · preview range':''}</p> | |
| </div>; | |
| } | |