-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
368 lines (311 loc) · 10.9 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
import { songList } from './musiclist.mjs';
// selection des elements du DOM
const trckImg = document.querySelector('.current-media__img');
const trckName = document.querySelector('.current-media__title');
const progressBar = document.querySelector('.progress-bar__progress');
const currTime = document.querySelector('.progress-bar__current-time');
const totalTime = document.querySelector('.progress-bar__total-time');
const playBtn = document.querySelector('.play-pause-btn');
const playBtnIcon = document.querySelector('.fa-play-circle');
const prevBtn = document.querySelector('.previous');
const nextBtn = document.querySelector('.next');
const repeatBtn = document.querySelector('.repeat');
const repeatBtnIcon = document.querySelector('.fa-redo');
const repeatTxt = document.querySelector('.repeat-text');
const rdmBtn = document.querySelector('.random');
const rdmBtnIcon = document.querySelector('.fa-random');
const playlistBtn = document.querySelector('.playlist-icon');
const playlistBtnLeft = document.querySelector('.left-bar');
const playlistBtnRight = document.querySelector('.right-bar');
const playlistBtnHide = document.querySelectorAll('.to-hide-bar');
const playlistSection = document.querySelector('.playlist-container');
// Creation de l'element audio
const currentTrack = document.createElement('audio');
// Variables des fonctions
let trackIndex = 0;
let progressTimer; // timer pour MAJ barre progression
let playing = false; // pour affichage picto lecture/pause
let repeatOn = 0; // compteur repeat
let noPlaylistRepeat = true; // variable activant la répétition de playlist ou non
let shuffle = 0; // compteur shuffle
let shuffleOn = false; // toggle shuffle
let shuffleArray = []; // tableau pour stocker les indexs de piste an shuffle
// Fonction principale - Chargement de la piste au chargement de la page + MAJ des infos
function loadTrack() {
// RAZ de l'intervale pour l'update de la barre de temps
clearInterval(progressTimer);
currentTrack.src = songList[trackIndex].trackSource;
trckImg.src = songList[trackIndex].trackImg;
trckName.innerText = `${songList[trackIndex].trackName}
${songList[trackIndex].trackArtist}`;
// Update de la barre de temps
progressTimer = setInterval(timeUpdate, 1000);
// Lancement de la piste suivante à la fin ou de la meme si repeat actif
currentTrack.addEventListener('ended', nextTrack);
}
// Play et pause de la piste
function playPauseTrack() {
if (!playing) {
playTrack();
} else {
pauseTrack();
}
}
function playTrack() {
currentTrack.play();
playBtnIcon.classList.remove('fa-play-circle');
playBtnIcon.classList.add('fa-pause-circle');
playing = true;
}
function pauseTrack() {
currentTrack.pause();
playBtnIcon.classList.add('fa-play-circle');
playBtnIcon.classList.remove('fa-pause-circle');
playing = false;
}
// Fonctions barre de temps
function timeUpdate() {
let timePosition = 0; // RAZ de la valeur du temps de la piste en cours
if (!isNaN(currentTrack.duration)) {
timePosition = (currentTrack.currentTime * 100) / currentTrack.duration;
progressBar.value = timePosition;
// MAJ des infos duree
currTime.innerText = toMinutes(currentTrack.currentTime);
totalTime.innerText = toMinutes(currentTrack.duration);
// MAJ de la barre de progression
progressBar.style.backgroundSize = `${timePosition}% 100%`;
}
}
// convertir le temps de seconde à minutes:secondes
function toMinutes(time) {
let minutes = Math.floor(time / 60);
let seconds = Math.floor(time - minutes * 60);
if (minutes < 10) {
minutes = `0${minutes}`;
}
if (seconds < 10) {
seconds = `0${seconds}`;
}
return `${minutes}:${seconds}`;
}
// fonction pour selection du temps de la piste par l'utilisateur
function changeTime() {
// recuperation du clic de l'utilisateur
let userTime = (currentTrack.duration * progressBar.value) / 100;
// if(playing){
// Definition de la durée en cours
currentTrack.currentTime = userTime;
}
// Piste precedente et suivante
function prevTrack() {
// Controle si arrive en fin de liste de lecture
if (trackIndex > 0) {
trackIndex--;
} else {
trackIndex = songList.length - 1;
}
// chargement de la nouvelle piste
loadTrack(trackIndex);
// lecture de la piste
playTrack();
}
function nextTrack() {
repeatTrack();
// chargement de la nouvelle piste
loadTrack(trackIndex);
if (noPlaylistRepeat && trackIndex === 0 && repeatOn !== 2 && !shuffleOn) {
// condition shuffle
// Derniere piste atteinte et pas de repetition de playlist
pauseTrack();
currentTrack.currentTime = 0;
} else {
// lecture de la piste
playTrack();
}
}
// Repetition des pistes
function repeatTrackAction() {
// Gestion du bouton de repeat
if (repeatOn >= 2) {
repeatOn = 0;
noPlaylistRepeat = true;
repeatBtnIcon.style.color = '#b83f87';
repeatTxt.innerText = '';
repeatBtnIcon.blur();
} else {
repeatOn++;
if (repeatOn === 1) {
noPlaylistRepeat = false;
repeatBtnIcon.style.color = '#fff';
repeatTxt.innerText = ' all';
}
if (repeatOn === 2) {
noPlaylistRepeat = true;
repeatBtnIcon.style.color = '#fff';
repeatTxt.innerText = ' 1';
}
}
}
function repeatTrack() {
// generation de l'index de piste selon le type de repetition
switch (repeatOn) {
case 0: // Si aucun repeat activé
// Si shuffle on : fonction shuffle
if (shuffleOn) {
shuffleTrack();
} else {
// Controle si arrive en fin de liste de lecture
if (trackIndex < songList.length - 1) {
trackIndex++;
} else {
trackIndex = 0;
// noPlaylistRepeat = true;
}
}
break;
case 1:
// Si shuffle on : fonction shuffle
if (shuffleOn) {
shuffleTrack();
} else {
if (trackIndex === songList.length - 1 && !shuffleOn) {
trackIndex = 0;
// noPlaylistRepeat = false;
} else {
trackIndex++;
}
}
break;
case 2:
// noPlaylistRepeat = true;
break;
default:
console.log('Valeur non-reconnue');
}
return trackIndex;
}
// Activation du shuffle
function shuffleTrackAction() {
// Gestion du bouton de shuffle
shuffle++;
if (shuffle > 1) {
shuffle = 0;
shuffleOn = false;
rdmBtnIcon.style.color = '#b83f87';
} else {
shuffleOn = true;
rdmBtnIcon.style.color = '#fff';
rdmBtnIcon.blur();
if (!playing) {
// trackIndex = Math.floor(Math.random() * songList.length);
nextTrack();
}
}
}
function shuffleTrack() {
let currentTrackIndex; // Stock l'index en cours pour ne pas le lire à nouveau à la suite
// Controle si toutes les pistes ont été jouées
if (shuffleArray.length >= songList.length && repeatOn !== 1) {
// si longueur tableau sup ou egale à lg playlist, arrêter le shuffle :
shuffleOn = false;
trackIndex = 0;
return trackIndex;
}
if (shuffleArray.length >= songList.length && repeatOn === 1) {
// si repeat all activé, vider le tableau :
shuffleArray = [];
currentTrackIndex = trackIndex;
}
trackIndex = Math.floor(Math.random() * songList.length);
// tant que trackIndex présent dans le tableau, generer un nouvel index
while (
shuffleArray.includes(trackIndex) ||
trackIndex === currentTrackIndex
) {
trackIndex = Math.floor(Math.random() * songList.length);
}
// inserer index dans tableau
shuffleArray.push(trackIndex);
return trackIndex;
}
// Génération de la playlist
function playlistTableGen() {
const playlistTable = document.createElement('table');
const playlistTableBody = document.createElement('tbody');
playlistTable.innerHTML += `<thead><tr><th colspan="3">${songList[0].trackAlbum}</th></tr></thead>`;
for (const song of songList) {
const newRow = `<tr class="song-row"><td class="song-nbr">${
songList.indexOf(song) + 1
}</td><td class="song-title">${
song.trackName
}</td><td class="song-artist">${song.trackArtist}</td></tr>`;
playlistTableBody.innerHTML += newRow; // Ajout de la piste dans le body du tableau
}
playlistTable.appendChild(playlistTableBody); // Ajout du tbody au tableau
playlistSection.appendChild(playlistTable); // Ajout du tableau dans la section
}
// Lancement de l'app au chargement de la page
window.addEventListener('load', () => {
loadTrack();
playlistTableGen();
const songRow = document.querySelectorAll('.song-row');
// lancement piste au clic dans la playlist
for (const song of songRow) {
song.addEventListener('click', () => {
// Remonter en haut de page sur mobile
window.scrollTo({ top: 0, behavior: 'smooth' });
// Suppression de la classe active pour toutes les lignes
songRow.forEach((el) => el.classList.remove('row-active'));
// Fermeture de la playlist au clic sur mobile
if (
window.matchMedia('(max-width: 710px)').matches ||
window.matchMedia('(max-width: 920px) and (orientation: landscape)')
.matches
) {
playlistSection.classList.toggle('show-playlist');
playlistBtnEffect();
}
// Ajout de la classe active pour la chanson cliquée
song.classList.add('row-active');
trackIndex = song.rowIndex - 1;
loadTrack();
playTrack();
});
}
});
// Actualisation de la barre de temps à chaque modif de l'input
progressBar.addEventListener('change', changeTime);
// control button events
playBtn.addEventListener('click', playPauseTrack);
prevBtn.addEventListener('click', prevTrack);
nextBtn.addEventListener('click', nextTrack);
// option button events
repeatBtn.addEventListener('click', repeatTrackAction);
rdmBtn.addEventListener('click', shuffleTrackAction);
// affichage playlist
playlistBtn.addEventListener('click', () => {
playlistSection.classList.toggle('show-playlist');
playlistBtnEffect();
playlistScrollEffect();
});
// Effets sur le button playlist
function playlistBtnEffect() {
playlistBtnLeft.classList.toggle('active-bar-1');
playlistBtnRight.classList.toggle('active-bar-2');
playlistBtnHide.forEach((item) => {
item.classList.toggle('hide-bar');
});
}
// Effets d'ouverture de la playlist
function playlistScrollEffect() {
let scrollToPlaylistDelay;
// Récupération de la position du haut de la playlist
let scrollHeight = playlistSection.offsetTop;
function scrollToPlaylist() {
window.scrollTo({ top: scrollHeight, behavior: 'smooth' });
clearTimeout(scrollToPlaylistDelay);
}
if (playlistSection.classList.contains('show-playlist')) {
scrollToPlaylistDelay = setTimeout(scrollToPlaylist, 25);
}
}