手把手教你10分钟做一个音乐播放器

Posted 北极光之夜。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你10分钟做一个音乐播放器相关的知识,希望对你有一定的参考价值。

一.话不多,先看效果:

视频B站效果演示地址~

 (大佬勿入,大佬勿入,大佬勿入)这是个单页面音乐播放器,只用到了 html+css 与很基础的vue语法,所以适合初学者,看一看10分钟就会了~

这个思路是借鉴黑马的~

二.详细制作步骤(完整代码在最后):

1.第一步当然是定义标签,对于每一个标签的作用注释都写得清清楚楚啦~:

<!-- 最底层的盒子 -->
<div class="container" id="container">
      <!-- 头部区域盒子 -->
      <div class="top">
          <!-- 搜索框 -->
          <input type="text"   class="txt" v-model='query' @keyup.enter="searchMusic">
      </div>
      <!-- 歌曲列表区域 -->
      <div class="list">
         <ul>
             <!-- 每个li是一首歌 -->
             <li v-for="(item,index) in musicList " :key="index">
                 <a href="javascript:;" @click="playMusic(item.id)"></a>
                 {{item.name}}
            </li>
        </ul>
         
      </div>
      <!-- 中间区域 -->
      <div class="middle">
          <!-- 那个旋转的杆 -->
          <img src="img/player_bar.png" alt="x" class="bar" :class="{playing:isPlay}">
          <!-- 唱片 -->
          <img src="img/disc.png" alt="x" class="disk" :class="{turn:isPlay}">
          <!-- 唱片中间的海报 -->
          <img :src="poster" class="poster">
      </div>
      <!-- 评论区 -->
      <h5 class="commentTxt">热门评论:</h5>
      <div class="comment">
          <ul>
          <!-- 每条评论 -->
              <li v-for="(item,index) in comment" :key="index">
              <!-- 头像 -->
                <img :src="item.user.avatarUrl" alt="" width="50px" height="50px">
                <!-- 网名 -->
                <h3>{{item.user.nickname}}</h3>
                <!-- 评论内容 -->
                 <p> {{item.content}}</p>
              </li>
          </ul>
      </div>
      <!-- 播放器进度条 -->
      <audio class="music" @play="play" @pause="pause" :src="url" controls autoplay loop></audio>
  </div>

标签里的vue语法解释(先看后面的js部分再看这里更好理解):

 <input type="text"   class="txt" v-model='query' @keyup.enter="searchMusic">

给这个标签 v-model='query’双向绑定数据query,@keyup.enter="searchMusic"绑定键盘回车事件,触发searMusic函数。

 {{item.name}}

放内容,写在{{}}里。item相对于变量。

 <li v-for="(item,index) in musicList " :key="index">

v-for="" 根据 musicList这个数组里元素的数量,动态生成多少个 li 。

 <a href="javascript:;" @click="playMusic(item.id)"></a>

@click="playMusic(item.id)点击事件,触发playMusic(item.id)函数,并传参数。

 <img src="img/player_bar.png" alt="x" class="bar" :class="{playing:isPlay}">

:class="{playing:isPlay},若isPlay值为真,playing这个选择器生效。

 <img :src="poster" class="poster">

:src="poster"地址的值为自己定义的变量poster。

后面都是相似的了,以此类推~

2.定义css部分,对一些不常见的属性都会解释~:

1.整体区域:
       /* 整体 */
       .container{
           width: 800px;
           height: 500px;
           background-color: rgba(248, 250, 252,0.3);
           border-radius: 10px;
           position: relative;
           overflow: hidden;
       }

border-radius: 10px; 角弧度
overflow: hidden;溢出隐藏

2.头部区域:
   /* 头部 */
   .top{
       position: absolute;
       top: 0;
       left: 0;
       width: 100%;
       height: 60px;
       border-radius: 10px 10px 0 0;
       background-image: linear-gradient(45deg,rgb(99, 202, 243),rgb(9, 253, 180),rgb(40, 106, 230));
       z-index: 11;
   }
   .txt{
       position: absolute;
       top: 15px;
       right: 50px;
       width: 200px;
       height: 30px;
       outline: none;
       border-radius: 15px;
       border: none;
       background-color: rgba(255, 255, 255,0.8);
       padding: 0  20px 0 20px;
       font-size: 13px;
   }

background-image: linear-gradient(45deg,rgb(99, 202, 243),rgb(9, 253, 180),rgb(40, 106, 230));渐变背景色。
z-index: 11; 显示的级别,就是防止被别的元素遮挡,越大越上
border: none; 取消边框

3. 歌曲列表部分:
   /* 歌曲列表 */
   .list{
       position: absolute;
       left: 0;
       top: 60px;
       width: 200px;
       height: 410px;
       background-color: rgba(255, 255, 255,0.5);
   }
   .list>ul{
       position: absolute;
       width: 100%;
       height: 100%;
       overflow: auto;
   }
   .list>ul>li{
       position: relative;
       width: 100%;
       height: 40px;
       line-height: 40px;
       font-family: 'fangsong';
       font-size: 16px;
       margin-top: 1px;
       padding-left: 30px;
       background-color: rgba(255, 255, 255, 0.9);
   }
   .list>ul>li>a{
       position: absolute;
       top: 50%;
       left: 5px;
       transform: translateY(-50%);
       width: 20px;
       height: 20px;
       background-image: url(img/play.png);
       background-size: 100% 100%;
       
   }

overflow: auto;如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。
transform: translateY(-50%); 偏移,通常在定位50%后再偏移自身大小50%达到居中效果。

