使用javascript,HTML5,CSS3打造移动端音乐播放器

前期准备

  1. 首先你要有一定的js,html5,css3的一些基层知识
  2. 你要要对H5的audio的API有一定的了解
  3. 你还要会一些css3的动画知识 

开发工具准备

webstrom,谷歌浏览器

开发思路

  • 首先我们要有一个歌曲的列表
  • 我们要想好我们播放器长什么样
  • 我们要做的交互效果

开始开发

首先看看我们的播放器要做成什么样:

有了设计我们开始开发吧
首先我们来获取歌曲的播放列表

<script>
    var songs=[];
    var curIndex=0;
    function initSongs(res) {
        songs=res.songs;
    }
</script>
<!--下面是用JSONP的方式来来获取歌曲列表-->
<script src="http://api.asilu.com/163music/?type=playlist&id=545888750&callback=initSongs&_=1494217574015"></script>
有了歌曲列表我们来写我们的页面结构和样式
页面样式:
<style>
    body{
        background-color: #333;
        margin: 0;
    }
    /*滑动时间的样式*/
    .slider-bar{
        height:4px;
        width: 100%;
        background-color: #6d6d6d;
        border-radius: 2px;
    }
    .slider-progress{
        position: relative;
        height: 100%;
        width: 0;
        background-color: #ff7471;
        border-radius: 2px;
    }
    .slider-dot-control{
        position: absolute;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        left: 100%;
        background-color: #ff7471;
        border: 6px solid #fff;
        top: 50%;
        margin-top: -9px;
        margin-left: -9px;
    }
    /*滑动时间的样式*/
    /*播放时间的样式*/
    .played-progress,.all-progress{
        display: flex;
        -webkit-justify-content: center;
        justify-content: center;
        padding: 0 10px;
        font-size: 14px;
    }
    .content-box{
        display: flex;
        height: 20px;
        color: #eee;
        margin-top: 20px;
    }
    .center-box{
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
    }
    .left-box{
        width: 100px;
        height: 100%;
        text-align: center;
        font-size: 14px;
    }
    .right-box{
        width: 100px;
        height: 100%;
        text-align: center;
        font-size: 14px;
    }
    /*播放时间的样式*/
    /*播放控制按钮的样式*/
    .control-box{
        color: #ccc;
        display: flex;
        align-items: center;
        height: 40px;
        -webkit-justify-content: center;
        justify-content: center;
        margin-top: 20px;
    }
    .control-box span{
        display: flex;
        width: 40px;
        height: 40px;
        align-items: center;
        -webkit-justify-content: center;
        justify-content: center;
        font-size: 30px;
    }
    .control-box span.play_bt{
        font-size: 35px;
    }
    /*播放控制按钮的样式*/
    /*歌曲信息的样式*/
    .song-info-txt{
        text-align: center;
        font-size: 14px;
        color: #ccc;
        line-height: 40px;
    }
    /*歌曲信息的样式*/
    /*歌曲封面的样式*/
    .poster-box img{
        display: block;
        width: 240px;
        height: 240px;
        border-radius: 50%;
        margin: 0 auto;
    }
    /*歌曲封面的样式*/
    /**************播放动画***************/
    @-webkit-keyframes rotateRound {
        0% {-webkit-transform: rotate(0deg);}
        100% {-webkit-transform: rotate(360deg);}
    }
    @-moz-keyframes rotateRound {
        0% {-moz-transform: rotate(0deg);}
        100% {-moz-transform: rotate(360deg);}
    }
    @keyframes rotateRound {
        0% {transform: rotate(0deg);}
        100% {transform: rotate(360deg);}
    }
    .playing{
        -moz-animation: rotateRound 20s linear infinite;
        -webkit-animation: rotateRound 20s linear infinite;
        animation: rotateRound 20s linear infinite;

    }
    /****************歌曲列表**********************/
    .music-list-body table{
        border-collapse: collapse;
        border-spacing: 0;
        width: 100%;
        color: #ccc;
        font-size: 12px;
    }
    .music-list-body table td,.music-list-body table th{
        text-align: left;
        line-height: 28px;
        padding: 0 10px;
        cursor: pointer;
    }
    .music-list-body table tbody tr:hover td{
        background-color: #1b1b1b;
    }
    .music-list-title{
        height: 32px;
        line-height: 32px;
        padding: 0 10px;
        font-size: 14px;
        color: #ccc;
        font-weight: bold;
        border-bottom: 1px solid #1b1b1b;
    }
    .music-list-box{
        height: 330px;
        overflow-y: auto;
    }
