1
+ const wrapper = document . querySelector ( ".wrapper" ) ,
2
+ musicImg = wrapper . querySelector ( ".img-area img" ) ,
3
+ musicName = wrapper . querySelector ( ".song-details .name" ) ,
4
+ musicArtist = wrapper . querySelector ( ".song-details .artist" ) ,
5
+ playPauseBtn = wrapper . querySelector ( ".play-pause" ) ,
6
+ prevBtn = wrapper . querySelector ( "#prev" ) ,
7
+ nextBtn = wrapper . querySelector ( "#next" ) ,
8
+ mainAudio = wrapper . querySelector ( "#main-audio" ) ,
9
+ progressArea = wrapper . querySelector ( ".progress-area" ) ,
10
+ progressBar = progressArea . querySelector ( ".progress-bar" ) ,
11
+ musicList = wrapper . querySelector ( ".music-list" ) ,
12
+ moreMusicBtn = wrapper . querySelector ( "#more-music" ) ,
13
+ closemoreMusic = musicList . querySelector ( "#close" ) ;
14
+
15
+ let musicIndex = Math . floor ( ( Math . random ( ) * allMusic . length ) + 1 ) ;
16
+ isMusicPaused = true ;
17
+
18
+ window . addEventListener ( "load" , ( ) => {
19
+ loadMusic ( musicIndex ) ;
20
+ playingSong ( ) ;
21
+ } ) ;
22
+
23
+ function loadMusic ( indexNumb ) {
24
+ musicName . innerText = allMusic [ indexNumb - 1 ] . name ;
25
+ musicArtist . innerText = allMusic [ indexNumb - 1 ] . artist ;
26
+ musicImg . src = `images/${ allMusic [ indexNumb - 1 ] . src } .jpg` ;
27
+ mainAudio . src = `songs/${ allMusic [ indexNumb - 1 ] . src } .mp3` ;
28
+ }
29
+
30
+ //play music function
31
+ function playMusic ( ) {
32
+ wrapper . classList . add ( "paused" ) ;
33
+ playPauseBtn . querySelector ( "i" ) . innerText = "pause" ;
34
+ mainAudio . play ( ) ;
35
+ }
36
+
37
+ //pause music function
38
+ function pauseMusic ( ) {
39
+ wrapper . classList . remove ( "paused" ) ;
40
+ playPauseBtn . querySelector ( "i" ) . innerText = "play_arrow" ;
41
+ mainAudio . pause ( ) ;
42
+ }
43
+
44
+ //prev music function
45
+ function prevMusic ( ) {
46
+ musicIndex -- ; //decrement of musicIndex by 1
47
+ //if musicIndex is less than 1 then musicIndex will be the array length so the last music play
48
+ musicIndex < 1 ? musicIndex = allMusic . length : musicIndex = musicIndex ;
49
+ loadMusic ( musicIndex ) ;
50
+ playMusic ( ) ;
51
+ playingSong ( ) ;
52
+ }
53
+
54
+ //next music function
55
+ function nextMusic ( ) {
56
+ musicIndex ++ ; //increment of musicIndex by 1
57
+ //if musicIndex is greater than array length then musicIndex will be 1 so the first music play
58
+ musicIndex > allMusic . length ? musicIndex = 1 : musicIndex = musicIndex ;
59
+ loadMusic ( musicIndex ) ;
60
+ playMusic ( ) ;
61
+ playingSong ( ) ;
62
+ }
63
+
64
+ // play or pause button event
65
+ playPauseBtn . addEventListener ( "click" , ( ) => {
66
+ const isMusicPlay = wrapper . classList . contains ( "paused" ) ;
67
+ //if isPlayMusic is true then call pauseMusic else call playMusic
68
+ isMusicPlay ? pauseMusic ( ) : playMusic ( ) ;
69
+ playingSong ( ) ;
70
+ } ) ;
71
+
72
+ //prev music button event
73
+ prevBtn . addEventListener ( "click" , ( ) => {
74
+ prevMusic ( ) ;
75
+ } ) ;
76
+
77
+ //next music button event
78
+ nextBtn . addEventListener ( "click" , ( ) => {
79
+ nextMusic ( ) ;
80
+ } ) ;
81
+
82
+ // update progress bar width according to music current time
83
+ mainAudio . addEventListener ( "timeupdate" , ( e ) => {
84
+ const currentTime = e . target . currentTime ; //getting playing song currentTime
85
+ const duration = e . target . duration ; //getting playing song total duration
86
+ let progressWidth = ( currentTime / duration ) * 100 ;
87
+ progressBar . style . width = `${ progressWidth } %` ;
88
+
89
+ let musicCurrentTime = wrapper . querySelector ( ".current-time" ) ,
90
+ musicDuartion = wrapper . querySelector ( ".max-duration" ) ;
91
+ mainAudio . addEventListener ( "loadeddata" , ( ) => {
92
+ // update song total duration
93
+ let mainAdDuration = mainAudio . duration ;
94
+ let totalMin = Math . floor ( mainAdDuration / 60 ) ;
95
+ let totalSec = Math . floor ( mainAdDuration % 60 ) ;
96
+ if ( totalSec < 10 ) { //if sec is less than 10 then add 0 before it
97
+ totalSec = `0${ totalSec } ` ;
98
+ }
99
+ musicDuartion . innerText = `${ totalMin } :${ totalSec } ` ;
100
+ } ) ;
101
+ // update playing song current time
102
+ let currentMin = Math . floor ( currentTime / 60 ) ;
103
+ let currentSec = Math . floor ( currentTime % 60 ) ;
104
+ if ( currentSec < 10 ) { //if sec is less than 10 then add 0 before it
105
+ currentSec = `0${ currentSec } ` ;
106
+ }
107
+ musicCurrentTime . innerText = `${ currentMin } :${ currentSec } ` ;
108
+ } ) ;
109
+
110
+ // update playing song currentTime on according to the progress bar width
111
+ progressArea . addEventListener ( "click" , ( e ) => {
112
+ let progressWidth = progressArea . clientWidth ; //getting width of progress bar
113
+ let clickedOffsetX = e . offsetX ; //getting offset x value
114
+ let songDuration = mainAudio . duration ; //getting song total duration
115
+
116
+ mainAudio . currentTime = ( clickedOffsetX / progressWidth ) * songDuration ;
117
+ playMusic ( ) ; //calling playMusic function
118
+ playingSong ( ) ;
119
+ } ) ;
120
+
121
+ //change loop, shuffle, repeat icon onclick
122
+ const repeatBtn = wrapper . querySelector ( "#repeat-plist" ) ;
123
+ repeatBtn . addEventListener ( "click" , ( ) => {
124
+ let getText = repeatBtn . innerText ; //getting this tag innerText
125
+ switch ( getText ) {
126
+ case "repeat" :
127
+ repeatBtn . innerText = "repeat_one" ;
128
+ repeatBtn . setAttribute ( "title" , "Song looped" ) ;
129
+ break ;
130
+ case "repeat_one" :
131
+ repeatBtn . innerText = "shuffle" ;
132
+ repeatBtn . setAttribute ( "title" , "Playback shuffled" ) ;
133
+ break ;
134
+ case "shuffle" :
135
+ repeatBtn . innerText = "repeat" ;
136
+ repeatBtn . setAttribute ( "title" , "Playlist looped" ) ;
137
+ break ;
138
+ }
139
+ } ) ;
140
+
141
+ //code for what to do after song ended
142
+ mainAudio . addEventListener ( "ended" , ( ) => {
143
+ // we'll do according to the icon means if user has set icon to
144
+ // loop song then we'll repeat the current song and will do accordingly
145
+ let getText = repeatBtn . innerText ; //getting this tag innerText
146
+ switch ( getText ) {
147
+ case "repeat" :
148
+ nextMusic ( ) ; //calling nextMusic function
149
+ break ;
150
+ case "repeat_one" :
151
+ mainAudio . currentTime = 0 ; //setting audio current time to 0
152
+ loadMusic ( musicIndex ) ; //calling loadMusic function with argument, in the argument there is a index of current song
153
+ playMusic ( ) ; //calling playMusic function
154
+ break ;
155
+ case "shuffle" :
156
+ let randIndex = Math . floor ( ( Math . random ( ) * allMusic . length ) + 1 ) ; //genereting random index/numb with max range of array length
157
+ do {
158
+ randIndex = Math . floor ( ( Math . random ( ) * allMusic . length ) + 1 ) ;
159
+ } while ( musicIndex == randIndex ) ; //this loop run until the next random number won't be the same of current musicIndex
160
+ musicIndex = randIndex ; //passing randomIndex to musicIndex
161
+ loadMusic ( musicIndex ) ;
162
+ playMusic ( ) ;
163
+ playingSong ( ) ;
164
+ break ;
165
+ }
166
+ } ) ;
167
+
168
+ //show music list onclick of music icon
169
+ moreMusicBtn . addEventListener ( "click" , ( ) => {
170
+ musicList . classList . toggle ( "show" ) ;
171
+ } ) ;
172
+ closemoreMusic . addEventListener ( "click" , ( ) => {
173
+ moreMusicBtn . click ( ) ;
174
+ } ) ;
175
+
176
+ const ulTag = wrapper . querySelector ( "ul" ) ;
177
+ // let create li tags according to array length for list
178
+ for ( let i = 0 ; i < allMusic . length ; i ++ ) {
179
+ //let's pass the song name, artist from the array
180
+ let liTag = `<li li-index="${ i + 1 } ">
181
+ <div class="row">
182
+ <span>${ allMusic [ i ] . name } </span>
183
+ <p>${ allMusic [ i ] . artist } </p>
184
+ </div>
185
+ <span id="${ allMusic [ i ] . src } " class="audio-duration">3:40</span>
186
+ <audio class="${ allMusic [ i ] . src } " src="songs/${ allMusic [ i ] . src } .mp3"></audio>
187
+ </li>` ;
188
+ ulTag . insertAdjacentHTML ( "beforeend" , liTag ) ; //inserting the li inside ul tag
189
+
190
+ let liAudioDuartionTag = ulTag . querySelector ( `#${ allMusic [ i ] . src } ` ) ;
191
+ let liAudioTag = ulTag . querySelector ( `.${ allMusic [ i ] . src } ` ) ;
192
+ liAudioTag . addEventListener ( "loadeddata" , ( ) => {
193
+ let duration = liAudioTag . duration ;
194
+ let totalMin = Math . floor ( duration / 60 ) ;
195
+ let totalSec = Math . floor ( duration % 60 ) ;
196
+ if ( totalSec < 10 ) { //if sec is less than 10 then add 0 before it
197
+ totalSec = `0${ totalSec } ` ;
198
+ } ;
199
+ liAudioDuartionTag . innerText = `${ totalMin } :${ totalSec } ` ; //passing total duation of song
200
+ liAudioDuartionTag . setAttribute ( "t-duration" , `${ totalMin } :${ totalSec } ` ) ; //adding t-duration attribute with total duration value
201
+ } ) ;
202
+ }
203
+
204
+ //play particular song from the list onclick of li tag
205
+ function playingSong ( ) {
206
+ const allLiTag = ulTag . querySelectorAll ( "li" ) ;
207
+
208
+ for ( let j = 0 ; j < allLiTag . length ; j ++ ) {
209
+ let audioTag = allLiTag [ j ] . querySelector ( ".audio-duration" ) ;
210
+
211
+ if ( allLiTag [ j ] . classList . contains ( "playing" ) ) {
212
+ allLiTag [ j ] . classList . remove ( "playing" ) ;
213
+ let adDuration = audioTag . getAttribute ( "t-duration" ) ;
214
+ audioTag . innerText = adDuration ;
215
+ }
216
+
217
+ //if the li tag index is equal to the musicIndex then add playing class in it
218
+ if ( allLiTag [ j ] . getAttribute ( "li-index" ) == musicIndex ) {
219
+ allLiTag [ j ] . classList . add ( "playing" ) ;
220
+ audioTag . innerText = "Playing" ;
221
+ }
222
+
223
+ allLiTag [ j ] . setAttribute ( "onclick" , "clicked(this)" ) ;
224
+ }
225
+ }
226
+
227
+ //particular li clicked function
228
+ function clicked ( element ) {
229
+ let getLiIndex = element . getAttribute ( "li-index" ) ;
230
+ musicIndex = getLiIndex ; //updating current song index with clicked li index
231
+ loadMusic ( musicIndex ) ;
232
+ playMusic ( ) ;
233
+ playingSong ( ) ;
234
+ }
0 commit comments