4. 中间部分:
   /* 中间部分 */
   .middle{
       position: absolute;
       left: 210px;
       top: 60px;
       width: 410px;
       height: 410px;
   }
   .disk{
       position: absolute;
       width: 280px;
       height: 280px;
       left: 50%;
       top: 50%;
       transform: translate(-50%,-50%) rotateZ(0deg);
   }
   .bar{
       position: absolute;
       top: -10px;
       left: 50%;
       z-index:10;
       transform-origin: 10px 10px;
      /*  10 -25 */
       transform: rotateZ(-25deg);
       transition: all 1s;
   }
   .poster{
       position: absolute;
       top: 50%;
       left: 50%;
       transform: translate(-50%,-50%);
       width: 160px;
       height: 160px;
       border-radius: 50%;
       object-fit: cover;
   }

transform: translate(-50%,-50%) rotateZ(0deg); translate(-50%,-50%)表偏移, rotateZ(0deg)表旋转。
transform-origin: 10px 10px; 旋转点就是绕哪个点旋转。
transition: all 1s; 过渡效果。
object-fit: cover; 保持图片原有尺寸比例。但部分内容可能被剪切。

5.评论区:
   /* 评论 */
   .comment{
      position: absolute;
      top: 80px;
      right: -20px;
      height: 410px;
      width: 230px;
      overflow: auto;
      background-color: rgba(255, 255, 255,.4);
      border-top-left-radius: 15px;
   }
   .commentTxt{
       position: absolute;
       top: 60px;
       right: 110px;
       width: 100px;
       height: 20px;
       line-height: 20px;
       font-size: 12px;
       color: rgb(0, 0, 0);
   }
   .comment>ul>li{
      width: 210px;
      min-height: 50px;
      margin-top: 10px;
      font-size: 13px;
      padding: 5px;
      text-align:justify;
   }
   .comment>ul>li>img{
       border-radius: 50%;
       display: inline-block;
       vertical-align: middle;
   }
   .comment>ul>li>h3{
       display: inline-block;
       padding-left: 5px;
   }
   .comment>ul>li>p{
       padding-top: 6px;
       display: block;
       text-indent: 2em;
   }

vertical-align: middle;该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐。
text-indent: 2em;将段落的第一行缩进xxx像素:

6. 播放器进度条部分:
   /* 进度条 */
   .music{
        position: absolute;
        bottom: 0px;
        left:0px;
        width: 800px;
        height: 34px;
        outline: none;
        background-color: rgb(241, 243, 244);         
   }
7. 杆和唱片转动
   /* 杆和唱片转动 */
   .playing{
       transform: rotateZ(10deg);
   }
   .turn{
     animation:turn 3s linear infinite;
   }
   @keyframes turn{
       0%{
        transform: translate(-50%,-50%) rotateZ(0deg);
       }
       100%{
        transform: translate(-50%,-50%) rotateZ(360deg);
       }
   }

3. js部分,用vue语法写

1.先引入:
     <!-- 开发环境版本,包含了有帮助的命令行警告 -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- 官网提供的 axios 在线地址 -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2.开始(详细请看注释):

歌曲主要调用的是网易云的公开API所得~

   new Vue({
      el:"#container",
      data(){
          return{
            //搜索关键字
            query:'',
            //歌曲列表
            musicList:[],
            //当前歌曲地址
            url:'',
            //海报地址
            poster:'./img/timg4.jpg',
            //判断是否正在播放
            isPlay: false,
            //评论
            comment:[]
          }
      },
      methods:{
         searchMusic(){
          // 判断搜索框有没有字
           if(this.query==''){
           //没有自己返回
               return;
           }
           // 发送请求获得数据
           axios({
               url:'https://autumnfish.cn/search',
               method:'get',
               params:{
                 keywords:this.query
               }
           }).then(res=>{
                //把获取数据传给musicList数组,可以通过 console.log(res);查看自己想要的数据
               this.musicList = res.data.result.songs;
           })
        },
         playMusic(id){
             //获得歌曲的url
             axios({
                url:'https://autumnfish.cn/song/url',
                method:'get',
                params:{
                   id:id
                }
             }).then(res=>{
                // 将当前歌曲地址设置为这个
                this.url = res.data.data[0].url;
             })
             //获取歌曲海豹
             axios({
                url:'https://autumnfish.cn/song/detail',
                method:'get',
                params:{
                   ids:id
                }
             }).then(res=>{
               // 把图片地址纯存在poster数组
                this.poster=res.data.songs[0].al.picUrl
             })
             //获取评论
             axios({
                url:'https://autumnfish.cn/comment/hot',
                method:'get',
                params:{
                   type:0,
                   id:id
                }
             }).then(res=>{
               // 把评论的数据存在comment数组,包括头像,网名等等,可以通过 console.log(res);查看自己想要的数据
                this.comment=res.data.hotComments
             })
         },  
         // 歌曲是正在播放触发
         play(){
           this.isPlay = true;
         },
           // 歌曲是停止触发
         pause(){
             this.isPlay = false;
         }
        }
  })

三. 完整代码(需要素材与源文件的私信或在评论区留下邮箱,我发你呀):

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>music</title>
    <style>
       *{
           margin: 0;
           padding: 0;
           box-sizing: border-box;
       }
       body{
           height: 100vh;
           display: flex;
           justify-content: center;
           align-items: center;
       }
       /* 背景图 */
       .bj{
           position: fixed;以上是关于手把手教你10分钟做一个音乐播放器的主要内容,如果未能解决你的问题,请参考以下文章

手把手教你做音乐播放器桌面小工具(上)

手把手教你做音乐播放器音乐列表的存储(上)

手把手教你做音乐播放器存储多首音乐

手把手教你做音乐播放器桌面小工具(下)(完)

游戏开发创新手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)

游戏开发创新手把手教你使用Unity制作一个高仿酷狗音乐播放器,滨崎步,旋律起,爷青回(声音可视化 | 频谱 | Audio)