I'm making a volume bar but for some reason, I'm able to drag the slider button past the timeline on the right side. It also seems to increase the width of my timeline when I do slide it off on the right side. I'm a bit lost as to why this is happening, help is appreciated!
// my volume bar component:
import React from 'react';
class AudioVolume extends React.Component {
constructor(props) {
super(props);
this.state = {
volume: 1,
mute: false
};
this.handlePosition = this.handlePosition.bind(this);
this.mouseMove = this.mouseMove.bind(this);
this.mouseDown = this.mouseDown.bind(this);
this.mouseUp = this.mouseUp.bind(this);
this.mute = this.mute.bind(this);
}
componentDidMount() {
const { volume } = this.props;
this.setState({ volume });
this.handle.style.width = this.timeline.offsetWidth + "px";
this.handleCircle.style.marginLeft = this.timeline.offsetWidth + "px";
}
handlePosition(position) {
let handleLeft = position - this.timeline.offsetLeft;
if (handleLeft > this.timeline.offsetWidth || this.state.volume === 1) {
this.handle.style.width = this.timeline.offsetWidth + "px";
this.handleCircle.style.marginLeft = this.timeline.offsetWidth + "px";
}
if (handleLeft >= 0 && handleLeft <= this.timeline.offsetWidth) {
this.handle.style.width = handleLeft + "px";
this.handleCircle.style.marginLeft = handleLeft + "px";
}
if (handleLeft < 0) {
this.handle.style.width = "0px";
this.handleCircle.style.marginLeft = "0px";
}
}
mouseMove(e) {
this.handlePosition(e.pageX);
this.setState({ mute: false });
let volume = ((e.pageX - this.timeline.offsetLeft) / this.timeline.offsetWidth) * 1;
if (volume >= 1) {
volume = 1;
} else if (volume <= 0) {
volume = 0;
}
this.setState({ volume });
this.props.receiveVolume(this.state.volume);
}
mouseDown(e) {
window.addEventListener('mousemove', this.mouseMove);
window.addEventListener('mouseup', this.mouseUp);
}
mouseUp(e) {
window.removeEventListener('mousemove', this.mouseMove);
window.removeEventListener('mouseup', this.mouseUp);
}
mute() {
if (!this.state.mute) {
this.setState({ mute: true });
this.props.receiveVolume(0);
} else {
this.setState({ mute: false });
this.props.receiveVolume(this.state.volume);
}
}
render() {
let volumeClass;
if (this.state.volume >= 0.6) {
volumeClass = "ap-volume-high";
} else if (this.state.volume > 0) {
volumeClass = "ap-volume-low";
} else if (this.state.volume === 0) {
volumeClass = "ap-volume-off";
}
if (this.state.mute) volumeClass = 'ap-volume-off';
return (
<div className="ap-volume-controls">
<div className="ap-volume-icon"><i className={volumeClass}></i></div>
<div id="ap-volume-timeline" onClick={this.mouseMove} ref={(timeline) => { this.timeline = timeline }}>
<div id="ap-volume-handle" onMouseDown={this.mouseDown} ref={(handle) => { this.handle = handle }} />
<div id="ap-volume-handle-circle" onMouseDown={this.mouseDown} ref={(handleCircle) => { this.handleCircle = handleCircle }} />
</div>
</div>
);
}
}
export default AudioVolume;
// my volume bar CSS:
.ap-volume-controls {
display: flex;
flex-direction: row;
justify-content: center;
width: 100px;
margin-top: 25px;
margin-left: 130px;
.ap-volume-icon {
margin-right: 10px;
.ap-volume-high {
content: image_url('audio_player/audio_volume_high.png');
width: 17px;
height: 14px;
}
.ap-volume-low {
content: image_url('audio_player/audio_volume_low.png');
width: 14px;
height: 13px;
}
.ap-volume-off {
content: image_url('audio_player/audio_volume_off.png');
width: 17px;
height: 13px;
}
}
#ap-volume-timeline {
margin-top: 5px;
width: 85px;
height: 4px;
border-radius: 15px;
background: $audio-slider-gray;
#ap-volume-handle {
width: 0;
height: 4px;
background: $green;
}
#ap-volume-handle-circle {
width: 12px;
height: 12px;
border-radius: 50%;
background: $white;
margin-top: -8px;
}
}
}
UPDATE: I'm not sure if this is why, but when I shrank my slider button down to 0, I could see an empty space that the progress bar didn't stretch to: