├── favicon.png ├── img ├── jacinto-1.jpg ├── jacinto-2.jpg ├── jacinto-3.jpg └── metric-1.jpg ├── index.html ├── music ├── jacinto-1.mp3 ├── jacinto-2.mp3 ├── jacinto-3.mp3 └── metric-1.mp3 ├── script.js └── style.css /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/favicon.png -------------------------------------------------------------------------------- /img/jacinto-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/img/jacinto-1.jpg -------------------------------------------------------------------------------- /img/jacinto-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/img/jacinto-2.jpg -------------------------------------------------------------------------------- /img/jacinto-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/img/jacinto-3.jpg -------------------------------------------------------------------------------- /img/metric-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/img/metric-1.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Music Player 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 | Album Art 16 |
17 |

Electric Chill Machine

18 |

Jacinto

19 | 20 | 21 |
22 |
23 |
24 | 0:00 25 | 2:06 26 |
27 |
28 | 29 |
30 | 31 | 32 | 33 |
34 |
35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /music/jacinto-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/music/jacinto-1.mp3 -------------------------------------------------------------------------------- /music/jacinto-2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/music/jacinto-2.mp3 -------------------------------------------------------------------------------- /music/jacinto-3.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/music/jacinto-3.mp3 -------------------------------------------------------------------------------- /music/metric-1.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JacintoDesign/music-player/0f774d120bef34c614da8493e5755694179e2559/music/metric-1.mp3 -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | const image = document.querySelector('img'); 2 | const title = document.getElementById('title'); 3 | const artist = document.getElementById('artist'); 4 | const music = document.querySelector('audio'); 5 | const currentTimeEl = document.getElementById('current-time'); 6 | const durationEl = document.getElementById('duration'); 7 | const progress = document.getElementById('progress'); 8 | const progressContainer = document.getElementById('progress-container'); 9 | const prevBtn = document.getElementById('prev'); 10 | const playBtn = document.getElementById('play'); 11 | const nextBtn = document.getElementById('next'); 12 | 13 | // Music 14 | const songs = [ 15 | { 16 | name: 'jacinto-1', 17 | displayName: 'Electric Chill Machine', 18 | artist: 'Jacinto Design', 19 | }, 20 | { 21 | name: 'jacinto-2', 22 | displayName: 'Seven Nation Army (Remix)', 23 | artist: 'Jacinto Design', 24 | }, 25 | { 26 | name: 'jacinto-3', 27 | displayName: 'Goodnight, Disco Queen', 28 | artist: 'Jacinto Design', 29 | }, 30 | { 31 | name: 'metric-1', 32 | displayName: 'Front Row (Remix)', 33 | artist: 'Metric/Jacinto Design', 34 | }, 35 | ]; 36 | 37 | // Check if Playing 38 | let isPlaying = false; 39 | 40 | // Play 41 | function playSong() { 42 | isPlaying = true; 43 | playBtn.classList.replace('fa-play', 'fa-pause'); 44 | playBtn.setAttribute('title', 'Pause'); 45 | music.play(); 46 | } 47 | 48 | // Pause 49 | function pauseSong() { 50 | isPlaying = false; 51 | playBtn.classList.replace('fa-pause', 'fa-play'); 52 | playBtn.setAttribute('title', 'Play'); 53 | music.pause(); 54 | } 55 | 56 | // Play or Pause Event Listener 57 | playBtn.addEventListener('click', () => (isPlaying ? pauseSong() : playSong())); 58 | 59 | // Update DOM 60 | function loadSong(song) { 61 | title.textContent = song.displayName; 62 | artist.textContent = song.artist; 63 | music.src = `music/${song.name}.mp3`; 64 | image.src = `img/${song.name}.jpg`; 65 | } 66 | 67 | // Current Song 68 | let songIndex = 0; 69 | 70 | // Previous Song 71 | function prevSong() { 72 | songIndex--; 73 | if (songIndex < 0) { 74 | songIndex = songs.length - 1; 75 | } 76 | loadSong(songs[songIndex]); 77 | playSong(); 78 | } 79 | 80 | // Next Song 81 | function nextSong() { 82 | songIndex++; 83 | if (songIndex > songs.length - 1) { 84 | songIndex = 0; 85 | } 86 | loadSong(songs[songIndex]); 87 | playSong(); 88 | } 89 | 90 | // On Load - Select First Song 91 | loadSong(songs[songIndex]); 92 | 93 | // Update Progress Bar & Time 94 | function updateProgressBar(e) { 95 | if (isPlaying) { 96 | const { duration, currentTime } = e.srcElement; 97 | // Update progress bar width 98 | const progressPercent = (currentTime / duration) * 100; 99 | progress.style.width = `${progressPercent}%`; 100 | // Calculate display for duration 101 | const durationMinutes = Math.floor(duration / 60); 102 | let durationSeconds = Math.floor(duration % 60); 103 | if (durationSeconds < 10) { 104 | durationSeconds = `0${durationSeconds}`; 105 | } 106 | // Delay switching duration Element to avoid NaN 107 | if (durationSeconds) { 108 | durationEl.textContent = `${durationMinutes}:${durationSeconds}`; 109 | } 110 | // Calculate display for currentTime 111 | const currentMinutes = Math.floor(currentTime / 60); 112 | let currentSeconds = Math.floor(currentTime % 60); 113 | if (currentSeconds < 10) { 114 | currentSeconds = `0${currentSeconds}`; 115 | } 116 | currentTimeEl.textContent = `${currentMinutes}:${currentSeconds}`; 117 | } 118 | } 119 | 120 | // Set Progress Bar 121 | function setProgressBar(e) { 122 | const width = this.clientWidth; 123 | const clickX = e.offsetX; 124 | const { duration } = music; 125 | music.currentTime = (clickX / width) * duration; 126 | } 127 | 128 | // Event Listeners 129 | prevBtn.addEventListener('click', prevSong); 130 | nextBtn.addEventListener('click', nextSong); 131 | music.addEventListener('ended', nextSong); 132 | music.addEventListener('timeupdate', updateProgressBar); 133 | progressContainer.addEventListener('click', setProgressBar); 134 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* Images created by: https://unsplash.com/@pawel_czerwinski */ 2 | 3 | @import url("https://fonts.googleapis.com/css?family=Spartan:400,700&display=swap"); 4 | 5 | html { 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | min-height: 100vh; 12 | background: #c9ced3; 13 | display: flex; 14 | justify-content: center; 15 | align-items: center; 16 | font-family: Spartan, sans-serif; 17 | font-size: 12px; 18 | } 19 | 20 | .player-container { 21 | height: 500px; 22 | width: 400px; 23 | background: #e7e7e7; 24 | border-radius: 20px; 25 | box-shadow: 0 15px 30px 5px rgba(0, 0, 0, 0.3); 26 | } 27 | 28 | .img-container { 29 | width: 300px; 30 | height: 300px; 31 | position: relative; 32 | top: -50px; 33 | left: 50px; 34 | } 35 | 36 | .img-container img { 37 | height: 100%; 38 | width: 100%; 39 | object-fit: cover; 40 | border-radius: 20px; 41 | box-shadow: 0 5px 30px 5px rgba(0, 0, 0, 0.5); 42 | } 43 | 44 | h2 { 45 | font-size: 25px; 46 | text-align: center; 47 | margin: 0; 48 | } 49 | 50 | h3 { 51 | font-size: 20px; 52 | text-align: center; 53 | font-weight: 400; 54 | margin: 5px 0 0; 55 | } 56 | 57 | /* Progress */ 58 | .progress-container { 59 | background: #fff; 60 | border-radius: 5px; 61 | cursor: pointer; 62 | margin: 40px 20px; 63 | height: 4px; 64 | width: 90%; 65 | } 66 | 67 | .progress { 68 | background: #242323; 69 | border-radius: 5px; 70 | height: 100%; 71 | width: 0%; 72 | transition: width 0.1s linear; 73 | } 74 | 75 | .duration-wrapper { 76 | position: relative; 77 | top: -25px; 78 | display: flex; 79 | justify-content: space-between; 80 | } 81 | 82 | /* Controls */ 83 | .player-controls { 84 | position: relative; 85 | top: -15px; 86 | left: 120px; 87 | width: 200px; 88 | } 89 | 90 | .fas { 91 | font-size: 30px; 92 | color: rgb(129, 129, 129); 93 | margin-right: 30px; 94 | cursor: pointer; 95 | user-select: none; 96 | } 97 | 98 | .fas:hover { 99 | filter: brightness(80%); 100 | } 101 | 102 | .main-button { 103 | font-size: 40px; 104 | position: relative; 105 | top: 3px; 106 | } 107 | 108 | /* Media Query: iPhone (Vertical) */ 109 | @media screen and (max-width: 376px) { 110 | .player-container { 111 | width: 95vw; 112 | } 113 | 114 | .img-container { 115 | left: 29px; 116 | } 117 | 118 | h2 { 119 | font-size: 20px; 120 | } 121 | 122 | h3 { 123 | font-size: 15px; 124 | } 125 | 126 | .player-controls { 127 | top: -10px; 128 | left: 100px; 129 | } 130 | } 131 | --------------------------------------------------------------------------------