Vue制作富有质感的方形HTML5音乐播放器

2022-05-07  本文已影响0人  ohityes

这是一款使用 Vue 制作的富有质感的方形 HTML5 音乐播放器,播放器左上角以浮起的方式显示封面,右侧是使用 svg 绘制的播放控制按钮,包含了收藏、上一首、下一首和播放,下面部分显示歌名、歌手名和播放进度条。这款播放器简洁精致,可用作独立的播放器使用。

HTML5音乐播放器
查看效果:Vue制作富有质感的方形HTML5音乐播放器

制作过程

1、HTML

<div class="wrapper" id="app">
    <div class="player">
        <div class="player__top">
            <div class="player-cover">
                <transition-group :name="transitionName">
                    <div
                        class="player-cover__item"
                        v-if="$index === currentTrackIndex"
                        :style="{ backgroundImage: `url(${track.cover})` }"
                        v-for="(track, $index) in tracks"
                        :key="$index"
                    ></div>
                </transition-group>
            </div>
            <div class="player-controls">
                <div
                    class="player-controls__item -favorite"
                    :class="{ active : currentTrack.favorited }"
                    @click="favorite"
                >
                    <svg class="icon">
                        <use xlink:href="#icon-heart-o"></use>
                    </svg>
                </div>
                <a :href="currentTrack.url" target="_blank" class="player-controls__item">
                    <svg class="icon">
                        <use xlink:href="#icon-link"></use>
                    </svg>
                </a>
                <div class="player-controls__item" @click="prevTrack">
                    <svg class="icon">
                        <use xlink:href="#icon-prev"></use>
                    </svg>
                </div>
                <div class="player-controls__item" @click="nextTrack">
                    <svg class="icon">
                        <use xlink:href="#icon-next"></use>
                    </svg>
                </div>
                <div class="player-controls__item -xl js-play" @click="play">
                    <svg class="icon">
                        <use xlink:href="#icon-pause" v-if="isTimerPlaying"></use>
                        <use xlink:href="#icon-play" v-else></use>
                    </svg>
                </div>
            </div>
        </div>
        <div class="progress" ref="progress">
            <div class="progress__top">
                <div class="album-info" v-if="currentTrack">
                    <div class="album-info__name">{{ currentTrack.artist }}</div>
                    <div class="album-info__track">{{ currentTrack.name }}</div>
                </div>
                <div class="progress__duration">{{ duration }}</div>
            </div>
            <div class="progress__bar" @click="clickProgress">
                <div class="progress__current" :style="{ width : barWidth }"></div>
            </div>
            <div class="progress__time">{{ currentTime }}</div>
        </div>
        <div v-cloak></div>
    </div>
</div>

2、CSS

.wrapper {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background-size: cover;
}
@media screen and (max-width: 700px), (max-height: 500px) {
    .wrapper {
        flex-wrap: wrap;
        flex-direction: column;
    }
}
.player {
    background: #eef3f7;
    width: 410px;
    min-height: 480px;
    box-shadow: 0px 15px 35px -5px rgba(50, 88, 130, 0.32);
    border-radius: 15px;
    padding: 30px;
}
@media screen and (max-width: 576px), (max-height: 500px) {
    .player {
        width: 95%;
        padding: 20px;
        margin-top: 75px;
        min-height: initial;
        padding-bottom: 30px;
        max-width: 400px;
    }
}
.player__top {
    display: flex;
    align-items: flex-start;
    position: relative;
    z-index: 4;
}
@media screen and (max-width: 576px), (max-height: 500px) {
    .player__top {
        flex-wrap: wrap;
    }
}
.player-cover {
    width: 300px;
    height: 300px;
    margin-left: -70px;
    flex-shrink: 0;
    position: relative;
    z-index: 2;
    border-radius: 15px;
    z-index: 1;
}
...

3、Javascript

new Vue({
    el: '#app',
    data() {
        return {
            audio: null,
            circleLeft: null,
            barWidth: null,
            duration: null,
            currentTime: null,
            isTimerPlaying: false,
            tracks: [
                {
                    name: 'Dawn',
                    artist: 'Skylike',
                    cover: 'img/1.jpg',
                    source: 'https://cdn.dowebok.com/mp3/2.mp3',
                    url: 'https://www.dowebok.com/8636.html',
                    favorited: false
                },
                ...
            ],
            currentTrack: null,
            currentTrackIndex: 0,
            transitionName: null
        }
    },
    created() {
        let vm = this
        this.currentTrack = this.tracks[0]
        this.audio = new Audio()
        this.audio.src = this.currentTrack.source
        this.audio.ontimeupdate = function () {
            vm.generateTime()
        }
        this.audio.onloadedmetadata = function () {
            vm.generateTime()
        }
        this.audio.onended = function () {
            vm.nextTrack()
            this.isTimerPlaying = true
        }
        for (let index = 0; index < this.tracks.length; index++) {
            const element = this.tracks[index]
            let link = document.createElement('link')
            link.rel = 'prefetch'
            link.href = element.cover
            link.as = 'image'
            document.head.appendChild(link)
        }
    },
    methods: {
        play() {
            if (this.audio.paused) {
                this.audio.play()
                this.isTimerPlaying = true
            } else {
                this.audio.pause()
                this.isTimerPlaying = false
            }
        },
        prevTrack() {
            this.transitionName = 'scale-in'
            this.isShowCover = false
            if (this.currentTrackIndex > 0) {
                this.currentTrackIndex--
            } else {
                this.currentTrackIndex = this.tracks.length - 1
            }
            this.currentTrack = this.tracks[this.currentTrackIndex]
            this.resetPlayer()
        },
        nextTrack() {
            this.transitionName = 'scale-out'
            this.isShowCover = false
            if (this.currentTrackIndex < this.tracks.length - 1) {
                this.currentTrackIndex++
            } else {
                this.currentTrackIndex = 0
            }
            this.currentTrack = this.tracks[this.currentTrackIndex]
            this.resetPlayer()
        },
        ...
    }
})

到这里就制作完了,由于代码过长,上面所展示的并不是全部的,如需下载代码,请前往:Vue制作富有质感的方形HTML5音乐播放器

上一篇下一篇

猜你喜欢

热点阅读