每天看一片代码系列(三):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
    width: 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
    width: 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
        width: 100%
        display: block
        overflow: hidden
        background-color: #fff

    div
        width: 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
            width: 50px
            background-repeat: no-repeat
            background-size: cover
            background-position: center center

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

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

    #progressbar
        width: 100%
        display: block
        overflow: hidden
        height: $progressHeight
        background-color: $color4 - 10
        cursor: pointer

        div
            width: 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
            width: 4px
            height: $progressHeight
            display: block
            float: right
            background-color: $color3
            transform: translate(100%,0)

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

.control
    width: 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
    );
时间: 2024-10-02 09:26:28

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

微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器

我的微信开发者工具 开篇语 好不容易,终于把所有的基础课程全部看完了!昨天,我很高兴地开始了看别人做的项目进行深度的学习.其实也说不上是项目吧,更多的像是一种给新手看的示例代码.然后我在这些代码上面进行我自己的改进.最后也就有了接下来我会给大家带来的这篇文章中的项目.这个项目是完整的,它包括了一个原本的示例代码中带着的莫名其妙的动画组件(可能是为了更多额展示微信小程序的控件体系)以及跑步的组件,还有我后来自己加上去的一个音乐播放组件.总共也就有了三个的功能:动画效果展示:跑步的定时以及定位功能:

Qt音乐播放器制作(三)Easy Player

今天发布了EasyPlayer的第一个版本,有兴趣的朋友可以到这里下载:基于Qt的在线音乐播放器EasyPlayer v1.0. 相对于上一篇文章,主要做了以下修改,还是先放图吧: 如图所示,爱折腾的博主又修改了界面. 最明显的变化在于去除了窗口边框,实现了自定义的最小化按钮和关闭按钮来操控窗体的相应动作. 然后,就是讲搜索列表和播放列表调换了位置,这么说来,搜索列表的右边按键要换了,改成"+"比较适合点. 最后,就是你们看到的,歌词显示界面了.第一个版本实现了歌词的同步搜索和显示,但

基于jQuery仿QQ音乐播放器网页版代码

基于jQuery仿QQ音乐播放器网页版代码是一款黑色样式风格的网页QQ音乐播放器样式代码.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class="m_player" id="divplayer" role="application" onselectstart="return false" style="left: 0px;"> <div class=&

RemoteViews用法三:包含的widget的类音乐播放器

关于widget的用法参考:RemoteViews用法一:widget简单用法 RemoteViews用法二:可以接收点击事件并改变外观的widget 这篇博文主要是完成一个类音乐播放器,全面的应用activity,widget,service这几个类. 下载: 代码不算少,就不在这里粘代码了,先把源码下载地址奉上:http://download.csdn.net/detail/u011647962/8184423 demo效果: 为什么这个demo叫类音乐播放器呢,因为只有播放器的形,没有播放

JS单曲调用百度mp3音乐播放器代码

在网上找的单曲调用百度mp3音乐播放器的代码,改了改,文本框输入歌曲名,中文逗号,歌手名,回车就可以试听了.几点说明:  百度音乐api 音乐文件地址,span,p,div,等都可以,ID 必须是songplay:  参数说明,第一个是歌曲名字,第二个是演唱者,最后一个如果为空则自动播放,不为空则手动播放.  参数间用中文逗号 , 分隔 ,点击按钮或者回车都可以播放. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN

android调用音乐播放器,三种方

小弟想请问一下,如何在自己写的程序中调用系统的音乐播放器呢. 我在google上搜索了,主要是有两种方法,但是都不是我想要的. 第一种是,使用mp3音乐文件的uri,和intent,进行调用,但是这种是针对某一首歌曲的播放使用的. /** * 播放指定名称的歌曲 * @param audioPath 指定默认播放的音乐 */ public static void playAudio(String audioPath){ Intent mIntent = new Intent(); mIntent

如何写一个正经的Android音乐播放器 三

实现音乐的播放. 为了快速实现音乐播放,我们使用MediaPlayer而不用SoundPool,据说SoundPool比MediaPlayer的自由度更大.不过,根据我的了解,soundpool并不支持音频的解码,得自己去解码,而MeidaPlayer已经内置了一些解码方案,我看到的是,音频除了ape无损格式,都能播放. 你需要阅读: MediaPlayer API: http://developer.android.com/reference/android/media/MediaPlayer

我的音乐播放器(3)逻辑代码

package com.jk.activity; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; imp

本地音乐播放器(三)

mainActivity (ui)代码! package cn.tedu.music_player_3.ui; import java.util.List; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter;