File size: 2,506 Bytes
0dfa89f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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>;
}