实现效果

img
一个简单的音频播放小卡片,固定在网页右下角。

上代码!

HTML + JS code

<div class="ccard">
    <div class="cover"></div>
    <div class="content">
        <div class="info">
            <div class="title">这里填歌名</div>
            <div class="artist">这里填作者名</div>
        </div>
        <div class="controls">
            <div class="progress-container">
                <div class="progress-bar"></div>
                <input type="range" id="progress" min="0" value="0" step="0.1">
            </div>
            <div class="controls-buttons">
                <button id="playPause"></button>
                <button id="loop"></button>
                <div class="volume-control">
                    <button id="volume">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" height="12" width="15" class="volume_button">
                            <path clip-rule="evenodd" d="M11.26 3.691A1.2 1.2 0 0 1 12 4.8v14.4a1.199 1.199 0 0 1-2.048.848L5.503 15.6H2.4a1.2 1.2 0 0 1-1.2-1.2V9.6a1.2 1.2 0 0 1 1.2-1.2h3.103l4.449-4.448a1.2 1.2 0 0 1 1.308-.26Zm6.328-.176a1.2 1.2 0 0 1 1.697 0A11.967 11.967 0 0 1 22.8 12a11.966 11.966 0 0 1-3.515 8.485 1.2 1.2 0 0 1-1.697-1.697A9.563 9.563 0 0 0 20.4 12a9.565 9.565 0 0 0-2.812-6.788 1.2 1.2 0 0 1 0-1.697Zm-3.394 3.393a1.2 1.2 0 0 1 1.698 0A7.178 7.178 0 0 1 18 12a7.18 7.18 0 0 1-2.108 5.092 1.2 1.2 0 1 1-1.698-1.698A4.782 4.782 0 0 0 15.6 12a4.78 4.78 0 0 0-1.406-3.394 1.2 1.2 0 0 1 0-1.698Z" fill-rule="evenodd"></path>
                        </svg>
                    </button>
                    <div class="volume-slider">
                        <input type="range" id="volume-slider" min="0" max="1" step="0.01" value="1">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <audio id="audio" src="这里填音频链接/目录"></audio>
</div>

<script>
    const playPauseButton = document.getElementById('playPause');
    const audio = document.getElementById('audio');
    const progressBar = document.querySelector('.progress-bar');
    const progressInput = document.getElementById('progress');
    const loopButton = document.getElementById('loop');
    const volumeButton = document.getElementById('volume');
    const volumeSlider = document.getElementById('volume-slider');
    const volumeSliderContainer = document.querySelector('.volume-slider');

    let isPlaying = false;
    let isLooping = false;
    let isVolumeSliderVisible = false;

    playPauseButton.addEventListener('click', () => {
        if (isPlaying) {
            audio.pause();
            playPauseButton.innerHTML = '▶'; // Play icon
        } else {
            audio.play();
            playPauseButton.innerHTML = '❚❚'; // Pause icon
        }
        isPlaying = !isPlaying;
    });

    loopButton.addEventListener('click', () => {
        isLooping = !isLooping;
        audio.loop = isLooping;
        loopButton.style.color = isLooping ? '#007bff' : '#333';
    });

    volumeButton.addEventListener('click', () => {
        isVolumeSliderVisible = !isVolumeSliderVisible;
        volumeSliderContainer.style.display = isVolumeSliderVisible ? 'block' : 'none';
    });

    volumeSlider.addEventListener('input', () => {
        audio.volume = volumeSlider.value;
    });

    audio.addEventListener('timeupdate', () => {
        const progress = (audio.currentTime / audio.duration) * 100;
        progressBar.style.width = `${progress}%`;
        progressInput.max = audio.duration;
        progressInput.value = audio.currentTime;
    });

    progressInput.addEventListener('input', () => {
        audio.currentTime = progressInput.value;
        progressBar.style.width = `${(audio.currentTime / audio.duration) * 100}%`;
    });
</script>

CSS code

.ccard {

  background-color: #fff;

  border-radius: 15px;

  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);

  width: 266.67px;

  overflow: hidden;

  display: flex;

  align-items: center;

  padding: 7.5px;

  box-sizing: border-box;

  gap: 7.5px;

  position: fixed;

  bottom: 10px;

  right: 10px;

  z-index: 1000;

}



.cover {

  width: 66.67px;

  height: 66.67px;

  background-size: cover;

  background-position: center;

  border-radius: 10px;

  flex-shrink: 0;

  background-image: url('这里填封面链接/目录');

}



.content {

  flex: 1;

  display: flex;

  flex-direction: column;

  justify-content: center;

}



.info {

  display: flex;

  flex-direction: column;

  align-items: center;

  margin-bottom: 7.5px;

}



.info .title {

  font-size: 14px;

  font-weight: bold;

  margin: 0;

  color: #333;

}



.info .artist {

  font-size: 11px;

  color: #777;

}



.controls {

  display: flex;

  flex-direction: column;

  align-items: center;

  width: 100%;

}



.controls .progress-container {

  width: 100%;

  height: 3.75px;

  background-color: #ddd;

  border-radius: 3.75px;

  margin-bottom: 7.5px;

  position: relative;

}



.controls .progress-bar {

  height: 100%;

  background-color: #007bff;

  width: 0%;

  border-radius: 3.75px;

  transition: width 0.2s;

}



.controls .progress-container input {

  opacity: 0;

  width: 100%;

  height: 100%;

  position: absolute;

  cursor: pointer;

}



.controls-buttons {

  display: flex;

  align-items: center;

  gap: 7.5px;

}



.controls-buttons button {

  background: none;

  border: none;

  cursor: pointer;

  font-size: 18px;

  transition: color 0.3s;

}



.controls-buttons button:hover {

  color: #007bff;

}



.volume-control {

  position: relative;

  display: flex;

  align-items: center;

  gap: 3.75px;

}



.volume-control button {

  background: none;

  border: none;

  cursor: pointer;

  font-size: 15px;

}



.volume-slider {

  display: none;

  position: absolute;

  top: -30px;

  right: 0;

  width: 75px;

  background: #fff;

  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);

  padding: 3.75px;

  border-radius: 3.75px;

  z-index: 2000;

}



.volume-slider input {

  width: 100%;
}

本文未经允许不得转载