音乐播放器
This commit is contained in:
parent
88fa436d89
commit
9f92b748b5
@ -91,6 +91,7 @@ export default {
|
|||||||
'/me/right-menu/setting',
|
'/me/right-menu/setting',
|
||||||
'/me/collect/video-collect',
|
'/me/collect/video-collect',
|
||||||
'/me/collect/music-collect',
|
'/me/collect/music-collect',
|
||||||
|
'/me/my-music',
|
||||||
|
|
||||||
'/login',
|
'/login',
|
||||||
'/login/other',
|
'/login/other',
|
||||||
|
|||||||
@ -96,9 +96,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="process"
|
<div class="progress"
|
||||||
v-if="duration > 60"
|
v-if="duration > 60"
|
||||||
:class="processClass"
|
:class="progressClass"
|
||||||
@touchmove="move"
|
@touchmove="move"
|
||||||
@touchend="end"
|
@touchend="end"
|
||||||
>
|
>
|
||||||
@ -157,7 +157,7 @@ export default {
|
|||||||
durationStyle() {
|
durationStyle() {
|
||||||
return {left: this.pageX + 'px'}
|
return {left: this.pageX + 'px'}
|
||||||
},
|
},
|
||||||
processClass() {
|
progressClass() {
|
||||||
if (this.isMove) {
|
if (this.isMove) {
|
||||||
return 'stop'
|
return 'stop'
|
||||||
} else {
|
} else {
|
||||||
@ -336,7 +336,7 @@ export default {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.isMove = false
|
this.isMove = false
|
||||||
}, 1000)
|
}, 1000)
|
||||||
this.currentTime = this.currentTime = Math.ceil(Math.ceil(e.changedTouches[0].pageX) / this.step)
|
this.currentTime = Math.ceil(Math.ceil(e.changedTouches[0].pageX) / this.step)
|
||||||
this.play()
|
this.play()
|
||||||
globalMethods.$stopPropagation(e)
|
globalMethods.$stopPropagation(e)
|
||||||
}
|
}
|
||||||
@ -628,7 +628,7 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.process {
|
.progress {
|
||||||
bottom: -1px;
|
bottom: -1px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<script>
|
<script>
|
||||||
import bus from "../utils/bus";
|
import bus from "../../utils/bus";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Indicator",
|
name: "Indicator",
|
||||||
@ -118,7 +118,7 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
@import "../assets/scss/index";
|
@import "../../assets/scss/index";
|
||||||
|
|
||||||
.indicator-ctn {
|
.indicator-ctn {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
@ -88,7 +88,7 @@
|
|||||||
<div class="bottom">发现超值好物</div>
|
<div class="bottom">发现超值好物</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item" @click="$no">
|
<div class="item" @click="$nav('/me/my-music')">
|
||||||
<img src="../../assets/img/icon/me/music-white.png" alt="">
|
<img src="../../assets/img/icon/me/music-white.png" alt="">
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="top">我的音乐</div>
|
<div class="top">我的音乐</div>
|
||||||
@ -324,7 +324,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import Posters from '../../components/Posters'
|
import Posters from '../../components/Posters'
|
||||||
import Footer from "../../components/Footer";
|
import Footer from "../../components/Footer";
|
||||||
import Indicator from '../../components/Indicator'
|
import Indicator from '../../components/slide/Indicator'
|
||||||
import {nextTick} from 'vue'
|
import {nextTick} from 'vue'
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import bus from "../../utils/bus";
|
import bus from "../../utils/bus";
|
||||||
|
|||||||
370
src/pages/me/MyMusic.vue
Normal file
370
src/pages/me/MyMusic.vue
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
<template>
|
||||||
|
<div class="MyMusic">
|
||||||
|
<Indicator
|
||||||
|
name="myMusicList"
|
||||||
|
tabStyleWidth="50%"
|
||||||
|
:tabTexts="['猜你爱听','我的收藏']"
|
||||||
|
v-model:active-index="slideIndex">
|
||||||
|
</Indicator>
|
||||||
|
<SlideRowList
|
||||||
|
style="height: calc(100vh - 5rem);"
|
||||||
|
name="myMusicList"
|
||||||
|
v-model:active-index="slideIndex">
|
||||||
|
<SlideItem>
|
||||||
|
<div class="music-play">
|
||||||
|
<div class="cover">
|
||||||
|
<img v-lazy="$imgPreview(music.cover)" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="lyrics-wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<div class="lyrics">111111111111111</div>
|
||||||
|
<div class="lyrics">222222222222222</div>
|
||||||
|
<div class="lyrics">333333333333333</div>
|
||||||
|
<div class="lyrics">444444444444444</div>
|
||||||
|
<div class="lyrics">555555555555555</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bottom">
|
||||||
|
<div class="desc">
|
||||||
|
<div class="left">
|
||||||
|
<div class="name">{{ music.name }}</div>
|
||||||
|
<div class="author">{{ music.author }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="btn">
|
||||||
|
<img src="../../assets/img/icon/star-white.png" alt="">
|
||||||
|
<span>收藏</span>
|
||||||
|
</div>
|
||||||
|
<div class="btn">
|
||||||
|
<img src="../../assets/img/icon/share-white-full.png" alt="">
|
||||||
|
<span>分享</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="progress">
|
||||||
|
<div class="start">{{ $durationTime(currentTime) }}</div>
|
||||||
|
<div class="bar">
|
||||||
|
<div class="slide-bar"
|
||||||
|
ref="slideBar"
|
||||||
|
@touchstart="start"
|
||||||
|
@touchmove="move"
|
||||||
|
@touchend="end"></div>
|
||||||
|
<div class="bar-line" :style="durationStyle(1)"></div>
|
||||||
|
<div class="bar-point" :style="durationStyle(2)"></div>
|
||||||
|
</div>
|
||||||
|
<div class="end">{{ $durationTime(duration) }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="options">
|
||||||
|
<img v-show="isLoop" src="../../assets/img/icon/me/loop.png" @click="isLoop = !isLoop">
|
||||||
|
<img v-show="!isLoop" src="../../assets/img/icon/me/play-normal.png" @click="isLoop = !isLoop">
|
||||||
|
<div class="center">
|
||||||
|
<img src="../../assets/img/icon/me/previous.png">
|
||||||
|
<img v-show="isPlay" class="control" src="../../assets/img/icon/me/pause.png" @click="togglePlay">
|
||||||
|
<img v-show="!isPlay" class="control" src="../../assets/img/icon/me/play.png" @click="togglePlay">
|
||||||
|
<img src="../../assets/img/icon/me/next.png">
|
||||||
|
</div>
|
||||||
|
<img src="../../assets/img/icon/me/music-list.png">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</SlideItem>
|
||||||
|
<SlideItem>
|
||||||
|
</SlideItem>
|
||||||
|
</SlideRowList>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {mapState} from "vuex";
|
||||||
|
import globalMethods from "../../utils/global-methods";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MyMusic",
|
||||||
|
components: {},
|
||||||
|
props: {
|
||||||
|
modelValue: false
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
slideIndex: 0,
|
||||||
|
music: {
|
||||||
|
name: '发如雪',
|
||||||
|
mp3: 'https://m3.8js.net:99/2014/211204142150965.mp3',
|
||||||
|
cover: require('../../assets/img/music-cover/7.png'),
|
||||||
|
author: '周杰伦',
|
||||||
|
duration: 60,
|
||||||
|
use_count: 37441000,
|
||||||
|
is_collect: false,
|
||||||
|
is_play: false,
|
||||||
|
},
|
||||||
|
isPlay: false,
|
||||||
|
isLoop: false,
|
||||||
|
isMove: false,
|
||||||
|
lastPageX: 0,
|
||||||
|
pageX: 0,
|
||||||
|
audio: new Audio(),
|
||||||
|
duration: 0,
|
||||||
|
currentTime: 0,
|
||||||
|
step: 0,
|
||||||
|
startX: 0,
|
||||||
|
slideBarWidth: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['bodyWidth'])
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.audio.src = this.music.mp3
|
||||||
|
this.audio.addEventListener('loadedmetadata', e => {
|
||||||
|
this.duration = this.audio.duration
|
||||||
|
this.slideBarWidth = this.$refs.slideBar.clientWidth
|
||||||
|
this.step = this.slideBarWidth / Math.floor(this.duration)
|
||||||
|
})
|
||||||
|
this.audio.addEventListener('timeupdate', e => {
|
||||||
|
if (!this.isMove) {
|
||||||
|
this.currentTime = Math.ceil(e.target.currentTime)
|
||||||
|
if (Math.ceil(e.target.currentTime) * this.step > this.slideBarWidth - 5) {
|
||||||
|
this.pageX = this.slideBarWidth - 5
|
||||||
|
} else {
|
||||||
|
this.pageX = Math.ceil(e.target.currentTime) * this.step
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.audio.addEventListener('play', e => this.isPlay = true)
|
||||||
|
this.audio.addEventListener('ended', e => {
|
||||||
|
if (this.isLoop) {
|
||||||
|
this.lastPageX = 0
|
||||||
|
this.audio.currentTime = 0
|
||||||
|
this.audio.play()
|
||||||
|
} else {
|
||||||
|
this.isPlay = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
togglePlay() {
|
||||||
|
this.isPlay = !this.isPlay
|
||||||
|
if (this.isPlay) {
|
||||||
|
this.audio.play()
|
||||||
|
} else {
|
||||||
|
this.audio.pause()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
start(e) {
|
||||||
|
this.startX = e.touches[0].pageX
|
||||||
|
},
|
||||||
|
move(e) {
|
||||||
|
this.isMove = true
|
||||||
|
this.pageX = this.lastPageX + (e.touches[0].pageX - this.startX)
|
||||||
|
if (this.pageX < 0) this.pageX = 0
|
||||||
|
if (this.pageX > this.slideBarWidth) this.pageX = this.slideBarWidth - 5
|
||||||
|
this.currentTime = Math.ceil(this.pageX / this.step)
|
||||||
|
globalMethods.$stopPropagation(e)
|
||||||
|
},
|
||||||
|
end(e) {
|
||||||
|
this.lastPageX = this.pageX
|
||||||
|
this.currentTime = Math.ceil(this.pageX / this.step)
|
||||||
|
this.audio.currentTime = this.currentTime
|
||||||
|
this.audio.play()
|
||||||
|
this.isMove = false
|
||||||
|
globalMethods.$stopPropagation(e)
|
||||||
|
},
|
||||||
|
$durationTime(time) {
|
||||||
|
if (time === 0) return '00:00'
|
||||||
|
else {
|
||||||
|
return this.$duration(time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
durationStyle(type) {
|
||||||
|
// return {}
|
||||||
|
if (type === 1) {
|
||||||
|
return {width: this.pageX + 'px'}
|
||||||
|
}
|
||||||
|
return {left: this.pageX + 'px'}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
@import "../../assets/scss/index";
|
||||||
|
|
||||||
|
.MyMusic {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
overflow: auto;
|
||||||
|
color: white;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
|
||||||
|
.music-play {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.cover {
|
||||||
|
margin-top: 4rem;
|
||||||
|
width: 80vw;
|
||||||
|
height: 80vw;
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-radius: 2.5rem;
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.lyrics-wrapper {
|
||||||
|
margin-top: 3rem;
|
||||||
|
overflow: auto;
|
||||||
|
height: 8rem;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
min-height: 8rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lyrics {
|
||||||
|
height: 4rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
width: 100vw;
|
||||||
|
padding: @padding-page;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 3.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
.name {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
margin-bottom: .4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
width: 100vw;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
padding: 0 @padding-page;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: gainsboro;
|
||||||
|
|
||||||
|
.bar {
|
||||||
|
margin: 0 .6rem;
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.slide-bar {
|
||||||
|
position: absolute;
|
||||||
|
height: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
top: -1rem;
|
||||||
|
z-index: 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
z-index: 9;
|
||||||
|
content: ' ';
|
||||||
|
height: 1.5px;
|
||||||
|
width: 100%;
|
||||||
|
background: gray;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-line {
|
||||||
|
z-index: 10;
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 1.5px;
|
||||||
|
width: 50vw;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bar-point {
|
||||||
|
z-index: 10;
|
||||||
|
position: absolute;
|
||||||
|
left: 50vw;
|
||||||
|
top: -3px;
|
||||||
|
height: .8rem;
|
||||||
|
width: .8rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
width: 100vw;
|
||||||
|
padding: @padding-page;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 3.8rem;
|
||||||
|
height: 3.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.control {
|
||||||
|
width: 5.5rem;
|
||||||
|
height: 5.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -209,7 +209,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Posters from '../../components/Posters'
|
import Posters from '../../components/Posters'
|
||||||
import Indicator from '../../components/Indicator'
|
import Indicator from '../../components/slide/Indicator'
|
||||||
import {nextTick} from 'vue'
|
import {nextTick} from 'vue'
|
||||||
import {mapState} from "vuex";
|
import {mapState} from "vuex";
|
||||||
import bus from "../../utils/bus";
|
import bus from "../../utils/bus";
|
||||||
|
|||||||
@ -129,7 +129,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import People from './components/People'
|
import People from './components/People'
|
||||||
import Search from '../../components/Search'
|
import Search from '../../components/Search'
|
||||||
import Indicator from '../../components/Indicator'
|
import Indicator from '../../components/slide/Indicator'
|
||||||
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
|
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|||||||
@ -55,6 +55,7 @@ import LivePage from "../pages/home/LivePage";
|
|||||||
import Test5 from "../pages/Test5";
|
import Test5 from "../pages/Test5";
|
||||||
import MusicCollect from "../pages/me/collect/MusicCollect";
|
import MusicCollect from "../pages/me/collect/MusicCollect";
|
||||||
import VideoCollect from "../pages/me/collect/VideoCollect";
|
import VideoCollect from "../pages/me/collect/VideoCollect";
|
||||||
|
import MyMusic from "../pages/me/MyMusic";
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
// {path: '', component: Music},
|
// {path: '', component: Music},
|
||||||
@ -111,6 +112,7 @@ const routes = [
|
|||||||
{path: '/me/right-menu/setting', component: Setting},
|
{path: '/me/right-menu/setting', component: Setting},
|
||||||
{path: '/me/collect/music-collect', component: MusicCollect},
|
{path: '/me/collect/music-collect', component: MusicCollect},
|
||||||
{path: '/me/collect/video-collect', component: VideoCollect},
|
{path: '/me/collect/video-collect', component: VideoCollect},
|
||||||
|
{path: '/me/my-music', component: MyMusic},
|
||||||
|
|
||||||
{path: '/login', component: Login},
|
{path: '/login', component: Login},
|
||||||
{path: '/login/other', component: OtherLogin},
|
{path: '/login/other', component: OtherLogin},
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import SlideRowList from "../components/slide/SlideRowList";
|
|||||||
import SlideColumnList from "../components/slide/SlideColumnList";
|
import SlideColumnList from "../components/slide/SlideColumnList";
|
||||||
import SlideColumnVirtualList from "../components/slide/SlideColumnVirtualList";
|
import SlideColumnVirtualList from "../components/slide/SlideColumnVirtualList";
|
||||||
import SlideItem from "../components/slide/SlideItem";
|
import SlideItem from "../components/slide/SlideItem";
|
||||||
import Indicator from "../components/Indicator";
|
import Indicator from "../components/slide/Indicator";
|
||||||
import Video from "../components/Video";
|
import Video from "../components/Video";
|
||||||
import Footer from "../components/Footer";
|
import Footer from "../components/Footer";
|
||||||
import Mask from "../components/Mask";
|
import Mask from "../components/Mask";
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user