Teach you to make a music player in 10 minutes

Posted by evanluke on Mon, 07 Mar 2022 01:31:32 +0100

I Don't talk too much, let's see the effect first:

Video station B effect demonstration address~

(no big guys, no big guys, no big guys) this is a single page music player. It only uses html+css and very basic vue syntax, so it is suitable for beginners. Take a look for 10 minutes~

This idea is based on the dark horse~

II Detailed production steps (the complete code is at the end):

1. The first step, of course, is to define labels. The function notes of each label are clearly written ~:

<!-- Bottom box -->
<div class="container" id="container">
      <!-- Head area box -->
      <div class="top">
          <!-- Search box -->
          <input type="text"   class="txt" v-model='query' @keyup.enter="searchMusic">
      </div>
      <!-- Song list area -->
      <div class="list">
         <ul>
             <!-- each li It's a song -->
             <li v-for="(item,index) in musicList " :key="index">
                 <a href="javascript:;" @click="playMusic(item.id)"></a>
                 {{item.name}}
            </li>
        </ul>
         
      </div>
      <!-- Intermediate area -->
      <div class="middle">
          <!-- The rotating rod -->
          <img src="img/player_bar.png" alt="x" class="bar" :class="{playing:isPlay}">
          <!-- record -->
          <img src="img/disc.png" alt="x" class="disk" :class="{turn:isPlay}">
          <!-- Poster in the middle of the record -->
          <img :src="poster" class="poster">
      </div>
      <!-- Comment area -->
      <h5 class="commentTxt">Top comments:</h5>
      <div class="comment">
          <ul>
          <!-- Each comment -->
              <li v-for="(item,index) in comment" :key="index">
              <!-- head portrait -->
                <img :src="item.user.avatarUrl" alt="" width="50px" height="50px">
                <!-- Net name -->
                <h3>{{item.user.nickname}}</h3>
                <!-- Comment content -->
                 <p> {{item.content}}</p>
              </li>
          </ul>
      </div>
      <!-- Player progress bar -->
      <audio class="music" @play="play" @pause="pause" :src="url" controls autoplay loop></audio>
  </div>

The vue syntax explanation in the tag (see the js section later for a better understanding):

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

Give this tag v-model='query 'two-way binding data query, @ Keyup Enter = "searchmusic" bind the keyboard enter event and trigger the searchmusic function.

 {{item.name}}

Put the content and write it in {}. item relative to variable.

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

v-for = "" how many li are dynamically generated according to the number of elements in the musicList array.

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

@click="playMusic(item.id)" click the event to trigger the playMusic(item.id) function and pass the parameters.

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

: class="{playing:isPlay}". If isPlay value is true, the selector "playing" will take effect.

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

: SRC = "postmaster" the value of the address is the self-defined variable postmer.

The following are similar, and so on~

2. Define css and explain some uncommon attributes ~:

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

border-radius: 10px; Angular radian
overflow: hidden; Overflow hiding

2. Head area:
   /* head */
   .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)); Gradient background color.
z-index: 11; The display level is to prevent it from being obscured by other elements. The larger it is, the higher it will be
border: none; Cancel border

3. Song list:
   /* Song list */
   .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; If the content is trimmed, the browser displays a scroll bar to see the rest of the content.
transform: translateY(-50%); Offset, usually offset 50% of its size after positioning, so as to achieve the centering effect.

4. Middle part:
   /* Middle part */
   .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%) table offset, rotatez (0DEG) table rotation.
transform-origin: 10px 10px; The rotation point is about which point to rotate.
transition: all 1s; Transition effect.
object-fit: cover; Keep the original size scale of the picture. But part of the content may be cut.

5. Comment area:
   /* comment */
   .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; This attribute defines the vertical alignment of the baseline of an element in a row with respect to the baseline of the row in which the element is located.
text-indent: 2em; Indent the first line of the paragraph by xxx pixels:

6. Player progress bar:
   /* progress bar */
   .music{
        position: absolute;
        bottom: 0px;
        left:0px;
        width: 800px;
        height: 34px;
        outline: none;
        background-color: rgb(241, 243, 244);         
   }
7. The rod and disc rotate
   /* The lever and disc rotate */
   .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 part, written in vue syntax

1. First introduce:
     <!-- Development environment version with helpful command line warnings -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- Available on the official website axios Online address -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
2. Start (see notes for details):

