diff options
Diffstat (limited to 'animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js')
| -rw-r--r-- | animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js new file mode 100644 index 0000000..7bbbc07 --- /dev/null +++ b/animism-align/frontend/app/views/viewer/player/components.media/video.scrubber.js @@ -0,0 +1,82 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +import actions from 'app/actions' +import { clamp, timestamp } from 'app/utils' +import { PlayButton, VolumeControl } from 'app/views/viewer/nav/viewer.icons' + +class VideoScrubber extends Component { + constructor(props) { + super(props) + this.scrubberRef = React.createRef() + this.handleScrubDotMouseDown = this.handleScrubDotMouseDown.bind(this) + this.handleScrubDotMouseMove = this.handleScrubDotMouseMove.bind(this) + this.handleScrubDotMouseUp = this.handleScrubDotMouseUp.bind(this) + } + componentDidMount() { + window.addEventListener('mousemove', this.handleScrubDotMouseMove) + window.addEventListener('mouseup', this.handleScrubDotMouseUp) + } + componentWillUnmount() { + window.removeEventListener('mousemove', this.handleScrubDotMouseMove) + window.removeEventListener('mouseup', this.handleScrubDotMouseUp) + } + scrub(x, scrubbing) { + const { timing, start_ts, onScrub } = this.props + const bounds = this.scrubberRef.current.getBoundingClientRect() + const percent = clamp((x - bounds.left) / bounds.width, 0, 1) + const seconds = percent * timing.duration + actions.audio.seek(start_ts + seconds) + onScrub({ + seek: seconds, + percent, seconds, scrubbing + }) + } + handleScrubDotMouseDown(e) { + e.stopPropagation() + this.scrub(e.pageX, true) + } + handleScrubDotMouseMove(e) { + e.stopPropagation() + if (!this.props.timing.scrubbing) return + this.scrub(e.pageX, true) + } + handleScrubDotMouseUp(e) { + e.stopPropagation() + this.props.onScrub({ scrubbing: false }) + } + render() { + const { playing, volume, timing } = this.props + return ( + <div className='video-scrubber'> + <div className='start-controls'> + <PlayButton playing={playing} /> + </div> + <div + className='scrub-bar-container' + onMouseDown={this.handleScrubDotMouseDown} + ref={this.scrubberRef} + > + <div className='scrub-bar' /> + <div + className='scrub-dot' + style={{ left: (100 * timing.percent) + "%" }} + /> + </div> + <div className='end-controls'> + <div className='playerTime'> + {timestamp(clamp(timing.seconds, 0, timing.duration))} + </div> + <VolumeControl volume={volume} /> + </div> + </div> + ) + } +} + +const mapStateToProps = state => ({ + playing: state.audio.playing, + volume: state.audio.volume, +}) + +export default connect(mapStateToProps)(VideoScrubber) |
