Created
January 31, 2018 21:34
-
-
Save Archakov06/43f9d2b8adf620eb27abd7cccf3a3065 to your computer and use it in GitHub Desktop.
audioplayer.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import styled from 'styled-components'; | |
import { Sprites } from './'; | |
import { COLORS } from '../constants/styles'; | |
const AudioBlock = styled.div` | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
width: 300px; | |
padding: 8px 13px 8px 8px; | |
border-radius: 30px; | |
background-color: #edf3f9c2; | |
`; | |
const PlayBtn = styled.button` | |
background-color: ${COLORS.BLUE}; | |
border-radius: 30px; | |
height: 30px; | |
width: 30px; | |
border: 0; | |
cursor: pointer; | |
svg { | |
position: relative; | |
top: 1px; | |
path { | |
fill: #fff !important; | |
} | |
} | |
`; | |
const Progress = styled.div` | |
flex: 1; | |
height: 5px; | |
border-radius: 30px; | |
background-color: ${({ type }) => | |
type !== 'inner' ? '#dfe8ec' : COLORS.BLUE}; | |
margin-left: ${({ type }) => (type !== 'inner' ? '10px' : '0')}; | |
width: ${({ width }) => width}%; | |
`; | |
const Time = styled.span` | |
margin-left: 10px; | |
font-size: 13px; | |
opacity: 0.6; | |
color: #3c4a50; | |
letter-spacing: 0.3px; | |
`; | |
class AudioPlayer extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
isPlaying: false, | |
audioDuration: 0, | |
currentTime: 0, | |
}; | |
} | |
play() { | |
if (!this.state.isPlaying) { | |
this.audioElem.play(); | |
} else { | |
this.audioElem.pause(); | |
} | |
} | |
onPlayPause(b) { | |
this.setState({ | |
isPlaying: b, | |
}); | |
} | |
componentDidMount() { | |
const audio = this.audioElem; | |
this.updateVolume(0.3); | |
} | |
updateVolume(volume) { | |
if (typeof volume === 'number' && volume !== this.audioElem.volume) { | |
this.audioElem.volume = volume; | |
} | |
} | |
convertToTime(number) { | |
const mins = Math.floor(number / 60); | |
const secs = (number % 60).toFixed(); | |
return `${mins < 10 ? '0' : ''}${mins}:${secs < 10 ? '0' : ''}${secs}`; | |
} | |
handleTimeUpdate() { | |
if (this.audioElem) { | |
console.log(this.audioElem.currentTime); | |
this.setState({ | |
currentTime: this.audioElem.currentTime, | |
}); | |
} | |
} | |
componentDidMount() { | |
if (this.audioElem) { | |
this.audioElem.addEventListener( | |
'timeupdate', | |
this.handleTimeUpdate.bind(this), | |
); | |
this.audioElem.addEventListener('loadedmetadata', () => { | |
this.setState({ | |
audioDuration: this.audioElem.duration || 0, | |
}); | |
}); | |
} | |
} | |
render() { | |
const { isPlaying, currentTime, audioDuration } = this.state; | |
const { src } = this.props; | |
const elapsedTime = this.convertToTime(currentTime); | |
const fullTime = this.convertToTime(audioDuration); | |
const timeRatio = `${elapsedTime} / ${fullTime}`; | |
const progressBarWidth = currentTime / audioDuration * 100; | |
return ( | |
<AudioBlock> | |
<audio | |
preload={true} | |
ref={ref => (this.audioElem = ref)} | |
onPlay={this.onPlayPause.bind(this, true)} | |
onPause={this.onPlayPause.bind(this, false)} | |
src={src} | |
/> | |
<PlayBtn onClick={this.play.bind(this)}> | |
{!isPlaying ? ( | |
<Sprites.Icon width={14} height={14} name="play" /> | |
) : ( | |
<Sprites.Icon width={14} height={14} name="pause" /> | |
)} | |
</PlayBtn> | |
<Progress> | |
<Progress width={progressBarWidth} type="inner" /> | |
</Progress> | |
<Time>{timeRatio}</Time> | |
</AudioBlock> | |
); | |
} | |
} | |
export default AudioPlayer; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment