soundwave-htmx / index.html
PsyEyes's picture
Давай сделаем красивый музыкальный плеер на HTMX и Tailwind визуально похожий на Spotify. Что нужно:
7421366 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SoundWave HTMX 🎶 - Spotify-like Music Player</title>
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<link rel="stylesheet" href="style.css">
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<style>
:root {
--primary-color: #1DB954;
--secondary-color: #191414;
--background-color: #121212;
--sidebar-color: #000000;
--player-color: #181818;
--card-bg: rgba(255, 255, 255, 0.05);
--card-hover: rgba(255, 255, 255, 0.1);
}
body {
background: linear-gradient(135deg, #121212 0%, #1a1a1a 100%);
color: white;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
height: 100vh;
overflow: hidden;
}
.glass-card {
background: var(--card-bg);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 12px;
}
.track-item {
transition: all 0.3s ease;
border-radius: 8px;
margin: 2px 0;
}
.track-item:hover {
background: var(--card-hover);
transform: translateY(-1px);
}
.track-item.active {
background: linear-gradient(90deg, rgba(29, 185, 84, 0.2), transparent);
border-left: 3px solid var(--primary-color);
}
.track-item.dragging {
opacity: 0.8;
background: rgba(29, 185, 84, 0.3);
transform: rotate(2deg);
z-index: 1000;
}
.track-item.drag-over {
border-top: 2px solid var(--primary-color);
}
.progress-bar {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
height: 4px;
outline: none;
appearance: none;
cursor: pointer;
}
.progress-bar::-webkit-slider-thumb {
appearance: none;
width: 12px;
height: 12px;
border-radius: 50%;
background: var(--primary-color);
cursor: pointer;
opacity: 0;
transition: opacity 0.3s;
}
.progress-bar:hover::-webkit-slider-thumb {
opacity: 1;
}
.volume-slider {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
height: 4px;
outline: none;
appearance: none;
}
.volume-slider::-webkit-slider-thumb {
appearance: none;
width: 14px;
height: 14px;
border-radius: 50%;
background: white;
cursor: pointer;
border: 2px solid var(--primary-color);
}
.sidebar-gradient {
background: linear-gradient(180deg, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.9));
}
.player-gradient {
background: linear-gradient(90deg, rgba(24, 24, 24, 0.95), rgba(18, 18, 18, 0.95));
}
.button-spotify {
background: var(--primary-color);
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(29, 185, 84, 0.3);
}
.button-spotify:hover {
background: #1ed760;
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(29, 185, 84, 0.4);
}
.scrollbar-custom::-webkit-scrollbar {
width: 8px;
}
.scrollbar-custom::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05);
border-radius: 4px;
}
.scrollbar-custom::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
}
.scrollbar-custom::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.3);
}
.pulse-playing {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.playlist-container {
max-height: calc(100vh - 320px);
overflow-y: auto;
}
.drag-handle {
cursor: grab;
opacity: 0.5;
transition: opacity 0.2s;
}
.track-item:hover .drag-handle {
opacity: 1;
}
.drag-handle:active {
cursor: grabbing;
}
</style>
</head>
<body class="h-screen flex flex-col">
<!-- Header -->
<header class="p-4 glass-card mx-4 mt-4 rounded-xl">
<div class="flex justify-between items-center">
<div class="flex items-center space-x-4">
<button class="rounded-full p-2 hover:bg-white hover:bg-opacity-10 transition-colors">
<i data-feather="arrow-left"></i>
</button>
<button class="rounded-full p-2 hover:bg-white hover:bg-opacity-10 transition-colors">
<i data-feather="arrow-right"></i>
</button>
</div>
<div class="flex items-center space-x-4">
<button class="bg-white bg-opacity-10 hover:bg-opacity-20 px-4 py-2 rounded-full text-sm font-medium transition-all">
Explore Premium
</button>
<button class="rounded-full p-2 hover:bg-white hover:bg-opacity-10 transition-colors">
<i data-feather="user"></i>
</button>
</div>
</div>
</header>
<div class="flex flex-1 overflow-hidden px-4 pb-4">
<!-- Sidebar -->
<aside class="w-72 sidebar-gradient rounded-xl mr-4 p-6 flex flex-col">
<div class="mb-8">
<h1 class="text-2xl font-bold flex items-center bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
<i data-feather="music" class="mr-3 text-green-400"></i>
SoundWave HTMX
</h1>
</div>
<nav class="space-y-2 mb-8">
<a href="#" class="flex items-center space-x-4 p-3 rounded-lg bg-white bg-opacity-10 hover:bg-opacity-20 transition-all">
<i data-feather="home"></i>
<span class="font-medium">Home</span>
</a>
<a href="#" class="flex items-center space-x-4 p-3 rounded-lg hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="search"></i>
<span class="font-medium">Search</span>
</a>
<a href="#" class="flex items-center space-x-4 p-3 rounded-lg hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="book-open"></i>
<span class="font-medium">Your Library</span>
</a>
</nav>
<div class="mt-auto space-y-4">
<button class="w-full flex items-center space-x-3 p-3 rounded-lg hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="plus-square"></i>
<span class="font-medium">Create Playlist</span>
</button>
<button class="w-full flex items-center space-x-3 p-3 rounded-lg hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="heart"></i>
<span class="font-medium">Liked Songs</span>
</button>
<hr class="border-white border-opacity-20">
<div class="space-y-2">
<button class="w-full flex items-center space-x-3 p-2 rounded hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="download"></i>
<span class="text-sm">Install App</span>
</button>
<button class="w-full flex items-center space-x-3 p-2 rounded hover:bg-white hover:bg-opacity-10 transition-all">
<i data-feather="settings"></i>
<span class="text-sm">Settings</span>
</button>
</div>
</div>
</aside>
<!-- Main Content -->
<main class="flex-1 overflow-auto">
<div class="glass-card rounded-xl p-8 h-full">
<div class="mb-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-4xl font-bold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent">
Good afternoon
</h2>
<div class="flex space-x-3">
<button class="p-2 rounded-full hover:bg-white hover:bg-opacity-10 transition-colors">
<i data-feather="grid-3x3"></i>
</button>
<button class="p-2 rounded-full hover:bg-white hover:bg-opacity-10 transition-colors">
<i data-feather="list"></i>
</button>
</div>
</div>
<div class="flex items-center mb-8">
<button id="select-folder-btn" class="button-spotify px-6 py-3 rounded-full flex items-center font-medium">
<i data-feather="folder" class="mr-3"></i>
Select Music Folder
</button>
<input type="file" id="folder-input" webkitdirectory directory multiple class="hidden">
<div id="track-count" class="ml-6 text-sm text-gray-400">
No tracks loaded
</div>
</div>
</div>
<div class="glass-card rounded-xl p-6">
<div id="playlist-header" class="grid grid-cols-12 gap-4 px-4 py-3 text-gray-400 border-b border-white border-opacity-20 text-sm font-medium">
<div class="col-span-1 flex items-center">
<span>#</span>
<i data-feather="move" class="ml-2 w-4 h-4 drag-handle"></i>
</div>
<div class="col-span-5">Title</div>
<div class="col-span-3">Album</div>
<div class="col-span-2">Duration</div>
<div class="col-span-1"></div>
</div>
<div id="tracks-list" class="scrollbar-custom divide-y divide-white divide-opacity-10 playlist-container">
<!-- Tracks will be populated here -->
</div>
</div>
</div>
</main>
</div>
<!-- Player -->
<div id="player" class="player-gradient border-t border-white border-opacity-10 p-4">
<div class="max-w-7xl mx-auto grid grid-cols-3 gap-6 items-center">
<!-- Current Track Info -->
<div class="flex items-center space-x-4">
<div id="current-track-cover" class="bg-gradient-to-br from-purple-500 to-pink-500 w-16 h-16 rounded-lg shadow-lg flex items-center justify-center">
<i data-feather="music" class="text-white"></i>
</div>
<div class="min-w-0 flex-1">
<div id="current-track-title" class="font-semibold truncate">No track selected</div>
<div id="current-track-artist" class="text-sm text-gray-400 truncate">Unknown artist</div>
</div>
<button id="favorite-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="heart"></i>
</button>
</div>
<!-- Player Controls -->
<div class="flex flex-col items-center">
<div class="flex items-center space-x-6 mb-3">
<button id="shuffle-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="shuffle"></i>
</button>
<button id="prev-btn" class="text-white hover:text-green-400 transition-colors">
<i data-feather="skip-back"></i>
</button>
<button id="play-pause-btn" class="bg-white text-black rounded-full p-3 hover:bg-green-400 hover:text-white transition-all transform hover:scale-105">
<i data-feather="play" class="w-5 h-5"></i>
</button>
<button id="next-btn" class="text-white hover:text-green-400 transition-colors">
<i data-feather="skip-forward"></i>
</button>
<button id="repeat-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="repeat"></i>
</button>
</div>
<div class="w-full flex items-center space-x-3">
<span id="current-time" class="text-xs text-gray-400 min-w-[40px]">0:00</span>
<input type="range" id="progress-bar" class="progress-bar flex-1" value="0" min="0" max="100">
<span id="total-time" class="text-xs text-gray-400 min-w-[40px]">0:00</span>
</div>
</div>
<!-- Volume Control -->
<div class="flex items-center justify-end space-x-4">
<button id="lyrics-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="align-left"></i>
</button>
<button id="queue-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="list"></i>
</button>
<div class="flex items-center space-x-3">
<button id="volume-btn" class="text-gray-400 hover:text-white transition-colors">
<i data-feather="volume-2"></i>
</button>
<input type="range" id="volume-slider" class="volume-slider w-24" value="80" min="0" max="100">
</div>
</div>
</div>
</div>
<!-- HTMX for dynamic updates -->
<script src="script.js"></script>
<script>
// Enhanced feather icons replacement
feather.replace();
// Smooth transitions for interactive elements
document.addEventListener('DOMContentLoaded', () => {
// Add subtle animation to buttons
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('mouseenter', () => {
button.style.transform = 'translateY(-1px)';
});
button.addEventListener('mouseleave', () => {
button.style.transform = 'translateY(0)';
});
});
});
</script>
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
</body>
</html>