html简单实现音乐播放

链接全是线上的直接在vs里运行即可用,使用es6语法书写的。

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue Music Player with Image Spin Control</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>        
  <style>
    body {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: flex-end;
      height: 90vh;
    }
    
    button{
      /* 清除默认边框 */
      border:0;
      outline:none;
      /*清除默认背景 */
      background-color: transparent;
      padding: 25px;
    }

    .music-player {
      text-align: center;
      position: relative;
      bottom: 0;
    }

    audio {
      width: 300px;
    }

    .disc-container {
      position: absolute;
      top: 30%;
      left: 50%;
      transform: translate(-50%, -50%);
    }

    @keyframes spin {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }

    .disc {
      width: 20vw;
      height: 20vw;
      border-radius: 50%;
      background-size: cover;
      animation: spin 20s linear infinite;
      border: 20px solid rgba(30, 29, 29, 0.5); /* 添加边框 */
    }
  </style>
</head>

<body>
  <div id="app">
    <div class="music-player">
      <audio ref="audioPlayer" controls @play="startImageSpin" @pause="stopImageSpin" @ended="stopImageSpin">
        <source :src="currentSong.url" type="audio/mpeg">
        Your browser does not support the audio element.
      </audio>
      <h2>{{ currentSong.title }}</h2>
      <button @click="playPrevious">
        <svg t="1730998212948" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1026" width="30" height="30"><path d="M256 224a32 32 0 0 1 32 32v512a32 32 0 0 1-64 0V256a32 32 0 0 1 32-32z m385.952 30.624a96 96 0 0 1 157.44 73.76v366.72a96 96 0 0 1-157.44 73.76l-220.032-183.36a96 96 0 0 1 0-147.52z m86.048 53.28a32 32 0 0 0-45.056-4.096l-220.032 183.36a32 32 0 0 0-4.096 4.096l-2.4 3.232a32 32 0 0 0 6.496 41.824l220.032 183.36a32 32 0 0 0 52.48-24.576v-366.72a32 32 0 0 0-7.424-20.48z" fill="#000000" p-id="1027"></path></svg>
      </button>
      <button @click="togglePlayPause">
        <svg t="1730998261628" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1330" width="30" height="30"><path d="M608.352 442.176a64 64 0 0 1 33.92 9.728l163.648 102.272a64 64 0 0 1 0 108.544l-163.648 102.272a64 64 0 0 1-97.92-54.272v-204.544a64 64 0 0 1 64-64zM448 704a32 32 0 0 1 0 64H224a32 32 0 0 1 0-64h224z m160.352-197.824v204.544l163.648-102.272-163.648-102.272zM448 448a32 32 0 0 1 0 64H224a32 32 0 0 1 0-64h224z m352-256a32 32 0 0 1 0 64H224a32 32 0 1 1 0-64h576z" fill="#000000" p-id="1331"></path></svg>
      </button>
      <button @click="playNext">
        <svg t="1730998244067" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1177" width="30" height="30"><path d="M768 224a32 32 0 0 1 32 32v512a32 32 0 0 1-64 0V256a32 32 0 0 1 32-32z m-386.336 31.36l220.032 183.36a96 96 0 0 1 0 147.52l-220.032 183.36a96 96 0 0 1-157.44-73.76v-366.72a96 96 0 0 1 157.44-73.76zM295.616 308.64a32 32 0 0 0-7.424 20.48v366.72a32 32 0 0 0 52.48 24.576l220.032-183.36a32 32 0 0 0 6.496-41.824l-2.4-3.264a32 32 0 0 0-4.096-4.096l-220.032-183.36a32 32 0 0 0-45.056 4.128z" fill="#000000" p-id="1178"></path></svg>
      </button>
    </div>
    <div class="disc-container">
        <div class="disc" :style="`background-image: url(${currentImage})`" ref="disc"></div>
    </div>
  </div>

  <script>
    const { createApp, ref, computed, onMounted } = Vue;

    createApp({
      setup() {
        const audioPlayer = ref(null);
        const discElement = ref(null);
        const currentSongIndex = ref(0);
        const songs = ref([
          { title: 'love my life', url: 'https://dlink.host/sharepoint/aHR0cHM6Ly9vbmVkcnYtbXkuc2hhcmVwb2ludC5jb20vOnU6L2cvcGVyc29uYWwvc3Rvcl9vbmVkcnZfb25taWNyb3NvZnRfY29tL0VabnZ0azhrRTI5TW5OdVR6WjRqWDB3Qm5jbnZTRHhYODAxM3RkbDBTZEszb1E.mp3', image: 'https://ts1.cn.mm.bing.net/th/id/R-C.287b85fd021e852cb71838589ee8c2ee?rik=45qFAASOHsQsUg&riu=http%3a%2f%2fwww.bing.yiyuen.com%2fapi%2fbing%2fwallpaper%2fgetSource%3fid%3d2492&ehk=haEuZL0kY%2fYBg22TnqK1rBVgNfl23ZpT%2f3YhQL6xUps%3d&risl=&pid=ImgRaw&r=0' },
          { title: '老街', url: 'https://dlink.host/musics/aHR0cHM6Ly9vbmVkcnYtbXkuc2hhcmVwb2ludC5jb20vOnU6L2cvcGVyc29uYWwvc3Rvcl9vbmVkcnZfb25taWNyb3NvZnRfY29tL0VkcjU3elIxemcxQ2pxOWFXY2FGMG1rQkszQUF5VXlqNTNxRWlfMl9BdWRwRHc.mp3', image: 'https://n.sinaimg.cn/sinakd20116/580/w690h690/20200418/f087-iskepxt3819684.jpg' },
          { title: '流沙', url: 'https://dlink.host/musics/aHR0cHM6Ly9vbmVkcnYtbXkuc2hhcmVwb2ludC5jb20vOnU6L2cvcGVyc29uYWwvc3Rvcl9vbmVkcnZfb25taWNyb3NvZnRfY29tL0VYSldHSzUwZmRGUHRHdVdUYVlVT21NQjlhM012UnR6OHFMakR4NWlHU2xsZGc.mp3', image: 'https://tse2-mm.cn.bing.net/th/id/OIP-C.Oy3BxwSSlARWVcca0IFCcAEsDv?rs=1&pid=ImgDetMain' }
        ]);
        const currentImage = ref(songs.value[0].image);
        const currentSong = computed(() => songs.value[currentSongIndex.value]);

        function playPrevious() {
          if (currentSongIndex.value > 0) {
            currentSongIndex.value--;
          } else {
            currentSongIndex.value = songs.value.length - 1;
          }
          updateImage();
          audioPlayer.value.load();
          audioPlayer.value.play();
        }

        function playNext() {
          if (currentSongIndex.value < songs.value.length - 1) {
            currentSongIndex.value++;
          } else {
            currentSongIndex.value = 0;
          }
          updateImage();
          audioPlayer.value.load();
          audioPlayer.value.play();
        }

        function togglePlayPause() {
          if (audioPlayer.value.paused) {
            audioPlayer.value.play();
          } else {
            audioPlayer.value.pause();
          }
        }

        function startImageSpin() {
          discElement.value.style.animationPlayState = 'running';
        }

        function stopImageSpin() {
          discElement.value.style.animationPlayState = 'paused';
        }

        function updateImage() {
          // Reset the rotation to 0 degrees
          discElement.value.style.transform = 'rotate(0deg)';
          currentImage.value = currentSong.value.image;
        }

        onMounted(() => {
          discElement.value = document.querySelector('.disc');
          updateImage();
          stopImageSpin();
        });

        return {
          currentSong,
          playPrevious,
          playNext,
          togglePlayPause,
          startImageSpin,
          stopImageSpin,
          currentImage,
          audioPlayer
        };
      }
    }).mount('#app');
  </script>
</body>

</html>
相关推荐
沉默璇年19 分钟前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder25 分钟前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_8827275734 分钟前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架
会发光的猪。1 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客1 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
猫爪笔记1 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
前端李易安2 小时前
Webpack 热更新(HMR)详解:原理与实现
前端·webpack·node.js
红绿鲤鱼2 小时前
React-自定义Hook与逻辑共享
前端·react.js·前端框架
Domain-zhuo2 小时前
什么是JavaScript原型链?
开发语言·前端·javascript·jvm·ecmascript·原型模式
小丁爱养花2 小时前
前端三剑客(三):JavaScript
开发语言·前端·javascript