</style>

页面结构
<!--audio标签-->
    <audio src="http://p2.music.126.net/u1VARyxbQw3Zd7cFzJA4lw==/2920302883895034.mp3"></audio>
<!--歌曲信息-->
    <div class="song-info-box">
        <div class="song-info-txt"><span class="song-name"></span>-<span class="song-author">那英</span></div>
        <div class="poster-box"><img src="http://p1.music.126.net/QoxZfieoPBb096HDahCwrQ==/18698294743793765.jpg" class="music-poster"></div>
    </div>
<!--时间进度条-->
    <div class="content-box">
        <div class="left-box played-progress">00:00</div>
        <div class="center-box"> <div class="slider-bar">
            <div class="slider-progress">
                <div class="slider-dot-control"></div>
            </div>
        </div></div>
        <div class="right-box all-progress">00:00</div>
    </div>
<!--控制按钮-->
    <div class="control-box">
        <span class="prev_bt icon-previous iconfont" title="上一首"></span>
        <span class="play_bt icon-bofang iconfont" title="播放/暂停"></span>
        <span class="next_bt icon-next iconfont" title="下一首"></span>
    </div>
<!--歌曲列表-->
    <div class="music-list-box">
        <div class="music-list-title">歌曲列表</div>
        <div class="music-list-body">
            <table>
                <thead>
                <tr>
                    <th>歌名</th><th>歌手</th><th>时长</th>
                </tr>
                </thead>
                <tbody></tbody>
            </table>
        </div>
    </div>
交互逻辑
    <script>
        //预先设置获取需要使用的数据和参数
        var lastX=0;
        var power=false;
        var silider=document.querySelector('.slider-bar');
        var progress=document.querySelector('.slider-progress');
        var dot=document.querySelector('.slider-dot-control');
        var audio=document.querySelector('audio');
        var playBtn=document.querySelector('.play_bt');
        var poster=document.querySelector('.music-poster');
        var songName=document.querySelector('.song-name');
        var songAuthor=document.querySelector('.song-author');
        var prevSong=document.querySelector('.prev_bt');
        var nextSong=document.querySelector('.next_bt');
//        设置时间滑块事件
        dot.addEventListener('touchstart',function (e) {
            var touch=e.touches[0];
            power=true;
            lastX=touch.clientX;
        })
        document.addEventListener('touchmove',function (e) {
            var touch=e.touches[0];
            if(power){
                var curX=touch.clientX;
                var addW=curX-lastX;
                var setW=progress.offsetWidth+addW;
                var maxW=silider.offsetWidth;
                if(setW>=0&&setW<=maxW){
                    lastX=curX;
                    var percen=setW/maxW;
                }else if(setW<0){
                    percen=0;
                }else {
                    percen=1;
                }
                progress.style.width=percen*100+"%";
            }
        })
        document.addEventListener('touchend',function (e) {
            if(power){
                var setW=progress.offsetWidth;
                var maxW=silider.offsetWidth;
                if(setW>=0&&setW<=maxW){
                    var percen=setW/maxW;
                }else if(setW<0){
                    percen=0;
                }else {
                    percen=1;
                }
                progress.style.width=percen*100+"%";
                upDateProgress(percen);
            }
            power=false;
        })
        silider.addEventListener('click',function (e) {
            var setW=e.clientX-this.offsetLeft;
            var maxW=silider.offsetWidth;
            if(setW>=0&&setW<=maxW){
                var percen=setW/maxW;
                progress.style.width=percen*100+"%";
                upDateProgress(percen)
            }
        })
//        上一曲
        prevSong.onclick=function () {
            curIndex--;
            if(curIndex<0){
                curIndex=songs.length-1;
            }
            changeSong(curIndex);
            setTimeout(function () {
                audio.play();
            },200)
        }
