-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
313 lines (255 loc) · 8.7 KB
/
Copy pathapp.js
File metadata and controls
313 lines (255 loc) · 8.7 KB
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
const trackUrls = [
'audio/all.m4a',
'audio/CheckYes.m4a',
'audio/ImYours.m4a',
];
const songLyrics = {
'carousel-item-1': `Check yes Juliet
Are you with me?
Rain is falling down on the sidewalk
I won't go until you come outside
Check yes Juliet
Kill the limbo
I'll keep tossing rocks at your window
There's no turning back for us tonight
Lace up your shoes
Eh oh eh oh
Here's how we do
Run, baby, run
Don't ever look back
They'll tear us apart
If you give them the chance
Don't sell your heart
Don't say we're not meant to be
Run, baby, run
Forever we'll be
You and me
Check yes Juliet
I'll be waiting
Wishing, wanting
Yours for the taking
Just sneak out
And don't tell a soul goodbye
Check yes Juliet
Here's the countdown
Three, two, one, now fall in my arms
Now they can change the locks
Don't let them change your mind
Lace up your shoes
Eh oh eh oh
Here's how we do
Run, baby, run
Don't ever look back
They'll tear us apart
If you give them the chance
Don't sell your heart
Don't say we're not meant to be
Run, baby, run
Forever we'll be
You and me
We're flying through the night
We're flying through the night
Way up high,
The view from here is getting better with
You by my side
Run, baby, run
Don't ever look back
They'll tear us apart
If you give them the chance
Don't sell your heart
Don't say we're not meant to be
Run, baby, run
Forever we'll be
You and me
Run, baby, run
Don't ever look back.
They'll tear us apart
If you give them the chance.
Don't sell your heart.
Don't say we're not meant to be.
Run, baby, run.
Forever we'll be
You and me.
You and me
You and me`,
'carousel-item-2': `Lyrics for song 2...`,
'carousel-item-3': `Lyrics for song 3...`,
'carousel-item-4': `Lyrics for song 4...`,
'carousel-item-5': `Lyrics for song 5...`,
};
const carouselItems = document.querySelectorAll('.carousel-item');
const trackName = document.querySelector('.player-info h2');
const artistName = document.querySelector('.player-info h3');
const albumCover = document.querySelector('.album-cover img');
let player = {};
function updateLyrics(songId) {
const lyricsContainer = document.getElementById('song-lyrics');
const lyricsContent = document.createElement('div');
lyricsContent.innerHTML = songLyrics[songId].split('\n').map(line => `<p>${line}</p>`).join('');
lyricsContainer.innerHTML = '';
lyricsContainer.appendChild(lyricsContent);
}
updateLyrics('carousel-item-1');
function updateBackgroundColor() {
const colorThief = new ColorThief();
albumCover.addEventListener('load', () => {
const color = colorThief.getColor(albumCover);
const secondaryColor = colorThief.getPalette(albumCover, 2)[1];
// Use the colors for styling
const mainColor = `rgb(${color[0]}, ${color[1]}, ${color[2]})`;
const secondaryRgbColor = `rgb(${secondaryColor[0]}, ${secondaryColor[1]}, ${secondaryColor[2]})`;
// Set the background color
document.body.style.background = `linear-gradient(90deg, ${mainColor}, ${secondaryRgbColor})`;
document.body.style.backgroundSize = "200% auto";
document.body.style.animation = "gradient linear infinite";
// Create color scale
const colorScale = [];
const steps = 10;
for (let i = 0; i < steps; i++) {
const r = color[0] + i * (secondaryColor[0] - color[0]) / steps;
const g = color[1] + i * (secondaryColor[1] - color[1]) / steps;
const b = color[2] + i * (secondaryColor[2] - color[2]) / steps;
colorScale.push([r, g, b]);
}
});
}
function initPlayer(src) {
if (player && typeof player.unload === 'function') {
player.unload(); // Unload the current track from memory
}
player = new Howl({
src: [src],
html5: true,
onloaderror: function () {
console.log('Error: Audio file could not be loaded.');
},
});
}
initPlayer('audio/all.m4a');
const playPauseBtn = document.getElementById('play-pause');
const nextBtn = document.getElementById('next');
const volumeSlider = document.getElementById('volume-slider');
playPauseBtn.addEventListener('click', () => {
if (player.playing()) {
player.pause();
playPauseBtn.innerHTML = '<i class="fas fa-play text-gray-700 cursor-pointer"></i>';
} else {
player.play();
playPauseBtn.innerHTML = '<i class="fas fa-pause text-gray-700 cursor-pointer"></i>';
}
});
let currentTrack = 0;
volumeSlider.addEventListener('input', () => {
player.volume(volumeSlider.value / 100);
});
const prevButton = document.querySelector('.carousel-control.prev');
const nextButton = document.querySelector('.carousel-control.next');
const playerInfo = document.querySelector('.player-info');
let activeIndex = 0;
function updateMetadata() {
const activeItem = carouselItems[activeIndex];
const title = activeItem.querySelector('h2').innerText;
const artist = activeItem.querySelector('h3').innerText;
const source = activeItem.querySelector('h4').innerText;
const cover = activeItem.querySelector('img').src;
playerInfo.innerHTML = `
<h2 class="text-xl font-semibold mb-1">${title}</h2>
<h3 class="text-md text-gray-700 mb-1">${artist}</h3>
<h4 class="text-sm text-gray-500">${source}</h4>
`;
document.querySelector('.album-cover img').src = cover;
updateBackgroundColor();
}
function changeCarouselItem(offset){
carouselItems[activeIndex].classList.remove('active');
activeIndex = (activeIndex + offset + carouselItems.length) % carouselItems.length;
carouselItems[activeIndex].classList.add('active');
updateMetadata();
}
prevButton.addEventListener('click', () => {
changeCarouselItem(-1);
updateTrack();
});
nextButton.addEventListener('click', () => {
changeCarouselItem(1);
updateTrack();
});
// Initialize with the first item's metadata
updateMetadata();
// Update the play/pause button and track when the carousel changes
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 256;
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
player.on('play', () => {
scrollLyrics(player, currentSongId);
console.log('rendame');
const source = audioCtx.createMediaElementSource(player._sounds[0]._node);
source.connect(analyser);
analyser.connect(audioCtx.destination);
const canvas = document.getElementById('audio-visualizer');
const canvasCtx = canvas.getContext('2d');
const WIDTH = canvas.width;
const HEIGHT = canvas.height;
const barWidth = (WIDTH / bufferLength) * 2.5;
let barHeight;
let x = 0;
function renderFrame() {
requestAnimationFrame(renderFrame);
x = 0;
analyser.getByteFrequencyData(dataArray);
canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
for (let i = 0; i < bufferLength; i++) {
barHeight = dataArray[i];
const colorScale = [ [255, 0, 0], // red
[255, 255, 0], // yellow
[0, 255, 0], // green
[0, 0, 255], // blue
[255, 0, 255], // magenta
];
const colorIndex = Math.floor((barHeight / 255) * colorScale.length);
const color = `rgb(${colorScale[colorIndex][0]}, ${colorScale[colorIndex][1]}, ${colorScale[colorIndex][2]})`;
canvasCtx.fillStyle = color;
canvasCtx.fillRect(x, HEIGHT - barHeight / 2, barWidth, barHeight / 2);
x += barWidth + 1;
}
}
renderFrame();
});
const songProgress = {
'carousel-item-1': [0, 5, 10, 15], // Add the timestamps for each line of the lyrics
'carousel-item-2': [0, 5, 10, 15],
'carousel-item-3': [0, 5, 10, 15],
'carousel-item-4': [0, 5, 10, 15],
'carousel-item-5': [0, 5, 10, 15],
};
let currentSongId = 'carousel-item-1';
let currentLine = 0;
function updateTrack() {
initPlayer(trackUrls[activeIndex]);
player.once('load', function () {
player.play();
playPauseBtn.innerHTML = '<i class="fas fa-pause text-gray-700 cursor-pointer"></i>';
currentSongId = 'carousel-item-' + (activeIndex + 1); // Update the currentSongId based on the activeIndex
updateLyrics(currentSongId); // Update the lyrics for the new song
scrollLyrics(player, currentSongId);
});
}
// ...
function scrollLyrics(currentSong, currentSongId) {
const lyricsContainer = document.getElementById('song-lyrics');
const duration = currentSong.duration();
const interval = setInterval(() => {
console.log("reaching")
const currentTime = currentSong.seek();
if (currentTime >= songProgress[currentSongId][currentLine]) {
lyricsContainer.children[currentLine].scrollIntoView({ behavior: 'smooth' });
currentLine++;
}
if (currentTime >= duration) {
clearInterval(interval);
currentLine = 0;
}
}, 1000);
}