691 lines
23 KiB
HTML
691 lines
23 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Playful Animation Media Player</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
:root {
|
|
--primary-pink: #FF6B9D;
|
|
--primary-yellow: #FFC857;
|
|
--primary-blue: #4ECDC4;
|
|
--primary-purple: #A8E6CF;
|
|
--primary-orange: #FF6F61;
|
|
--bg-color: #FAF3F0;
|
|
--text-dark: #2D3436;
|
|
--white: #FFFFFF;
|
|
--shadow: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
@keyframes bounce {
|
|
0%, 100% { transform: translateY(0) scale(1); }
|
|
50% { transform: translateY(-10px) scale(1.05); }
|
|
}
|
|
|
|
@keyframes wiggle {
|
|
0%, 100% { transform: rotate(0deg); }
|
|
25% { transform: rotate(-5deg); }
|
|
75% { transform: rotate(5deg); }
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { transform: scale(1); }
|
|
50% { transform: scale(1.1); }
|
|
}
|
|
|
|
@keyframes dance {
|
|
0%, 100% { transform: translateX(0) rotate(0deg); }
|
|
25% { transform: translateX(-5px) rotate(-2deg); }
|
|
75% { transform: translateX(5px) rotate(2deg); }
|
|
}
|
|
|
|
@keyframes rainbow {
|
|
0% { filter: hue-rotate(0deg); }
|
|
100% { filter: hue-rotate(360deg); }
|
|
}
|
|
|
|
@keyframes float {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(-20px); }
|
|
}
|
|
|
|
body {
|
|
font-family: 'Comic Sans MS', cursive, sans-serif;
|
|
background: var(--bg-color);
|
|
min-height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20px;
|
|
overflow-x: hidden;
|
|
}
|
|
|
|
main {
|
|
width: 100%;
|
|
max-width: 800px;
|
|
}
|
|
|
|
h1 {
|
|
text-align: center;
|
|
color: var(--text-dark);
|
|
margin-bottom: 30px;
|
|
font-size: 2.5em;
|
|
animation: wiggle 2s ease-in-out infinite;
|
|
text-shadow: 3px 3px 0px var(--primary-pink);
|
|
}
|
|
|
|
.media-player {
|
|
background: var(--white);
|
|
border-radius: 30px;
|
|
box-shadow: 0 20px 40px var(--shadow);
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* Visualizer Section */
|
|
.visualizer {
|
|
height: 200px;
|
|
background: linear-gradient(135deg, var(--primary-blue) 0%, var(--primary-purple) 100%);
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.wave {
|
|
position: absolute;
|
|
bottom: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: flex-end;
|
|
justify-content: space-around;
|
|
padding: 0 20px;
|
|
}
|
|
|
|
.wave-bar {
|
|
width: 6%;
|
|
background: var(--white);
|
|
border-radius: 10px 10px 0 0;
|
|
transition: height 0.2s ease;
|
|
animation: dance 1s ease-in-out infinite;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.wave-bar:nth-child(odd) {
|
|
animation-delay: 0.1s;
|
|
background: var(--primary-yellow);
|
|
}
|
|
|
|
.wave-bar:nth-child(even) {
|
|
animation-delay: 0.2s;
|
|
background: var(--primary-pink);
|
|
}
|
|
|
|
/* Current Song Display */
|
|
.current-song {
|
|
padding: 20px;
|
|
text-align: center;
|
|
background: var(--white);
|
|
position: relative;
|
|
}
|
|
|
|
.song-title {
|
|
font-size: 1.5em;
|
|
color: var(--text-dark);
|
|
margin-bottom: 5px;
|
|
animation: pulse 2s ease-in-out infinite;
|
|
}
|
|
|
|
.song-artist {
|
|
color: #7D8E95;
|
|
font-size: 1.1em;
|
|
}
|
|
|
|
/* Controls Section */
|
|
.controls {
|
|
padding: 20px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 20px;
|
|
background: var(--white);
|
|
}
|
|
|
|
.control-btn {
|
|
background: var(--primary-pink);
|
|
border: none;
|
|
color: var(--white);
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
font-size: 1.5em;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
box-shadow: 0 5px 15px rgba(255, 107, 157, 0.3);
|
|
}
|
|
|
|
.control-btn:hover {
|
|
animation: bounce 0.5s ease-in-out;
|
|
transform: scale(1.1);
|
|
box-shadow: 0 10px 25px rgba(255, 107, 157, 0.5);
|
|
}
|
|
|
|
.control-btn:active {
|
|
transform: scale(0.95);
|
|
}
|
|
|
|
.play-btn {
|
|
background: var(--primary-blue);
|
|
width: 80px;
|
|
height: 80px;
|
|
font-size: 2em;
|
|
box-shadow: 0 5px 15px rgba(78, 205, 196, 0.3);
|
|
}
|
|
|
|
.play-btn:hover {
|
|
box-shadow: 0 10px 25px rgba(78, 205, 196, 0.5);
|
|
}
|
|
|
|
/* Progress Bar */
|
|
.progress-container {
|
|
padding: 0 20px 20px;
|
|
background: var(--white);
|
|
}
|
|
|
|
.progress-bar {
|
|
width: 100%;
|
|
height: 20px;
|
|
background: #F0F0F0;
|
|
border-radius: 10px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, var(--primary-pink) 0%, var(--primary-yellow) 50%, var(--primary-blue) 100%);
|
|
width: 35%;
|
|
border-radius: 10px;
|
|
position: relative;
|
|
transition: width 0.3s ease;
|
|
animation: rainbow 3s linear infinite;
|
|
}
|
|
|
|
.progress-handle {
|
|
position: absolute;
|
|
right: -10px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 30px;
|
|
height: 30px;
|
|
background: var(--white);
|
|
border: 4px solid var(--primary-pink);
|
|
border-radius: 50%;
|
|
cursor: grab;
|
|
box-shadow: 0 2px 10px var(--shadow);
|
|
animation: pulse 1s ease-in-out infinite;
|
|
}
|
|
|
|
/* Playlist Section */
|
|
.playlist-container {
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
padding: 20px;
|
|
background: #F8F8F8;
|
|
}
|
|
|
|
.playlist-item {
|
|
background: var(--white);
|
|
padding: 15px;
|
|
margin-bottom: 10px;
|
|
border-radius: 15px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 15px;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.playlist-item:hover {
|
|
transform: translateX(10px);
|
|
animation: dance 0.5s ease-in-out;
|
|
box-shadow: 0 5px 15px var(--shadow);
|
|
}
|
|
|
|
.playlist-item.active {
|
|
background: linear-gradient(135deg, var(--primary-pink) 0%, var(--primary-purple) 100%);
|
|
color: var(--white);
|
|
animation: dance 2s ease-in-out infinite;
|
|
}
|
|
|
|
.playlist-number {
|
|
width: 40px;
|
|
height: 40px;
|
|
background: var(--primary-yellow);
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: bold;
|
|
color: var(--text-dark);
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
.playlist-item.active .playlist-number {
|
|
background: var(--white);
|
|
animation: bounce 1s ease-in-out infinite;
|
|
}
|
|
|
|
/* Quality Selector */
|
|
.quality-selector {
|
|
padding: 20px;
|
|
background: var(--white);
|
|
display: flex;
|
|
gap: 15px;
|
|
justify-content: center;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.quality-bubble {
|
|
width: 60px;
|
|
height: 60px;
|
|
border-radius: 50%;
|
|
background: var(--primary-purple);
|
|
color: var(--text-dark);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: bold;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
font-size: 0.9em;
|
|
position: relative;
|
|
box-shadow: 0 5px 10px var(--shadow);
|
|
}
|
|
|
|
.quality-bubble:hover {
|
|
animation: float 1s ease-in-out;
|
|
transform: scale(1.2);
|
|
}
|
|
|
|
.quality-bubble.active {
|
|
background: var(--primary-orange);
|
|
color: var(--white);
|
|
animation: pulse 1s ease-in-out infinite;
|
|
transform: scale(1.3);
|
|
}
|
|
|
|
.quality-bubble.low { width: 50px; height: 50px; font-size: 0.8em; }
|
|
.quality-bubble.medium { width: 60px; height: 60px; }
|
|
.quality-bubble.high { width: 70px; height: 70px; font-size: 1em; }
|
|
.quality-bubble.ultra { width: 80px; height: 80px; font-size: 1.1em; }
|
|
|
|
/* Share Button */
|
|
.share-section {
|
|
padding: 20px;
|
|
background: var(--white);
|
|
text-align: center;
|
|
border-top: 2px dashed #E0E0E0;
|
|
}
|
|
|
|
.share-btn {
|
|
background: linear-gradient(135deg, var(--primary-orange) 0%, var(--primary-pink) 100%);
|
|
color: var(--white);
|
|
border: none;
|
|
padding: 15px 40px;
|
|
border-radius: 30px;
|
|
font-size: 1.2em;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
font-weight: bold;
|
|
box-shadow: 0 5px 15px rgba(255, 111, 97, 0.3);
|
|
}
|
|
|
|
.share-btn:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 10px 25px rgba(255, 111, 97, 0.5);
|
|
animation: wiggle 0.5s ease-in-out;
|
|
}
|
|
|
|
/* Confetti */
|
|
.confetti {
|
|
position: fixed;
|
|
width: 10px;
|
|
height: 10px;
|
|
top: -10px;
|
|
animation: confetti-fall 3s linear forwards;
|
|
z-index: 1000;
|
|
}
|
|
|
|
@keyframes confetti-fall {
|
|
0% {
|
|
transform: translateY(0) rotate(0deg);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
transform: translateY(100vh) rotate(720deg);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 600px) {
|
|
h1 { font-size: 2em; }
|
|
.control-btn { width: 50px; height: 50px; font-size: 1.2em; }
|
|
.play-btn { width: 70px; height: 70px; font-size: 1.8em; }
|
|
.quality-bubble { width: 50px; height: 50px; font-size: 0.8em; }
|
|
.quality-bubble.low { width: 40px; height: 40px; font-size: 0.7em; }
|
|
.quality-bubble.medium { width: 50px; height: 50px; }
|
|
.quality-bubble.high { width: 60px; height: 60px; font-size: 0.9em; }
|
|
.quality-bubble.ultra { width: 70px; height: 70px; font-size: 1em; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<h1>🎵 Bouncy Music Box 🎵</h1>
|
|
|
|
<div class="media-player">
|
|
<!-- Visualizer -->
|
|
<div class="visualizer">
|
|
<div class="wave" id="waveContainer">
|
|
<!-- Wave bars will be generated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Current Song Display -->
|
|
<div class="current-song">
|
|
<div class="song-title" id="songTitle">Happy Dance Time</div>
|
|
<div class="song-artist" id="songArtist">The Joyful Beats</div>
|
|
</div>
|
|
|
|
<!-- Progress Bar -->
|
|
<div class="progress-container">
|
|
<div class="progress-bar" id="progressBar">
|
|
<div class="progress-fill" id="progressFill">
|
|
<div class="progress-handle"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Controls -->
|
|
<div class="controls">
|
|
<button class="control-btn" id="prevBtn">⏮️</button>
|
|
<button class="control-btn play-btn" id="playBtn">▶️</button>
|
|
<button class="control-btn" id="nextBtn">⏭️</button>
|
|
</div>
|
|
|
|
<!-- Quality Selector -->
|
|
<div class="quality-selector">
|
|
<div class="quality-bubble low" data-quality="low">128k</div>
|
|
<div class="quality-bubble medium" data-quality="medium">256k</div>
|
|
<div class="quality-bubble high active" data-quality="high">320k</div>
|
|
<div class="quality-bubble ultra" data-quality="ultra">FLAC</div>
|
|
</div>
|
|
|
|
<!-- Playlist -->
|
|
<div class="playlist-container">
|
|
<div class="playlist-item active" data-index="0">
|
|
<div class="playlist-number">1</div>
|
|
<div>
|
|
<div>Happy Dance Time</div>
|
|
<small>The Joyful Beats</small>
|
|
</div>
|
|
</div>
|
|
<div class="playlist-item" data-index="1">
|
|
<div class="playlist-number">2</div>
|
|
<div>
|
|
<div>Bouncy Castle Dreams</div>
|
|
<small>Rainbow Unicorns</small>
|
|
</div>
|
|
</div>
|
|
<div class="playlist-item" data-index="2">
|
|
<div class="playlist-number">3</div>
|
|
<div>
|
|
<div>Bubble Pop Symphony</div>
|
|
<small>Giggle Factory</small>
|
|
</div>
|
|
</div>
|
|
<div class="playlist-item" data-index="3">
|
|
<div class="playlist-number">4</div>
|
|
<div>
|
|
<div>Marshmallow Clouds</div>
|
|
<small>Sweet Melodies</small>
|
|
</div>
|
|
</div>
|
|
<div class="playlist-item" data-index="4">
|
|
<div class="playlist-number">5</div>
|
|
<div>
|
|
<div>Confetti Carnival</div>
|
|
<small>Party Pirates</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Share Section -->
|
|
<div class="share-section">
|
|
<button class="share-btn" id="shareBtn">🎉 Share the Joy! 🎉</button>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<script>
|
|
// Playlist data
|
|
const playlist = [
|
|
{ title: 'Happy Dance Time', artist: 'The Joyful Beats' },
|
|
{ title: 'Bouncy Castle Dreams', artist: 'Rainbow Unicorns' },
|
|
{ title: 'Bubble Pop Symphony', artist: 'Giggle Factory' },
|
|
{ title: 'Marshmallow Clouds', artist: 'Sweet Melodies' },
|
|
{ title: 'Confetti Carnival', artist: 'Party Pirates' }
|
|
];
|
|
|
|
let currentSongIndex = 0;
|
|
let isPlaying = false;
|
|
let progress = 35;
|
|
let animationFrame;
|
|
let currentQuality = 'high';
|
|
|
|
// Create wave bars
|
|
const waveContainer = document.getElementById('waveContainer');
|
|
for (let i = 0; i < 15; i++) {
|
|
const bar = document.createElement('div');
|
|
bar.className = 'wave-bar';
|
|
bar.style.height = '20%';
|
|
bar.style.animationDelay = `${i * 0.1}s`;
|
|
waveContainer.appendChild(bar);
|
|
}
|
|
|
|
// Visualizer animation
|
|
function animateVisualizer() {
|
|
const bars = document.querySelectorAll('.wave-bar');
|
|
bars.forEach((bar, index) => {
|
|
if (isPlaying) {
|
|
const height = Math.random() * 80 + 20;
|
|
bar.style.height = `${height}%`;
|
|
|
|
// More complex animations for higher quality
|
|
if (currentQuality === 'ultra') {
|
|
bar.style.transform = `scaleX(${1 + Math.random() * 0.2}) rotate(${Math.random() * 5 - 2.5}deg)`;
|
|
} else if (currentQuality === 'high') {
|
|
bar.style.transform = `scaleX(${1 + Math.random() * 0.1})`;
|
|
}
|
|
} else {
|
|
bar.style.height = '20%';
|
|
bar.style.transform = 'scaleX(1) rotate(0deg)';
|
|
}
|
|
});
|
|
|
|
animationFrame = requestAnimationFrame(animateVisualizer);
|
|
}
|
|
|
|
// Play/Pause functionality
|
|
const playBtn = document.getElementById('playBtn');
|
|
playBtn.addEventListener('click', () => {
|
|
isPlaying = !isPlaying;
|
|
playBtn.textContent = isPlaying ? '⏸️' : '▶️';
|
|
|
|
if (isPlaying) {
|
|
animateVisualizer();
|
|
simulateProgress();
|
|
// Make playlist item dance more when playing
|
|
document.querySelector('.playlist-item.active').style.animationDuration = '0.5s';
|
|
} else {
|
|
document.querySelector('.playlist-item.active').style.animationDuration = '2s';
|
|
}
|
|
});
|
|
|
|
// Progress simulation
|
|
function simulateProgress() {
|
|
if (isPlaying && progress < 100) {
|
|
progress += 0.1;
|
|
document.getElementById('progressFill').style.width = `${progress}%`;
|
|
requestAnimationFrame(simulateProgress);
|
|
}
|
|
}
|
|
|
|
// Progress bar click
|
|
document.getElementById('progressBar').addEventListener('click', (e) => {
|
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
progress = ((e.clientX - rect.left) / rect.width) * 100;
|
|
document.getElementById('progressFill').style.width = `${progress}%`;
|
|
});
|
|
|
|
// Song navigation
|
|
function changeSong(index) {
|
|
// Update current song index
|
|
currentSongIndex = index;
|
|
if (currentSongIndex < 0) currentSongIndex = playlist.length - 1;
|
|
if (currentSongIndex >= playlist.length) currentSongIndex = 0;
|
|
|
|
// Update UI
|
|
document.getElementById('songTitle').textContent = playlist[currentSongIndex].title;
|
|
document.getElementById('songArtist').textContent = playlist[currentSongIndex].artist;
|
|
|
|
// Update playlist active state
|
|
document.querySelectorAll('.playlist-item').forEach((item, i) => {
|
|
item.classList.toggle('active', i === currentSongIndex);
|
|
});
|
|
|
|
// Reset progress
|
|
progress = 0;
|
|
document.getElementById('progressFill').style.width = '0%';
|
|
|
|
// Bounce effect on song change
|
|
const songDisplay = document.querySelector('.current-song');
|
|
songDisplay.style.animation = 'bounce 0.5s ease-in-out';
|
|
setTimeout(() => {
|
|
songDisplay.style.animation = '';
|
|
}, 500);
|
|
}
|
|
|
|
// Previous/Next buttons
|
|
document.getElementById('prevBtn').addEventListener('click', () => {
|
|
changeSong(currentSongIndex - 1);
|
|
});
|
|
|
|
document.getElementById('nextBtn').addEventListener('click', () => {
|
|
changeSong(currentSongIndex + 1);
|
|
});
|
|
|
|
// Playlist item clicks
|
|
document.querySelectorAll('.playlist-item').forEach((item, index) => {
|
|
item.addEventListener('click', () => {
|
|
changeSong(index);
|
|
});
|
|
});
|
|
|
|
// Quality selector
|
|
document.querySelectorAll('.quality-bubble').forEach(bubble => {
|
|
bubble.addEventListener('click', () => {
|
|
document.querySelectorAll('.quality-bubble').forEach(b => b.classList.remove('active'));
|
|
bubble.classList.add('active');
|
|
currentQuality = bubble.dataset.quality;
|
|
|
|
// Bounce all quality bubbles for fun
|
|
document.querySelectorAll('.quality-bubble').forEach(b => {
|
|
b.style.animation = 'bounce 0.5s ease-in-out';
|
|
setTimeout(() => {
|
|
b.style.animation = '';
|
|
}, 500);
|
|
});
|
|
|
|
// Update visualizer complexity based on quality
|
|
const bars = document.querySelectorAll('.wave-bar');
|
|
bars.forEach((bar, i) => {
|
|
if (currentQuality === 'ultra') {
|
|
bar.style.width = '5%';
|
|
} else if (currentQuality === 'high') {
|
|
bar.style.width = '6%';
|
|
} else if (currentQuality === 'medium') {
|
|
bar.style.width = '7%';
|
|
} else {
|
|
bar.style.width = '8%';
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
// Share button with confetti
|
|
document.getElementById('shareBtn').addEventListener('click', () => {
|
|
// Create confetti burst
|
|
for (let i = 0; i < 50; i++) {
|
|
const confetti = document.createElement('div');
|
|
confetti.className = 'confetti';
|
|
confetti.style.left = Math.random() * window.innerWidth + 'px';
|
|
confetti.style.backgroundColor = ['#FF6B9D', '#FFC857', '#4ECDC4', '#A8E6CF', '#FF6F61'][Math.floor(Math.random() * 5)];
|
|
confetti.style.animationDelay = Math.random() * 0.5 + 's';
|
|
confetti.style.animationDuration = (Math.random() * 2 + 2) + 's';
|
|
document.body.appendChild(confetti);
|
|
|
|
setTimeout(() => confetti.remove(), 4000);
|
|
}
|
|
|
|
// Bounce the share button
|
|
const btn = document.getElementById('shareBtn');
|
|
btn.style.animation = 'bounce 0.5s ease-in-out';
|
|
setTimeout(() => {
|
|
btn.style.animation = '';
|
|
}, 500);
|
|
|
|
// Show mock share message
|
|
const originalText = btn.textContent;
|
|
btn.textContent = '🎊 Shared! 🎊';
|
|
setTimeout(() => {
|
|
btn.textContent = originalText;
|
|
}, 2000);
|
|
});
|
|
|
|
// Start visualizer animation
|
|
animateVisualizer();
|
|
|
|
// Add some fun interactions
|
|
document.addEventListener('mousemove', (e) => {
|
|
if (isPlaying) {
|
|
const x = e.clientX / window.innerWidth;
|
|
const y = e.clientY / window.innerHeight;
|
|
|
|
// Subtle tilt effect on the player
|
|
const player = document.querySelector('.media-player');
|
|
const tiltX = (y - 0.5) * 5;
|
|
const tiltY = (x - 0.5) * -5;
|
|
player.style.transform = `perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg)`;
|
|
}
|
|
});
|
|
|
|
// Reset tilt on mouse leave
|
|
document.addEventListener('mouseleave', () => {
|
|
document.querySelector('.media-player').style.transform = '';
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |