搜索结果

×

搜索结果将在这里显示。

💜 网页音乐播放器隐藏在右侧

功能说明:

  1. 初始状态:播放器隐藏在右侧,只显示圆形专辑封面
  2. 点击封面:在隐藏状态下可播放/暂停音乐
  3. 点击封面:展开完整播放器界面
  4. 完整功能:播放控制、进度条、播放列表等
  5. 关闭按钮:点击右上角X可收起播放器
    隐藏效果:

展开的效果:

代码如下


<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>圆形封面音乐播放器</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            text-align: center;
            color: white;
        }

        h1 {
            margin-bottom: 30px;
            text-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
        }

        .description {
            background: rgba(255, 255, 255, 0.1);
            padding: 20px;
            border-radius: 10px;
            margin-bottom: 30px;
            backdrop-filter: blur(10px);
        }

        /* 迷你播放器样式 */
        .mini-player {
            position: fixed;
            right: 0;
            top: 50%;
            transform: translateY(-50%);
            width: 70px;
            height: 70px;
            background: rgba(0, 0, 0, 0.8);
            box-shadow: -2px 0 10px rgba(0, 0, 0, 0.3);
            z-index: 1000;
            cursor: pointer;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50% 0 0 50%;
        }

        .mini-player:hover {
            background: rgba(0, 0, 0, 0.9);
        }

        .album-cover-mini {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            overflow: hidden;
            border: 2px solid rgba(255, 255, 255, 0.2);
        }

        .album-cover-mini img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;
        }

        /* 完整播放器样式 */
        .full-player {
            position: fixed;
            right: -330px;
            top: 50%;
            transform: translateY(-50%);
            width: 330px;
            -height: 500px;
            background: rgba(0, 0, 0, 0.9);
            box-shadow: -5px 0 15px rgba(0, 0, 0, 0.3);
            transition: all 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
            z-index: 1001;
            display: flex;
            flex-direction: column;
            border-radius: 10px 0 0 10px;
        }

        .full-player.expanded {
            right: 0;
        }

        .player-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 20px;
            background: rgba(255, 71, 87, 0.9);
            border-radius: 10px 0 0 0;
        }

        .player-title {
            font-size: 18px;
            font-weight: bold;
            color: white;
        }

        .close-btn {
            background: none;
            border: none;
            color: white;
            font-size: 20px;
            cursor: pointer;
            width: 30px;
            height: 30px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: background 0.3s;
        }

        .close-btn:hover {
            background: rgba(255, 255, 255, 0.2);
        }

        .player-content {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
        }

        .current-track {
            text-align: center;
            margin-bottom: 30px;
        }

        .current-album-cover {
            width: 200px;
            height: 200px;
            border-radius: 50%;
            overflow: hidden;
            margin: 0 auto 20px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            border: 3px solid rgba(255, 255, 255, 0.3);
        }

        .current-album-cover img {
            width: 100%;
            height: 100%;
            object-fit: cover;
            transition: transform 0.3s ease;
        }

        .track-info h2 {
            font-size: 20px;
            margin-bottom: 5px;
        }

        .track-info p {
            color: #aaa;
            font-size: 14px;
        }

        .controls-section {
            margin: 30px 0;
        }

        .progress-container {
            margin-bottom: 20px;
        }

        .progress-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 8px;
            font-size: 12px;
            color: #aaa;
        }

        .progress-bar {
            width: 100%;
            height: 4px;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 2px;
            overflow: hidden;
            cursor: pointer;
        }

        .progress {
            height: 100%;
            background: #ff4757;
            width: 0%;
            transition: width 0.1s;
        }

        .player-controls {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 20px;
            margin: 20px 0;
        }

        .control-btn {
            background: rgba(255, 255, 255, 0.1);
            border: none;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            color: white;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
        }

        .control-btn:hover {
            background: rgba(255, 255, 255, 0.2);
            transform: scale(1.1);
        }

        .control-btn.play-pause {
            width: 50px;
            height: 50px;
            background: #ff4757;
        }

        .playlist-section {
            margin-top: 20px;
        }

        .playlist-title {
            font-size: 16px;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid rgba(255, 255, 255, 0.1);
        }

        .playlist-items {
            max-height: 150px;
            overflow-y: auto;
        }

        .playlist-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 10px 15px;
            background: rgba(255, 255, 255, 0.05);
            border-radius: 5px;
            margin-bottom: 8px;
            cursor: pointer;
            transition: background 0.2s;
        }

        .playlist-item:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        .playlist-item.active {
            background: rgba(255, 71, 87, 0.2);
            border-left: 3px solid #ff4757;
        }

        .song-info {
            flex: 1;
        }

        .song-title {
            font-size: 14px;
            margin-bottom: 3px;
        }

        .song-artist {
            font-size: 12px;
            color: #aaa;
        }

        .song-duration {
            font-size: 12px;
            color: #aaa;
        }

        /* 滚动条样式 */
        .playlist-items::-webkit-scrollbar {
            width: 5px;
        }

        .playlist-items::-webkit-scrollbar-track {
            background: rgba(255, 255, 255, 0.1);
        }

        .playlist-items::-webkit-scrollbar-thumb {
            background: #ff4757;
            border-radius: 5px;
        }

        /* 旋转动画 */
        @keyframes rotate {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        .playing-img {
            animation: rotate 10s linear infinite;
        }

        .paused-img {
            animation-play-state: paused;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>圆形封面音乐播放器</h1>
        <div class="description">
            <h2>功能说明:</h2>
            <p>1. 初始状态:播放器隐藏在右侧,只显示圆形专辑封面</p>
            <p>2. 点击封面:在隐藏状态下可播放/暂停音乐</p>
            <p>3. 点击封面:展开完整播放器界面</p>
            <p>4. 完整功能:播放控制、进度条、播放列表等</p>
            <p>5. 关闭按钮:点击右上角X可收起播放器</p>
        </div>
    </div>

    <!-- 迷你播放器(右侧隐藏状态) -->
    <div class="mini-player" id="miniPlayer">
        <div class="album-cover-mini">
            <img src="https://picsum.photos/200/200?music" alt="专辑封面" id="miniAlbumCover">
        </div>
    </div>

    <!-- 完整播放器 -->
    <div class="full-player" id="fullPlayer">
        <div class="player-header">
            <div class="player-title">音乐播放器</div>
            <button class="close-btn" id="closePlayer">×</button>
        </div>

        <div class="player-content">
            <div class="current-track">
                <div class="current-album-cover">
                    <img src="https://picsum.photos/200/200?music" alt="专辑封面" id="currentAlbumCover">
                </div>
                <div class="track-info">
                    <h2 id="currentSongTitle">歌曲名称</h2>
                    <p id="currentSongArtist">艺术家</p>
                </div>
            </div>

            <div class="controls-section">
                <div class="progress-container">
                    <div class="progress-info">
                        <span id="currentTime">00:00</span>
                        <span id="totalTime">00:00</span>
                    </div>
                    <div class="progress-bar" id="progressBar">
                        <div class="progress" id="progress"></div>
                    </div>
                </div>

                <div class="player-controls">
                    <button class="control-btn prev-btn" id="prevBtn">◀◀</button>
                    <button class="control-btn play-pause" id="playPauseBtn">▶</button>
                    <button class="control-btn next-btn" id="nextBtn">▶▶</button>
                </div>
            </div>

            <div class="playlist-section">
                <div class="playlist-title">播放列表</div>
                <div class="playlist-items" id="playlistItems">
                    <!-- 播放列表动态生成 -->
                </div>
            </div>
        </div>

        <audio id="audioElement"></audio>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 播放列表数据
            const playlist = [
                {
                    id: 1,
                    title: '青舞',
                    artist: '来自网络',
                    src: 'https://audio.jukehost.co.uk/SN3m8tzBVwZE8HuHWEkPlulULCpXNddg.mp3',
                    cover: 'https://picsum.photos/200/200?music1',
                    duration: '00:55'
                },
                {
                    id: 2,
                    title: '易燃易爆炸',
                    artist: '陈粒',
                    src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3',
                    cover: 'https://picsum.photos/200/200?music2',
                    duration: '04:20'
                },
                {
                    id: 3,
                    title: '知否知否',
                    artist: '胡夏/郁可唯',
                    src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3',
                    cover: 'https://picsum.photos/200/200?music3',
                    duration: '04:55'
                },
                {
                    id: 4,
                    title: '起风了',
                    artist: '买辣椒也用券',
                    src: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3',
                    cover: 'https://picsum.photos/200/200?music4',
                    duration: '05:30'
                }
            ];

            // 元素引用
            const audio = document.getElementById('audioElement');
            const miniPlayer = document.getElementById('miniPlayer');
            const fullPlayer = document.getElementById('fullPlayer');
            const closeBtn = document.getElementById('closePlayer');
            const playPauseBtn = document.getElementById('playPauseBtn');
            const prevBtn = document.getElementById('prevBtn');
            const nextBtn = document.getElementById('nextBtn');
            const progressBar = document.getElementById('progressBar');
            const progress = document.getElementById('progress');
            const currentTimeEl = document.getElementById('currentTime');
            const totalTimeEl = document.getElementById('totalTime');
            const currentAlbumCover = document.getElementById('currentAlbumCover');
            const miniAlbumCover = document.getElementById('miniAlbumCover');
            const currentSongTitle = document.getElementById('currentSongTitle');
            const currentSongArtist = document.getElementById('currentSongArtist');
            const playlistItems = document.getElementById('playlistItems');

            let currentSongIndex = 0;
            let isPlaying = false;
            let isDragging = false;

            // 初始化播放器
            function init() {
                loadSong(currentSongIndex);
                renderPlaylist();
                setupEventListeners();
            }

            // 加载歌曲
            function loadSong(index) {
                const song = playlist[index];
                audio.src = song.src;
                currentSongTitle.textContent = song.title;
                currentSongArtist.textContent = song.artist;
                currentAlbumCover.src = song.cover;
                miniAlbumCover.src = song.cover;
                totalTimeEl.textContent = song.duration;

                // 重置旋转状态
                if (isPlaying) {
                    playSong();
                } else {
                    pauseSong();
                }

                updateActivePlaylistItem(index);
            }

            // 渲染播放列表
            function renderPlaylist() {
                playlistItems.innerHTML = '';
                playlist.forEach((song, index) => {
                    const item = document.createElement('div');
                    item.className = 'playlist-item';
                    item.innerHTML = `
                        <div class="song-info">
                            <div class="song-title">${song.title}</div>
                            <div class="song-artist">${song.artist}</div>
                        </div>
                        <div class="song-duration">${song.duration}</div>
                    `;
                    item.addEventListener('click', () => {
                        currentSongIndex = index;
                        loadSong(index);
                        if (isPlaying) {
                            playSong();
                        }
                    });
                    playlistItems.appendChild(item);
                });
                updateActivePlaylistItem(currentSongIndex);
            }

            // 更新活动播放列表项
            function updateActivePlaylistItem(index) {
                const items = document.querySelectorAll('.playlist-item');
                items.forEach((item, i) => {
                    item.classList.toggle('active', i === index);
                });
            }

            // 播放歌曲
            function playSong() {
                isPlaying = true;
                audio.play();
                playPauseBtn.textContent = '❚❚';

                // 确保移除所有可能干扰的类
                currentAlbumCover.classList.remove('paused-img');
                miniAlbumCover.classList.remove('paused-img');

                // 添加旋转类
                currentAlbumCover.classList.add('playing-img');
                miniAlbumCover.classList.add('playing-img');
            }

            // 暂停歌曲
            function pauseSong() {
                isPlaying = false;
                audio.pause();
                playPauseBtn.textContent = '▶';

                // 确保移除所有可能干扰的类
                currentAlbumCover.classList.remove('playing-img');
                miniAlbumCover.classList.remove('playing-img');

                // 添加暂停类
                currentAlbumCover.classList.add('paused-img');
                miniAlbumCover.classList.add('paused-img');
            }

            // 更新进度
            function updateProgress() {
                if (isDragging) return;

                const currentTime = audio.currentTime;
                const duration = audio.duration;

                if (duration) {
                    const progressPercent = (currentTime / duration) * 100;
                    progress.style.width = `${progressPercent}%`;

                    // 更新时间显示
                    const currentMinutes = Math.floor(currentTime / 60);
                    const currentSeconds = Math.floor(currentTime % 60);
                    currentTimeEl.textContent = `${currentMinutes}:${currentSeconds.toString().padStart(2, '0')}`;
                }
            }

            // 设置事件监听器
            function setupEventListeners() {
                // 展开播放器
                miniPlayer.addEventListener('click', function(e) {
                    e.stopPropagation();
                    fullPlayer.classList.add('expanded');
                });

                // 收起播放器
                closeBtn.addEventListener('click', function(e) {
                    e.stopPropagation();
                    fullPlayer.classList.remove('expanded');
                });

                // 迷你播放器点击播放
                miniPlayer.addEventListener('click', function(e) {
                    if (!fullPlayer.classList.contains('expanded')) {
                        togglePlayPause();
                        e.stopPropagation();
                    }
                });

                // 播放/暂停按钮
                playPauseBtn.addEventListener('click', togglePlayPause);

                // 上一首/下一首
                prevBtn.addEventListener('click', () => {
                    currentSongIndex = (currentSongIndex - 1 + playlist.length) % playlist.length;
                    loadSong(currentSongIndex);
                    if (isPlaying) playSong();
                });

                nextBtn.addEventListener('click', () => {
                    currentSongIndex = (currentSongIndex + 1) % playlist.length;
                    loadSong(currentSongIndex);
                    if (isPlaying) playSong();
                });

                // 进度条控制
                progressBar.addEventListener('click', (e) => {
                    const rect = progressBar.getBoundingClientRect();
                    const percent = (e.clientX - rect.left) / rect.width;
                    audio.currentTime = percent * audio.duration;
                });

                progressBar.addEventListener('mousedown', () => isDragging = true);
                document.addEventListener('mouseup', () => isDragging = false);

                progressBar.addEventListener('mousemove', (e) => {
                    if (isDragging) {
                        const rect = progressBar.getBoundingClientRect();
                        const percent = (e.clientX - rect.left) / rect.width;
                        audio.currentTime = percent * audio.duration;
                    }
                });

                // 音频事件
                audio.addEventListener('timeupdate', updateProgress);
                audio.addEventListener('ended', () => {
                    currentSongIndex = (currentSongIndex + 1) % playlist.length;
                    loadSong(currentSongIndex);
                    if (isPlaying) playSong();
                });

                // 点击外部收起播放器
                document.addEventListener('click', (e) => {
                    if (!fullPlayer.contains(e.target) && !miniPlayer.contains(e.target)) {
                        fullPlayer.classList.remove('expanded');
                    }
                });
            }

            // 切换播放/暂停
            function togglePlayPause() {
                if (isPlaying) {
                    pauseSong();
                } else {
                    playSong();
                }
            }

            // 初始化
            init();
        });
    </script>
</body>
</html>

演示效果

https://5blog.cn/tx/ycyb.html

阅读:50
发布时间:
请先 登录 再评论