initial commit
This commit is contained in:
67
FrontEnd/components/MotionPanel.tsx
Normal file
67
FrontEnd/components/MotionPanel.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Move } from 'lucide-react';
|
||||
import { RobotTarget, AxisPosition } from '../types';
|
||||
import { PanelHeader } from './common/PanelHeader';
|
||||
import { TechButton } from './common/TechButton';
|
||||
|
||||
const MOCK_POSITIONS: AxisPosition[] = [
|
||||
{ id: 'p1', name: 'Home Position', axis: 'X', value: 0, speed: 100, acc: 100, dec: 100 },
|
||||
{ id: 'p2', name: 'Pick Pos A', axis: 'X', value: -1.5, speed: 500, acc: 200, dec: 200 },
|
||||
{ id: 'p3', name: 'Place Pos B', axis: 'X', value: 1.5, speed: 500, acc: 200, dec: 200 },
|
||||
{ id: 'p4', name: 'Scan Index', axis: 'X', value: 0.5, speed: 300, acc: 100, dec: 100 },
|
||||
{ id: 'py1', name: 'Rear Limit', axis: 'Y', value: -1.5, speed: 200, acc: 100, dec: 100 },
|
||||
{ id: 'pz1', name: 'Safe Height', axis: 'Z', value: 0, speed: 50, acc: 50, dec: 50 },
|
||||
];
|
||||
|
||||
interface MotionPanelProps {
|
||||
robotTarget: RobotTarget;
|
||||
onMove: (axis: 'X' | 'Y' | 'Z', val: number) => void;
|
||||
}
|
||||
|
||||
export const MotionPanel: React.FC<MotionPanelProps> = ({ robotTarget, onMove }) => {
|
||||
const [axis, setAxis] = useState<'X' | 'Y' | 'Z'>('X');
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col">
|
||||
<PanelHeader title="Servo Control" icon={Move} />
|
||||
<div className="flex gap-2 mb-4">
|
||||
{['X', 'Y', 'Z'].map(a => (
|
||||
<button
|
||||
key={a}
|
||||
onClick={() => setAxis(a as any)}
|
||||
className={`flex-1 py-2 font-tech font-bold text-lg border-b-2 transition-all ${axis === a ? 'text-neon-blue border-neon-blue bg-neon-blue/10' : 'text-slate-500 border-slate-700 hover:text-slate-300'}`}
|
||||
>
|
||||
{a}-AXIS
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="bg-black/40 p-4 rounded border border-white/10 mb-4 text-center">
|
||||
<div className="text-[10px] text-slate-400 uppercase tracking-widest mb-1">Current Position</div>
|
||||
<div className="font-mono text-3xl text-neon-blue text-shadow-glow-blue">
|
||||
{robotTarget[axis.toLowerCase() as 'x' | 'y' | 'z'].toFixed(3)}
|
||||
<span className="text-sm text-slate-500 ml-2">mm</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2 overflow-y-auto flex-1 pr-2 custom-scrollbar">
|
||||
{MOCK_POSITIONS.filter(p => p.axis === axis).map(p => (
|
||||
<div key={p.id} className="flex items-center justify-between p-3 bg-white/5 border border-white/5 hover:border-neon-blue/50 transition-all group">
|
||||
<span className="text-xs font-bold text-slate-300 group-hover:text-white">{p.name}</span>
|
||||
<button
|
||||
onClick={() => onMove(axis, p.value)}
|
||||
className="px-3 py-1 bg-slate-800 hover:bg-neon-blue hover:text-black text-xs font-mono transition-colors"
|
||||
>
|
||||
GO {p.value}
|
||||
</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2 mt-4">
|
||||
<TechButton className="flex-1 font-mono text-lg" onClick={() => onMove(axis, robotTarget[axis.toLowerCase() as 'x' | 'y' | 'z'] - 0.1)}>-</TechButton>
|
||||
<TechButton className="flex-1 font-mono text-lg" onClick={() => onMove(axis, robotTarget[axis.toLowerCase() as 'x' | 'y' | 'z'] + 0.1)}>+</TechButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user