.music-player {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 24px;
padding: 32px;
width: 100%;
max-width: 420px;
margin: auto;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.1);
color: white;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
position: relative;
overflow: hidden;
}
.music-player::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%);
pointer-events: none;
}
.album-art {
display: flex;
justify-content: center;
margin-bottom: 24px;
}
.album-cover {
width: 200px;
height: 200px;
background: linear-gradient(45deg, #ff6b6b, #4ecdc4, #45b7d1, #96ceb4);
border-radius: 20px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.2);
animation: albumRotate 20s linear infinite;
}
@keyframes albumRotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.play-indicator {
width: 60px;
height: 60px;
background: rgba(255, 255, 255, 0.9);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.1); opacity: 1; }
}
.song-info {
text-align: center;
margin-bottom: 24px;
}
.song-info h3 {
font-size: 24px;
font-weight: 700;
margin: 0 0 8px 0;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.song-info p {
font-size: 16px;
opacity: 0.8;
margin: 0;
font-weight: 400;
}
.progress-section {
margin-bottom: 24px;
}
.time-display {
display: flex;
justify-content: space-between;
font-size: 12px;
opacity: 0.7;
margin-bottom: 8px;
}
.progress-bar {
height: 6px;
background: rgba(255, 255, 255, 0.2);
border-radius: 3px;
position: relative;
cursor: pointer;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
border-radius: 3px;
width: 35%;
transition: width 0.3s ease;
}
.progress-handle {
width: 16px;
height: 16px;
background: white;
border-radius: 50%;
position: absolute;
top: 50%;
left: 35%;
transform: translate(-50%, -50%);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
cursor: pointer;
transition: all 0.3s ease;
}
.progress-handle:hover {
transform: translate(-50%, -50%) scale(1.2);
}
.player-controls {
display: flex;
justify-content: center;
align-items: center;
gap: 16px;
margin-bottom: 24px;
}
.control-btn {
width: 48px;
height: 48px;
border: none;
border-radius: 50%;
background: rgba(255, 255, 255, 0.15);
color: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
backdrop-filter: blur(10px);
}
.control-btn:hover {
background: rgba(255, 255, 255, 0.25);
transform: scale(1.1);
}
.control-btn svg {
width: 20px;
height: 20px;
}
.play-btn {
width: 64px;
height: 64px;
background: linear-gradient(135deg, #ff6b6b, #4ecdc4);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
.play-btn:hover {
background: linear-gradient(135deg, #ff5252, #26c6da);
transform: scale(1.05);
}
.play-btn svg {
width: 24px;
height: 24px;
}
.volume-section {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 24px;
padding: 0 8px;
}
.volume-icon {
width: 20px;
height: 20px;
opacity: 0.7;
}
.volume-bar {
flex: 1;
height: 4px;
background: rgba(255, 255, 255, 0.2);
border-radius: 2px;
position: relative;
cursor: pointer;
}
.volume-fill {
height: 100%;
background: linear-gradient(90deg, #ff6b6b, #4ecdc4);
border-radius: 2px;
width: 60%;
transition: width 0.3s ease;
}
.volume-handle {
width: 12px;
height: 12px;
background: white;
border-radius: 50%;
position: absolute;
top: 50%;
left: 60%;
transform: translate(-50%, -50%);
cursor: pointer;
transition: all 0.3s ease;
}
.volume-handle:hover {
transform: translate(-50%, -50%) scale(1.3);
}
.playlist {
background: rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 16px;
backdrop-filter: blur(10px);
}
.playlist h4 {
margin: 0 0 12px 0;
font-size: 14px;
font-weight: 600;
opacity: 0.8;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.playlist-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
margin-bottom: 4px;
}
.playlist-item:hover {
background: rgba(255, 255, 255, 0.1);
transform: translateX(4px);
}
.playlist-item.active {
background: rgba(255, 255, 255, 0.15);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.song-details {
display: flex;
flex-direction: column;
gap: 2px;
}
.song-name {
font-weight: 500;
font-size: 14px;
}
.artist-name {
font-size: 12px;
opacity: 0.7;
}
.song-duration {
font-size: 12px;
opacity: 0.6;
font-weight: 400;
}
@media (max-width: 480px) {
.music-player {
padding: 24px;
margin: 16px;
}
.album-cover {
width: 160px;
height: 160px;
}
.song-info h3 {
font-size: 20px;
}
.control-btn {
width: 44px;
height: 44px;
}
.play-btn {
width: 56px;
height: 56px;
}
}
document.addEventListener('DOMContentLoaded', () => {
// DOM Elements
const playBtn = document.getElementById('play-btn');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const shuffleBtn = document.getElementById('shuffle-btn');
const repeatBtn = document.getElementById('repeat-btn');
const audioPlayer = document.getElementById('audio-player');
const songTitle = document.getElementById('song-title');
const songArtist = document.getElementById('song-artist');
const currentTimeEl = document.getElementById('current-time');
const totalTimeEl = document.getElementById('total-time');
const progressFill = document.getElementById('progress-fill');
const progressHandle = document.getElementById('progress-handle');
const progressBar = document.querySelector('.progress-bar');
const volumeFill = document.getElementById('volume-fill');
const volumeHandle = document.getElementById('volume-handle');
const volumeBar = document.querySelector('.volume-bar');
const playlistItems = document.querySelectorAll('.playlist-item');
const playIcon = document.querySelector('.play-icon');
const pauseIcon = document.querySelector('.pause-icon');
const albumCover = document.querySelector('.album-cover');
// State
let currentSongIndex = 0;
let isPlaying = false;
let isShuffled = false;
let repeatMode = 0; // 0: no repeat, 1: repeat all, 2: repeat one
let isDraggingProgress = false;
let isDraggingVolume = false;
// Initialize
audioPlayer.volume = 0.6;
updateVolumeDisplay();
function loadSong(index) {
const song = playlistItems[index];
const title = song.dataset.title || song.querySelector('.song-name').textContent;
const artist = song.dataset.artist || song.querySelector('.artist-name').textContent;
const duration = song.dataset.duration || '0:00';
audioPlayer.src = song.dataset.src;
songTitle.textContent = title;
songArtist.textContent = artist;
totalTimeEl.textContent = duration;
playlistItems.forEach(item => item.classList.remove('active'));
song.classList.add('active');
// Reset progress
progressFill.style.width = '0%';
progressHandle.style.left = '0%';
currentTimeEl.textContent = '0:00';
}
function togglePlayPause() {
if (audioPlayer.paused) {
audioPlayer.play();
isPlaying = true;
playIcon.style.display = 'none';
pauseIcon.style.display = 'block';
albumCover.style.animationPlayState = 'running';
} else {
audioPlayer.pause();
isPlaying = false;
playIcon.style.display = 'block';
pauseIcon.style.display = 'none';
albumCover.style.animationPlayState = 'paused';
}
}
function nextSong() {
if (isShuffled) {
currentSongIndex = Math.floor(Math.random() * playlistItems.length);
} else {
currentSongIndex = (currentSongIndex + 1) % playlistItems.length;
}
loadSong(currentSongIndex);
if (isPlaying) audioPlayer.play();
}
function prevSong() {
if (isShuffled) {
currentSongIndex = Math.floor(Math.random() * playlistItems.length);
} else {
currentSongIndex = (currentSongIndex - 1 + playlistItems.length) % playlistItems.length;
}
loadSong(currentSongIndex);
if (isPlaying) audioPlayer.play();
}
function toggleShuffle() {
isShuffled = !isShuffled;
shuffleBtn.style.opacity = isShuffled ? '1' : '0.7';
shuffleBtn.style.background = isShuffled ? 'rgba(255, 255, 255, 0.25)' : 'rgba(255, 255, 255, 0.15)';
}
function toggleRepeat() {
repeatMode = (repeatMode + 1) % 3;
const opacity = repeatMode === 0 ? '0.7' : '1';
const background = repeatMode === 0 ? 'rgba(255, 255, 255, 0.15)' : 'rgba(255, 255, 255, 0.25)';
repeatBtn.style.opacity = opacity;
repeatBtn.style.background = background;
}
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs.toString().padStart(2, '0')}`;
}
function updateProgress() {
if (!isDraggingProgress && audioPlayer.duration) {
const progress = (audioPlayer.currentTime / audioPlayer.duration) * 100;
progressFill.style.width = `${progress}%`;
progressHandle.style.left = `${progress}%`;
currentTimeEl.textContent = formatTime(audioPlayer.currentTime);
}
}
function updateVolumeDisplay() {
const volumePercent = audioPlayer.volume * 100;
volumeFill.style.width = `${volumePercent}%`;
volumeHandle.style.left = `${volumePercent}%`;
}
function setProgress(e) {
const rect = progressBar.getBoundingClientRect();
const percent = (e.clientX - rect.left) / rect.width;
const time = percent * audioPlayer.duration;
audioPlayer.currentTime = time;
updateProgress();
}
function setVolume(e) {
const rect = volumeBar.getBoundingClientRect();
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
audioPlayer.volume = percent;
updateVolumeDisplay();
}
// Event Listeners
playBtn.addEventListener('click', togglePlayPause);
nextBtn.addEventListener('click', nextSong);
prevBtn.addEventListener('click', prevSong);
shuffleBtn.addEventListener('click', toggleShuffle);
repeatBtn.addEventListener('click', toggleRepeat);
// Progress bar events
progressBar.addEventListener('click', setProgress);
progressHandle.addEventListener('mousedown', () => isDraggingProgress = true);
document.addEventListener('mousemove', (e) => {
if (isDraggingProgress) setProgress(e);
});
document.addEventListener('mouseup', () => isDraggingProgress = false);
// Volume bar events
volumeBar.addEventListener('click', setVolume);
volumeHandle.addEventListener('mousedown', () => isDraggingVolume = true);
document.addEventListener('mousemove', (e) => {
if (isDraggingVolume) setVolume(e);
});
document.addEventListener('mouseup', () => isDraggingVolume = false);
// Audio events
audioPlayer.addEventListener('timeupdate', updateProgress);
audioPlayer.addEventListener('loadedmetadata', () => {
totalTimeEl.textContent = formatTime(audioPlayer.duration);
});
audioPlayer.addEventListener('ended', () => {
if (repeatMode === 2) {
audioPlayer.currentTime = 0;
audioPlayer.play();
} else if (repeatMode === 1 || currentSongIndex < playlistItems.length - 1) {
nextSong();
} else {
isPlaying = false;
playIcon.style.display = 'block';
pauseIcon.style.display = 'none';
albumCover.style.animationPlayState = 'paused';
}
});
// Playlist events
playlistItems.forEach((item, index) => {
item.addEventListener('click', () => {
currentSongIndex = index;
loadSong(currentSongIndex);
if (!isPlaying) togglePlayPause();
});
});
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
if (e.target.tagName === 'INPUT') return;
switch(e.code) {
case 'Space':
e.preventDefault();
togglePlayPause();
break;
case 'ArrowRight':
nextSong();
break;
case 'ArrowLeft':
prevSong();
break;
case 'ArrowUp':
e.preventDefault();
audioPlayer.volume = Math.min(1, audioPlayer.volume + 0.1);
updateVolumeDisplay();
break;
case 'ArrowDown':
e.preventDefault();
audioPlayer.volume = Math.max(0, audioPlayer.volume - 0.1);
updateVolumeDisplay();
break;
}
});
// Initialize first song
loadSong(currentSongIndex);
});