The song mainly calls the public API of Netease cloud~

   new Vue({
      el:"#container",
      data(){
          return{
            //Keyword search
            query:'',
            //Song list
            musicList:[],
            //Current song address
            url:'',
            //Poster address
            poster:'./img/timg4.jpg',
            //Determine whether it is playing
            isPlay: false,
            //comment
            comment:[]
          }
      },
      methods:{
         searchMusic(){
          // Determine whether there are words in the search box
           if(this.query==''){
           //Did not return by itself
               return;
           }
           // Send request to get data
           axios({
               url:'https://autumnfish.cn/search',
               method:'get',
               params:{
                 keywords:this.query
               }
           }).then(res=>{
                //Pass the obtained data to the musicList array through console log(res); View the data you want
               this.musicList = res.data.result.songs;
           })
        },
         playMusic(id){
             //Get the url of the song
             axios({
                url:'https://autumnfish.cn/song/url',
                method:'get',
                params:{
                   id:id
                }
             }).then(res=>{
                // Set the current song address to this
                this.url = res.data.data[0].url;
             })
             //Get song seals
             axios({
                url:'https://autumnfish.cn/song/detail',
                method:'get',
                params:{
                   ids:id
                }
             }).then(res=>{
               // Store the picture address purely in the poster array
                this.poster=res.data.songs[0].al.picUrl
             })
             //Get comments
             axios({
                url:'https://autumnfish.cn/comment/hot',
                method:'get',
                params:{
                   type:0,
                   id:id
                }
             }).then(res=>{
               // Store the comment data in the comment array, including avatar, network name, etc., through console log(res); View the data you want
                this.comment=res.data.hotComments
             })
         },  
         // Song is playing trigger
         play(){
           this.isPlay = true;
         },
           // The song is a stop trigger
         pause(){
             this.isPlay = false;
         }
        }
  })

III Complete code (if you need a private letter of material and source files or leave an email in the comment area, I'll send it to you):

<!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;
       }
       /* Background map */
       .bj{
           position: fixed;
           top: 0;
           left: 0;
           width: 100%;
           height: 100%;
           object-fit: cover;
           z-index: -1000;
       }
       /* whole */
       .container{
           width: 800px;
           height: 500px;
           background-color: rgba(248, 250, 252,0.3);
           border-radius: 10px;
           position: relative;
           overflow: hidden;
       }
       /* head */
       .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;
       }
       /* Song list */
       .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%;
           
       }
       /* Middle part */
       .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;
       }
       /* comment */
       .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;
       }
       /* progress bar */
       .music{
            position: absolute;
            bottom: 0px;
            left:0px;
            width: 800px;
            height: 34px;
            outline: none;
            background-color: rgb(241, 243, 244);         
       }
       /* The lever and disc rotate */
       .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);
           }
       }
    </style>
</head>
<body>
  <video src="./video.mp4" class="bj" muted autoplay loop ></video> 
  <div class="container" id="container">
      <!-- head -->
      <div class="top">
          <input type="text"   class="txt" v-model='query' @keyup.enter="searchMusic">
      </div>
      <div class="list">
         <ul>
             <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">
          <!-- rod -->
          <img src="img/player_bar.png" alt="x" class="bar" :class="{playing:isPlay}">
          <!-- record -->
          <img src="img/disc.png" alt="x" class="disk" :class="{turn:isPlay}">
          <!-- poster -->
          <img :src="poster" class="poster">
      </div>
      <h5 class="commentTxt">Top comments:</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>
     
     <!-- Development environment version with helpful command line warnings -->
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- Available on the official website axios Online address -->
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <script>
       new Vue({
          el:"#container",
          data(){
              return{
                //Keyword search
                query:'',
                //Song list
                musicList:[],
                //Current song address
                url:'',
                //poster
                poster:'./img/timg4.jpg',
                //Determine whether it is playing
                isPlay: false,
                //comment
                comment:[]
              }
          },
          methods:{
             searchMusic(){
               if(this.query==''){
                   return;
               }
               axios({
                   url:'https://autumnfish.cn/search',
                   method:'get',
                   params:{
                     keywords:this.query
                   }
               }).then(res=>{
                   this.musicList = res.data.result.songs;
               })
            },
             playMusic(id){
                 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=>{
                    this.poster=res.data.songs[0].al.picUrl
                 })
                 axios({
                    url:'https://autumnfish.cn/comment/hot',
                    method:'get',
                    params:{
                       type:0,
                       id:id
                    }
                 }).then(res=>{
                    this.comment=res.data.hotComments
                 })
             },  
             play(){
               this.isPlay = true;
             },
             pause(){
                 this.isPlay = false;
             }
            }
      })
  </script>
</body>
</html>

IV Summary:

That's it~
Again, if you need a private letter between the material and the source file, or leave your email in the comment area, I'll send it to you. You can compare the source code and article notes to learn~
By the way, have you seen Xia Mu's friend account? It's cured again~

other:

Text smoke effect html+css+js
Surround reflection loading effect html+css
Bubble floating background effect html+css
Simple clock effect html+css+js
Cyberpunk style button html+css
Simulated Netease cloud official website rotation map html+css+js
Water wave loading animation html+css
Navigation bar scrolling gradient effect html+css+js
Book page turning html+css
3D photo album html+css
Neon painting board effect html+css+js
Summary of some css attributes (1)
Sass summary notes
... wait
Go to my home page to see more~

Topics: Java Front-end JSON html list