diff options
Diffstat (limited to 'src/components/ModelControls.tsx')
| -rw-r--r-- | src/components/ModelControls.tsx | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/src/components/ModelControls.tsx b/src/components/ModelControls.tsx new file mode 100644 index 0000000..31366b0 --- /dev/null +++ b/src/components/ModelControls.tsx @@ -0,0 +1,158 @@ +import React from "react"; +import { useStore } from "../store/store.ts"; +import { ControlSlider } from "./ControlSlider.tsx"; + +export const ModelControls: React.FC = () => { + const selectedModelId = useStore((state) => state.selectedModelId); + const models = useStore((state) => state.models); + const updateModel = useStore((state) => state.updateModel); + const removeModel = useStore((state) => state.removeModel); + const selectModel = useStore((state) => state.selectModel); + + const selectedModel = models.find((model) => model.id === selectedModelId); + + if (!selectedModel) { + return null; + } + + const handlePositionChange = (axis: "x" | "y" | "z", value: string) => { + const numericValue = parseFloat(value) || 0; + updateModel(selectedModel.id, { + position: { + ...selectedModel.position, + [axis]: numericValue, + }, + }); + }; + + const handleRotationChange = (axis: "x" | "y" | "z", value: string) => { + const numericValue = parseFloat(value) || 0; + updateModel(selectedModel.id, { + rotation: { + ...selectedModel.rotation, + [axis]: numericValue, + }, + }); + }; + + const handleHueShiftChange = ( + color: "red" | "green" | "blue", + value: string, + ) => { + const numericValue = parseFloat(value) || 0; + updateModel(selectedModel.id, { + hueShift: { + ...selectedModel.hueShift, + [color]: numericValue, + }, + }); + }; + + const handleDelete = () => { + removeModel(selectedModel.id); + selectModel(null); + }; + + return ( + <div className="model-controls"> + <h3 className="controls-title">{selectedModel.name}</h3> + + <div className="control-section"> + <h4>Position</h4> + <ControlSlider + label="X" + name="position-x" + min={-200} + max={200} + step={1} + value={selectedModel.position.x} + onChange={(value) => handlePositionChange("x", value)} + /> + <ControlSlider + label="Y" + name="position-y" + min={0} + max={200} + step={1} + value={selectedModel.position.y} + onChange={(value) => handlePositionChange("y", value)} + /> + <ControlSlider + label="Z" + name="position-z" + min={-200} + max={200} + step={1} + value={selectedModel.position.z} + onChange={(value) => handlePositionChange("z", value)} + /> + </div> + + <div className="control-section"> + <h4>Rotation</h4> + <ControlSlider + label="X" + name="rotation-x" + min={-Math.PI} + max={Math.PI} + step={0.01} + value={selectedModel.rotation.x} + onChange={(value) => handleRotationChange("x", value)} + /> + <ControlSlider + label="Y" + name="rotation-y" + min={-Math.PI} + max={Math.PI} + step={0.01} + value={selectedModel.rotation.y} + onChange={(value) => handleRotationChange("y", value)} + /> + <ControlSlider + label="Z" + name="rotation-z" + min={-Math.PI} + max={Math.PI} + step={0.01} + value={selectedModel.rotation.z} + onChange={(value) => handleRotationChange("z", value)} + /> + </div> + + <div className="control-section"> + <h4>Hue Shift</h4> + <ControlSlider + label="Red" + name="hue-red" + min={-1} + max={1} + step={0.01} + value={selectedModel.hueShift.red} + onChange={(value) => handleHueShiftChange("red", value)} + /> + <ControlSlider + label="Green" + name="hue-green" + min={-1} + max={1} + step={0.01} + value={selectedModel.hueShift.green} + onChange={(value) => handleHueShiftChange("green", value)} + /> + <ControlSlider + label="Blue" + name="hue-blue" + min={-1} + max={1} + step={0.01} + value={selectedModel.hueShift.blue} + onChange={(value) => handleHueShiftChange("blue", value)} + /> + </div> + + <button className="delete-model" onClick={handleDelete}> + Delete Model + </button> + </div> + ); +}; |