//        下一曲
        nextSong.onclick=function () {
            curIndex++;
            if(curIndex>=songs.length){
                curIndex=0;
            }
            changeSong(curIndex);
            setTimeout(function () {
                audio.play();
            },200)
        }
//        更改进度条
        function upDateProgress(percence) {
            audio.currentTime=percence*audio.duration;
        }
//        切换歌曲
        function changeSong(index) {
            if((0<=index)&&(index<songs.length)){
                var curSong=songs[index];
                audio.src=curSong.src;
                poster.src=curSong.image;
                songName.innerHTML=curSong.title;
                songAuthor.innerHTML=curSong.author;
            }
        }
//        监听播放事件
        audio.onplay=function () {
            playBtn.className='play_bt icon-zanting iconfont';
            poster.className='playing music-poster';
        }
//        监听暂停事件
        audio.onpause=function () {
            playBtn.className='play_bt icon-bofang iconfont';
            poster.className='music-poster';
        }
//        播放或暂停
        playBtn.onclick=function () {
            if(audio.paused){
                audio.play()
            }else {
                audio.pause()
            }
        }
//        监听可以播放事件
        audio.oncanplay=function () {
            document.querySelector('.all-progress').innerHTML=duration(parseInt(audio.duration))
            if(!power){
                var prence=audio.currentTime/audio.duration;
                progress.style.width=prence*100+"%";
            }
            if(audio.paused){
                playBtn.className='play_bt icon-bofang iconfont';
                poster.className='music-poster';
            }else {
                playBtn.className='play_bt icon-zanting iconfont';
                poster.className='playing music-poster';
            }
        }
//        监听播放时间变化事件
        audio.ontimeupdate=function () {
            document.querySelector('.played-progress').innerHTML=duration(parseInt(audio.currentTime))
            if(!power){
                var prence=audio.currentTime/audio.duration;
                progress.style.width=prence*100+"%";
            }
        }
//        监听播放结束事件
        audio.onended=function () {
            curIndex++;
            if(curIndex>=songs.length){
                curIndex=0;
            }
            changeSong(curIndex);
            setTimeout(function () {
                audio.play();
            },200)
        }
//        格式化时间格式
        var duration=function (time) {
            var fen=parseInt(time/60);
            var miao=time%60;
            if(fen<=9){
                fen="0"+fen;
            }
            if(miao<=9){
                miao="0"+miao;
            }
            return fen+':'+miao;
        }
        changeSong(0);
        setList(songs);
//        初始化显示歌曲列表
        function setList(songs) {
            var list=document.querySelector('table tbody');
            songs.forEach(function (song,idx){
                var html='<tr οnclick="playSong('+idx+')"><td>'+song.title+'</td><td>'+song.author+'</td><td>--:--</td></tr>';
                list.innerHTML+=html;
            })
        }
//        播放指定位置的歌曲
        function playSong(i) {
            if(curIndex!=i){
                curIndex=i;
                changeSong(curIndex);
                setTimeout(function () {
                    audio.play();
                },200)
            }else {
                audio.play();
            }
        }
    </script>
到这里我们就完成了全部的开发工作和播放器的基本功能。接下来让我们运行一下看看效果怎么样。

好的大功告成。浓浓的黑色风格。接下来就是测试了。测试很简单就是看看我们的实际效果与我们设计预想的效果有哪些差别。
测试完了是时候总结一波了。

开发总结

  • 开发过程中我们要想到我们作品是要运行在移动端的。我们的滑块时间轴要用touch事件来做。
  • 我们要想到如何获取滑动的距离和触控点的位置
  • 我们要想到播放器时间变化事件改变时间进度条不能与我们滑动时间进度条互相冲突
  • 最后就是功能的扩展了比如说:显示歌词,播放顺序的控制,让我们的播放器隐藏在网页的某个角落,映射歌曲的播放状态,做一些播放歌曲特效等等
最后的最后就是让我们的作品发布的网上。这里我就不作介绍,有兴趣的的小伙伴自己去搜索。
  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值