Skip to content

Commit

Permalink
播放页
Browse files Browse the repository at this point in the history
  • Loading branch information
HUA616436641 committed May 24, 2019
1 parent 58db071 commit 89c83f2
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 44 deletions.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
-->
<title>React App</title>
<script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
<link rel="stylesheet" href="//at.alicdn.com/t/font_1183883_8sp7kwstwnb.css"/>
<link rel="stylesheet" href="//at.alicdn.com/t/font_1183883_k998zh6mui.css"/>
<script>
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function () {
Expand Down
132 changes: 98 additions & 34 deletions src/pages/play.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { NavBar, Icon, Slider } from 'antd-mobile';
import { NavBar, Icon, Slider, Button } from 'antd-mobile';
import './play.scss';
import { home } from '@/api'
import BScroll from 'better-scroll'
Expand All @@ -9,17 +9,24 @@ export default class Play extends React.Component {
super()
this.state = {
songUrl: '',
lrcArray: [],
curTimeStamp: '00:00',
length: 0
picUrl: '',
lrcArr: [],
curTimeStamp: 0,
duration: 0,
// 是否拖动状态
draging: false,
// 是否播放状态
playing: true

}
}
componentWillMount () {
let id = this.props.match.params.id
if (!id) return
home.getSongDetail({ ids: id }).then(res => {
this.setState({
length: res.songs[0].dt
duration: res.songs[0].dt,
picUrl: res.songs[0].al.picUrl
})
})
home.getSongUrl({ id }).then(res => {
Expand All @@ -28,25 +35,24 @@ export default class Play extends React.Component {
})
})
home.getLyric({ id }).then(res => {
let lrcArray = this.parseLrc(res.lrc.lyric)
this.setState({
lrcArray
})
if (res.lrc && res.lrc.lyric) {
let lrcArr = this.parseLrc(res.lrc.lyric)
this.setState({
lrcArr
})
}
})

}
componentDidMount () {
let wrapper = document.querySelector('.lrc-wrap')
lrcScroll = new BScroll(wrapper, {})
setTimeout(() => {
document.querySelector('.player').currentTime = 10
}, 1000)
}
formatToTime (timeStamp) {
let time = parseInt(timeStamp) / 1000
let m = Math.floor(time / 60)
// let time = parseInt(timeStamp) / 1000
let m = Math.floor(timeStamp / 60)
m < 10 && (m = '0' + m)
let s = Math.floor(time % 60)
let s = Math.floor(timeStamp % 60)
s < 10 && (s = '0' + s)
return `${m}:${s}`
}
Expand All @@ -57,7 +63,7 @@ export default class Play extends React.Component {
}
parseLrc (text) {
let res = text.split('\n')
let timeReg = /^\[(\d{2}):(\d{2})\.(\d{2})\]/
let timeReg = /^\[(\d{2}):(\d{2})\.(\d*)\]/
res = res.map(line => {
let obj = {}
let result = line.match(timeReg)
Expand All @@ -67,28 +73,79 @@ export default class Play extends React.Component {
}
return obj
})
return res.filter(line => line.content !== '')
return res
}
onTimeUpdate (e) {
let curTimeStamp = this.formatToTime(e.timeStamp)
let idx = this.state.lrcArray.findIndex(line => line.timeStamp === curTimeStamp)
onTimeUpdate () {
let curTimeStamp = document.querySelector('.player').currentTime
let idx = this.state.lrcArr.findIndex(line => line.timeStamp === this.formatToTime(curTimeStamp))
if (idx >= 0) {
// 滚动歌词
let el = document.querySelector('.lrc-list')
let lrcEl = el.querySelectorAll('.lrc-item')[idx]
lrcScroll.scrollToElement(lrcEl, 300, 0, -150)

// 歌词高亮
let lrcArr = this.state.lrcArr.map(line => ({
...line,
active: line.timeStamp === this.formatToTime(curTimeStamp)
}))
this.setState({
lrcArr
})
}
if (!this.state.draging) {
this.setState({
curTimeStamp
})
}
}
onTimeChange (val) {
let state = this.state
// 设置播放时间
this.setState({
curTimeStamp
draging: true,
curTimeStamp: val
})
}
onAfterTimeChange (val) {
let state = this.state
document.querySelector('.player').currentTime = val
this.setState({
curTimeStamp: val
})
this.setState({
draging: false
})
// 滚动歌词
let idx = state.lrcArr.findIndex(line => line.timeStamp === this.formatToTime(val))
if (idx) {
let el = document.querySelector('.lrc-list')
let lrcEl = el.querySelectorAll('.lrc-item')[idx]
lrcScroll.scrollToElement(lrcEl, 300, 0, -150)
}
}
togglePlay () {
let player = document.querySelector('.player')
if (player.paused) {
player.play()
this.setState({
playing: true
})
} else {
player.pause()
this.setState({
playing: false
})
}
}
render () {
let state = this.state
// let detail = this.state.detail
let lrcList
if (this.state.lrcArray.length) {
if (this.state.lrcArr.length) {
lrcList = (
this.state.lrcArray.map((item, index) => (
<div className={`lrc-item ${item.timeStamp === this.state.curTimeStamp ? 'active' : ''}`} key={index}>
this.state.lrcArr.map((item, index) => (
<div className={`lrc-item ${item.active ? 'active' : ''}`} key={index}>
{item.content}
</div>
)))
Expand All @@ -106,28 +163,35 @@ export default class Play extends React.Component {
]}
>
</NavBar>
<audio src={state.songUrl} onTimeUpdate={this.onTimeUpdate.bind(this)} controls autoPlay={true} className="player"> </audio>
<div className="content">
<audio src={this.state.songUrl} onTimeUpdate={this.onTimeUpdate.bind(this)} controls autoPlay={true} className="player"> </audio>
<div className="lrc-wrap" style={{ transform: `translateY(${this.state.lrcTop}px)` }}>
<div className="lrc-wrap">
<div className="lrc-list">
{lrcList}
</div>
</div>
<div className="control">
<div className="slider">
<span className="cur-time">{state.curTimeStamp}</span>
<span className="cur-time">{this.formatToTime(state.curTimeStamp)}</span>
<Slider
style={{ marginLeft: 10, marginRight: 10 }}
defaultValue={0}
value={this.formatToNum(state.curTimeStamp)}
value={state.curTimeStamp}
min={0}
max={30}
onChange={() => { }}
onAfterChange={() => { }}
max={Math.floor(state.duration / 1000)}
onChange={this.onTimeChange.bind(this)}
onAfterChange={this.onAfterTimeChange.bind(this)}
onClick={() => { console.log(555) }}
aa={123}
/>
<span className="total-time">{this.formatToTime(state.length)}</span>
<span className="total-time">{this.formatToTime(state.duration / 1000)}</span>
</div>
<div className="play-btns">
<span className="iconfont icon-danqu"></span>
<span className="iconfont icon-prev"></span>
<span className={`iconfont ${state.playing ? 'icon-pause' : 'icon-play1'}`} onClick={this.togglePlay.bind(this)}></span>
<span className="iconfont icon-next"></span>
<span className="iconfont icon-play-list"></span>
</div>

</div>
</div>
</div>
Expand Down
32 changes: 26 additions & 6 deletions src/pages/play.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@
.play-p{
.player{
// z-index: -9999;
position: absolute;
// visibility: hidden;
// position: absolute;
visibility: hidden;
}
.content{
padding: 0.35rem;
display: flex;
flex-direction: column;
.lrc-wrap{
overflow: auto;
flex: 1 1 auto;
}
.control{
height: 2rem;
height: 3rem;
flex: 0 0 auto;
}
}
Expand All @@ -27,18 +28,19 @@
}
.lrc-item{
line-height: 1.3;
margin: 0.5rem;
margin: 0.7rem 0.2rem;
padding-left: 10px;
color: fff;
color: #ccc;
transition: color .5s;
text-align: center;
@include fs(0.45rem);
@include fs(0.4rem);
}
.lrc-item.active{
color: greenyellow;
transition: color .5s;
}
.lrc-list{
padding: 4rem 0;
transition-duration: .3s !important;
}
.lrc-list .slider-frame{
Expand All @@ -48,6 +50,12 @@
.slider{
display: flex;
align-items: center;
margin: 0.3rem 0 0.5rem;
}
.am-slider{
margin-left: 10px;
margin-right: 10px;
touch-action: none;
}
.am-slider-wrapper{
flex: 1 0 auto;
Expand All @@ -57,5 +65,17 @@
width: 1rem;
flex: 0 1 auto;
}
.play-btns{
display: flex;
align-items: center;
.iconfont{
text-align: center;
@include fs(0.6rem);
flex: 1;
&.icon-play1,&.icon-pause{
@include fs(1.3rem);
}
}
}
}
}
1 change: 1 addition & 0 deletions src/styles/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ code {
.content{
background-color: rgba(0,0,0,.4);
overflow: auto;
flex: 1 1 auto;
}
}
@mixin ellipsis{
Expand Down
11 changes: 8 additions & 3 deletions src/utils/http.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import axios from 'axios'
import qs from 'qs'
import { Toast } from 'antd-mobile';

// let baseURL = 'http://localhost:3000'
let baseURL = 'http://192.168.10.115:3000'
// let baseURL = 'http://192.168.1.104:3000'
Expand All @@ -11,11 +13,14 @@ axios.interceptors.request.use(config => {
})

axios.interceptors.response.use(response => {
// console.log(response)
return response.data
}, error => {
// console.log(response)
return Promise.resolve(error.response)
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
Toast.offline('请求超时', 1);
return
}
Toast.fail(error.message, 1);
return Promise.reject(error)
})

// function checkStatus (response) {
Expand Down

0 comments on commit 89c83f2

Please sign in to comment.