Skip to content

Commit c76b15a

Browse files
author
dashdashzako
committed
Fix seek slider position calculation
1 parent e571b94 commit c76b15a

File tree

1 file changed

+24
-26
lines changed

1 file changed

+24
-26
lines changed

src/components/progress/Progress.tsx

+24-26
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import SeekBarExpander from './SeekBarExpander';
2626
import SeekBar from './SeekBar';
2727

2828
interface IState {
29-
sliderWidth: number;
3029
userInteracting: boolean;
3130
}
3231

@@ -106,8 +105,10 @@ const Div = styled.div`
106105
class Progress extends Component<ISeekBarSlider, IState> {
107106
static contextType = MediaContext;
108107

108+
sliderPosition = 0;
109+
sliderWidth = 0;
110+
109111
readonly state = {
110-
sliderWidth: 0,
111112
userInteracting: false
112113
};
113114

@@ -179,17 +180,18 @@ class Progress extends Component<ISeekBarSlider, IState> {
179180
}
180181

181182
setPosition = () => {
182-
const sliderEl = document.querySelector('.aip-progress__slider');
183+
const slider = document.querySelector('.aip-progress__slider');
183184

184-
if (!sliderEl) {
185+
if (!slider) {
185186
return;
186187
}
187188

188189
// recalculate slider element position to ensure no external
189190
// event (such as fullscreen or window redimension) changed it.
190-
this.setState({
191-
sliderWidth: sliderEl.getBoundingClientRect().width
192-
});
191+
const { left, width } = slider!.getBoundingClientRect();
192+
193+
this.sliderWidth = width;
194+
this.sliderPosition = left;
193195
};
194196

195197
clickHandler = (evt: React.MouseEvent<HTMLElement>) => {
@@ -203,43 +205,40 @@ class Progress extends Component<ISeekBarSlider, IState> {
203205
this.setPosition();
204206

205207
// trigger first recomputation to simulate simple click.
206-
const el = document.querySelector('.aip-progress')! as HTMLElement;
207-
const mouseX = evt.pageX - el.offsetLeft;
208+
const newTime = this.getTimeFromPosition(evt.pageX);
208209

209-
this.props.seek(this.getTimeFromPosition(mouseX));
210+
this.props.seek(newTime);
210211
this.setState({ userInteracting: true });
211-
this.updateCurrentTime(mouseX);
212+
this.updateCurrentTime(newTime);
212213

213214
document.addEventListener('mousemove', this.mouseMoveHandler, true);
214215
document.addEventListener('mouseup', this.mouseUpHandler, true);
215216
};
216217

217218
mouseUpHandler = (evt: MouseEvent) => {
218219
(document.querySelector('.aip-progress__slider') as HTMLElement)!.blur();
219-
const el = document.querySelector('.aip-progress')! as HTMLElement;
220220

221221
this.setState({ userInteracting: false });
222+
const newTime = this.getTimeFromPosition(evt.pageX);
222223

223-
this.updateCurrentTime(evt.pageX - el.offsetLeft);
224+
this.updateCurrentTime(newTime);
224225

225226
document.removeEventListener('mousemove', this.mouseMoveHandler, true);
226227
document.removeEventListener('mouseup', this.mouseUpHandler, true);
227228
};
228229

229230
mouseMoveHandler = (evt: MouseEvent) => {
230-
const el = document.querySelector('.aip-progress')! as HTMLElement;
231-
const mouseX = evt.pageX - el.offsetLeft;
231+
const newTime = this.getTimeFromPosition(evt.pageX);
232232

233-
this.props.seek(this.getTimeFromPosition(mouseX));
234-
this.throttledUpdateCurrentTime(mouseX);
233+
this.props.seek(newTime);
234+
this.throttledUpdateCurrentTime(newTime);
235235
};
236236

237-
updateCurrentTime = (mouseX: number) => {
237+
updateCurrentTime = (time: number) => {
238238
const [media] = this.context;
239-
const newCurrentTime = this.getTimeFromPosition(mouseX);
240239

241-
if (newCurrentTime !== this.props.currentTime) {
242-
media.currentTime = newCurrentTime;
240+
if (time !== this.props.currentTime) {
241+
media.currentTime = time;
243242
}
244243
};
245244

@@ -248,11 +247,10 @@ class Progress extends Component<ISeekBarSlider, IState> {
248247
getTimeFromPosition = (mouseX: number) => {
249248
const { duration } = this.props;
250249

251-
const positionDifference = bounded(mouseX, 0, this.state.sliderWidth);
252-
253-
const time = round(
254-
duration * unitToRatio(positionDifference, this.state.sliderWidth)
255-
);
250+
const sliderXMax = this.sliderPosition + this.sliderWidth;
251+
const boundedX = bounded(mouseX, this.sliderPosition, sliderXMax);
252+
const positionDifference = boundedX - this.sliderPosition;
253+
const time = duration * unitToRatio(positionDifference, this.sliderWidth);
256254

257255
return time;
258256
};

0 commit comments

Comments
 (0)