Skip to content

Commit e2dc8d6

Browse files
committedMar 14, 2021
add music player
1 parent 141e4de commit e2dc8d6

File tree

4 files changed

+278
-0
lines changed

4 files changed

+278
-0
lines changed
 

‎68-music player/index.html

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!-- Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio -->
2+
3+
<!DOCTYPE html>
4+
<html lang="en">
5+
<head>
6+
<meta charset="UTF-8" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<link
9+
rel="stylesheet"
10+
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css"
11+
integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA=="
12+
crossorigin="anonymous"
13+
/>
14+
<link rel="stylesheet" href="style.css" />
15+
<title>Music Player</title>
16+
</head>
17+
<body>
18+
<h1>Music Player</h1>
19+
<div class="music-container" id="music-container">
20+
<div class="music-info">
21+
<h2 id="title" class="title"></h2>
22+
<div class="progress-container" id="progress-container">
23+
<div class="progress" id="progress"></div>
24+
</div>
25+
</div>
26+
<audio
27+
src="https://github.com/bradtraversy/vanillawebprojects/blob/master/music-player/music/ukulele.mp3?raw=true"
28+
id="audio"
29+
></audio>
30+
<div class="img-container">
31+
<img
32+
src="https://github.com/bradtraversy/vanillawebprojects/blob/master/music-player/images/ukulele.jpg?raw=true"
33+
alt="music-cover"
34+
id="cover"
35+
/>
36+
</div>
37+
<div class="navigation">
38+
<button id="prev" class="action-btn">
39+
<i class="fas fa-backward"></i>
40+
</button>
41+
<button id="play" class="action-btn action-btn-big">
42+
<i class="fas fa-play"></i>
43+
</button>
44+
<button id="next" class="action-btn">
45+
<i class="fas fa-forward"></i>
46+
</button>
47+
</div>
48+
</div>
49+
<script src="script.js"></script>
50+
</body>
51+
</html>

‎68-music player/script.js

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
const musicContainer = document.getElementById("music-container");
2+
const playButton = document.getElementById("play");
3+
const prevButton = document.getElementById("prev");
4+
const nextButton = document.getElementById("next");
5+
const audio = document.getElementById("audio");
6+
const progress = document.getElementById("progress");
7+
const progressContainer = document.getElementById("progress-container");
8+
const title = document.getElementById("title");
9+
const cover = document.getElementById("cover");
10+
11+
const songs = ["hey", "summer", "ukulele"];
12+
let songIndex = 2;
13+
14+
function getSongTitle(song) {
15+
return song.charAt(0).toUpperCase() + song.slice(1);
16+
}
17+
18+
function loadSong(song) {
19+
title.innerText = getSongTitle(song);
20+
audio.src = `https://github.com/bradtraversy/vanillawebprojects/blob/master/music-player/music/${song}.mp3?raw=true`;
21+
cover.src = `https://github.com/bradtraversy/vanillawebprojects/blob/master/music-player/images/${song}.jpg?raw=true`;
22+
}
23+
24+
function playSong() {
25+
musicContainer.classList.add("play");
26+
playButton.querySelector("i.fas").classList.remove("fa-play");
27+
playButton.querySelector("i.fas").classList.add("fa-pause");
28+
audio.play();
29+
}
30+
31+
function pauseSong() {
32+
musicContainer.classList.remove("play");
33+
playButton.querySelector("i.fas").classList.remove("fa-pause");
34+
playButton.querySelector("i.fas").classList.add("fa-play");
35+
audio.pause();
36+
}
37+
38+
function prevSong() {
39+
songIndex--;
40+
if (songIndex < 0) songIndex = songs.length - 1;
41+
loadSong(songs[songIndex]);
42+
playSong();
43+
}
44+
45+
function nextSong() {
46+
songIndex++;
47+
if (songIndex > songs.length - 1) songIndex = 0;
48+
loadSong(songs[songIndex]);
49+
playSong();
50+
}
51+
52+
function updateProgress(e) {
53+
const { duration, currentTime } = e.srcElement;
54+
const progressPercent = (currentTime / duration) * 100;
55+
progress.style.width = `${progressPercent}%`;
56+
}
57+
58+
function setProgress(e) {
59+
const width = this.clientWidth;
60+
const clickX = e.offsetX;
61+
const duration = audio.duration;
62+
audio.currentTime = (clickX / width) * duration;
63+
}
64+
65+
// Event Listeners
66+
playButton.addEventListener("click", () => {
67+
const isPlaying = musicContainer.classList.contains("play");
68+
isPlaying ? pauseSong() : playSong();
69+
});
70+
71+
prevButton.addEventListener("click", prevSong);
72+
nextButton.addEventListener("click", nextSong);
73+
74+
audio.addEventListener("timeupdate", updateProgress);
75+
progressContainer.addEventListener("click", setProgress);
76+
77+
audio.addEventListener("ended", nextSong);
78+
79+
// Init
80+
loadSong(songs[songIndex]);

