• 每天看一片代码系列(三):codepen上一个音乐播放器的实现


    今天我们看的是一个使用纯HTML+CSS+JS实现音乐播放器的例子,效果还是很赞的: codePen地址

    HTML部分

    首先我们要思考一下,一个播放器主要包含哪些元素。首先要有播放的进度信息,还有播放/暂停或者上一首下一首等必要的按钮,同时还要显示一些当前播放的音乐名称等信息。播放多首歌曲时,要显示播放列表。。。因此,从语义上可以构造出基本的HTML结构:

    // 背景区块,用于显示当前播放音乐的图片
    <div class='background' id='background'></div>
    
    // 播放器区块
    <div id='player'>
        <audio id='mytrack' src=''></audio>
        //顶部区域,只显示一幅画
        <div id='artwork'></div>
        // 播放列表
        <div id='tracks'>
            <div trackartist='Tobu & Syndec' trackname='Dusk' trackartwork='01.jpg'></div>
            <div trackartist='Disfigure' trackname='Blank' trackartwork='02.jpg'></div>
            <div trackartist='Alan Walker' trackname='Fade' trackartwork='03.jpg'></div>
        </div>
       
        //播放器的UI部分
        <div id='ui'>
            //播放器已播放时间和总的时间
            <div id="time">
                <span id='elapsedtime'>00:00</span>
                <span id='totaltime'>00:00</span>
            </div>
            //进度条
            <div id='progressbar'>
                <div>
                    <span id='pointer'></span>
                </div>
            </div>
         // 播放器控件
            <div id='controls'>
                <button id='prev' class='control'></button>
                <button id='play' class='control'></button>
                <button id='stop' class='control'></button>
                <button id='next' class='control'></button>
            </div>
    
        </div>
    </div>

    CSS部分

    接下来看css部分。首先将player区块进行了居中,并添加了背景和阴影:

    #player
         300px
        position: absolute
        left: 50%
        top: 50%
        box-shadow: 0px 5px 10px #000
        background-color: $color4
        transform: translate(-50%, -50%)
        -o-transform: translate(-50%, -50%)
        -moz-transform: translate(-50%, -50%)
        -webkit-transform: translate(-50%, -50%)

    对于顶部的图像区块,设置充满宽度,并设置图像水平和垂直方向都居中,当图像切换时,增加了1s的过渡效果。

    #artwork
         100%
        height: 0
        padding-bottom: 100%
        display: block
        position: relative
        overflow: hidden
        background-image: url("../artworks/01.jpg")
        background-repeat: no-repeat
        background-size: cover
        background-position: center center
        transition: background 1s ease 0s
        -o-transition: background 1s ease 0s
        -moz-transition: background 1s ease 0s
        -webkit-transition: background 1s ease 0s

    这里将height设置为0,然后padding-bottom设置为100%(相对与父元素的宽度),由于它的宽和父元素的宽相同,结果就是将它的宽和高设成相同,即300px * 300px。

    播放列表区块首先是一个列表,因此我们直观地想到了用ul/li来实现,但是这里用的是将父元素设置display:table,然后每项的图片和名字设置为display: table-cell的形式:

        #tracks
             100%
            display: block
            overflow: hidden
            background-color: #fff
    
        div
             100%
            display: table
            background-color: #fff
            transition: all 0.5s ease 0s
            -o-transition: all 0.5s ease 0s
            -moz-transition: all 0.5s ease 0s
            -webkit-transition: all 0.5s ease 0s
            cursor: pointer
    
            span
                margin-right: 10px
                display: table-cell
                padding: 0px 10px
                height: 50px
                line-height: 50px
                font-size: 1.2em
                color: #aaa
    
            artwork
                text-align: center
                display: table-cell
                 50px
                background-repeat: no-repeat
                background-size: cover
                background-position: center center

    UI区块是重点,主要包括时间、进度条和控件三个部分。时间按理来说在布局上比较简单,但这里它又用到了我们想不到的display:list-item来实现(相当于ul,其实我觉得这里没有写这些),然后又用了css3中的first-of-type伪类用来匹配该类型的第一个元素等。

    进度条主要是通过将div的宽度逐渐增大并进行过渡。还有一个pointer,通过将它的背景设置为发亮,表明当前播放的位置。

        #progressbar
             100%
            display: block
            overflow: hidden
            height: $progressHeight
            background-color: $color4 - 10
            cursor: pointer
    
            div
                 0%
                height: $progressHeight
                display: block
                float: left
                background-color: $color3 - 40
                transition: width 0.1s ease 0s
                -o-transition: width 0.1s ease 0s
                -moz-transition: width 0.1s ease 0s
                -webkit-transition: width 0.1s ease 0s
    
            #pointer
                 4px
                height: $progressHeight
                display: block
                float: right
                background-color: $color3
                transform: translate(100%,0)

    最后是控件部分。每个控件的宽度设为25%向左浮动,并再次用到了display:list-item

    .control
         25%
        height: 50px
        float: left
        display: list-item
        list-style: none
        background-repeat: no-repeat
        background-color: transparent
        background-size: 20px
        background-position: center center
        transition: background 0.1s ease 0s
        -o-transition: background 0.1s ease 0s
        -moz-transition: background 0.1s ease 0s
        -webkit-transition: background 0.1s ease 0s
    
        &:hover
            cursor: pointer

    JS部分

    最后我们要看的是交互部分。交互主要包括:

    1. 换歌:在列表中高亮当前播放的歌曲,切换背景图片,播放
    2. 播放:播放声音,调整进度条,显示正确的按钮背景
    3. 上一条/下一条:=换歌,但还要考虑到第一首和最后一首的特殊情况
    4. 暂停/恢复:暂停/恢复音频的播放,显示正确的按钮背景
    5. 进度条点击:更新当前播放的时间点

    总之,包含的有:currentAudio, isPlaying, audioPosition这几个状态信息。

    比如点击了下一首,它会做这么几个交互上的改变:

    1. 按钮背景有一个状态按下的效果
    2. 停止当前歌曲的播放
    3. 重置进度条的位置
    4. 歌曲列表当前项显示有更新
    5. 顶部的封面有更新
    6. 如果当前isPlaying为true,则播放歌曲,更新进度条
        // 1
        if(this.classList[0] !== "shadow")
              {
                for(var x = 0; x < audioControls.children.length; x++)
                {
                  audioControls.children[x].classList.remove("shadow");
                }
    
                this.classList.add("shadow");
              }
    
    
        // 2
        audio.currentTime = 0;
        clearInterval(timer);
    
         // 3
         updateProgressBarPosition()
    
        // 4
        updateActiveTrack(currentTrack);
    
        // 5
         changeBackgroundImage(artwork, artworkSrc);
    
        // 6
        audio.play();
        audioState = "play";
        changeBackgroundImage(play, iconsFolder + "pause.png");
    
        // Update the time
        timer = setInterval(
          function()
          {
            updateTime();
          },
          100
        );
  • 相关阅读:
    大厂的面试官是如何挑人的?
    搞懂这7个Maven问题,带你吊打面试官!
    Spring Cloud Eureka 注册安全一定要做到位!
    09 webpack的介绍
    08 node.js 的使用
    07 Node.js安装及环境配置
    06-Nodejs介绍
    05-面向对象
    Mysql 的使用方法
    04-对象的单体模式
  • 原文地址:https://www.cnblogs.com/cubika/p/4440159.html
Copyright © 2020-2023  润新知