Demiath commited on
Commit
37677dc
·
verified ·
1 Parent(s): 741dc31

Deploy from anycoder

Browse files
Files changed (1) hide show
  1. index.html +778 -19
index.html CHANGED
@@ -1,19 +1,778 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="es">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Sherlock Music - Tu Estación de Música</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ :root {
17
+ --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
18
+ --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
19
+ --dark-bg: #0f0f23;
20
+ --card-bg: rgba(255, 255, 255, 0.05);
21
+ --glass-bg: rgba(255, 255, 255, 0.1);
22
+ --text-primary: #ffffff;
23
+ --text-secondary: #b0b3b8;
24
+ --accent: #ff6b6b;
25
+ --success: #51cf66;
26
+ }
27
+
28
+ body {
29
+ font-family: 'Inter', sans-serif;
30
+ background: var(--dark-bg);
31
+ color: var(--text-primary);
32
+ overflow-x: hidden;
33
+ min-height: 100vh;
34
+ }
35
+
36
+ /* Animated Background */
37
+ .bg-animation {
38
+ position: fixed;
39
+ top: 0;
40
+ left: 0;
41
+ width: 100%;
42
+ height: 100%;
43
+ z-index: -1;
44
+ background: radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
45
+ radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),
46
+ radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%);
47
+ animation: float 20s ease-in-out infinite;
48
+ }
49
+
50
+ @keyframes float {
51
+ 0%, 100% { transform: translateY(0px) rotate(0deg); }
52
+ 50% { transform: translateY(-20px) rotate(1deg); }
53
+ }
54
+
55
+ /* Header */
56
+ .header {
57
+ position: fixed;
58
+ top: 0;
59
+ width: 100%;
60
+ padding: 1rem 2rem;
61
+ backdrop-filter: blur(20px);
62
+ background: var(--glass-bg);
63
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
64
+ z-index: 1000;
65
+ display: flex;
66
+ justify-content: space-between;
67
+ align-items: center;
68
+ }
69
+
70
+ .logo {
71
+ font-size: 1.8rem;
72
+ font-weight: 700;
73
+ background: var(--primary-gradient);
74
+ -webkit-background-clip: text;
75
+ -webkit-text-fill-color: transparent;
76
+ background-clip: text;
77
+ display: flex;
78
+ align-items: center;
79
+ gap: 0.5rem;
80
+ }
81
+
82
+ .header-actions {
83
+ display: flex;
84
+ gap: 1rem;
85
+ align-items: center;
86
+ }
87
+
88
+ .theme-toggle {
89
+ background: var(--card-bg);
90
+ border: 1px solid rgba(255, 255, 255, 0.1);
91
+ color: var(--text-primary);
92
+ padding: 0.8rem;
93
+ border-radius: 50%;
94
+ cursor: pointer;
95
+ transition: all 0.3s ease;
96
+ font-size: 1.1rem;
97
+ }
98
+
99
+ .theme-toggle:hover {
100
+ background: var(--glass-bg);
101
+ transform: scale(1.05);
102
+ }
103
+
104
+ /* Main Content */
105
+ .main-content {
106
+ margin-top: 80px;
107
+ padding: 2rem;
108
+ max-width: 1400px;
109
+ margin-left: auto;
110
+ margin-right: auto;
111
+ }
112
+
113
+ /* Hero Section */
114
+ .hero {
115
+ text-align: center;
116
+ margin-bottom: 4rem;
117
+ padding: 2rem;
118
+ }
119
+
120
+ .hero h1 {
121
+ font-size: clamp(2.5rem, 5vw, 4rem);
122
+ font-weight: 700;
123
+ margin-bottom: 1rem;
124
+ background: var(--primary-gradient);
125
+ -webkit-background-clip: text;
126
+ -webkit-text-fill-color: transparent;
127
+ background-clip: text;
128
+ }
129
+
130
+ .hero p {
131
+ font-size: 1.3rem;
132
+ color: var(--text-secondary);
133
+ max-width: 600px;
134
+ margin: 0 auto;
135
+ }
136
+
137
+ /* Music Player */
138
+ .music-player {
139
+ background: var(--card-bg);
140
+ backdrop-filter: blur(20px);
141
+ border-radius: 24px;
142
+ padding: 2.5rem;
143
+ border: 1px solid rgba(255, 255, 255, 0.1);
144
+ margin-bottom: 3rem;
145
+ position: relative;
146
+ overflow: hidden;
147
+ }
148
+
149
+ .music-player::before {
150
+ content: '';
151
+ position: absolute;
152
+ top: 0;
153
+ left: 0;
154
+ right: 0;
155
+ height: 4px;
156
+ background: var(--primary-gradient);
157
+ border-radius: 24px 24px 0 0;
158
+ }
159
+
160
+ .album-art {
161
+ width: 200px;
162
+ height: 200px;
163
+ border-radius: 20px;
164
+ margin: 0 auto 2rem;
165
+ background: var(--primary-gradient);
166
+ display: flex;
167
+ align-items: center;
168
+ justify-content: center;
169
+ font-size: 4rem;
170
+ color: white;
171
+ animation: rotate 20s linear infinite paused;
172
+ box-shadow: 0 20px 40px rgba(102, 126, 234, 0.3);
173
+ }
174
+
175
+ .album-art.playing {
176
+ animation-play-state: running;
177
+ }
178
+
179
+ @keyframes rotate {
180
+ from { transform: rotate(0deg); }
181
+ to { transform: rotate(360deg); }
182
+ }
183
+
184
+ .track-info h2 {
185
+ font-size: 1.8rem;
186
+ margin-bottom: 0.5rem;
187
+ text-align: center;
188
+ }
189
+
190
+ .track-artist {
191
+ color: var(--text-secondary);
192
+ text-align: center;
193
+ margin-bottom: 2rem;
194
+ }
195
+
196
+ .progress-container {
197
+ margin-bottom: 2rem;
198
+ }
199
+
200
+ .progress-bar {
201
+ width: 100%;
202
+ height: 6px;
203
+ background: rgba(255, 255, 255, 0.1);
204
+ border-radius: 3px;
205
+ overflow: hidden;
206
+ cursor: pointer;
207
+ position: relative;
208
+ }
209
+
210
+ .progress {
211
+ height: 100%;
212
+ background: var(--primary-gradient);
213
+ width: 0%;
214
+ border-radius: 3px;
215
+ transition: width 0.1s ease;
216
+ }
217
+
218
+ .time-display {
219
+ display: flex;
220
+ justify-content: space-between;
221
+ margin-bottom: 2rem;
222
+ font-size: 0.9rem;
223
+ color: var(--text-secondary);
224
+ }
225
+
226
+ .controls {
227
+ display: flex;
228
+ justify-content: center;
229
+ align-items: center;
230
+ gap: 2rem;
231
+ margin-bottom: 1rem;
232
+ }
233
+
234
+ .control-btn {
235
+ width: 60px;
236
+ height: 60px;
237
+ border-radius: 50%;
238
+ border: none;
239
+ background: var(--glass-bg);
240
+ color: var(--text-primary);
241
+ font-size: 1.3rem;
242
+ cursor: pointer;
243
+ transition: all 0.3s ease;
244
+ display: flex;
245
+ align-items: center;
246
+ justify-content: center;
247
+ }
248
+
249
+ .control-btn:hover {
250
+ background: var(--primary-gradient);
251
+ transform: scale(1.1);
252
+ }
253
+
254
+ .play-pause {
255
+ width: 80px;
256
+ height: 80px;
257
+ font-size: 1.8rem;
258
+ background: var(--primary-gradient);
259
+ }
260
+
261
+ .play-pause:hover {
262
+ transform: scale(1.05);
263
+ }
264
+
265
+ .volume-container {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 1rem;
269
+ justify-content: center;
270
+ }
271
+
272
+ .volume-bar {
273
+ width: 120px;
274
+ height: 4px;
275
+ background: rgba(255, 255, 255, 0.1);
276
+ border-radius: 2px;
277
+ cursor: pointer;
278
+ }
279
+
280
+ /* Playlist */
281
+ .playlist-section {
282
+ display: grid;
283
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
284
+ gap: 2rem;
285
+ margin-bottom: 3rem;
286
+ }
287
+
288
+ .playlist-card {
289
+ background: var(--card-bg);
290
+ backdrop-filter: blur(20px);
291
+ border-radius: 20px;
292
+ padding: 2rem;
293
+ border: 1px solid rgba(255, 255, 255, 0.1);
294
+ transition: all 0.3s ease;
295
+ cursor: pointer;
296
+ }
297
+
298
+ .playlist-card:hover {
299
+ transform: translateY(-10px);
300
+ border-color: rgba(255, 255, 255, 0.2);
301
+ }
302
+
303
+ .playlist-card.playing {
304
+ border-color: var(--accent);
305
+ box-shadow: 0 20px 40px rgba(255, 107, 107, 0.3);
306
+ }
307
+
308
+ .playlist-icon {
309
+ width: 60px;
310
+ height: 60px;
311
+ border-radius: 12px;
312
+ display: flex;
313
+ align-items: center;
314
+ justify-content: center;
315
+ font-size: 1.5rem;
316
+ margin-bottom: 1rem;
317
+ }
318
+
319
+ .playlist-1 .playlist-icon { background: var(--primary-gradient); }
320
+ .playlist-2 .playlist-icon { background: var(--secondary-gradient); }
321
+ .playlist-3 .playlist-icon { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
322
+
323
+ .playlist-title {
324
+ font-size: 1.3rem;
325
+ font-weight: 600;
326
+ margin-bottom: 0.5rem;
327
+ }
328
+
329
+ .playlist-tracks {
330
+ font-size: 0.9rem;
331
+ color: var(--text-secondary);
332
+ }
333
+
334
+ /* Recently Played */
335
+ .recently-section {
336
+ margin-top: 3rem;
337
+ }
338
+
339
+ .section-title {
340
+ font-size: 2rem;
341
+ margin-bottom: 2rem;
342
+ display: flex;
343
+ align-items: center;
344
+ gap: 1rem;
345
+ }
346
+
347
+ .tracks-grid {
348
+ display: grid;
349
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
350
+ gap: 1.5rem;
351
+ }
352
+
353
+ .track-item {
354
+ background: var(--card-bg);
355
+ border-radius: 16px;
356
+ padding: 1.5rem;
357
+ cursor: pointer;
358
+ transition: all 0.3s ease;
359
+ border: 1px solid transparent;
360
+ position: relative;
361
+ overflow: hidden;
362
+ }
363
+
364
+ .track-item::before {
365
+ content: '';
366
+ position: absolute;
367
+ top: 0;
368
+ left: 0;
369
+ right: 0;
370
+ height: 3px;
371
+ background: var(--primary-gradient);
372
+ transform: scaleX(0);
373
+ transition: transform 0.3s ease;
374
+ }
375
+
376
+ .track-item:hover::before {
377
+ transform: scaleX(1);
378
+ }
379
+
380
+ .track-item:hover {
381
+ transform: translateY(-5px);
382
+ border-color: rgba(255, 255, 255, 0.2);
383
+ }
384
+
385
+ .track-item.active {
386
+ border-color: var(--accent);
387
+ }
388
+
389
+ .track-thumb {
390
+ width: 50px;
391
+ height: 50px;
392
+ border-radius: 8px;
393
+ background: var(--primary-gradient);
394
+ margin-bottom: 1rem;
395
+ display: flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ font-size: 1.2rem;
399
+ }
400
+
401
+ .track-title {
402
+ font-weight: 500;
403
+ margin-bottom: 0.3rem;
404
+ }
405
+
406
+ .track-duration {
407
+ color: var(--text-secondary);
408
+ font-size: 0.9rem;
409
+ }
410
+
411
+ /* Responsive */
412
+ @media (max-width: 768px) {
413
+ .main-content {
414
+ padding: 1rem;
415
+ margin-top: 100px;
416
+ }
417
+
418
+ .header {
419
+ padding: 1rem;
420
+ }
421
+
422
+ .controls {
423
+ gap: 1rem;
424
+ }
425
+
426
+ .playlist-section {
427
+ grid-template-columns: 1fr;
428
+ }
429
+
430
+ .tracks-grid {
431
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
432
+ }
433
+ }
434
+
435
+ /* Custom Scrollbar */
436
+ ::-webkit-scrollbar {
437
+ width: 8px;
438
+ }
439
+
440
+ ::-webkit-scrollbar-track {
441
+ background: rgba(255, 255, 255, 0.05);
442
+ }
443
+
444
+ ::-webkit-scrollbar-thumb {
445
+ background: var(--primary-gradient);
446
+ border-radius: 4px;
447
+ }
448
+
449
+ /* Pulse Animation */
450
+ @keyframes pulse {
451
+ 0%, 100% { opacity: 1; }
452
+ 50% { opacity: 0.7; }
453
+ }
454
+
455
+ .pulse {
456
+ animation: pulse 2s infinite;
457
+ }
458
+ </style>
459
+ </head>
460
+ <body>
461
+ <div class="bg-animation"></div>
462
+
463
+ <header class="header">
464
+ <div class="logo">
465
+ <i class="fas fa-music"></i>
466
+ Sherlock Music
467
+ </div>
468
+ <div class="header-actions">
469
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank"
470
+ style="color: var(--text-primary); text-decoration: none; font-weight: 500;">
471
+ Built with anycoder
472
+ </a>
473
+ <div class="theme-toggle" id="themeToggle">
474
+ <i class="fas fa-moon"></i>
475
+ </div>
476
+ </div>
477
+ </header>
478
+
479
+ <main class="main-content">
480
+ <section class="hero">
481
+ <h1>Tu Estación de Música</h1>
482
+ <p>Descubre nueva música, crea tus listas personalizadas y disfruta de una experiencia única con nuestro reproductor premium.</p>
483
+ </section>
484
+
485
+ <section class="music-player" id="musicPlayer">
486
+ <div class="album-art" id="albumArt">
487
+ <i class="fas fa-music"></i>
488
+ </div>
489
+ <div class="track-info">
490
+ <h2 id="trackTitle">Canción Actual</h2>
491
+ <p class="track-artist" id="trackArtist">Artista Desconocido</p>
492
+ </div>
493
+
494
+ <div class="progress-container">
495
+ <div class="progress-bar" id="progressBar">
496
+ <div class="progress" id="progress"></div>
497
+ </div>
498
+ <div class="time-display">
499
+ <span id="currentTime">0:00</span>
500
+ <span id="duration">0:00</span>
501
+ </div>
502
+ </div>
503
+
504
+ <div class="controls">
505
+ <button class="control-btn" id="prevBtn">
506
+ <i class="fas fa-step-backward"></i>
507
+ </button>
508
+ <button class="control-btn play-pause" id="playPauseBtn">
509
+ <i class="fas fa-play"></i>
510
+ </button>
511
+ <button class="control-btn" id="nextBtn">
512
+ <i class="fas fa-step-forward"></i>
513
+ </button>
514
+ </div>
515
+
516
+ <div class="volume-container">
517
+ <i class="fas fa-volume-up"></i>
518
+ <div class="volume-bar" id="volumeBar"></div>
519
+ </div>
520
+ </section>
521
+
522
+ <section class="playlist-section">
523
+ <div class="playlist-card playlist-1" data-playlist="1">
524
+ <div class="playlist-icon">
525
+ <i class="fas fa-guitar"></i>
526
+ </div>
527
+ <div class="playlist-title">Pop Hits 2024</div>
528
+ <div class="playlist-tracks">12 canciones • 45 min</div>
529
+ </div>
530
+ <div class="playlist-card playlist-2" data-playlist="2">
531
+ <div class="playlist-icon">
532
+ <i class="fas fa-drum"></i>
533
+ </div>
534
+ <div class="playlist-title">Rock Clásico</div>
535
+ <div class="playlist-tracks">15 canciones • 1h 2min</div>
536
+ </div>
537
+ <div class="playlist-card playlist-3" data-playlist="3">
538
+ <div class="playlist-icon">
539
+ <i class="fas fa-headphones"></i>
540
+ </div>
541
+ <div class="playlist-title">Chill Vibes</div>
542
+ <div class="playlist-tracks">20 canciones • 1h 30min</div>
543
+ </div>
544
+ </section>
545
+
546
+ <section class="recently-section">
547
+ <h2 class="section-title">
548
+ <i class="fas fa-history"></i>
549
+ Reproducidas Recientemente
550
+ </h2>
551
+ <div class="tracks-grid" id="tracksGrid">
552
+ <!-- Tracks will be populated by JavaScript -->
553
+ </div>
554
+ </section>
555
+ </main>
556
+
557
+ <script>
558
+ class MusicPlayer {
559
+ constructor() {
560
+ this.audio = new Audio();
561
+ this.audio.volume = 0.5;
562
+ this.isPlaying = false;
563
+ this.currentTrack = 0;
564
+ this.tracks = [
565
+ { title: "Noche Estelar", artist: "Luna Vargas", duration: "3:45", color: "#667eea" },
566
+ { title: "Ritmo Urbano", artist: "DJ Flow", duration: "2:58", color: "#f093fb" },
567
+ { title: "Sueños Rotos", artist: "Marta Sol", duration: "4:12", color: "#4facfe" },
568
+ { title: "Fuego en la Pista", artist: "Carlos Rey", duration: "3:22", color: "#ff6b6b" },
569
+ { title: "Alma Libre", artist: "Sofía Luna", duration: "4:01", color: "#51cf66" },
570
+ { title: "Eco del Tiempo", artist: "Raúl Mendoza", duration: "3:37", color: "#764ba2" }
571
+ ];
572
+
573
+ this.playlists = {
574
+ 1: ["Noche Estelar", "Ritmo Urbano", "Sueños Rotos"],
575
+ 2: ["Fuego en la Pista", "Eco del Tiempo"],
576
+ 3: ["Alma Libre", "Sueños Rotos"]
577
+ };
578
+
579
+ this.init();
580
+ }
581
+
582
+ init() {
583
+ this.bindEvents();
584
+ this.loadTrack(0);
585
+ this.renderTracks();
586
+ this.updateVolumeBar();
587
+ }
588
+
589
+ bindEvents() {
590
+ // Player controls
591
+ document.getElementById('playPauseBtn').addEventListener('click', () => this.togglePlay());
592
+ document.getElementById('prevBtn').addEventListener('click', () => this.prevTrack());
593
+ document.getElementById('nextBtn').addEventListener('click', () => this.nextTrack());
594
+
595
+ // Progress bar
596
+ const progressBar = document.getElementById('progressBar');
597
+ progressBar.addEventListener('click', (e) => this.setProgress(e));
598
+
599
+ // Volume
600
+ const volumeBar = document.getElementById('volumeBar');
601
+ volumeBar.addEventListener('click', (e) => this.setVolume(e));
602
+
603
+ // Audio events
604
+ this.audio.addEventListener('timeupdate', () => this.updateProgress());
605
+ this.audio.addEventListener('loadedmetadata', () => this.updateDuration());
606
+ this.audio.addEventListener('ended', () => this.nextTrack());
607
+
608
+ // Playlist cards
609
+ document.querySelectorAll('.playlist-card').forEach(card => {
610
+ card.addEventListener('click', (e) => this.playPlaylist(card.dataset.playlist));
611
+ });
612
+
613
+ // Track items
614
+ document.addEventListener('click', (e) => {
615
+ if (e.target.closest('.track-item')) {
616
+ const index = parseInt(e.target.closest('.track-item').dataset.index);
617
+ this.loadTrack(index);
618
+ }
619
+ });
620
+
621
+ // Keyboard shortcuts
622
+ document.addEventListener('keydown', (e) => {
623
+ if (e.code === 'Space') {
624
+ e.preventDefault();
625
+ this.togglePlay();
626
+ } else if (e.code === 'ArrowLeft') {
627
+ this.prevTrack();
628
+ } else if (e.code === 'ArrowRight') {
629
+ this.nextTrack();
630
+ }
631
+ });
632
+ }
633
+
634
+ loadTrack(index) {
635
+ this.currentTrack = index;
636
+ const track = this.tracks[index];
637
+
638
+ document.getElementById('trackTitle').textContent = track.title;
639
+ document.getElementById('trackArtist').textContent = track.artist;
640
+
641
+ // Update album art color
642
+ const albumArt = document.getElementById('albumArt');
643
+ albumArt.style.background = track.color;
644
+
645
+ // Simulate audio loading
646
+ this.audio.currentTime = 0;
647
+ this.audio.pause();
648
+ this.isPlaying = false;
649
+
650
+ this.updateActiveTrack();
651
+ this.updatePlayButton();
652
+ }
653
+
654
+ togglePlay() {
655
+ if (this.isPlaying) {
656
+ this.audio.pause();
657
+ } else {
658
+ this.audio.play();
659
+ document.getElementById('albumArt').classList.add('playing');
660
+ }
661
+ this.isPlaying = !this.isPlaying;
662
+ this.updatePlayButton();
663
+ }
664
+
665
+ nextTrack() {
666
+ this.loadTrack((this.currentTrack + 1) % this.tracks.length);
667
+ if (this.isPlaying) {
668
+ this.audio.play();
669
+ document.getElementById('albumArt').classList.add('playing');
670
+ }
671
+ }
672
+
673
+ prevTrack() {
674
+ this.loadTrack((this.currentTrack - 1 + this.tracks.length) % this.tracks.length);
675
+ if (this.isPlaying) {
676
+ this.audio.play();
677
+ document.getElementById('albumArt').classList.add('playing');
678
+ }
679
+ }
680
+
681
+ playPlaylist(playlistId) {
682
+ const playlistTracks = this.playlists[playlistId];
683
+ const firstTrackIndex = this.tracks.findIndex(track =>
684
+ playlistTracks.includes(track.title)
685
+ );
686
+ this.loadTrack(firstTrackIndex);
687
+ this.togglePlay();
688
+ }
689
+
690
+ updatePlayButton() {
691
+ const btn = document.getElementById('playPauseBtn');
692
+ const icon = btn.querySelector('i');
693
+ icon.className = this.isPlaying ? 'fas fa-pause' : 'fas fa-play';
694
+ }
695
+
696
+ updateProgress() {
697
+ if (this.audio.duration) {
698
+ const progress = (this.audio.currentTime / this.audio.duration) * 100;
699
+ document.getElementById('progress').style.width = progress + '%';
700
+ document.getElementById('currentTime').textContent =
701
+ this.formatTime(this.audio.currentTime);
702
+ }
703
+ }
704
+
705
+ updateDuration() {
706
+ document.getElementById('duration').textContent =
707
+ this.formatTime(this.audio.duration);
708
+ }
709
+
710
+ setProgress(e) {
711
+ const progressBar = document.getElementById('progressBar');
712
+ const rect = progressBar.getBoundingClientRect();
713
+ const pos = (e.clientX - rect.left) / rect.width;
714
+ this.audio.currentTime = pos * this.audio.duration;
715
+ }
716
+
717
+ setVolume(e) {
718
+ const volumeBar = document.getElementById('volumeBar');
719
+ const rect = volumeBar.getBoundingClientRect();
720
+ const pos = (e.clientX - rect.left) / rect.width;
721
+ this.audio.volume = Math.max(0, Math.min(1, pos));
722
+ this.updateVolumeBar();
723
+ }
724
+
725
+ updateVolumeBar() {
726
+ const volumeBar = document.getElementById('volumeBar');
727
+ const progress = document.createElement('div');
728
+ progress.style.width = (this.audio.volume * 100) + '%';
729
+ progress.style.height = '100%';
730
+ progress.style.background = 'var(--primary-gradient)';
731
+ progress.style.borderRadius = '2px';
732
+ progress.style.transition = 'width 0.1s ease';
733
+ volumeBar.innerHTML = '';
734
+ volumeBar.appendChild(progress);
735
+ }
736
+
737
+ formatTime(seconds) {
738
+ const mins = Math.floor(seconds / 60);
739
+ const secs = Math.floor(seconds % 60);
740
+ return `${mins}:${secs.toString().padStart(2, '0')}`;
741
+ }
742
+
743
+ renderTracks() {
744
+ const container = document.getElementById('tracksGrid');
745
+ container.innerHTML = this.tracks.map((track, index) => `
746
+ <div class="track-item" data-index="${index}">
747
+ <div class="track-thumb" style="background: ${track.color}">
748
+ <i class="fas fa-music"></i>
749
+ </div>
750
+ <div class="track-title">${track.title}</div>
751
+ <div class="track-duration">${track.artist} • ${track.duration}</div>
752
+ </div>
753
+ `).join('');
754
+ }
755
+
756
+ updateActiveTrack() {
757
+ document.querySelectorAll('.track-item').forEach((item, index) => {
758
+ item.classList.toggle('active', index === this.currentTrack);
759
+ });
760
+ }
761
+ }
762
+
763
+ // Initialize player when DOM is loaded
764
+ document.addEventListener('DOMContentLoaded', () => {
765
+ new MusicPlayer();
766
+ });
767
+
768
+ // Simulate audio visualization
769
+ setInterval(() => {
770
+ if (document.getElementById('albumArt').classList.contains('playing')) {
771
+ const albumArt = document.getElementById('albumArt');
772
+ const scale = 1 + Math.sin(Date.now() / 200) * 0.05;
773
+ albumArt.style.transform = `scale(${scale})`;
774
+ }
775
+ }, 100);
776
+ </script>
777
+ </body>
778
+ </html>