‎68-music player/style.css

+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;700&display=swap');
2+
3+
* {
4+
box-sizing: border-box;
5+
}
6+
7+
body {
8+
background-image: linear-gradient(
9+
0deg,
10+
rgba(247,247,247, 1) 23.8%,
11+
rgba(252, 221, 221, 1) 92%
12+
);
13+
font-family: "Rubik", sans-serif;
14+
display: flex;
15+
flex-direction: column;
16+
align-items: center;
17+
justify-content: center;
18+
height: 100vh;
19+
overflow: hidden;
20+
margin: 0;
21+
}
22+
23+
.music-container {
24+
background-color: #fff;
25+
border-radius: 15px;
26+
box-shadow: 0 20px 20px 0 rgba(252, 169, 169, 0.6);
27+
display: flex;
28+
padding: 20px 30px;
29+
position: relative;
30+
margin: 100px 0;
31+
z-index: 10;
32+
}
33+
34+
.img-container {
35+
position: relative;
36+
width: 110px;
37+
}
38+
39+
.img-container img {
40+
border-radius: 50%;
41+
object-fit: cover;
42+
height: 110px;
43+
width: inherit;
44+
position: absolute;
45+
bottom: 0;
46+
left: 0;
47+
animation: rotateImage 3s linear infinite;
48+
animation-play-state: paused;
49+
}
50+
51+
.img-container::after {
52+
content: '';
53+
position: absolute;
54+
background-color: #fff;
55+
border-radius: 50%;
56+
bottom: 100%;
57+
left: 50%;
58+
height: 20px;
59+
width: 20px;
60+
transform: translate(-50%, 50%);
61+
}
62+
63+
.music-container.play .img-container img {
64+
animation-play-state: running;
65+
}
66+
67+
@keyframes rotateImage {
68+
from {
69+
transform: rotate(0deg);
70+
}
71+
to {
72+
transform: rotate(360deg);
73+
}
74+
}
75+
76+
.navigation {
77+
display: flex;
78+
align-items: center;
79+
justify-content: center;
80+
z-index: 1;
81+
}
82+
83+
.action-btn {
84+
background-color: #fff;
85+
border: 0;
86+
color: #dfdbdf;
87+
font-size: 20px;
88+
cursor: pointer;
89+
padding: 10px;
90+
margin: 0 20px;
91+
}
92+
93+
.action-btn:focus {
94+
outline: none;
95+
}
96+
97+
.action-btn:hover, .action-btn.action-btn-big:hover {
98+
color: #fe8daa;
99+
}
100+
101+
.action-btn.action-btn-big {
102+
color: #cdc2d0;
103+
font-size: 30px;
104+
}
105+
106+
.music-info {
107+
background-color: rgba(255,255,255,0.5);
108+
border-radius: 15px 15px 0 0;
109+
position: absolute;
110+
width: calc(100% - 40px);
111+
padding: 10px 10px 10px 150px;
112+
top: 0;
113+
left: 20px;
114+
opacity: 0;
115+
transform: translateY(0%);
116+
transition: transform 0.3s ease-in, opacity 0.3s ease-in;
117+
z-index: 0;
118+
}
119+
120+
.music-container.play .music-info {
121+
opacity: 1;
122+
transform: translateY(-100%);
123+
}
124+
125+
.music-info h2 {
126+
font-size: 1rem;
127+
font-weight: bold;
128+
margin: 0;
129+
}
130+
131+
.progress-container {
132+
background-color: #fff;
133+
border-radius: 5px;
134+
cursor: pointer;
135+
margin: 10px 0;
136+
height: 4px;
137+
width: 100%;
138+
}
139+
140+
.progress {
141+
background-color: #fe8daa;
142+
border-radius: 5px;
143+
height: 100%;
144+
width: 0%;
145+
transition: width 0.1s linear;
146+
}

‎README.md

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
| 65 | [Hangman Game](https://github.com/solygambas/html-css-fifty-projects/tree/master/65-hangman%20game) | [Live Demo](https://codepen.io/solygambas/full/MWbLEYr) |
7474
| 66 | [Meal Finder](https://github.com/solygambas/html-css-fifty-projects/tree/master/66-meal%20finder) | [Live Demo](https://codepen.io/solygambas/full/dyOagYE) |
7575
| 67 | [Expense Tracker](https://github.com/solygambas/html-css-fifty-projects/tree/master/67-expense%20tracker) | [Live Demo](https://codepen.io/solygambas/full/OJbqyro) |
76+
| 68 | [Music Player](https://github.com/solygambas/html-css-fifty-projects/tree/master/68-music%20player) | [Live Demo](https://codepen.io/solygambas/full/LYbaZNG) |
7677

7778
Mainly based on 2 courses by Brad Traversy (2020):
7879

0 commit comments

Comments
 (0)