134 lines
4.3 KiB
TypeScript
134 lines
4.3 KiB
TypeScript
import React, { useState, useRef, useEffect } from "react";
|
|
import { ExitIcon, PlayStopIcon, ResetIcon } from "../../icons/SimulationIcons";
|
|
import { usePlayButtonStore } from "../../../store/usePlayButtonStore";
|
|
|
|
const SimulationPlayer: React.FC = () => {
|
|
const [speed, setSpeed] = useState<number>(1);
|
|
const [playSimulation, setPlaySimulation] = useState(false);
|
|
const { setIsPlaying } = usePlayButtonStore();
|
|
const sliderRef = useRef<HTMLDivElement>(null);
|
|
const isDragging = useRef(false);
|
|
|
|
// Button functions
|
|
const handleReset = () => {
|
|
setSpeed(1);
|
|
};
|
|
const handlePlayStop = () => {
|
|
setPlaySimulation(!playSimulation);
|
|
};
|
|
const handleExit = () => {
|
|
setPlaySimulation(false);
|
|
setIsPlaying(false);
|
|
};
|
|
|
|
// Slider functions starts
|
|
const handleSpeedChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
setSpeed(parseFloat(event.target.value));
|
|
};
|
|
|
|
const calculateHandlePosition = () => {
|
|
return ((speed - 0.5) / (50 - 0.5)) * 100;
|
|
};
|
|
|
|
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"
|
|
max="50"
|
|
step="0.1"
|
|
value={speed}
|
|
onChange={handleSpeedChange}
|
|
className="slider-input"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div className="max-value">50x</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default SimulationPlayer;
|