replace slider with a better behaved one

This commit is contained in:
Gwilym Inzani 2023-07-05 13:20:01 +01:00 committed by Corwin
parent 3323d6a4e7
commit 489e95de9f
No known key found for this signature in database
3 changed files with 75 additions and 11 deletions

View file

@ -5,6 +5,7 @@ import { styled } from "styled-components";
import { useOnKeyUp } from "./useOnKeyUp.hook"; import { useOnKeyUp } from "./useOnKeyUp.hook";
import { useLocalStorage } from "./useLocalStorage.hook"; import { useLocalStorage } from "./useLocalStorage.hook";
import { useAvoidItchIoScrolling } from "./useAvoidItchIoScrolling"; import { useAvoidItchIoScrolling } from "./useAvoidItchIoScrolling";
import { Slider } from "./Slider";
const BindingsDialog = styled.dialog` const BindingsDialog = styled.dialog`
border-radius: 5px; border-radius: 5px;
@ -118,14 +119,7 @@ function BindingsWindow({
<BindingsDialog open onClose={hide}> <BindingsDialog open onClose={hide}>
<VolumeLabel> <VolumeLabel>
Volume: Volume:
<input <Slider value={volume} onChange={(e) => setVolume(e)} />
type="range"
value={volume}
min="0"
max="1"
step="0.05"
onChange={(e) => setVolume(Number(e.target.value))}
/>
</VolumeLabel> </VolumeLabel>
<BindingsControl <BindingsControl
bindings={bindings} bindings={bindings}

73
website/src/Slider.tsx Normal file
View file

@ -0,0 +1,73 @@
import { useRef } from "react";
import { styled } from "styled-components";
const SliderWrapper = styled.div`
padding: 1ex 0;
width: 100%;
`;
const SliderContainer = styled.div`
display: block;
position: relative;
width: 100%;
height: 0.25ex;
background-color: black;
margin: auto;
min-width: 10ex;
`;
const SliderBox = styled.div<{ $proportion: number }>`
position: absolute;
width: 1ex;
height: 1ex;
top: -0.3ex;
background-color: black;
left: ${(props) => props.$proportion * 90}%;
`;
export function Slider({
value,
onChange,
}: {
value: number;
onChange: (newValue: number) => void;
}) {
const slider = useRef<HTMLDivElement>(null);
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
onChange(
event.nativeEvent.offsetX / (event.target as HTMLDivElement).offsetWidth
);
event.stopPropagation();
};
const handleDrag = (event: React.MouseEvent<HTMLDivElement>) => {
const sliderRef = slider.current;
if (!sliderRef || event.buttons !== 1) {
return;
}
const relativePosition =
event.clientX - sliderRef.getBoundingClientRect().left;
const proportion = relativePosition / sliderRef.offsetWidth;
const clamped = Math.min(1, Math.max(0, proportion));
onChange(clamped);
};
return (
<SliderWrapper ref={slider} onClick={handleClick} onMouseMove={handleDrag}>
<SliderContainer>
<SliderBox
$proportion={value}
onClick={(e: React.MouseEvent) => {
e.stopPropagation();
}}
/>
</SliderContainer>
</SliderWrapper>
);
}

View file

@ -57,7 +57,6 @@ export const Mgba = forwardRef<MgbaHandle, MgbaProps>(
mgbaModule.current.FS.writeFile(gamePath, new Uint8Array(gameData)); mgbaModule.current.FS.writeFile(gamePath, new Uint8Array(gameData));
mgbaModule.current.loadGame(gamePath); mgbaModule.current.loadGame(gamePath);
mgbaModule.current.setVolume(0.1); // for some reason you have to do this or you get no sound mgbaModule.current.setVolume(0.1); // for some reason you have to do this or you get no sound
console.log(mgbaModule.current.getVolume());
setGameLoaded(true); setGameLoaded(true);
})(); })();
}, [state, gameUrl]); }, [state, gameUrl]);
@ -113,9 +112,7 @@ export const Mgba = forwardRef<MgbaHandle, MgbaProps>(
useEffect(() => { useEffect(() => {
if (!gameLoaded) return; if (!gameLoaded) return;
console.log("before", mgbaModule.current.getVolume());
mgbaModule.current.setVolume(volume ?? 1.0); mgbaModule.current.setVolume(volume ?? 1.0);
console.log("after", mgbaModule.current.getVolume());
}, [gameLoaded, volume]); }, [gameLoaded, volume]);
useEffect(() => { useEffect(() => {