Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Italian Brinarot</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%); | |
| } | |
| .character-card { | |
| transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); | |
| perspective: 1000px; | |
| } | |
| .character-card:hover { | |
| transform: translateY(-8px); | |
| box-shadow: 0 15px 30px rgba(0,0,0,0.12); | |
| } | |
| .image-container { | |
| /* REMOVED clip-path: circle(50% at 50% 50%); */ | |
| background: linear-gradient(145deg, #ffffff, #e6e6e6); | |
| box-shadow: 0 4px 15px rgba(0,0,0,0.1); | |
| /* Tailwind classes will handle rounding and overflow */ | |
| } | |
| .play-btn { | |
| transition: all 0.2s ease; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| } | |
| .play-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(118, 75, 162, 0.4); | |
| } | |
| .play-btn:active { | |
| transform: translateY(0); | |
| } | |
| .gradient-text { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| } | |
| .header-divider { | |
| height: 4px; | |
| background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); | |
| } | |
| @media (max-width: 640px) { | |
| .character-name { | |
| font-size: 1rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen"> | |
| <div class="container mx-auto px-4 py-8"> | |
| <!-- Header --> | |
| <header class="text-center mb-12"> | |
| <h1 class="text-4xl md:text-5xl font-bold gradient-text mb-2">Italian Brinarot</h1> | |
| <div class="header-divider w-32 mx-auto rounded-full mb-6"></div> | |
| <p class="text-gray-600 max-w-2xl mx-auto">Discover the magical sounds of Italian Brinarot characters</p> | |
| </header> | |
| <!-- Character Grid --> | |
| <div id="characterGrid" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8"></div> | |
| </div> | |
| <!-- Embedded Character Data --> | |
| <script> | |
| const characterData = { | |
| "Bombardiro Crocodilo": { | |
| "image_path": "./assets/Bombardiro_Crocodilo.png", | |
| "audio_path": "./assets/Bombardiro_Crocodilo.wav" | |
| }, | |
| "Tralalero Tralala": { | |
| "image_path": "./assets/Tralalero_Tralala.png", | |
| "audio_path": "./assets/Tralalero_Tralala.wav" | |
| }, | |
| "Bombombini Gusini": { | |
| "image_path": "./assets/Bombombini_Gusini.png", | |
| "audio_path": "./assets/Bombombini_Gusini.wav" | |
| }, | |
| "Tung Tung Tung Tung Tung Tung Tung Tung Tung Sahur": { | |
| "image_path": "./assets/Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Sahur.png", | |
| "audio_path": "./assets/Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Tung_Sahur.wav" | |
| }, | |
| "Brr Brr Patapim": { | |
| "image_path": "./assets/Brr_Brr_Patapim.png", | |
| "audio_path": "./assets/Brr_Brr_Patapim.wav" | |
| }, | |
| "Cappuccino Assassino": { | |
| "image_path": "./assets/Cappuccino_Assassino.png", | |
| "audio_path": "./assets/Cappuccino_Assassino.wav" | |
| }, | |
| "Lirili Larila": { | |
| "image_path": "./assets/Lirili_Larila.png", | |
| "audio_path": "./assets/Lirili_Larila.wav" | |
| }, | |
| "Trulimero Trulichina": { | |
| "image_path": "./assets/Trulimero_Trulichina.png", | |
| "audio_path": "./assets/Trulimero_Trulichina.wav" | |
| }, | |
| "Boneca Ambalabu": { | |
| "image_path": "./assets/Boneca_Ambalabu.png", | |
| "audio_path": "./assets/Boneca_Ambalabu.wav" | |
| }, | |
| "Chimpanzini Bananini": { | |
| "image_path": "./assets/Chimpanzini_Bananini.png", | |
| "audio_path": "./assets/Chimpanzini_Bananini.wav" | |
| }, | |
| "Bananita Dolfinita": { | |
| "image_path": "./assets/Bananita_Dolfinita.png", | |
| "audio_path": "./assets/Bananita_Dolfinita.wav" | |
| }, | |
| "Bluberini Octopusini": { | |
| "image_path": "./assets/Bluberini_Octopusini.png", | |
| "audio_path": "./assets/Bluberini_Octopusini.wav" | |
| }, | |
| "Bobrito Bandito": { | |
| "image_path": "./assets/Bobrito_Bandito.png", | |
| "audio_path": "./assets/Bobrito_Bandito.wav" | |
| }, | |
| "Brri Brri Bicus Dicus": { | |
| "image_path": "./assets/Brri_Brri_Bicus_Dicus.png", | |
| "audio_path": "./assets/Brri_Brri_Bicus_Dicus.wav" | |
| }, | |
| "Burbaloni Luliloli": { | |
| "image_path": "./assets/Burbaloni_Luliloli.png", | |
| "audio_path": "./assets/Burbaloni_Luliloli.wav" | |
| }, | |
| "Chimpanzini Annasini": { | |
| "image_path": "./assets/Chimpanzini_Annasini.png", | |
| "audio_path": "./assets/Chimpanzini_Annasini.wav" | |
| }, | |
| "Chimpanzini Cocosini": { | |
| "image_path": "./assets/Chimpanzini_Cocosini.png", | |
| "audio_path": "./assets/Chimpanzini_Cocosini.wav" | |
| }, | |
| "Cocofanto Elefanto": { | |
| "image_path": "./assets/Cocofanto_Elefanto.png", | |
| "audio_path": "./assets/Cocofanto_Elefanto.wav" | |
| }, | |
| "Frigo Camelo Buffardello": { | |
| "image_path": "./assets/frigo_camelo_buffardello.png", | |
| "audio_path": "./assets/frigo_camelo_buffardello.wav" | |
| }, | |
| "Giraffe Celeste": { | |
| "image_path": "./assets/Giraffe_Celeste.png", | |
| "audio_path": "./assets/Giraffe_Celeste.wav" | |
| }, | |
| "Glorbo Fruttodrillo": { | |
| "image_path": "./assets/Glorbo_Fruttodrillo.png", | |
| "audio_path": "./assets/Glorbo_Fruttodrillo.wav" | |
| }, | |
| "Il Cacto Hipopotoma": { | |
| "image_path": "./assets/il_cacto_hipopotoma.png", | |
| "audio_path": "./assets/il_cacto_hipopotoma.wav" | |
| }, | |
| "Trippi Troppi Troppa Trippa": { | |
| "image_path": "./assets/Trippi_Troppi_Troppa_Trippa.png", | |
| "audio_path": "./assets/Trippi_Troppi_Troppa_Trippa.wav" | |
| } | |
| }; | |
| // Function to load and display characters | |
| function loadCharacters() { | |
| const characterGrid = document.getElementById('characterGrid'); | |
| // Clear any existing content | |
| characterGrid.innerHTML = ''; | |
| // Create cards for each character | |
| Object.entries(characterData).forEach(([name, data]) => { | |
| const card = document.createElement('div'); | |
| card.className = 'character-card bg-white rounded-2xl overflow-hidden shadow-md flex flex-col items-center p-6'; | |
| // Image container - **MODIFIED** for square with rounded corners | |
| const imageContainer = document.createElement('div'); | |
| // Added rounded-xl (you can change this) and overflow-hidden | |
| imageContainer.className = 'image-container mb-4 w-40 h-40 flex items-center justify-center rounded-2xl overflow-hidden'; // <-- MODIFIED LINE | |
| const image = document.createElement('img'); | |
| image.src = data.image_path.replace(/\\/g, '/'); | |
| image.alt = name; | |
| image.className = 'w-full h-full object-cover'; // object-cover ensures the image fills the square container | |
| imageContainer.appendChild(image); | |
| // Character name | |
| const nameElement = document.createElement('h3'); | |
| nameElement.className = 'character-name text-lg md:text-xl font-semibold text-gray-800 mb-3 text-center'; | |
| nameElement.textContent = name; | |
| // Play/Pause button | |
| const playButton = document.createElement('button'); | |
| // **MODIFIED** - Adjusted button gradient for better contrast/look (Optional) | |
| playButton.className = 'play-btn text-white font-medium py-2 px-6 rounded-full flex items-center'; | |
| const playIcon = document.createElement('i'); | |
| playIcon.className = 'fas fa-play mr-2'; | |
| playButton.appendChild(playIcon); | |
| playButton.appendChild(document.createTextNode('Play')); | |
| // Audio element | |
| const audio = new Audio(data.audio_path.replace(/\\/g, '/')); | |
| let isPlaying = false; | |
| // Keep track of all audios and buttons to manage pause state | |
| let currentAudio = null; | |
| let currentButton = null; | |
| // Play/Pause button click handler - **REVISED** for better pause handling | |
| playButton.addEventListener('click', () => { | |
| // Stop any other audio that might be playing | |
| document.querySelectorAll('audio').forEach(a => { | |
| if (a !== audio && !a.paused) { | |
| a.pause(); | |
| // Reset the button associated with that audio | |
| const relatedButton = a.nextElementSibling; // Assuming button is the next sibling | |
| if (relatedButton && relatedButton.classList.contains('play-btn')) { | |
| relatedButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play'; | |
| relatedButton.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'; // Reset background | |
| // Find the 'isPlaying' state for that audio (more complex, simplified here) | |
| } | |
| } | |
| }); | |
| // Find *all* buttons and reset their state visually if they aren't the current one | |
| document.querySelectorAll('.play-btn').forEach(btn => { | |
| if (btn !== playButton && !btn.previousElementSibling.paused) { // Check if audio associated with *other* button is playing | |
| // This part is tricky without a direct link; the logic below handles the active one better. | |
| } else if (btn !== playButton) { | |
| btn.innerHTML = '<i class="fas fa-play mr-2"></i>Play'; | |
| btn.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'; | |
| } | |
| }); | |
| if (isPlaying) { | |
| audio.pause(); | |
| playButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play'; | |
| playButton.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'; // Reset background | |
| isPlaying = false; | |
| currentAudio = null; | |
| currentButton = null; | |
| } else { | |
| audio.currentTime = 0; | |
| audio.play(); | |
| playButton.innerHTML = '<i class="fas fa-pause mr-2"></i>Pause'; | |
| playButton.style.background = '#ef4444'; // Example: Red background for pause state | |
| isPlaying = true; | |
| currentAudio = audio; | |
| currentButton = playButton; | |
| } | |
| }); | |
| // When audio ends, reset button | |
| audio.addEventListener('ended', () => { | |
| playButton.innerHTML = '<i class="fas fa-play mr-2"></i>Play'; | |
| playButton.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'; // Reset background | |
| isPlaying = false; | |
| currentAudio = null; | |
| currentButton = null; | |
| }); | |
| // Assemble the card | |
| card.appendChild(imageContainer); | |
| card.appendChild(nameElement); | |
| card.appendChild(audio); // Keep audio in DOM for easier access if needed, hide it | |
| audio.style.display = 'none'; | |
| card.appendChild(playButton); | |
| // Add card to the grid | |
| characterGrid.appendChild(card); | |
| }); | |
| // Improved pause handling: Add a global listener if needed, or rely on the button click logic above. | |
| // The revised click handler above should now pause other audios when a new one is played. | |
| } | |
| // Load characters when the page loads | |
| window.addEventListener('DOMContentLoaded', loadCharacters); | |
| </script> | |
| </body> | |
| </html> |