|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>BotRad.io AI Radio | Future of Radio</title> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
:root { |
|
|
--primary: #00e0ff; |
|
|
--secondary: #7b00ff; |
|
|
--dark: #141414; |
|
|
--darker: #0a0a0a; |
|
|
--light: #f0f0f0; |
|
|
--glass: rgba(20, 20, 20, 0.5); |
|
|
} |
|
|
|
|
|
* { |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
box-sizing: border-box; |
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
|
|
} |
|
|
|
|
|
body { |
|
|
background: linear-gradient(to right bottom, var(--darker), var(--dark)); |
|
|
color: var(--light); |
|
|
min-height: 100vh; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
overflow-x: hidden; |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
body::before { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: radial-gradient(circle at 30% 50%, var(--secondary), transparent 70%); |
|
|
opacity: 0.2; |
|
|
z-index: -1; |
|
|
} |
|
|
|
|
|
body::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
right: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: radial-gradient(circle at 70% 50%, var(--primary), transparent 70%); |
|
|
opacity: 0.2; |
|
|
z-index: -1; |
|
|
} |
|
|
|
|
|
.container { |
|
|
width: 90%; |
|
|
max-width: 1200px; |
|
|
background: var(--glass); |
|
|
backdrop-filter: blur(10px); |
|
|
-webkit-backdrop-filter: blur(10px); |
|
|
border-radius: 20px; |
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); |
|
|
overflow: hidden; |
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.container:hover { |
|
|
box-shadow: 0 35px 60px -10px rgba(0, 224, 255, 0.3); |
|
|
} |
|
|
|
|
|
.header { |
|
|
background: linear-gradient(to right, var(--secondary), var(--primary)); |
|
|
padding: 1.5rem; |
|
|
text-align: center; |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.header::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: url("data:image/svg+xml,%3Csvg viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 20 L100 0 L100 20 Z' fill='rgba(0,0,0,0.1)' /%3E%3C/svg%3E"); |
|
|
opacity: 0.5; |
|
|
} |
|
|
|
|
|
.header h1 { |
|
|
font-size: 2.5rem; |
|
|
font-weight: 800; |
|
|
margin-bottom: 0.5rem; |
|
|
background: linear-gradient(to right, var(--light), #c8e8ff); |
|
|
-webkit-background-clip: text; |
|
|
background-clip: text; |
|
|
color: transparent; |
|
|
position: relative; |
|
|
z-index: 1; |
|
|
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); |
|
|
} |
|
|
|
|
|
.header p { |
|
|
font-size: 1rem; |
|
|
opacity: 0.9; |
|
|
color: var(--light); |
|
|
position: relative; |
|
|
z-index: 1; |
|
|
font-weight: 300; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
|
|
|
.player-container { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
padding: 2rem; |
|
|
gap: 2rem; |
|
|
} |
|
|
|
|
|
.station-info { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
text-align: center; |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.station-cover { |
|
|
width: 200px; |
|
|
height: 200px; |
|
|
border-radius: 15px; |
|
|
object-fit: cover; |
|
|
border: 3px solid rgba(255, 255, 255, 0.1); |
|
|
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.5); |
|
|
transition: transform 0.3s ease; |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.station-cover img { |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
object-fit: cover; |
|
|
} |
|
|
|
|
|
.station-cover::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: radial-gradient(circle at center, transparent 30%, rgba(0, 0, 0, 0.5) 100%); |
|
|
} |
|
|
|
|
|
.station-cover:hover { |
|
|
transform: scale(1.05); |
|
|
} |
|
|
|
|
|
.station-text { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.station-name { |
|
|
font-size: 1.8rem; |
|
|
font-weight: 600; |
|
|
background: linear-gradient(to right, var(--primary), var(--secondary)); |
|
|
-webkit-background-clip: text; |
|
|
background-clip: text; |
|
|
color: transparent; |
|
|
} |
|
|
|
|
|
.station-desc { |
|
|
font-size: 0.9rem; |
|
|
opacity: 0.8; |
|
|
font-weight: 300; |
|
|
max-width: 500px; |
|
|
} |
|
|
|
|
|
.controls { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 1.5rem; |
|
|
} |
|
|
|
|
|
.main-controls { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 2rem; |
|
|
} |
|
|
|
|
|
.control-btn { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border: none; |
|
|
width: 50px; |
|
|
height: 50px; |
|
|
border-radius: 50%; |
|
|
color: var(--light); |
|
|
font-size: 1.2rem; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.control-btn::after { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: linear-gradient(to right, var(--primary), var(--secondary)); |
|
|
opacity: 0; |
|
|
transition: opacity 0.3s ease; |
|
|
z-index: -1; |
|
|
} |
|
|
|
|
|
.control-btn:hover { |
|
|
transform: translateY(-5px); |
|
|
color: white; |
|
|
} |
|
|
|
|
|
.control-btn:hover::after { |
|
|
opacity: 1; |
|
|
} |
|
|
|
|
|
.play-btn { |
|
|
width: 70px; |
|
|
height: 70px; |
|
|
font-size: 1.8rem; |
|
|
background: linear-gradient(to right, var(--primary), var(--secondary)); |
|
|
color: white; |
|
|
} |
|
|
|
|
|
.play-btn:hover { |
|
|
transform: scale(1.1); |
|
|
} |
|
|
|
|
|
.progress-container { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 0.5rem; |
|
|
width: 100%; |
|
|
} |
|
|
|
|
|
.time-info { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
font-size: 0.8rem; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
.progress-bar { |
|
|
height: 6px; |
|
|
width: 100%; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-radius: 3px; |
|
|
cursor: pointer; |
|
|
position: relative; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.progress-bar::before { |
|
|
content: ''; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
height: 100%; |
|
|
width: var(--progress, 0%); |
|
|
background: linear-gradient(to right, var(--primary), var(--secondary)); |
|
|
border-radius: 3px; |
|
|
transition: width 0.1s linear; |
|
|
} |
|
|
|
|
|
.volume-container { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.volume-icon { |
|
|
color: var(--light); |
|
|
opacity: 0.8; |
|
|
} |
|
|
|
|
|
.volume-slider { |
|
|
width: 100px; |
|
|
height: 4px; |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
border-radius: 2px; |
|
|
appearance: none; |
|
|
outline: none; |
|
|
cursor: pointer; |
|
|
} |
|
|
|
|
|
.volume-slider::-webkit-slider-thumb { |
|
|
appearance: none; |
|
|
width: 12px; |
|
|
height: 12px; |
|
|
border-radius: 50%; |
|
|
background: var(--primary); |
|
|
cursor: pointer; |
|
|
transition: all 0.2s ease; |
|
|
} |
|
|
|
|
|
.volume-slider::-webkit-slider-thumb:hover { |
|
|
background: var(--secondary); |
|
|
transform: scale(1.2); |
|
|
} |
|
|
|
|
|
.stations { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); |
|
|
gap: 1rem; |
|
|
margin-top: 1rem; |
|
|
} |
|
|
|
|
|
.station { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 10px; |
|
|
padding: 1rem; |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
border: 1px solid rgba(255, 255, 255, 0.05); |
|
|
} |
|
|
|
|
|
.station:hover { |
|
|
background: rgba(255, 255, 255, 0.1); |
|
|
transform: translateY(-5px); |
|
|
box-shadow: 0 10px 20px -10px rgba(0, 224, 255, 0.2); |
|
|
} |
|
|
|
|
|
.station.active { |
|
|
background: rgba(0, 224, 255, 0.1); |
|
|
border: 1px solid var(--primary); |
|
|
position: relative; |
|
|
} |
|
|
|
|
|
.station.active::after { |
|
|
content: '🔊'; |
|
|
position: absolute; |
|
|
top: 5px; |
|
|
right: 5px; |
|
|
font-size: 0.8rem; |
|
|
} |
|
|
|
|
|
.station-avatar { |
|
|
width: 50px; |
|
|
height: 50px; |
|
|
border-radius: 50%; |
|
|
background: linear-gradient(to right, var(--primary), var(--secondary)); |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
font-size: 1.2rem; |
|
|
} |
|
|
|
|
|
.station-title { |
|
|
font-size: 0.9rem; |
|
|
text-align: center; |
|
|
font-weight: 500; |
|
|
} |
|
|
|
|
|
.wave-animation { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 3px; |
|
|
height: 30px; |
|
|
margin-top: 0.5rem; |
|
|
} |
|
|
|
|
|
.wave-bar { |
|
|
width: 3px; |
|
|
height: 100%; |
|
|
background: var(--primary); |
|
|
border-radius: 3px; |
|
|
animation: wave 1.5s ease-in-out infinite; |
|
|
transform-origin: bottom; |
|
|
} |
|
|
|
|
|
.wave-bar:nth-child(1) { |
|
|
animation-delay: 0.1s; |
|
|
height: 60%; |
|
|
} |
|
|
|
|
|
.wave-bar:nth-child(2) { |
|
|
animation-delay: 0.3s; |
|
|
height: 100%; |
|
|
} |
|
|
|
|
|
.wave-bar:nth-child(3) { |
|
|
animation-delay: 0.5s; |
|
|
height: 80%; |
|
|
} |
|
|
|
|
|
.wave-bar:nth-child(4) { |
|
|
animation-delay: 0.2s; |
|
|
height: 70%; |
|
|
} |
|
|
|
|
|
.wave-bar:nth-child(5) { |
|
|
animation-delay: 0.4s; |
|
|
height: 90%; |
|
|
} |
|
|
|
|
|
@keyframes wave { |
|
|
0%, 100% { |
|
|
transform: scaleY(0.8); |
|
|
} |
|
|
50% { |
|
|
transform: scaleY(1.5); |
|
|
} |
|
|
} |
|
|
|
|
|
.footer { |
|
|
padding: 1.5rem; |
|
|
text-align: center; |
|
|
background: rgba(0, 0, 0, 0.2); |
|
|
font-size: 0.8rem; |
|
|
opacity: 0.7; |
|
|
} |
|
|
|
|
|
|
|
|
.radio-waves { |
|
|
position: absolute; |
|
|
width: 300px; |
|
|
height: 300px; |
|
|
border-radius: 50%; |
|
|
pointer-events: none; |
|
|
z-index: -1; |
|
|
} |
|
|
|
|
|
.wave { |
|
|
position: absolute; |
|
|
top: 50%; |
|
|
left: 50%; |
|
|
transform: translate(-50%, -50%); |
|
|
border: 2px solid var(--primary); |
|
|
border-radius: 50%; |
|
|
opacity: 0; |
|
|
animation: ripple 3s infinite; |
|
|
} |
|
|
|
|
|
.wave:nth-child(1) { |
|
|
width: 10rem; |
|
|
height: 10rem; |
|
|
animation-delay: 0s; |
|
|
} |
|
|
|
|
|
.wave:nth-child(2) { |
|
|
width: 15rem; |
|
|
height: 15rem; |
|
|
animation-delay: 1s; |
|
|
} |
|
|
|
|
|
.wave:nth-child(3) { |
|
|
width: 20rem; |
|
|
height: 20rem; |
|
|
animation-delay: 2s; |
|
|
} |
|
|
|
|
|
@keyframes ripple { |
|
|
0% { |
|
|
width: 10rem; |
|
|
height: 10rem; |
|
|
opacity: 0.4; |
|
|
} |
|
|
100% { |
|
|
width: 30rem; |
|
|
height: 30rem; |
|
|
opacity: 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@media (max-width: 768px) { |
|
|
.container { |
|
|
width: 95%; |
|
|
} |
|
|
|
|
|
.header h1 { |
|
|
font-size: 2rem; |
|
|
} |
|
|
|
|
|
.stations { |
|
|
grid-template-columns: repeat(2, 1fr); |
|
|
} |
|
|
|
|
|
.station-cover { |
|
|
width: 150px; |
|
|
height: 150px; |
|
|
} |
|
|
} |
|
|
|
|
|
@media (max-width: 480px) { |
|
|
.player-container { |
|
|
padding: 1.5rem; |
|
|
} |
|
|
|
|
|
.main-controls { |
|
|
gap: 1rem; |
|
|
} |
|
|
|
|
|
.control-btn { |
|
|
width: 40px; |
|
|
height: 40px; |
|
|
font-size: 1rem; |
|
|
} |
|
|
|
|
|
.play-btn { |
|
|
width: 60px; |
|
|
height: 60px; |
|
|
font-size: 1.5rem; |
|
|
} |
|
|
|
|
|
.stations { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
.now-playing { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
gap: 0.5rem; |
|
|
margin-top: 0.5rem; |
|
|
font-size: 0.8rem; |
|
|
color: var(--primary); |
|
|
opacity: 0.8; |
|
|
text-transform: uppercase; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
|
|
|
.now-playing span { |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
background: var(--primary); |
|
|
border-radius: 50%; |
|
|
display: inline-block; |
|
|
animation: pulse 1.5s infinite; |
|
|
} |
|
|
|
|
|
.now-playing span:nth-child(1) { |
|
|
animation-delay: 0s; |
|
|
} |
|
|
|
|
|
.now-playing span:nth-child(2) { |
|
|
animation-delay: 0.3s; |
|
|
} |
|
|
|
|
|
.now-playing span:nth-child(3) { |
|
|
animation-delay: 0.6s; |
|
|
} |
|
|
|
|
|
@keyframes pulse { |
|
|
0%, 100% { |
|
|
transform: scale(0.8); |
|
|
opacity: 0.5; |
|
|
} |
|
|
50% { |
|
|
transform: scale(1.2); |
|
|
opacity: 1; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
<div class="header"> |
|
|
<h1>BotRad.io</h1> |
|
|
<p>The Future of AI-Powered Radio Streaming</p> |
|
|
</div> |
|
|
|
|
|
<div class="player-container"> |
|
|
<div class="station-info"> |
|
|
<div class="station-cover"> |
|
|
<img src="https://source.unsplash.com/random/400x400/?music,technology" alt="Station Cover"> |
|
|
</div> |
|
|
<div class="station-text"> |
|
|
<h2 class="station-name">Quantum Beats</h2> |
|
|
<p class="station-desc">AI-generated electronic music with futuristic soundscapes</p> |
|
|
<div class="now-playing"> |
|
|
<span></span> |
|
|
<span></span> |
|
|
<span></span> |
|
|
Now Playing |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="wave-animation"> |
|
|
<div class="wave-bar"></div> |
|
|
<div class="wave-bar"></div> |
|
|
<div class="wave-bar"></div> |
|
|
<div class="wave-bar"></div> |
|
|
<div class="wave-bar"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="controls"> |
|
|
<div class="progress-container"> |
|
|
<div class="progress-bar" id="progressBar"></div> |
|
|
<div class="time-info"> |
|
|
<span id="currentTime">0:00</span> |
|
|
<span id="totalTime">3:42</span> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="main-controls"> |
|
|
<button class="control-btn" id="prevBtn"> |
|
|
<i class="fas fa-step-backward"></i> |
|
|
</button> |
|
|
<button class="control-btn play-btn" id="playBtn"> |
|
|
<i class="fas fa-play" id="playIcon"></i> |
|
|
</button> |
|
|
<button class="control-btn" id="nextBtn"> |
|
|
<i class="fas fa-step-forward"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="volume-container"> |
|
|
<i class="fas fa-volume-up volume-icon"></i> |
|
|
<input type="range" class="volume-slider" id="volumeSlider" min="0" max="100" value="80"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<h3 style="margin-top: 1rem; text-align: center; font-weight: 400;">AI Stations</h3> |
|
|
<div class="stations"> |
|
|
<div class="station active" data-id="1"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-atom"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Quantum Beats</h4> |
|
|
</div> |
|
|
<div class="station" data-id="2"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-brain"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Neural Waves</h4> |
|
|
</div> |
|
|
<div class="station" data-id="3"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-robot"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Synthetic Soul</h4> |
|
|
</div> |
|
|
<div class="station" data-id="4"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-code"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Algorithm Jazz</h4> |
|
|
</div> |
|
|
<div class="station" data-id="5"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-cloud-moon"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Dream Generator</h4> |
|
|
</div> |
|
|
<div class="station" data-id="6"> |
|
|
<div class="station-avatar"> |
|
|
<i class="fas fa-meteor"></i> |
|
|
</div> |
|
|
<h4 class="station-title">Cosmic Vibes</h4> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="footer"> |
|
|
© 2023 BotRad.io AI Radio | Made with <i class="fas fa-heart" style="color: #ff3366;"></i> by AI |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="radio-waves"> |
|
|
<div class="wave"></div> |
|
|
<div class="wave"></div> |
|
|
<div class="wave"></div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const playBtn = document.getElementById('playBtn'); |
|
|
const playIcon = document.getElementById('playIcon'); |
|
|
const prevBtn = document.getElementById('prevBtn'); |
|
|
const nextBtn = document.getElementById('nextBtn'); |
|
|
const progressBar = document.getElementById('progressBar'); |
|
|
const currentTimeEl = document.getElementById('currentTime'); |
|
|
const totalTimeEl = document.getElementById('totalTime'); |
|
|
const volumeSlider = document.getElementById('volumeSlider'); |
|
|
const stations = document.querySelectorAll('.station'); |
|
|
const stationCover = document.querySelector('.station-cover img'); |
|
|
const stationName = document.querySelector('.station-name'); |
|
|
const stationDesc = document.querySelector('.station-desc'); |
|
|
const waveAnimation = document.querySelector('.wave-animation'); |
|
|
|
|
|
|
|
|
const stationData = [ |
|
|
{ |
|
|
id: 1, |
|
|
name: "Quantum Beats", |
|
|
description: "AI-generated electronic music with futuristic soundscapes", |
|
|
cover: "https://source.unsplash.com/random/400x400/?technology,future", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
}, |
|
|
{ |
|
|
id: 2, |
|
|
name: "Neural Waves", |
|
|
description: "Brainwave synchronizing ambient for deep focus", |
|
|
cover: "https://source.unsplash.com/random/400x400/?brain,science", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
}, |
|
|
{ |
|
|
id: 3, |
|
|
name: "Synthetic Soul", |
|
|
description: "AI-composed emotional music that feels human", |
|
|
cover: "https://source.unsplash.com/random/400x400/?robot,art", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
}, |
|
|
{ |
|
|
id: 4, |
|
|
name: "Algorithm Jazz", |
|
|
description: "Machine learning jazz improvisation in real-time", |
|
|
cover: "https://source.unsplash.com/random/400x400/?jazz,code", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
}, |
|
|
{ |
|
|
id: 5, |
|
|
name: "Dream Generator", |
|
|
description: "Hypnotic soundscapes for lucid dreaming", |
|
|
cover: "https://source.unsplash.com/random/400x400/?dream,space", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
}, |
|
|
{ |
|
|
id: 6, |
|
|
name: "Cosmic Vibes", |
|
|
description: "Music generated from astronomical data patterns", |
|
|
cover: "https://source.unsplash.com/random/400x400/?universe,stars", |
|
|
audio: "https://samplelib.com/lib/preview/mp3/sample-3s.mp3" |
|
|
} |
|
|
]; |
|
|
|
|
|
|
|
|
let audio = new Audio(); |
|
|
let isPlaying = false; |
|
|
let currentStation = 1; |
|
|
let updateTimeInterval; |
|
|
|
|
|
|
|
|
function loadStation(stationId) { |
|
|
const station = stationData.find(s => s.id === stationId); |
|
|
if (!station) return; |
|
|
|
|
|
currentStation = stationId; |
|
|
audio.src = station.audio; |
|
|
stationCover.src = station.cover; |
|
|
stationName.textContent = station.name; |
|
|
stationDesc.textContent = station.description; |
|
|
|
|
|
|
|
|
stations.forEach(s => { |
|
|
if (parseInt(s.dataset.id) === stationId) { |
|
|
s.classList.add('active'); |
|
|
} else { |
|
|
s.classList.remove('active'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
if (isPlaying) { |
|
|
audio.play(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function togglePlay() { |
|
|
if (isPlaying) { |
|
|
audio.pause(); |
|
|
playIcon.classList.replace('fa-pause', 'fa-play'); |
|
|
waveAnimation.style.opacity = '0.5'; |
|
|
} else { |
|
|
audio.play(); |
|
|
playIcon.classList.replace('fa-play', 'fa-pause'); |
|
|
waveAnimation.style.opacity = '1'; |
|
|
} |
|
|
isPlaying = !isPlaying; |
|
|
} |
|
|
|
|
|
|
|
|
function updateProgress() { |
|
|
const { currentTime, duration } = audio; |
|
|
const progressPercent = (currentTime / duration) * 100; |
|
|
progressBar.style.setProperty('--progress', `${progressPercent}%`); |
|
|
|
|
|
|
|
|
const formatTime = (time) => { |
|
|
const minutes = Math.floor(time / 60); |
|
|
const seconds = Math.floor(time % 60); |
|
|
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`; |
|
|
}; |
|
|
|
|
|
currentTimeEl.textContent = formatTime(currentTime); |
|
|
|
|
|
|
|
|
if (!totalTimeEl.dataset.set || isNaN(duration)) { |
|
|
totalTimeEl.textContent = formatTime(duration); |
|
|
totalTimeEl.dataset.set = 'true'; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function setProgress(e) { |
|
|
const width = this.clientWidth; |
|
|
const clickX = e.offsetX; |
|
|
const duration = audio.duration; |
|
|
audio.currentTime = (clickX / width) * duration; |
|
|
} |
|
|
|
|
|
|
|
|
function setVolume() { |
|
|
audio.volume = this.value / 100; |
|
|
} |
|
|
|
|
|
|
|
|
function changeStation(stationId) { |
|
|
loadStation(stationId); |
|
|
if (isPlaying) { |
|
|
togglePlay(); |
|
|
setTimeout(togglePlay, 100); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function prevStation() { |
|
|
let newStation = currentStation - 1; |
|
|
if (newStation < 1) newStation = stationData.length; |
|
|
changeStation(newStation); |
|
|
} |
|
|
|
|
|
|
|
|
function nextStation() { |
|
|
let newStation = currentStation + 1; |
|
|
if (newStation > stationData.length) newStation = 1; |
|
|
changeStation(newStation); |
|
|
} |
|
|
|
|
|
|
|
|
playBtn.addEventListener('click', togglePlay); |
|
|
prevBtn.addEventListener('click', prevStation); |
|
|
nextBtn.addEventListener('click', nextStation); |
|
|
progressBar.addEventListener('click', setProgress); |
|
|
volumeSlider.addEventListener('input', setVolume); |
|
|
|
|
|
stations.forEach(station => { |
|
|
station.addEventListener('click', function() { |
|
|
const stationId = parseInt(this.dataset.id); |
|
|
changeStation(stationId); |
|
|
}); |
|
|
}); |
|
|
|
|
|
audio.addEventListener('timeupdate', updateProgress); |
|
|
audio.addEventListener('ended', nextStation); |
|
|
audio.addEventListener('canplay', function() { |
|
|
if (isPlaying) { |
|
|
audio.play(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
loadStation(currentStation); |
|
|
audio.volume = volumeSlider.value / 100; |
|
|
|
|
|
|
|
|
totalTimeEl.textContent = "3:42"; |
|
|
}); |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: absolute; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">This website has been generated by <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body> |
|
|
</html> |