| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>AvatarSync Studio - Create Animated Avatars</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <script src="https://unpkg.com/feather-icons"></script> |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> |
| <style> |
| @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); |
| |
| body { |
| font-family: 'Poppins', sans-serif; |
| overflow-x: hidden; |
| } |
| |
| .dropzone { |
| border: 2px dashed #9CA3AF; |
| transition: all 0.3s ease; |
| } |
| |
| .dropzone.active { |
| border-color: #4F46E5; |
| background-color: rgba(79, 70, 229, 0.05); |
| } |
| |
| .theme-selector input:checked + label { |
| border-color: #4F46E5; |
| box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2); |
| } |
| |
| .color-picker { |
| -webkit-appearance: none; |
| -moz-appearance: none; |
| appearance: none; |
| width: 40px; |
| height: 40px; |
| border: none; |
| cursor: pointer; |
| border-radius: 50%; |
| padding: 0; |
| } |
| |
| .color-picker::-webkit-color-swatch { |
| border-radius: 50%; |
| border: 2px solid white; |
| box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); |
| } |
| |
| #previewCanvas { |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); |
| border-radius: 12px; |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); |
| } |
| |
| .animation-preview { |
| transition: all 0.5s cubic-bezier(0.68, -0.6, 0.32, 1.6); |
| } |
| |
| .animation-preview:hover { |
| transform: scale(1.05); |
| } |
| |
| .tooltip { |
| visibility: hidden; |
| opacity: 0; |
| transition: opacity 0.3s; |
| } |
| |
| .has-tooltip:hover .tooltip { |
| visibility: visible; |
| opacity: 1; |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 min-h-screen"> |
| |
| <div id="vanta-bg" class="fixed top-0 left-0 w-full h-full -z-10"></div> |
| |
| |
| <div class="container mx-auto px-4 py-12 max-w-6xl"> |
| |
| <header class="text-center mb-12"> |
| <h1 class="text-4xl md:text-5xl font-bold text-gray-800 mb-2">AvatarSync Studio</h1> |
| <p class="text-lg text-gray-600 max-w-2xl mx-auto">Transform your image and audio into a personalized animated avatar with synchronized movements</p> |
| <div class="flex justify-center mt-4"> |
| <div class="w-16 h-1 bg-indigo-500 rounded-full"></div> |
| </div> |
| </header> |
| |
| |
| <div class="bg-white rounded-xl shadow-xl overflow-hidden mb-12"> |
| |
| <div class="flex justify-between items-center px-8 py-4 border-b"> |
| <div class="flex items-center space-x-2"> |
| <div class="w-8 h-8 rounded-full bg-indigo-500 text-white flex items-center justify-center">1</div> |
| <span class="font-medium text-indigo-600">Upload Media</span> |
| </div> |
| <div class="flex items-center space-x-2"> |
| <div class="w-8 h-8 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center">2</div> |
| <span class="font-medium text-gray-500">Customize</span> |
| </div> |
| <div class="flex items-center space-x-2"> |
| <div class="w-8 h-8 rounded-full bg-gray-200 text-gray-600 flex items-center justify-center">3</div> |
| <span class="font-medium text-gray-500">Generate</span> |
| </div> |
| </div> |
| |
| |
| <div class="p-8"> |
| |
| <div id="step1" class=""> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Upload Your Media</h2> |
| |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8"> |
| |
| <div class="space-y-4"> |
| <h3 class="text-lg font-medium text-gray-700 flex items-center"> |
| <i data-feather="image" class="mr-2"></i> Avatar Image |
| </h3> |
| <div class="dropzone rounded-lg p-8 text-center cursor-pointer" id="imageDropzone"> |
| <i data-feather="upload" class="w-12 h-12 mx-auto text-gray-400 mb-3"></i> |
| <p class="text-gray-500 mb-2">Drag & drop your image here</p> |
| <p class="text-sm text-gray-400">or click to browse files</p> |
| <input type="file" id="imageInput" accept="image/*" class="hidden"> |
| </div> |
| <div class="flex justify-center"> |
| <button id="clearImageBtn" class="text-sm text-gray-500 hover:text-gray-700 flex items-center" disabled> |
| <i data-feather="trash-2" class="w-4 h-4 mr-1"></i> Clear |
| </button> |
| </div> |
| </div> |
| |
| |
| <div class="space-y-4"> |
| <h3 class="text-lg font-medium text-gray-700 flex items-center"> |
| <i data-feather="music" class="mr-2"></i> Audio Track |
| </h3> |
| <div class="dropzone rounded-lg p-8 text-center cursor-pointer" id="audioDropzone"> |
| <i data-feather="upload" class="w-12 h-12 mx-auto text-gray-400 mb-3"></i> |
| <p class="text-gray-500 mb-2">Drag & drop your audio file here</p> |
| <p class="text-sm text-gray-400">or click to browse files</p> |
| <input type="file" id="audioInput" accept="audio/*" class="hidden"> |
| </div> |
| <div class="flex justify-center"> |
| <button id="clearAudioBtn" class="text-sm text-gray-500 hover:text-gray-700 flex items-center" disabled> |
| <i data-feather="trash-2" class="w-4 h-4 mr-1"></i> Clear |
| </button> |
| </div> |
| </div> |
| </div> |
| |
| <div class="flex justify-end"> |
| <button id="nextStep1Btn" class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded-lg flex items-center disabled:opacity-50" disabled> |
| Next <i data-feather="arrow-right" class="w-4 h-4 ml-2"></i> |
| </button> |
| </div> |
| </div> |
| |
| |
| <div id="step2" class="hidden"> |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> |
| |
| <div class="lg:col-span-2"> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Customize Your Animation</h2> |
| |
| <div class="bg-gray-100 rounded-xl p-4 mb-6"> |
| <canvas id="previewCanvas" class="w-full h-64 md:h-96 mx-auto"></canvas> |
| </div> |
| |
| <div class="bg-gray-100 rounded-xl p-4"> |
| <div class="flex items-center justify-between mb-2"> |
| <span class="text-gray-700">Audio Timeline</span> |
| <button id="playPauseBtn" class="text-indigo-500 hover:text-indigo-700"> |
| <i data-feather="play" class="w-5 h-5"></i> |
| </button> |
| </div> |
| <div class="relative h-2 bg-gray-300 rounded-full"> |
| <div id="progressBar" class="absolute top-0 left-0 h-full bg-indigo-500 rounded-full" style="width: 0%"></div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div> |
| <h3 class="text-xl font-semibold text-gray-800 mb-4">Customization</h3> |
| |
| |
| <div class="mb-6"> |
| <h4 class="text-sm font-medium text-gray-700 uppercase tracking-wider mb-3">Color Scheme</h4> |
| <div class="grid grid-cols-2 gap-4"> |
| <div> |
| <label class="block text-sm text-gray-600 mb-1">Primary Color</label> |
| <input type="color" class="color-picker" value="#4F46E5" id="primaryColor"> |
| </div> |
| <div> |
| <label class="block text-sm text-gray-600 mb-1">Secondary Color</label> |
| <input type="color" class="color-picker" value="#EC4899" id="secondaryColor"> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h4 class="text-sm font-medium text-gray-700 uppercase tracking-wider mb-3">Theme Style</h4> |
| <div class="grid grid-cols-3 gap-2"> |
| <div> |
| <input type="radio" name="theme" id="theme-light" value="light" class="hidden" checked> |
| <label for="theme-light" class="theme-selector block p-2 border rounded-lg cursor-pointer text-center"> |
| <div class="w-full h-16 bg-gradient-to-br from-gray-100 to-gray-200 rounded-md mb-1"></div> |
| <span class="text-xs">Light</span> |
| </label> |
| </div> |
| <div> |
| <input type="radio" name="theme" id="theme-dark" value="dark" class="hidden"> |
| <label for="theme-dark" class="theme-selector block p-2 border rounded-lg cursor-pointer text-center"> |
| <div class="w-full h-16 bg-gradient-to-br from-gray-800 to-gray-900 rounded-md mb-1"></div> |
| <span class="text-xs">Dark</span> |
| </label> |
| </div> |
| <div> |
| <input type="radio" name="theme" id="theme-neon" value="neon" class="hidden"> |
| <label for="theme-neon" class="theme-selector block p-2 border rounded-lg cursor-pointer text-center"> |
| <div class="w-full h-16 bg-gradient-to-br from-purple-900 to-pink-600 rounded-md mb-1"></div> |
| <span class="text-xs">Neon</span> |
| </label> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h4 class="text-sm font-medium text-gray-700 uppercase tracking-wider mb-3">Animation Style</h4> |
| <select class="w-full px-3 py-2 text-gray-700 bg-gray-100 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"> |
| <option>3D Cartoon</option> |
| <option>2D Minimal</option> |
| <option>Realistic</option> |
| <option>Anime Style</option> |
| <option>Pixel Art</option> |
| </select> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h4 class="text-sm font-medium text-gray-700 uppercase tracking-wider mb-3">Motion Intensity</h4> |
| <input type="range" min="0" max="100" value="50" class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer" id="motionRange"> |
| <div class="flex justify-between text-xs text-gray-500 mt-1"> |
| <span>Subtle</span> |
| <span>Dynamic</span> |
| </div> |
| </div> |
| |
| |
| <div class="mb-6"> |
| <h4 class="text-sm font-medium text-gray-700 uppercase tracking-wider mb-3">Sync Options</h4> |
| <div class="space-y-2"> |
| <label class="flex items-center space-x-2"> |
| <input type="checkbox" class="rounded text-indigo-500" checked> |
| <span>Sync to Beat</span> |
| </label> |
| <label class="flex items-center space-x-2"> |
| <input type="checkbox" class="rounded text-indigo-500" checked> |
| <span>Lip Sync</span> |
| </label> |
| <label class="flex items-center space-x-2"> |
| <input type="checkbox" class="rounded text-indigo-500"> |
| <span>Head Movement</span> |
| </label> |
| <label class="flex items-center space-x-2"> |
| <input type="checkbox" class="rounded text-indigo-500" checked> |
| <span>Hand Gestures</span> |
| </label> |
| </div> |
| </div> |
| |
| <div class="flex justify-between"> |
| <button id="backStep2Btn" class="text-gray-600 hover:text-gray-800 px-4 py-2 rounded-lg flex items-center"> |
| <i data-feather="arrow-left" class="w-4 h-4 mr-2"></i> Back |
| </button> |
| <button id="nextStep2Btn" class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded-lg flex items-center"> |
| Next <i data-feather="arrow-right" class="w-4 h-4 ml-2"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div id="step3" class="hidden"> |
| <h2 class="text-2xl font-semibold text-gray-800 mb-6">Generate Your Animated Avatar</h2> |
| |
| <div class="bg-gray-100 rounded-xl p-8 text-center mb-8"> |
| <div id="processingAnimation" class="flex justify-center mb-4"> |
| <div class="w-16 h-16 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin"></div> |
| </div> |
| <h3 class="text-xl font-medium text-gray-800 mb-2">Processing Your Animation</h3> |
| <p class="text-gray-600 max-w-md mx-auto">We're synchronizing your avatar with the audio and applying your customizations. This may take a few moments.</p> |
| <div class="w-full bg-gray-300 rounded-full h-2.5 mt-6"> |
| <div id="progressBar" class="bg-indigo-600 h-2.5 rounded-full" style="width: 0%"></div> |
| </div> |
| </div> |
| |
| <div id="resultSection" class="hidden"> |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8"> |
| <div class="bg-gray-100 rounded-xl p-4"> |
| <h3 class="text-lg font-medium text-gray-700 mb-3">Preview</h3> |
| <div class="animation-preview bg-white rounded-lg overflow-hidden shadow-md"> |
| <video id="resultVideo" class="w-full" controls></video> |
| </div> |
| </div> |
| <div class="space-y-6"> |
| <div> |
| <h3 class="text-lg font-medium text-gray-700 mb-3">Export Options</h3> |
| <div class="grid grid-cols-2 gap-4"> |
| <button class="bg-gray-200 hover:bg-gray-300 text-gray-800 py-3 rounded-lg flex flex-col items-center justify-center"> |
| <i data-feather="download" class="w-6 h-6 mb-2"></i> |
| <span>Download Video</span> |
| </button> |
| <button class="bg-gray-200 hover:bg-gray-300 text-gray-800 py-3 rounded-lg flex flex-col items-center justify-center"> |
| <i data-feather="image" class="w-6 h-6 mb-2"></i> |
| <span>Download GIF</span> |
| </button> |
| </div> |
| </div> |
| |
| <div> |
| <h3 class="text-lg font-medium text-gray-700 mb-3">Share</h3> |
| <div class="flex space-x-3"> |
| <button class="bg-blue-500 hover:bg-blue-600 text-white p-3 rounded-full"> |
| <i data-feather="facebook" class="w-5 h-5"></i> |
| </button> |
| <button class="bg-pink-500 hover:bg-pink-600 text-white p-3 rounded-full"> |
| <i data-feather="instagram" class="w-5 h-5"></i> |
| </button> |
| <button class="bg-blue-400 hover:bg-blue-500 text-white p-3 rounded-full"> |
| <i data-feather="twitter" class="w-5 h-5"></i> |
| </button> |
| <button class="bg-gray-800 hover:bg-gray-900 text-white p-3 rounded-full"> |
| <i data-feather="share-2" class="w-5 h-5"></i> |
| </button> |
| </div> |
| </div> |
| |
| <div> |
| <h3 class="text-lg font-medium text-gray-700 mb-3">Save Project</h3> |
| <div class="flex items-center space-x-4"> |
| <input type="text" placeholder="Project Name" class="flex-1 px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500"> |
| <button class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded-lg"> |
| Save |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="flex justify-center space-x-4"> |
| <button id="newProjectBtn" class="bg-white border border-indigo-500 text-indigo-500 hover:bg-indigo-50 px-6 py-2 rounded-lg flex items-center"> |
| <i data-feather="plus" class="w-4 h-4 mr-2"></i> Create New |
| </button> |
| <button id="helpBtn" class="bg-indigo-500 hover:bg-indigo-600 text-white px-6 py-2 rounded-lg flex items-center"> |
| <i data-feather="help-circle" class="w-4 h-4 mr-2"></i> How to Use |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| |
| <div class="mb-16"> |
| <h2 class="text-2xl font-semibold text-gray-800 text-center mb-8">Features</h2> |
| <div class="grid grid-cols-1 md:grid-cols-3 gap-8"> |
| <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow"> |
| <div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> |
| <i data-feather="sliders" class="text-indigo-500 w-6 h-6"></i> |
| </div> |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Advanced Customization</h3> |
| <p class="text-gray-600">Fine-tune colors, themes, and animation styles to match your brand or personal style.</p> |
| </div> |
| <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow"> |
| <div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> |
| <i data-feather="zap" class="text-indigo-500 w-6 h-6"></i> |
| </div> |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Real-time Sync</h3> |
| <p class="text-gray-600">Perfect synchronization between audio and avatar movements for natural-looking animations.</p> |
| </div> |
| <div class="bg-white p-6 rounded-xl shadow-md hover:shadow-lg transition-shadow"> |
| <div class="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> |
| <i data-feather="download" class="text-indigo-500 w-6 h-6"></i> |
| </div> |
| <h3 class="text-lg font-medium text-gray-800 mb-2">Multiple Formats</h3> |
| <p class="text-gray-600">Export as high-quality video or GIF for use on any platform or device.</p> |
| </div> |
| </div> |
| </div> |
| |
| |
| <footer class="text-center text-gray-600 text-sm"> |
| <p>© 2023 AvatarSync Studio. All rights reserved.</p> |
| <p class="mt-1">Made with <i data-feather="heart" class="w-4 h-4 inline text-red-500"></i> for content creators</p> |
| </footer> |
| </div> |
| |
| <script> |
| |
| VANTA.GLOBE({ |
| el: "#vanta-bg", |
| mouseControls: true, |
| touchControls: true, |
| gyroControls: false, |
| minHeight: 200.00, |
| minWidth: 200.00, |
| scale: 1.00, |
| scaleMobile: 1.00, |
| color: 0x4f46e5, |
| backgroundColor: 0xf5f7fa, |
| size: 0.8 |
| }); |
| |
| |
| feather.replace(); |
| |
| |
| document.addEventListener('DOMContentLoaded', function() { |
| const imageDropzone = document.getElementById('imageDropzone'); |
| const audioDropzone = document.getElementById('audioDropzone'); |
| const imageInput = document.getElementById('imageInput'); |
| const audioInput = document.getElementById('audioInput'); |
| const clearImageBtn = document.getElementById('clearImageBtn'); |
| const clearAudioBtn = document.getElementById('clearAudioBtn'); |
| const nextStep1Btn = document.getElementById('nextStep1Btn'); |
| |
| let hasImage = false; |
| let hasAudio = false; |
| |
| |
| imageDropzone.addEventListener('click', () => imageInput.click()); |
| imageInput.addEventListener('change', handleImageFile); |
| |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| imageDropzone.addEventListener(eventName, preventDefaults, false); |
| }); |
| |
| ['dragenter', 'dragover'].forEach(eventName => { |
| imageDropzone.addEventListener(eventName, highlightImage, false); |
| }); |
| |
| ['dragleave', 'drop'].forEach(eventName => { |
| imageDropzone.addEventListener(eventName, unhighlightImage, false); |
| }); |
| |
| imageDropzone.addEventListener('drop', handleImageDrop, false); |
| |
| |
| audioDropzone.addEventListener('click', () => audioInput.click()); |
| audioInput.addEventListener('change', handleAudioFile); |
| |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| audioDropzone.addEventListener(eventName, preventDefaults, false); |
| }); |
| |
| ['dragenter', 'dragover'].forEach(eventName => { |
| audioDropzone.addEventListener(eventName, highlightAudio, false); |
| }); |
| |
| ['dragleave', 'drop'].forEach(eventName => { |
| audioDropzone.addEventListener(eventName, unhighlightAudio, false); |
| }); |
| |
| audioDropzone.addEventListener('drop', handleAudioDrop, false); |
| |
| |
| clearImageBtn.addEventListener('click', clearImage); |
| clearAudioBtn.addEventListener('click', clearAudio); |
| |
| nextStep1Btn.addEventListener('click', goToStep2); |
| document.getElementById('backStep2Btn').addEventListener('click', goToStep1); |
| document.getElementById('nextStep2Btn').addEventListener('click', goToStep3); |
| document.getElementById('newProjectBtn').addEventListener('click', resetAll); |
| document.getElementById('helpBtn').addEventListener('click', showHelp); |
| function preventDefaults(e) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
| |
| function highlightImage() { |
| imageDropzone.classList.add('active'); |
| } |
| |
| function unhighlightImage() { |
| imageDropzone.classList.remove('active'); |
| } |
| |
| function highlightAudio() { |
| audioDropzone.classList.add('active'); |
| } |
| |
| function unhighlightAudio() { |
| audioDropzone.classList.remove('active'); |
| } |
| |
| function handleImageDrop(e) { |
| const dt = e.dataTransfer; |
| const file = dt.files[0]; |
| handleImageFile({ target: { files: [file] } }); |
| } |
| |
| function handleAudioDrop(e) { |
| const dt = e.dataTransfer; |
| const file = dt.files[0]; |
| handleAudioFile({ target: { files: [file] } }); |
| } |
| |
| function handleImageFile(e) { |
| const file = e.target.files[0]; |
| if (file && file.type.match('image.*')) { |
| const reader = new FileReader(); |
| |
| reader.onload = function(e) { |
| imageDropzone.innerHTML = ` |
| <div class="flex flex-col items-center"> |
| <img src="${e.target.result}" class="h-32 object-contain mb-2" alt="Preview"> |
| <p class="text-sm text-gray-600">${file.name}</p> |
| </div> |
| `; |
| hasImage = true; |
| clearImageBtn.disabled = false; |
| checkNextButton(); |
| }; |
| |
| reader.readAsDataURL(file); |
| } |
| } |
| |
| function handleAudioFile(e) { |
| const file = e.target.files[0]; |
| if (file && file.type.match('audio.*')) { |
| const reader = new FileReader(); |
| |
| reader.onload = function(e) { |
| audioDropzone.innerHTML = ` |
| <div class="flex flex-col items-center"> |
| <i data-feather="music" class="w-12 h-12 mx-auto text-indigo-400 mb-3"></i> |
| <p class="text-sm text-gray-600 truncate w-full">${file.name}</p> |
| </div> |
| `; |
| feather.replace(); |
| hasAudio = true; |
| clearAudioBtn.disabled = false; |
| checkNextButton(); |
| }; |
| |
| reader.readAsDataURL(file); |
| } |
| } |
| |
| function clearImage() { |
| imageDropzone.innerHTML = ` |
| <i data-feather="upload" class="w-12 h-12 mx-auto text-gray-400 mb-3"></i> |
| <p class="text-gray-500 mb-2">Drag & drop your image here</p> |
| <p class="text-sm text-gray-400">or click to browse files</p> |
| `; |
| feather.replace(); |
| imageInput.value = ''; |
| hasImage = false; |
| clearImageBtn.disabled = true; |
| checkNextButton(); |
| } |
| |
| function clearAudio() { |
| audioDropzone.innerHTML = ` |
| <i data-feather="upload" class="w-12 h-12 mx-auto text-gray-400 mb-3"></i> |
| <p class="text-gray-500 mb-2">Drag & drop your audio file here</p> |
| <p class="text-sm text-gray-400">or click to browse files</p> |
| `; |
| feather.replace(); |
| audioInput.value = ''; |
| hasAudio = false; |
| clearAudioBtn.disabled = true; |
| checkNextButton(); |
| } |
| |
| function checkNextButton() { |
| nextStep1Btn.disabled = !(hasImage && hasAudio); |
| } |
| |
| function goToStep2() { |
| document.getElementById('step1').classList.add('hidden'); |
| document.getElementById('step2').classList.remove('hidden'); |
| |
| |
| setTimeout(() => { |
| const canvas = document.getElementById('previewCanvas'); |
| const ctx = canvas.getContext('2d'); |
| |
| |
| canvas.width = canvas.offsetWidth; |
| canvas.height = canvas.offsetHeight; |
| |
| |
| ctx.fillStyle = '#4F46E5'; |
| ctx.beginPath(); |
| ctx.arc(canvas.width/2, canvas.height/2, 80, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| ctx.fillStyle = '#ffffff'; |
| ctx.beginPath(); |
| ctx.arc(canvas.width/2 - 30, canvas.height/2 - 20, 10, 0, Math.PI * 2); |
| ctx.arc(canvas.width/2 + 30, canvas.height/2 - 20, 10, 0, Math.PI * 2); |
| ctx.fill(); |
| |
| ctx.beginPath(); |
| ctx.arc(canvas.width/2, canvas.height/2 + 20, 30, 0, Math.PI); |
| ctx.strokeStyle = '#ffffff'; |
| ctx.lineWidth = 3; |
| ctx.stroke(); |
| }, 300); |
| } |
| |
| function goToStep1() { |
| document.getElementById('step2').classList.add('hidden'); |
| document.getElementById('step1').classList.remove('hidden'); |
| } |
| |
| function goToStep3() { |
| document.getElementById('step2').classList.add('hidden'); |
| document.getElementById('step3').classList.remove('hidden'); |
| |
| |
| const progressBar = document.getElementById('progressBar'); |
| const processingAnimation = document.getElementById('processingAnimation'); |
| const resultSection = document.getElementById('resultSection'); |
| |
| let progress = 0; |
| const interval = setInterval(() => { |
| progress += 5; |
| progressBar.style.width = `${progress}%`; |
| |
| if (progress >= 100) { |
| clearInterval(interval); |
| processingAnimation.classList.add('hidden'); |
| resultSection.classList.remove('hidden'); |
| |
| |
| const resultVideo = document.getElementById('resultVideo'); |
| resultVideo.src = "https://sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"; |
| resultVideo.load(); |
| } |
| }, 200); |
| } |
| function showHelp() { |
| alert("How to use AvatarSync Studio:\n\n1. Upload an image (your avatar) and an audio file\n2. Customize the animation style and colors\n3. Generate your animated avatar\n4. Download or share your creation!"); |
| } |
| |
| function resetAll() { |
| document.getElementById('step3').classList.add('hidden'); |
| document.getElementById('step1').classList.remove('hidden'); |
| document.getElementById('processingAnimation').classList.remove('hidden'); |
| document.getElementById('resultSection').classList.add('hidden'); |
| document.getElementById('progressBar').style.width = '0%'; |
| |
| clearImage(); |
| clearAudio(); |
| } |
| |
| |
| document.getElementById('playPauseBtn').addEventListener('click', function() { |
| const icon = this.querySelector('i'); |
| if (icon.dataset.feather === 'play') { |
| icon.dataset.feather = 'pause'; |
| feather.replace(); |
| |
| } else { |
| icon.dataset.feather = 'play'; |
| feather.replace(); |
| |
| } |
| }); |
| }); |
| </script> |
| </body> |
| </html> |
|
|