Files
Dwinzo_dev/app/src/components/ui/simulation/simulationPlayer.tsx

146 lines
4.6 KiB
TypeScript
Raw Normal View History

2025-03-27 10:55:44 +05:30
import React, { useState, useRef, useEffect } from "react";
import { ExitIcon, PlayStopIcon, ResetIcon } from "../../icons/SimulationIcons";
2025-04-04 09:46:18 +05:30
import { useActiveTool } from "../../../store/store";
2025-04-04 18:02:53 +05:30
import {
useAnimationPlaySpeed,
usePauseButtonStore,
usePlayButtonStore,
useResetButtonStore,
} from "../../../store/usePlayButtonStore";
2025-03-27 10:55:44 +05:30
const SimulationPlayer: React.FC = () => {
2025-04-04 18:02:53 +05:30
const { speed, setSpeed } = useAnimationPlaySpeed();
2025-03-27 10:55:44 +05:30
const [playSimulation, setPlaySimulation] = useState(false);
const { setIsPlaying } = usePlayButtonStore();
const sliderRef = useRef<HTMLDivElement>(null);
const isDragging = useRef(false);
2025-04-04 09:46:18 +05:30
const { setActiveTool } = useActiveTool();
2025-04-04 18:02:53 +05:30
const { isPaused, setIsPaused } = usePauseButtonStore();
const { isReset, setReset } = useResetButtonStore();
2025-03-27 10:55:44 +05:30
// Button functions
const handleReset = () => {
2025-04-04 18:02:53 +05:30
setReset(true);
2025-03-27 10:55:44 +05:30
setSpeed(1);
};
const handlePlayStop = () => {
2025-04-04 18:02:53 +05:30
setIsPaused(!isPaused);
2025-03-27 10:55:44 +05:30
setPlaySimulation(!playSimulation);
};
const handleExit = () => {
setPlaySimulation(false);
setIsPlaying(false);
2025-04-04 09:46:18 +05:30
setActiveTool("cursor")
2025-03-27 10:55:44 +05:30
};
// Slider functions starts
const handleSpeedChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setSpeed(parseFloat(event.target.value));
};
const calculateHandlePosition = () => {
2025-04-04 18:02:53 +05:30
return ((speed - 0.5) / (8 - 0.5)) * 100;
2025-03-27 10:55:44 +05:30
};
const handleMouseDown = () => {
isDragging.current = true;
document.addEventListener("mousemove", handleMouseMove);
document.addEventListener("mouseup", handleMouseUp);
};
const handleMouseMove = (e: MouseEvent) => {
if (!isDragging.current || !sliderRef.current) return;
const sliderRect = sliderRef.current.getBoundingClientRect();
const offsetX = e.clientX - sliderRect.left;
const percentage = Math.min(Math.max(offsetX / sliderRect.width, 0), 1);
const newValue = 0.5 + percentage * (50 - 0.5);
setSpeed(parseFloat(newValue.toFixed(1)));
};
const handleMouseUp = () => {
isDragging.current = false;
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
};
useEffect(() => {
return () => {
document.removeEventListener("mousemove", handleMouseMove);
document.removeEventListener("mouseup", handleMouseUp);
};
}, []);
// Slider function ends
return (
<div className="simulation-player-wrapper">
<div className="simulation-player-container">
<div className="controls-container">
<div
className="simulation-button-container"
onClick={() => {
handleReset();
}}
>
<ResetIcon />
Reset
</div>
<div
className="simulation-button-container"
onClick={() => {
handlePlayStop();
}}
>
<PlayStopIcon />
{playSimulation ? "Play" : "Stop"}
</div>
<div
className="simulation-button-container"
onClick={() => {
handleExit();
}}
>
<ExitIcon />
Exit
</div>
</div>
<div className="speed-control-container">
<div className="min-value">0.5x</div>
<div className="slider-container" ref={sliderRef}>
<div className="marker marker-10"></div>
<div className="marker marker-20"></div>
<div className="marker marker-30"></div>
<div className="marker marker-40"></div>
<div className="marker marker-50"></div>
<div className="marker marker-60"></div>
<div className="marker marker-70"></div>
<div className="marker marker-80"></div>
<div className="marker marker-90"></div>
<div className="custom-slider">
<div
className={`slider-handle ${isDragging ? "dragging" : ""}`}
style={{ left: `${calculateHandlePosition()}%` }}
onMouseDown={handleMouseDown}
>
{speed.toFixed(1)}x
</div>
<input
type="range"
min="0.5"
2025-04-04 18:02:53 +05:30
max="8"
2025-03-27 10:55:44 +05:30
step="0.1"
value={speed}
onChange={handleSpeedChange}
className="slider-input"
/>
</div>
</div>
2025-04-04 18:02:53 +05:30
<div className="max-value">8x</div>
2025-03-27 10:55:44 +05:30
</div>
</div>
</div>
);
};
export default SimulationPlayer;