Avatars have become an essential part of our digital identity, representing us in various online platforms. From social media profiles to gaming characters, avatars offer a unique way to express individuality.
In this article, we will explore 10 diverse avatar examples that showcase creativity and innovation. Whether you're looking for inspiration or simply curious, these examples highlight the endless possibilities of digital representation.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Designing your own avatar has never been easier with Subframe. Its drag-and-drop interface and intuitive, responsive canvas ensure pixel-perfect UI every time. Loved by designers and developers alike, Subframe makes creativity effortless.
Start for free and bring your digital identity to life today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI design game? With Subframe, you can create stunning, pixel-perfect avatars and interfaces in minutes. Its drag-and-drop editor ensures efficiency and precision.
Don't wait! Start for free and begin designing immediately. Unleash your creativity with Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Avatar Generator</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); overflow: hidden; } .container { width: 100%; max-width: 650px; padding: 20px; display: flex; flex-direction: column; align-items: center; gap: 25px; } h1 { font-size: 2.2rem; color: #2d3748; text-align: center; margin-bottom: 10px; background: linear-gradient(to right, #4a00e0, #8e2de2); -webkit-background-clip: text; background-clip: text; color: transparent; } p.tagline { text-align: center; color: #4a5568; max-width: 500px; margin-bottom: 5px; font-size: 1.1rem; } .avatar-preview { position: relative; width: 200px; height: 200px; margin: 15px auto; border-radius: 50%; background: #fff; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); overflow: hidden; transition: all 0.3s ease; } .avatar-content { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 3rem; color: white; text-transform: uppercase; transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .avatar-preview:hover { transform: scale(1.05); cursor: pointer; } .avatar-preview:hover .avatar-content { filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.7)); } .controls { display: flex; flex-direction: column; align-items: center; width: 100%; max-width: 500px; gap: 20px; } .color-picker { display: flex; justify-content: center; flex-wrap: wrap; gap: 12px; margin-bottom: 10px; } .color-option { width: 40px; height: 40px; border-radius: 50%; cursor: pointer; transition: transform 0.2s; border: 2px solid transparent; } .color-option:hover { transform: scale(1.1); } .color-option.active { border: 2px solid #fff; box-shadow: 0 0 0 2px #000; } .icon-picker { display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; margin-bottom: 10px; } .icon-option { width: 40px; height: 40px; display: flex; justify-content: center; align-items: center; background: #edf2f7; border-radius: 8px; cursor: pointer; transition: all 0.2s; font-size: 20px; } .icon-option:hover { background: #e2e8f0; transform: translateY(-3px); } .icon-option.active { background: #4299e1; color: white; } .text-input { width: 100%; padding: 12px 15px; border-radius: 10px; border: 2px solid #e2e8f0; background-color: #f8fafc; font-size: 1rem; transition: border-color 0.3s; margin-bottom: 10px; } .text-input:focus { outline: none; border-color: #4299e1; } .download-btn { background: linear-gradient(to right, #6a11cb, #2575fc); color: white; border: none; padding: 12px 25px; border-radius: 50px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s; display: flex; align-items: center; gap: 8px; margin-top: 10px; box-shadow: 0 4px 15px rgba(106, 17, 203, 0.4); } .download-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(106, 17, 203, 0.5); } .download-btn:active { transform: translateY(0); } .patterns { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; } .pattern { position: absolute; opacity: 0.3; } .particles-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; overflow: hidden; } .particle { position: absolute; border-radius: 50%; pointer-events: none; opacity: 0; animation: float 3s infinite ease-in-out; } @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0; } 25% { opacity: 0.8; } 50% { opacity: 0.4; } 75% { opacity: 0.6; } } @media (max-width: 600px) { .container { padding: 15px; } h1 { font-size: 1.8rem; } p.tagline { font-size: 0.9rem; } .avatar-preview { width: 160px; height: 160px; } .color-option, .icon-option { width: 30px; height: 30px; } .icon-option { font-size: 16px; } } </style> </head> <body> <div class="container"> <div> <h1>Vibrant Avatar Creator</h1> <p class="tagline">Design a bold, playful avatar for your social profiles with interactive hover effects</p> </div> <div class="avatar-preview" id="avatar"> <div class="avatar-content" id="avatarContent"> <span id="initialsDisplay">VS</span> </div> </div> <div class="controls"> <div class="color-picker"> <div class="color-option active" style="background: linear-gradient(45deg, #ff3366, #ff6b6b)" data-color="linear-gradient(45deg, #ff3366, #ff6b6b)"></div> <div class="color-option" style="background: linear-gradient(45deg, #36d1dc, #5b86e5)" data-color="linear-gradient(45deg, #36d1dc, #5b86e5)"></div> <div class="color-option" style="background: linear-gradient(45deg, #834d9b, #d04ed6)" data-color="linear-gradient(45deg, #834d9b, #d04ed6)"></div> <div class="color-option" style="background: linear-gradient(45deg, #f7971e, #ffd200)" data-color="linear-gradient(45deg, #f7971e, #ffd200)"></div> <div class="color-option" style="background: linear-gradient(45deg, #43cea2, #185a9d)" data-color="linear-gradient(45deg, #43cea2, #185a9d)"></div> <div class="color-option" style="background: linear-gradient(45deg, #4776e6, #8e54e9)" data-color="linear-gradient(45deg, #4776e6, #8e54e9)"></div> </div> <input type="text" class="text-input" id="initialsInput" placeholder="Enter your initials (1-2 characters)" maxlength="2"> <div class="icon-picker"> <div class="icon-option" data-icon="๐">๐</div> <div class="icon-option" data-icon="๐">๐</div> <div class="icon-option" data-icon="๐ฎ">๐ฎ</div> <div class="icon-option" data-icon="๐ง">๐ง</div> <div class="icon-option" data-icon="๐ฑ">๐ฑ</div> <div class="icon-option" data-icon="๐">๐</div> </div> <button class="download-btn" id="downloadBtn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 16L12 8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M9 13L12 16L15 13" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M20 16V18C20 19.1046 19.1046 20 18 20H6C4.89543 20 4 19.1046 4 18V16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Download Avatar </button> </div> </div> <div class="particles-container" id="particles"></div> <script> document.addEventListener('DOMContentLoaded', () => { const avatar = document.getElementById('avatar'); const avatarContent = document.getElementById('avatarContent'); const initialsInput = document.getElementById('initialsInput'); const initialsDisplay = document.getElementById('initialsDisplay'); const colorOptions = document.querySelectorAll('.color-option'); const iconOptions = document.querySelectorAll('.icon-option'); const downloadBtn = document.getElementById('downloadBtn'); const particlesContainer = document.getElementById('particles'); let currentColor = 'linear-gradient(45deg, #ff3366, #ff6b6b)'; let currentIcon = null; let particles = []; // Set initial background avatarContent.style.background = currentColor; // Input handler for initials initialsInput.addEventListener('input', (e) => { const value = e.target.value.toUpperCase(); initialsDisplay.textContent = value || 'VS'; }); // Color picker functionality colorOptions.forEach(option => { option.addEventListener('click', () => { colorOptions.forEach(opt => opt.classList.remove('active')); option.classList.add('active'); currentColor = option.getAttribute('data-color'); avatarContent.style.background = currentColor; createParticles(); }); }); // Icon picker functionality iconOptions.forEach(option => { option.addEventListener('click', () => { iconOptions.forEach(opt => opt.classList.remove('active')); option.classList.add('active'); currentIcon = option.getAttribute('data-icon'); initialsDisplay.textContent = currentIcon; initialsInput.value = ''; }); }); // Avatar hover effects avatar.addEventListener('mouseover', createParticles); // Create interactive particles function createParticles() { // Clear existing particles while(particlesContainer.firstChild) { particlesContainer.removeChild(particlesContainer.firstChild); } // Create new particles for (let i = 0; i < 15; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // Random properties const size = Math.random() * 10 + 5; const posX = Math.random() * window.innerWidth; const posY = Math.random() * window.innerHeight; const duration = Math.random() * 2 + 2; const delay = Math.random() * 1; // Get the current gradient colors let gradientMatch = currentColor.match(/linear-gradient\(.*?, (.*?), (.*?)\)/); let particleColor; if (gradientMatch && gradientMatch.length >= 3) { // Choose one of the gradient colors randomly particleColor = Math.random() > 0.5 ? gradientMatch[1] : gradientMatch[2]; } else { particleColor = '#ff3366'; // Fallback color } // Apply styles particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.left = `${posX}px`; particle.style.top = `${posY}px`; particle.style.background = particleColor; particle.style.animationDuration = `${duration}s`; particle.style.animationDelay = `${delay}s`; // Add random animation path const translateX = (Math.random() - 0.5) * 100; const translateY = (Math.random() - 0.5) * 100; const rotate = Math.random() * 360; particle.style.animationName = `float`; particle.style.transform = `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg)`; particlesContainer.appendChild(particle); particles.push(particle); } } // Download functionality downloadBtn.addEventListener('click', () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const size = 400; canvas.width = size; canvas.height = size; // Draw circular background ctx.beginPath(); ctx.arc(size/2, size/2, size/2, 0, Math.PI * 2); ctx.closePath(); ctx.clip(); // Create gradient let gradientMatch = currentColor.match(/linear-gradient\((\d+)deg, (.*?), (.*?)\)/); if (gradientMatch && gradientMatch.length >= 4) { const angle = parseInt(gradientMatch[1]); const color1 = gradientMatch[2]; const color2 = gradientMatch[3]; // Convert angle to starting and ending points const angleRad = (angle - 90) * (Math.PI / 180); const gradientSize = size * 1.5; const centerX = size / 2; const centerY = size / 2; const startX = centerX + Math.cos(angleRad) * (gradientSize / 2); const startY = centerY + Math.sin(angleRad) * (gradientSize / 2); const endX = centerX - Math.cos(angleRad) * (gradientSize / 2); const endY = centerY - Math.sin(angleRad) * (gradientSize / 2); const gradient = ctx.createLinearGradient(startX, startY, endX, endY); gradient.addColorStop(0, color1); gradient.addColorStop(1, color2); ctx.fillStyle = gradient; } else { ctx.fillStyle = '#ff3366'; } ctx.fillRect(0, 0, size, size); // Draw text ctx.fillStyle = 'white'; ctx.font = 'bold 180px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText(initialsDisplay.textContent, size/2, size/2); // Create download link const dataURL = canvas.toDataURL('image/png'); const link = document.createElement('a'); link.download = 'vibrant-avatar.png'; link.href = dataURL; link.click(); }); // Initial particles createParticles(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate Identity Avatar Creator</title> <style> :root { --primary: #2c3e50; --secondary: #34495e; --accent: #3498db; --light: #ecf0f1; --neutral: #95a5a6; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f5f6fa; display: flex; justify-content: center; align-items: center; min-height: 700px; width: 100%; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; padding: 2rem; display: flex; flex-direction: column; position: relative; overflow: hidden; } .header { text-align: center; margin-bottom: 1.5rem; position: relative; z-index: 2; } h1 { color: var(--primary); font-size: 1.8rem; font-weight: 600; margin-bottom: 0.5rem; position: relative; display: inline-block; } h1::after { content: ''; position: absolute; bottom: -6px; left: 50%; transform: translateX(-50%); width: 60px; height: 3px; background-color: var(--accent); border-radius: 3px; } .description { color: var(--secondary); font-size: 0.9rem; line-height: 1.5; max-width: 500px; margin: 0 auto; } .avatar-builder { display: flex; flex-direction: column; align-items: center; gap: 2rem; flex: 1; position: relative; z-index: 2; } .avatar-preview { width: 180px; height: 180px; border-radius: 50%; overflow: hidden; position: relative; background-color: var(--light); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; display: flex; justify-content: center; align-items: center; cursor: pointer; } .avatar-preview:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); } .avatar-content { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; position: relative; transition: all 0.3s ease; } .avatar-initials { font-size: 64px; font-weight: 600; color: white; text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); } .avatar-icon { position: absolute; bottom: 15%; right: 15%; width: 30px; height: 30px; stroke: white; stroke-width: 2; filter: drop-shadow(1px 1px 2px rgba(0, 0, 0, 0.3)); opacity: 0.9; } .options-container { width: 100%; display: flex; flex-direction: column; gap: 1.5rem; } .option-section { width: 100%; } .option-title { font-size: 0.85rem; color: var(--secondary); margin-bottom: 0.75rem; font-weight: 600; display: flex; align-items: center; } .option-title svg { width: 16px; height: 16px; margin-right: 6px; stroke: var(--secondary); } .input-group { position: relative; margin-bottom: 1rem; } input[type="text"] { width: 100%; padding: 0.75rem 1rem; border: 1px solid #ddd; border-radius: 6px; font-size: 0.9rem; transition: all 0.3s ease; background-color: white; color: var(--primary); } input[type="text"]:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2); } .color-palette { display: flex; gap: 0.5rem; flex-wrap: wrap; } .color-option { width: 32px; height: 32px; border-radius: 6px; cursor: pointer; position: relative; transition: transform 0.2s ease; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .color-option:hover { transform: scale(1.1); } .color-option.active::after { content: ''; position: absolute; top: -3px; right: -3px; bottom: -3px; left: -3px; border: 2px solid var(--accent); border-radius: 8px; } .icon-selection { display: flex; gap: 0.85rem; flex-wrap: wrap; } .icon-option { width: 36px; height: 36px; border-radius: 6px; cursor: pointer; display: flex; justify-content: center; align-items: center; background-color: white; border: 1px solid #ddd; transition: all 0.2s ease; } .icon-option:hover { background-color: #f8f9fa; transform: translateY(-2px); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.08); } .icon-option.active { border-color: var(--accent); background-color: rgba(52, 152, 219, 0.1); } .icon-option svg { width: 18px; height: 18px; stroke: var(--primary); opacity: 0.8; } .download-btn { margin-top: 1.5rem; padding: 0.75rem 1.5rem; background-color: var(--primary); color: white; border: none; border-radius: 6px; font-size: 0.9rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; display: flex; align-items: center; justify-content: center; gap: 8px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .download-btn:hover { background-color: #1c2c3c; transform: translateY(-2px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); } .download-btn svg { width: 16px; height: 16px; stroke: white; } .bg-pattern { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1; opacity: 0.04; pointer-events: none; } @media (max-width: 600px) { .container { padding: 1.5rem; } h1 { font-size: 1.5rem; } .avatar-preview { width: 150px; height: 150px; } .avatar-initials { font-size: 52px; } } /* Tooltip Styles */ .tooltip { position: relative; display: inline-block; } .tooltip .tooltiptext { visibility: hidden; width: 120px; background-color: var(--secondary); color: white; text-align: center; border-radius: 4px; padding: 5px; position: absolute; z-index: 10; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 0.75rem; } .tooltip .tooltiptext::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: var(--secondary) transparent transparent transparent; } .tooltip:hover .tooltiptext { visibility: visible; opacity: 1; } /* Success notification */ .notification { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(100px); background-color: var(--primary); color: white; padding: 12px 24px; border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); opacity: 0; transition: all 0.4s ease; z-index: 1000; display: flex; align-items: center; gap: 10px; } .notification.show { transform: translateX(-50%) translateY(0); opacity: 1; } .notification svg { width: 18px; height: 18px; stroke: white; } </style> </head> <body> <div class="container"> <div class="bg-pattern"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg"> <pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse"> <rect width="1" height="1" fill="#000" /> </pattern> <rect x="0" y="0" width="100%" height="100%" fill="url(#pattern)" /> </svg> </div> <div class="header"> <h1>Corporate Identity Avatar</h1> <p class="description">Create a sleek, professional avatar for your business profiles. Customize with initials, colors, and icons to match your brand identity.</p> </div> <div class="avatar-builder"> <div class="avatar-preview tooltip"> <div class="avatar-content"> <span class="avatar-initials">JP</span> <svg class="avatar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <circle cx="12" cy="7" r="4"></circle> </svg> </div> <span class="tooltiptext">Click to download</span> </div> <div class="options-container"> <div class="option-section"> <div class="option-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <circle cx="12" cy="7" r="4"></circle> </svg> Initials </div> <div class="input-group"> <input type="text" id="initials-input" placeholder="Enter your initials (max 2 characters)" maxlength="2"> </div> </div> <div class="option-section"> <div class="option-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <path d="M12 8v8"></path> <path d="M8 12h8"></path> </svg> Background Color </div> <div class="color-palette" id="background-colors"> <div class="color-option active" data-color="#2c3e50" style="background-color: #2c3e50;"></div> <div class="color-option" data-color="#34495e" style="background-color: #34495e;"></div> <div class="color-option" data-color="#3498db" style="background-color: #3498db;"></div> <div class="color-option" data-color="#2980b9" style="background-color: #2980b9;"></div> <div class="color-option" data-color="#16a085" style="background-color: #16a085;"></div> <div class="color-option" data-color="#27ae60" style="background-color: #27ae60;"></div> <div class="color-option" data-color="#8e44ad" style="background-color: #8e44ad;"></div> <div class="color-option" data-color="#e74c3c" style="background-color: #e74c3c;"></div> <div class="color-option" data-color="#d35400" style="background-color: #d35400;"></div> <div class="color-option" data-color="#7f8c8d" style="background-color: #7f8c8d;"></div> </div> </div> <div class="option-section"> <div class="option-title"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon> </svg> Icon Selection </div> <div class="icon-selection" id="icon-selection"> <div class="icon-option active" data-icon="user"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <circle cx="12" cy="7" r="4"></circle> </svg> </div> <div class="icon-option" data-icon="briefcase"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect> <path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path> </svg> </div> <div class="icon-option" data-icon="code"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <polyline points="16 18 22 12 16 6"></polyline> <polyline points="8 6 2 12 8 18"></polyline> </svg> </div> <div class="icon-option" data-icon="globe"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <line x1="2" y1="12" x2="22" y2="12"></line> <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path> </svg> </div> <div class="icon-option" data-icon="star"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon> </svg> </div> <div class="icon-option" data-icon="shield"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path> </svg> </div> <div class="icon-option" data-icon="zap"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon> </svg> </div> <div class="icon-option" data-icon="none"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <line x1="18" y1="6" x2="6" y2="18"></line> <line x1="6" y1="6" x2="18" y2="18"></line> </svg> </div> </div> </div> <button class="download-btn" id="download-btn"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path> <polyline points="7 10 12 15 17 10"></polyline> <line x1="12" y1="15" x2="12" y2="3"></line> </svg> Export Avatar </button> </div> </div> </div> <div class="notification" id="notification"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"> <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> <polyline points="22 4 12 14.01 9 11.01"></polyline> </svg> <span>Avatar copied to clipboard!</span> </div> <script> document.addEventListener('DOMContentLoaded', function() { const initialsInput = document.getElementById('initials-input'); const avatarInitials = document.querySelector('.avatar-initials'); const backgroundColors = document.querySelectorAll('#background-colors .color-option'); const avatarContent = document.querySelector('.avatar-content'); const iconOptions = document.querySelectorAll('#icon-selection .icon-option'); const avatarIcon = document.querySelector('.avatar-icon'); const downloadBtn = document.getElementById('download-btn'); const avatarPreview = document.querySelector('.avatar-preview'); const notification = document.getElementById('notification'); // Set default values let currentBgColor = '#2c3e50'; let currentInitials = 'JP'; let currentIcon = 'user'; // Initialize the avatar avatarInitials.textContent = currentInitials; avatarContent.style.backgroundColor = currentBgColor; // Handle initials input initialsInput.addEventListener('input', function() { let value = this.value.toUpperCase(); // Only allow letters value = value.replace(/[^A-Z]/g, ''); this.value = value; currentInitials = value || 'JP'; avatarInitials.textContent = currentInitials; // Add gentle animation avatarInitials.style.transform = 'scale(1.1)'; setTimeout(() => { avatarInitials.style.transform = 'scale(1)'; }, 150); }); // Handle background color selection backgroundColors.forEach(color => { color.addEventListener('click', function() { backgroundColors.forEach(c => c.classList.remove('active')); this.classList.add('active'); currentBgColor = this.getAttribute('data-color'); // Animate color change avatarContent.style.opacity = '0.8'; setTimeout(() => { avatarContent.style.backgroundColor = currentBgColor; avatarContent.style.opacity = '1'; }, 150); }); }); // Handle icon selection iconOptions.forEach(icon => { icon.addEventListener('click', function() { iconOptions.forEach(i => i.classList.remove('active')); this.classList.add('active'); currentIcon = this.getAttribute('data-icon'); // Update icon or hide it if "none" is selected if (currentIcon === 'none') { avatarIcon.style.display = 'none'; } else { const iconSVG = this.querySelector('svg').cloneNode(true); avatarIcon.innerHTML = ''; avatarIcon.appendChild(iconSVG); avatarIcon.style.display = 'block'; // Animation for icon change avatarIcon.style.transform = 'scale(0.8)'; setTimeout(() => { avatarIcon.style.transform = 'scale(1)'; }, 150); } }); }); // Handle avatar download (simulated for this demo) function downloadAvatar() { // In a real implementation, this would convert the avatar to an image and download it // For this demo, we'll just show a notification notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); // Highlight effect on the avatar when "downloading" avatarPreview.style.boxShadow = '0 0 0 4px rgba(52, 152, 219, 0.5), 0 8px 25px rgba(0, 0, 0, 0.15)'; setTimeout(() => { avatarPreview.style.boxShadow = '0 4px 15px rgba(0, 0, 0, 0.1)'; }, 400); } downloadBtn.addEventListener('click', downloadAvatar); avatarPreview.addEventListener('click', downloadAvatar); // Add subtle hover animations function setupHoverEffects() { const colorOptions = document.querySelectorAll('.color-option'); colorOptions.forEach(option => { option.addEventListener('mouseenter', function() { if (!this.classList.contains('active')) { this.style.transform = 'scale(1.1)'; } }); option.addEventListener('mouseleave', function() { if (!this.classList.contains('active')) { this.style.transform = 'scale(1)'; } }); }); } setupHoverEffects(); // Easter egg: Secret shake animation when typing certain initials initialsInput.addEventListener('change', function() { if (this.value.toUpperCase() === 'CEO' || this.value.toUpperCase() === 'VIP') { avatarPreview.style.animation = 'shake 0.5s ease'; setTimeout(() => { avatarPreview.style.animation = ''; }, 500); } }); // Add shake keyframes const style = document.createElement('style'); style.textContent = ` @keyframes shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 50% { transform: translateX(5px); } 75% { transform: translateX(-5px); } } `; document.head.appendChild(style); }); </script> </body> </html>
<html> <head> <style> :root { --purple: #8a2be2; --blue: #4169e1; --cyan: #00ffff; --pink: #ff1493; --yellow: #ffd700; --dark: #121212; } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--dark); display: flex; justify-content: center; align-items: center; min-height: 100vh; overflow: hidden; padding: 20px; } .container { width: 700px; height: 700px; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; z-index: 1; } .avatar-container { position: relative; width: 300px; height: 300px; margin-bottom: 30px; cursor: pointer; perspective: 1000px; } .avatar { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s cubic-bezier(0.175, 0.885, 0.32, 1.275); } .avatar-container:hover .avatar { transform: rotateY(180deg); } .avatar-front, .avatar-back { width: 100%; height: 100%; position: absolute; backface-visibility: hidden; border-radius: 20px; overflow: hidden; box-shadow: 0 0 30px rgba(138, 43, 226, 0.5); } .avatar-back { transform: rotateY(180deg); background: linear-gradient(45deg, var(--purple), var(--blue)); display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; } .avatar-back p { color: white; font-size: 18px; text-align: center; margin-bottom: 10px; text-shadow: 0 0 5px rgba(0, 0, 0, 0.5); } .avatar-back .stats { display: flex; justify-content: space-between; width: 100%; margin-top: 20px; } .stat { display: flex; flex-direction: column; align-items: center; } .stat-value { font-size: 24px; font-weight: bold; color: var(--yellow); } .stat-label { font-size: 12px; color: white; opacity: 0.8; } .pixel-avatar { width: 100%; height: 100%; position: relative; } .pixel-art { width: 100%; height: 100%; background: linear-gradient(135deg, var(--purple), var(--blue)); position: relative; display: grid; grid-template-columns: repeat(16, 1fr); grid-template-rows: repeat(16, 1fr); border-radius: 20px; } .pixel { background-color: transparent; transition: all 0.3s ease; } .pixel.active { background-color: rgba(255, 255, 255, 0.8); box-shadow: 0 0 5px white; } .gradient-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, rgba(138, 43, 226, 0.4), rgba(65, 105, 225, 0.4), rgba(0, 255, 255, 0.4), rgba(255, 20, 147, 0.4)); border-radius: 20px; opacity: 0.7; mix-blend-mode: screen; pointer-events: none; } .avatar-glow { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 120%; height: 120%; background: radial-gradient(circle, rgba(138, 43, 226, 0.3) 0%, rgba(0, 0, 0, 0) 70%); z-index: -1; border-radius: 50%; filter: blur(20px); animation: pulseGlow 3s infinite alternate; } @keyframes pulseGlow { 0% { transform: translate(-50%, -50%) scale(0.9); opacity: 0.3; } 100% { transform: translate(-50%, -50%) scale(1.1); opacity: 0.6; } } .controls { display: flex; flex-wrap: wrap; justify-content: center; gap: 15px; margin-top: 20px; width: 100%; } .control-btn { padding: 12px 20px; border: none; border-radius: 8px; font-weight: bold; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; color: white; background: linear-gradient(to right, var(--purple), var(--blue)); text-transform: uppercase; letter-spacing: 1px; } .control-btn:before { content: ''; position: absolute; top: 0; left: 0; width: 0; height: 100%; background: rgba(255, 255, 255, 0.2); transition: all 0.3s ease; } .control-btn:hover:before { width: 100%; } .control-btn:active { transform: scale(0.95); } .title { color: white; font-size: 2.5rem; margin-bottom: 20px; text-align: center; text-shadow: 0 0 10px var(--purple); font-weight: 800; background: linear-gradient(to right, var(--purple), var(--blue), var(--cyan), var(--pink)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; letter-spacing: 1px; } .sub-title { color: white; font-size: 1.2rem; margin-bottom: 30px; text-align: center; opacity: 0.8; } .pixel-animation { animation: pixelFade 1s infinite alternate; } @keyframes pixelFade { 0% { opacity: 0.3; } 100% { opacity: 1; } } .level-badge { position: absolute; top: -10px; right: -10px; width: 60px; height: 60px; background: linear-gradient(135deg, var(--pink), var(--purple)); border-radius: 50%; display: flex; justify-content: center; align-items: center; color: white; font-weight: bold; font-size: 24px; box-shadow: 0 0 15px rgba(255, 20, 147, 0.7); z-index: 10; border: 3px solid white; } .avatar-name { position: absolute; bottom: -20px; left: 50%; transform: translateX(-50%); background: linear-gradient(90deg, var(--blue), var(--purple)); padding: 8px 25px; border-radius: 20px; color: white; font-weight: bold; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); white-space: nowrap; } .control-info { color: rgba(255, 255, 255, 0.7); text-align: center; margin-top: 20px; font-style: italic; font-size: 14px; } @media (max-width: 600px) { .avatar-container { width: 220px; height: 220px; } .title { font-size: 1.8rem; } .sub-title { font-size: 1rem; } .control-btn { padding: 10px 15px; font-size: 12px; } .level-badge { width: 50px; height: 50px; font-size: 20px; } } .particles { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; } .particle { position: absolute; width: 3px; height: 3px; background-color: white; border-radius: 50%; opacity: 0.5; } </style> </head> <body> <div class="particles" id="particles"></div> <div class="container"> <h1 class="title">PIXELBLAZE</h1> <p class="sub-title">Forge your legendary gaming identity</p> <div class="avatar-container" id="avatarContainer"> <div class="avatar"> <div class="avatar-front"> <div class="pixel-avatar"> <div class="pixel-art" id="pixelArt"></div> <div class="gradient-overlay"></div> <div class="level-badge">42</div> <div class="avatar-name">NEON_WRAITH</div> </div> </div> <div class="avatar-back"> <p>NEON_WRAITH</p> <p style="font-size: 14px; opacity: 0.8;">Master of the Digital Realm</p> <div class="stats"> <div class="stat"> <span class="stat-value">98</span> <span class="stat-label">WINS</span> </div> <div class="stat"> <span class="stat-value">42</span> <span class="stat-label">LEVEL</span> </div> <div class="stat"> <span class="stat-value">15K</span> <span class="stat-label">XP</span> </div> </div> </div> </div> <div class="avatar-glow"></div> </div> <div class="controls"> <button class="control-btn" id="randomizeBtn">Randomize</button> <button class="control-btn" id="glitchBtn">Glitch Effect</button> <button class="control-btn" id="colorBtn">Change Colors</button> <button class="control-btn" id="saveBtn">Save Avatar</button> </div> <p class="control-info">Click avatar to flip โข Click buttons to customize</p> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Create pixel grid const pixelArt = document.getElementById('pixelArt'); const colors = [ '#8a2be2', // purple '#4169e1', // blue '#00ffff', // cyan '#ff1493', // pink '#ffd700', // yellow 'rgba(255, 255, 255, 0.8)' // white ]; for (let i = 0; i < 16 * 16; i++) { const pixel = document.createElement('div'); pixel.classList.add('pixel'); pixelArt.appendChild(pixel); } // Generate basic face pattern generateFace(); // Create particles createParticles(); // Handle button clicks document.getElementById('randomizeBtn').addEventListener('click', function() { clearPixels(); generateRandomAvatar(); playClickSound(); triggerButtonEffect(this); }); document.getElementById('glitchBtn').addEventListener('click', function() { triggerGlitchEffect(); playClickSound(); triggerButtonEffect(this); }); document.getElementById('colorBtn').addEventListener('click', function() { changeAvatarColors(); playClickSound(); triggerButtonEffect(this); }); document.getElementById('saveBtn').addEventListener('click', function() { saveAnimation(); playClickSound(); triggerButtonEffect(this); }); // Avatar container click document.getElementById('avatarContainer').addEventListener('click', function() { playFlipSound(); }); // Functions function generateFace() { const pixels = document.querySelectorAll('.pixel'); // Reset all pixels pixels.forEach(p => p.classList.remove('active')); // Basic face - eyes pixels[70].classList.add('active'); pixels[73].classList.add('active'); // Mouth pixels[102].classList.add('active'); pixels[103].classList.add('active'); pixels[104].classList.add('active'); pixels[105].classList.add('active'); // Random accent pixels for (let i = 0; i < 50; i++) { const randomIndex = Math.floor(Math.random() * pixels.length); if (Math.random() > 0.7) { pixels[randomIndex].classList.add('active'); } } } function generateRandomAvatar() { const pixels = document.querySelectorAll('.pixel'); // Reset all pixels pixels.forEach(p => p.classList.remove('active')); // Generate random pattern for (let i = 0; i < pixels.length; i++) { if (Math.random() > 0.75) { pixels[i].classList.add('active'); } } // Ensure some symmetry for (let y = 0; y < 16; y++) { for (let x = 0; x < 8; x++) { const pixelIndex = y * 16 + x; const mirrorIndex = y * 16 + (15 - x); if (pixels[pixelIndex].classList.contains('active')) { pixels[mirrorIndex].classList.add('active'); } } } } function clearPixels() { const pixels = document.querySelectorAll('.pixel'); pixels.forEach(p => p.classList.remove('active', 'pixel-animation')); } function triggerGlitchEffect() { const pixels = document.querySelectorAll('.pixel.active'); // Add glitch animation pixels.forEach(pixel => { pixel.classList.add('pixel-animation'); // Random timing for glitch effect setTimeout(() => { if (Math.random() > 0.7) { pixel.classList.remove('active'); } }, Math.random() * 500); // Restore after glitch setTimeout(() => { pixel.classList.remove('pixel-animation'); }, 1000); }); // Add some new random pixels const allPixels = document.querySelectorAll('.pixel'); for (let i = 0; i < 20; i++) { const randomIndex = Math.floor(Math.random() * allPixels.length); setTimeout(() => { allPixels[randomIndex].classList.add('active', 'pixel-animation'); setTimeout(() => { allPixels[randomIndex].classList.remove('pixel-animation'); }, 500); }, Math.random() * 500); } } function changeAvatarColors() { const root = document.documentElement; const hue = Math.floor(Math.random() * 360); root.style.setProperty('--purple', `hsl(${hue}, 75%, 60%)`); root.style.setProperty('--blue', `hsl(${(hue + 40) % 360}, 75%, 60%)`); root.style.setProperty('--cyan', `hsl(${(hue + 80) % 360}, 75%, 60%)`); root.style.setProperty('--pink', `hsl(${(hue + 180) % 360}, 75%, 60%)`); root.style.setProperty('--yellow', `hsl(${(hue + 120) % 360}, 75%, 60%)`); // Flash effect on color change const avatar = document.querySelector('.avatar-container'); avatar.style.boxShadow = '0 0 60px white'; setTimeout(() => { avatar.style.boxShadow = ''; }, 300); } function saveAnimation() { const saveBtn = document.getElementById('saveBtn'); const originalText = saveBtn.textContent; saveBtn.textContent = 'Saved!'; // Flash effect on save const avatar = document.querySelector('.avatar-container'); avatar.style.transform = 'scale(1.05)'; setTimeout(() => { avatar.style.transform = ''; }, 300); setTimeout(() => { saveBtn.textContent = originalText; }, 1500); } function createParticles() { const particlesContainer = document.getElementById('particles'); for (let i = 0; i < 50; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // Random position and animation const x = Math.random() * 100; const y = Math.random() * 100; const size = Math.random() * 3 + 1; const duration = Math.random() * 20 + 10; const delay = Math.random() * 10; particle.style.left = `${x}%`; particle.style.top = `${y}%`; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.animation = `float ${duration}s ${delay}s infinite linear`; const hue = Math.floor(Math.random() * 360); particle.style.backgroundColor = `hsla(${hue}, 100%, 70%, 0.6)`; particlesContainer.appendChild(particle); } } // Audio feedback function playClickSound() { // Using AudioContext for better browser compatibility const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sine'; oscillator.frequency.value = 600; gainNode.gain.value = 0.1; oscillator.start(); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.2); oscillator.stop(audioContext.currentTime + 0.2); } function playFlipSound() { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sine'; oscillator.frequency.value = 300; gainNode.gain.value = 0.1; oscillator.start(); oscillator.frequency.exponentialRampToValueAtTime(600, audioContext.currentTime + 0.2); gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + 0.3); oscillator.stop(audioContext.currentTime + 0.3); } function triggerButtonEffect(button) { button.style.transform = 'scale(0.95)'; setTimeout(() => { button.style.transform = ''; }, 150); } // Animation for floating particles const style = document.createElement('style'); style.textContent = ` @keyframes float { 0% { transform: translateY(0) translateX(0); opacity: 0; } 10% { opacity: 0.8; } 90% { opacity: 0.6; } 100% { transform: translateY(-100vh) translateX(20px); opacity: 0; } } `; document.head.appendChild(style); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>E-commerce User Avatar</title> <style> :root { --primary: #a6d8e2; --secondary: #f5c0c0; --tertiary: #f8e6a8; --accent: #c5a3ff; --text: #4a4a4a; --light: #ffffff; --bg: #f7f9fc; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--bg); color: var(--text); display: flex; justify-content: center; align-items: center; min-height: 700px; overflow: hidden; position: relative; } .container { width: 100%; max-width: 700px; height: 700px; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px; position: relative; } .header { text-align: center; margin-bottom: 30px; position: relative; z-index: 10; } h1 { font-size: 2.2rem; margin-bottom: 15px; color: var(--text); font-weight: 600; } p.tagline { font-size: 1.1rem; color: var(--text); opacity: 0.85; max-width: 500px; line-height: 1.5; } .avatar-container { width: 300px; position: relative; margin: 20px auto 40px; perspective: 800px; } .avatar { width: 180px; height: 180px; background: var(--light); border-radius: 50%; margin: 0 auto; position: relative; box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.3s ease, box-shadow 0.3s ease; overflow: hidden; z-index: 3; } .avatar-face { position: relative; width: 100px; height: 100px; } .avatar-eyes { display: flex; justify-content: space-between; width: 70px; position: absolute; top: 35px; left: 15px; } .avatar-eye { width: 18px; height: 18px; background: var(--text); border-radius: 50%; position: relative; overflow: hidden; } .avatar-eye::after { content: ''; position: absolute; width: 6px; height: 6px; background: var(--light); border-radius: 50%; top: 2px; right: 2px; } .avatar-mouth { width: 40px; height: 20px; border-radius: 0 0 20px 20px; background: var(--text); position: absolute; bottom: 20px; left: 30px; overflow: hidden; } .avatar-tongue { width: 20px; height: 10px; background: var(--secondary); border-radius: 10px 10px 0 0; position: absolute; bottom: 0; left: 10px; transform: translateY(100%); transition: transform 0.3s ease; } .avatar:hover .avatar-tongue { transform: translateY(40%); } .colors { display: flex; justify-content: center; gap: 15px; margin-top: 25px; position: relative; z-index: 5; } .color-option { width: 40px; height: 40px; border-radius: 50%; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; position: relative; } .color-option::after { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; border: 3px solid transparent; top: 0; left: 0; transition: border 0.2s ease; } .color-option.active::after { border-color: var(--text); } .color-option:hover { transform: scale(1.15); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); } .blue { background: var(--primary); } .pink { background: var(--secondary); } .yellow { background: var(--tertiary); } .purple { background: var(--accent); } .avatar-features { margin-top: 30px; display: flex; flex-wrap: wrap; justify-content: center; gap: 15px; max-width: 500px; } .feature { background: var(--light); padding: 12px 20px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); display: flex; align-items: center; gap: 10px; cursor: pointer; transition: transform 0.2s ease, box-shadow 0.2s ease; } .feature:hover { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } .feature-icon { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--primary); color: var(--text); font-weight: bold; } .feature-text { font-size: 0.95rem; } .avatar-glow { position: absolute; width: 250px; height: 250px; border-radius: 50%; filter: blur(40px); opacity: 0.15; z-index: 1; transition: opacity 0.5s ease, background 0.5s ease; } .avatar-accessories { position: absolute; width: 100%; height: 100%; top: 0; left: 0; z-index: 2; pointer-events: none; } .hat, .glasses { position: absolute; opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease; } .hat { width: 100px; height: 60px; border-radius: 50% 50% 0 0; border: 5px solid var(--text); border-bottom: none; top: -30px; left: 40px; transform: rotate(-15deg) translateY(10px); } .glasses { height: 15px; width: 70px; border: 3px solid var(--text); border-bottom: none; border-radius: 10px 10px 0 0; top: 40px; left: 15px; display: flex; justify-content: space-between; } .glasses::before, .glasses::after { content: ''; width: 20px; height: 15px; border: 3px solid var(--text); border-radius: 50%; position: absolute; top: 0; } .glasses::before { left: -3px; } .glasses::after { right: -3px; } .animated-circles { position: absolute; width: 100%; height: 100%; top: 0; left: 0; overflow: hidden; z-index: 0; } .circle { position: absolute; border-radius: 50%; opacity: 0.1; filter: blur(3px); animation: float 12s infinite linear; } @keyframes float { 0% { transform: translateY(0) translateX(0) rotate(0deg); } 50% { transform: translateY(-20px) translateX(15px) rotate(180deg); } 100% { transform: translateY(0) translateX(0) rotate(360deg); } } .save-button { background: var(--text); color: var(--light); border: none; padding: 14px 30px; border-radius: 12px; font-size: 1rem; font-weight: 600; cursor: pointer; margin-top: 30px; transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease; position: relative; overflow: hidden; z-index: 10; } .save-button::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); transition: left 0.7s ease; } .save-button:hover { transform: translateY(-3px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); } .save-button:hover::before { left: 100%; } .save-button:active { transform: translateY(0); } .save-message { position: fixed; top: 20px; left: 50%; transform: translateX(-50%) translateY(-100px); background: var(--text); color: var(--light); padding: 15px 25px; border-radius: 12px; font-size: 1rem; opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; z-index: 100; } .save-message.show { transform: translateX(-50%) translateY(0); opacity: 1; } @media screen and (max-width: 600px) { h1 { font-size: 1.8rem; } p.tagline { font-size: 1rem; } .avatar { width: 150px; height: 150px; } .avatar-face { width: 80px; height: 80px; } .avatar-eyes { width: 60px; top: 25px; left: 10px; } .avatar-eye { width: 15px; height: 15px; } .avatar-mouth { width: 35px; height: 15px; bottom: 18px; left: 22px; } .colors { gap: 10px; } .color-option { width: 35px; height: 35px; } .feature { padding: 10px 15px; } .feature-text { font-size: 0.85rem; } } </style> </head> <body> <div class="container"> <div class="animated-circles"></div> <div class="header"> <h1>Your Shopping Buddy</h1> <p class="tagline">Create a friendly avatar that follows you across our store, remembers your preferences, and guides your shopping journey.</p> </div> <div class="avatar-container"> <div class="avatar-glow"></div> <div class="avatar"> <div class="avatar-face"> <div class="avatar-eyes"> <div class="avatar-eye left-eye"></div> <div class="avatar-eye right-eye"></div> </div> <div class="avatar-mouth"> <div class="avatar-tongue"></div> </div> </div> </div> <div class="avatar-accessories"> <div class="hat"></div> <div class="glasses"></div> </div> </div> <div class="colors"> <div class="color-option blue active"></div> <div class="color-option pink"></div> <div class="color-option yellow"></div> <div class="color-option purple"></div> </div> <div class="avatar-features"> <div class="feature" data-feature="hat"> <div class="feature-icon">H</div> <div class="feature-text">Add Hat</div> </div> <div class="feature" data-feature="glasses"> <div class="feature-icon">G</div> <div class="feature-text">Add Glasses</div> </div> <div class="feature" data-feature="blink"> <div class="feature-icon">B</div> <div class="feature-text">Blink Animation</div> </div> <div class="feature" data-feature="bounce"> <div class="feature-icon">A</div> <div class="feature-text">Hover Bounce</div> </div> </div> <button class="save-button">Save My Shopping Buddy</button> </div> <div class="save-message">Your avatar has been saved!</div> <script> document.addEventListener('DOMContentLoaded', function() { // Current avatar state const avatarState = { color: 'var(--primary)', hat: false, glasses: false, blink: false, bounce: false }; // DOM Elements const avatar = document.querySelector('.avatar'); const avatarGlow = document.querySelector('.avatar-glow'); const colorOptions = document.querySelectorAll('.color-option'); const features = document.querySelectorAll('.feature'); const saveButton = document.querySelector('.save-button'); const saveMessage = document.querySelector('.save-message'); const hat = document.querySelector('.hat'); const glasses = document.querySelector('.glasses'); const leftEye = document.querySelector('.left-eye'); const rightEye = document.querySelector('.right-eye'); const animatedCircles = document.querySelector('.animated-circles'); // Create animated background circles function createCircles() { const colors = ['var(--primary)', 'var(--secondary)', 'var(--tertiary)', 'var(--accent)']; for (let i = 0; i < 15; i++) { const circle = document.createElement('div'); circle.classList.add('circle'); circle.style.width = `${Math.random() * 80 + 20}px`; circle.style.height = circle.style.width; circle.style.left = `${Math.random() * 100}%`; circle.style.top = `${Math.random() * 100}%`; circle.style.background = colors[Math.floor(Math.random() * colors.length)]; circle.style.animationDuration = `${Math.random() * 10 + 5}s`; circle.style.animationDelay = `${Math.random() * 5}s`; animatedCircles.appendChild(circle); } } createCircles(); // Update avatar color function updateAvatarColor(color) { avatarState.color = color; avatar.style.borderColor = color; avatarGlow.style.background = color; } // Initial setup avatarGlow.style.background = avatarState.color; // Color option click events colorOptions.forEach(option => { option.addEventListener('click', function() { // Remove active class from all options colorOptions.forEach(opt => opt.classList.remove('active')); // Add active class to clicked option this.classList.add('active'); // Get the color from the clicked option's class const colorClass = Array.from(this.classList).find(c => c !== 'color-option' && c !== 'active'); // Update avatar color based on CSS variable let selectedColor; switch(colorClass) { case 'blue': selectedColor = 'var(--primary)'; break; case 'pink': selectedColor = 'var(--secondary)'; break; case 'yellow': selectedColor = 'var(--tertiary)'; break; case 'purple': selectedColor = 'var(--accent)'; break; default: selectedColor = 'var(--primary)'; } avatarState.color = selectedColor; avatarGlow.style.background = selectedColor; }); }); // Feature click events features.forEach(feature => { feature.addEventListener('click', function() { const featureType = this.getAttribute('data-feature'); switch(featureType) { case 'hat': avatarState.hat = !avatarState.hat; hat.style.opacity = avatarState.hat ? '1' : '0'; hat.style.transform = avatarState.hat ? 'rotate(-15deg) translateY(0)' : 'rotate(-15deg) translateY(10px)'; break; case 'glasses': avatarState.glasses = !avatarState.glasses; glasses.style.opacity = avatarState.glasses ? '1' : '0'; break; case 'blink': avatarState.blink = !avatarState.blink; if (avatarState.blink) { startBlinking(); } else { stopBlinking(); } break; case 'bounce': avatarState.bounce = !avatarState.bounce; break; } // Toggle active status visually if (avatarState[featureType]) { this.style.backgroundColor = avatarState.color; this.style.color = 'white'; } else { this.style.backgroundColor = 'var(--light)'; this.style.color = 'var(--text)'; } }); }); // Blink animation let blinkInterval; function startBlinking() { blinkInterval = setInterval(() => { leftEye.style.height = '1px'; rightEye.style.height = '1px'; setTimeout(() => { leftEye.style.height = '18px'; rightEye.style.height = '18px'; }, 200); }, 3000); } function stopBlinking() { clearInterval(blinkInterval); leftEye.style.height = '18px'; rightEye.style.height = '18px'; } // Hover effects avatar.addEventListener('mouseenter', function() { if (avatarState.bounce) { this.style.transform = 'scale(1.05)'; this.style.boxShadow = '0 15px 40px rgba(0, 0, 0, 0.15)'; // Bounce animation setTimeout(() => { this.style.transform = 'scale(1.05) translateY(-10px)'; }, 100); setTimeout(() => { this.style.transform = 'scale(1.05) translateY(0)'; }, 200); } // Glow animation avatarGlow.style.opacity = '0.3'; }); avatar.addEventListener('mouseleave', function() { this.style.transform = ''; this.style.boxShadow = '0 8px 30px rgba(0, 0, 0, 0.12)'; avatarGlow.style.opacity = '0.15'; }); // Save button click saveButton.addEventListener('click', function() { // Show success message saveMessage.classList.add('show'); // Add success animation this.style.backgroundColor = '#4CAF50'; // Hide message after 3 seconds setTimeout(() => { saveMessage.classList.remove('show'); this.style.backgroundColor = 'var(--text)'; }, 3000); }); // Eye tracking document.addEventListener('mousemove', function(e) { const x = e.clientX; const y = e.clientY; const eyes = document.querySelectorAll('.avatar-eye'); eyes.forEach(eye => { const rect = eye.getBoundingClientRect(); const eyeX = rect.left + rect.width / 2; const eyeY = rect.top + rect.height / 2; // Calculate angle between mouse and eye const angle = Math.atan2(y - eyeY, x - eyeX); // Calculate offset (smaller for more subtle movement) const offset = 3; const offsetX = Math.cos(angle) * offset; const offsetY = Math.sin(angle) * offset; // Apply translation to the pupil (::after) eye.style.setProperty('--pupil-x', `${offsetX}px`); eye.style.setProperty('--pupil-y', `${offsetY}px`); // Move the pupil const pupil = eye.querySelector('::after'); if (pupil) { pupil.style.transform = `translate(${offsetX}px, ${offsetY}px)`; } }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #4285F4; --secondary: #FBBC05; --accent: #34A853; --danger: #EA4335; --light: #F8F9FA; --dark: #202124; --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f5f5f7; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; padding: 20px; } .container { width: 100%; max-width: 680px; height: auto; max-height: 680px; background-color: white; border-radius: 24px; box-shadow: 0 12px 28px rgba(0, 0, 0, 0.1); padding: 30px; position: relative; overflow: hidden; } .header { text-align: center; margin-bottom: 30px; } .header h1 { color: var(--dark); font-size: 28px; margin-bottom: 10px; font-weight: 700; } .header p { color: #606770; font-size: 16px; max-width: 80%; margin: 0 auto; } .tabs { display: flex; justify-content: center; margin-bottom: 30px; position: relative; z-index: 1; } .tab-btn { padding: 12px 20px; background: transparent; border: none; font-size: 16px; font-weight: 600; color: #606770; cursor: pointer; position: relative; transition: var(--transition); } .tab-btn.active { color: var(--primary); } .tab-indicator { height: 3px; width: 100px; background-color: var(--primary); position: absolute; bottom: -2px; border-radius: 3px; transition: var(--transition); left: 0; } .avatars-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 25px; max-height: 400px; overflow-y: auto; padding: 10px 5px; position: relative; } /* Customize scrollbar */ .avatars-container::-webkit-scrollbar { width: 6px; } .avatars-container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } .avatars-container::-webkit-scrollbar-thumb { background: #d0d0d0; border-radius: 10px; } .avatars-container::-webkit-scrollbar-thumb:hover { background: #a8a8a8; } .avatar-card { width: 130px; display: flex; flex-direction: column; align-items: center; cursor: pointer; transition: var(--transition); padding: 10px; border-radius: 16px; } .avatar-card:hover { transform: translateY(-5px); background-color: rgba(66, 133, 244, 0.05); } .avatar-wrapper { width: 100px; height: 100px; border-radius: 50%; position: relative; margin-bottom: 12px; display: flex; justify-content: center; align-items: center; transition: var(--transition); background: #fff; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); } .avatar-border { position: absolute; width: 100%; height: 100%; border-radius: 50%; border: 6px solid transparent; transition: var(--transition); top: 0; left: 0; } .avatar-img { width: 70%; height: 70%; object-fit: contain; border-radius: 50%; transition: var(--transition); } .student .avatar-border { border-color: var(--primary); } .teacher .avatar-border { border-color: var(--accent); } .avatar-card.selected .avatar-wrapper { transform: scale(1.05); } .avatar-card.selected .avatar-border { box-shadow: 0 0 0 4px rgba(66, 133, 244, 0.2); } .avatar-card.offline .avatar-wrapper { opacity: 0.7; } .avatar-card.online .status-dot { position: absolute; width: 12px; height: 12px; background-color: var(--accent); border-radius: 50%; bottom: 5px; right: 5px; border: 2px solid white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .avatar-name { font-size: 14px; font-weight: 600; color: var(--dark); text-align: center; transition: var(--transition); } .avatar-role { font-size: 12px; color: #606770; margin-top: 2px; } .customization-panel { margin-top: 25px; border-top: 1px solid rgba(0, 0, 0, 0.1); padding-top: 20px; display: flex; flex-direction: column; align-items: center; transition: var(--transition); opacity: 0; height: 0; overflow: hidden; } .customization-panel.active { opacity: 1; height: auto; } .colors { display: flex; gap: 10px; margin-bottom: 15px; } .color-option { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; transition: var(--transition); border: 2px solid white; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); } .color-option:hover, .color-option.selected { transform: scale(1.2); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.15); } .color-primary { background-color: var(--primary); } .color-secondary { background-color: var(--secondary); } .color-accent { background-color: var(--accent); } .color-danger { background-color: var(--danger); } .status-toggle { margin-top: 15px; background-color: #f1f1f1; border-radius: 20px; padding: 4px; display: flex; position: relative; width: 170px; height: 36px; } .status-option { z-index: 1; flex: 1; text-align: center; padding: 8px 0; cursor: pointer; border-radius: 16px; font-size: 14px; font-weight: 500; color: #606770; transition: var(--transition); } .status-option.active { color: white; } .status-slider { position: absolute; width: 50%; height: 28px; background-color: var(--primary); border-radius: 16px; top: 4px; left: 4px; transition: var(--transition); } .status-slider.right { left: calc(50% - 4px); } .character-bubbles { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; overflow: hidden; z-index: -1; } .bubble { position: absolute; background-color: rgba(66, 133, 244, 0.1); border-radius: 50%; animation: float 8s infinite ease-in-out; } @keyframes float { 0%, 100% { transform: translateY(0) translateX(0); } 25% { transform: translateY(-20px) translateX(10px); } 50% { transform: translateY(-10px) translateX(20px); } 75% { transform: translateY(-30px) translateX(-10px); } } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } @media (max-width: 600px) { .container { padding: 20px 15px; border-radius: 20px; } .header h1 { font-size: 24px; } .header p { font-size: 14px; } .avatar-card { width: 110px; } .avatar-wrapper { width: 85px; height: 85px; } .colors { gap: 8px; } .color-option { width: 25px; height: 25px; } } /* Animation for new avatars */ @keyframes popIn { 0% { transform: scale(0.8); opacity: 0; } 70% { transform: scale(1.05); } 100% { transform: scale(1); opacity: 1; } } .avatar-card.new-avatar { animation: popIn 0.5s forwards; } .interaction-hint { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); background-color: rgba(0,0,0,0.7); color: white; padding: 8px 16px; border-radius: 20px; font-size: 14px; opacity: 0; transition: opacity 0.3s ease; } .interaction-hint.show { opacity: 1; } </style> </head> <body> <div class="container"> <div class="character-bubbles"> <div class="bubble" style="width: 50px; height: 50px; top: 10%; left: 10%;"></div> <div class="bubble" style="width: 30px; height: 30px; top: 30%; left: 20%;"></div> <div class="bubble" style="width: 40px; height: 40px; top: 70%; left: 15%;"></div> <div class="bubble" style="width: 60px; height: 60px; top: 20%; right: 10%;"></div> <div class="bubble" style="width: 35px; height: 35px; top: 60%; right: 20%;"></div> </div> <div class="header"> <h1>Learning Buddy Avatars</h1> <p>Select a playful avatar for your educational profile</p> </div> <div class="tabs"> <button class="tab-btn active" data-tab="student">Student Avatars</button> <button class="tab-btn" data-tab="teacher">Teacher Avatars</button> <div class="tab-indicator"></div> </div> <div class="avatars-container" id="avatars-container"> <!-- Avatars will be inserted here by JavaScript --> </div> <div class="customization-panel" id="customization-panel"> <div class="colors"> <div class="color-option color-primary selected" data-color="var(--primary)"></div> <div class="color-option color-secondary" data-color="var(--secondary)"></div> <div class="color-option color-accent" data-color="var(--accent)"></div> <div class="color-option color-danger" data-color="var(--danger)"></div> </div> <div class="status-toggle"> <div class="status-option active" data-status="online">Online</div> <div class="status-option" data-status="offline">Offline</div> <div class="status-slider"></div> </div> </div> <div class="interaction-hint" id="interaction-hint">Try clicking on an avatar!</div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Avatar data const avatars = { student: [ { name: 'Alex', role: 'Science Explorer', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iI2ZmY2MwMCIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTY1LDcwQzY1LDcwLDU1LDgwLDM1LDcwIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' }, { name: 'Taylor', role: 'Math Whiz', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzRjYWY1MCIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTM1LDY1QzM1LDY1LDU1LDc1LDY1LDY1IiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' }, { name: 'Jordan', role: 'Art Enthusiast', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iI2YwNTc0NSIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTM1LDY1QzM1LDY1LDUwLDU1LDY1LDY1IiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' }, { name: 'Riley', role: 'Literature Lover', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzQyYTVmNSIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTQwLDY1QzQwLDY1LDUwLDcwLDYwLDY1IiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' }, { name: 'Casey', role: 'History Buff', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iI2ZmOTgwMCIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTQwLDcwQzQwLDcwLDUwLDYwLDYwLDcwIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' }, { name: 'Morgan', role: 'Coding Genius', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzllMjdmZiIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiMzMzMiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjMzMzIi8+PHBhdGggZD0iTTM1LDYwQzM1LDYwLDUwLDgwLDY1LDYwIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PC9zdmc+' } ], teacher: [ { name: 'Dr. Quinn', role: 'Science Mentor', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzA5NTdhZCIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTM1LDY1QzM1LDY1LDUwLDc1LDY1LDY1IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PHBhdGggZD0iTTMwLDMwQzMwLDMwLDIwLDIwLDIwLDIwIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik03MCwzMEM3MCwzMCw4MCwyMCw4MCwyMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4=' }, { name: 'Prof. Lee', role: 'Math Expert', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzM4OGUzYyIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTM1LDcwQzM1LDcwLDUwLDgwLDY1LDcwIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PHBhdGggZD0iTTI1LDIwQzI1LDIwLDM1LDE1LDQwLDIwIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik03NSwyMEM3NSwyMCw2NSwxNSw2MCwyMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4=' }, { name: 'Ms. Parker', role: 'Literature Guide', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iI2Q4MWIzMCIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQwLDY1QzQwLDY1LDUwLDc1LDYwLDY1IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PHBhdGggZD0iTTIwLDI1QzIwLDI1LDMwLDE1LDQwLDI1IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik04MCwyNUM4MCwyNSw3MCwxNSw2MCwyNSIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4=' }, { name: 'Dr. Garcia', role: 'History Advisor', img: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMDAgMTAwIj48Y2lyY2xlIGN4PSI1MCIgY3k9IjUwIiByPSI0MCIgZmlsbD0iIzc5NTU0NSIvPjxjaXJjbGUgY3g9IjM1IiBjeT0iNDAiIHI9IjUiIGZpbGw9IiNmZmYiLz48Y2lyY2xlIGN4PSI2NSIgY3k9IjQwIiByPSI1IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTM1LDY1QzM1LDY1LDUwLDcwLDY1LDY1IiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIi8+PHBhdGggZD0iTTQwLDMwQzQwLDMwLDMwLDIwLDIwLDMwIiBzdHJva2U9IiNmZmYiIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik02MCwzMEM2MCwzMCw3MCwyMCw4MCwzMCIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjIiIGZpbGw9Im5vbmUiLz48L3N2Zz4=' } ] }; // Current state let currentTab = 'student'; let selectedAvatar = null; let currentBorderColor = 'var(--primary)'; let currentStatus = 'online'; // DOM elements const tabButtons = document.querySelectorAll('.tab-btn'); const tabIndicator = document.querySelector('.tab-indicator'); const avatarsContainer = document.getElementById('avatars-container'); const customizationPanel = document.getElementById('customization-panel'); const colorOptions = document.querySelectorAll('.color-option'); const statusOptions = document.querySelectorAll('.status-option'); const statusSlider = document.querySelector('.status-slider'); const interactionHint = document.getElementById('interaction-hint'); // Initialize renderAvatars(currentTab); updateTabIndicator(); // Show interaction hint after 2 seconds setTimeout(() => { interactionHint.classList.add('show'); setTimeout(() => { interactionHint.classList.remove('show'); }, 3000); }, 2000); // Tab switching tabButtons.forEach(button => { button.addEventListener('click', function() { currentTab = this.dataset.tab; tabButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); renderAvatars(currentTab); updateTabIndicator(); customizationPanel.classList.remove('active'); selectedAvatar = null; }); }); // Update tab indicator position function updateTabIndicator() { const activeTab = document.querySelector('.tab-btn.active'); tabIndicator.style.width = `${activeTab.offsetWidth}px`; tabIndicator.style.left = `${activeTab.offsetLeft}px`; } // Render avatars function renderAvatars(tab) { avatarsContainer.innerHTML = ''; avatars[tab].forEach((avatar, index) => { const avatarCard = document.createElement('div'); avatarCard.className = 'avatar-card new-avatar'; avatarCard.style.animationDelay = `${index * 0.1}s`; avatarCard.innerHTML = ` <div class="avatar-wrapper"> <div class="avatar-border"></div> <img src="${avatar.img}" class="avatar-img" alt="${avatar.name}"> </div> <div class="avatar-name">${avatar.name}</div> <div class="avatar-role">${avatar.role}</div> `; // Add random status if (Math.random() > 0.5) { avatarCard.className += ' online'; const statusDot = document.createElement('div'); statusDot.className = 'status-dot'; avatarCard.querySelector('.avatar-wrapper').appendChild(statusDot); } else { avatarCard.className += ' offline'; } avatarCard.addEventListener('click', function() { document.querySelectorAll('.avatar-card').forEach(card => card.classList.remove('selected')); this.classList.add('selected'); selectedAvatar = this; customizationPanel.classList.add('active'); updateAvatarBorder(); }); avatarsContainer.appendChild(avatarCard); }); } // Color picker colorOptions.forEach(option => { option.addEventListener('click', function() { colorOptions.forEach(opt => opt.classList.remove('selected')); this.classList.add('selected'); currentBorderColor = this.dataset.color; updateAvatarBorder(); // Also update status slider color statusSlider.style.backgroundColor = currentBorderColor; }); }); // Status toggle statusOptions.forEach(option => { option.addEventListener('click', function() { statusOptions.forEach(opt => opt.classList.remove('active')); this.classList.add('active'); currentStatus = this.dataset.status; if (currentStatus === 'offline') { statusSlider.classList.add('right'); } else { statusSlider.classList.remove('right'); } updateAvatarStatus(); }); }); // Update avatar border function updateAvatarBorder() { if (selectedAvatar) { const border = selectedAvatar.querySelector('.avatar-border'); border.style.borderColor = currentBorderColor; } } // Update avatar status function updateAvatarStatus() { if (selectedAvatar) { if (currentStatus === 'online') { selectedAvatar.classList.add('online'); selectedAvatar.classList.remove('offline'); // Add status dot if it doesn't exist if (!selectedAvatar.querySelector('.status-dot')) { const statusDot = document.createElement('div'); statusDot.className = 'status-dot'; selectedAvatar.querySelector('.avatar-wrapper').appendChild(statusDot); } } else { selectedAvatar.classList.remove('online'); selectedAvatar.classList.add('offline'); // Remove status dot if it exists const statusDot = selectedAvatar.querySelector('.status-dot'); if (statusDot) { statusDot.remove(); } } } } // Keep bubbles animated const bubbles = document.querySelectorAll('.bubble'); bubbles.forEach((bubble, index) => { bubble.style.animationDelay = `${index * 0.7}s`; bubble.style.opacity = 0.7 - (index * 0.1); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Healthcare Portal Avatar</title> <style> :root { --primary-blue: #4285a6; --light-blue: #a6cfe8; --teal: #5EB6B8; --light-teal: #B2E0E1; --soft-green: #7FC8A9; --light-green: #d0f0e4; --off-white: #f9fcfd; --light-text: #f0f5fa; --dark-text: #2c3e50; --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, var(--light-blue) 0%, var(--light-teal) 50%, var(--light-green) 100%); height: 700px; width: 700px; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } .pattern-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(circle at 10% 20%, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.05) 5%, transparent 5%, transparent 100%), radial-gradient(circle at 30% 50%, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.07) 3%, transparent 3%, transparent 100%), radial-gradient(circle at 70% 80%, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.05) 4%, transparent 4%, transparent 100%); background-size: 100px 100px, 150px 150px, 200px 200px; z-index: 0; pointer-events: none; opacity: 0.7; } .container { background-color: var(--off-white); width: 85%; max-width: 600px; height: auto; border-radius: 24px; box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07); display: flex; flex-direction: column; align-items: center; padding: 40px 30px; position: relative; z-index: 2; overflow: hidden; } .portal-header { text-align: center; margin-bottom: 30px; width: 100%; } .portal-header h1 { color: var(--primary-blue); font-size: 28px; font-weight: 600; margin-bottom: 10px; } .portal-header p { color: var(--dark-text); font-size: 16px; line-height: 1.5; opacity: 0.85; } .avatar-container { display: flex; flex-direction: column; align-items: center; justify-content: center; margin-bottom: 30px; position: relative; } .avatar-outer { width: 140px; height: 140px; border-radius: 50%; position: relative; background: linear-gradient(135deg, var(--primary-blue), var(--teal)); padding: 5px; cursor: pointer; transition: var(--transition); box-shadow: 0 6px 16px rgba(66, 133, 166, 0.15); } .avatar-inner { width: 100%; height: 100%; border-radius: 50%; background-color: var(--off-white); display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } .avatar-face { position: relative; width: 90px; height: 90px; display: flex; flex-direction: column; align-items: center; justify-content: center; } .avatar-eyes { display: flex; width: 60px; justify-content: space-between; margin-top: 10px; position: relative; } .avatar-eye { width: 18px; height: 18px; border-radius: 50%; background-color: var(--primary-blue); position: relative; overflow: hidden; transition: var(--transition); } .avatar-pupil { width: 8px; height: 8px; border-radius: 50%; background-color: var(--off-white); position: absolute; top: 3px; right: 3px; transition: var(--transition); } .avatar-mouth { width: 30px; height: 10px; border-radius: 0 0 20px 20px; background-color: var(--primary-blue); margin-top: 15px; position: relative; transition: var(--transition); } .pulse-ring { position: absolute; width: 100%; height: 100%; border-radius: 50%; border: 3px solid var(--light-teal); opacity: 0; transform: scale(1); transition: opacity 0.2s ease-out; } .avatar-status { width: 20px; height: 20px; border-radius: 50%; background: var(--soft-green); position: absolute; bottom: 10px; right: 10px; border: 3px solid var(--off-white); z-index: 2; box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); transition: var(--transition); } .avatar-name { margin-top: 15px; font-size: 18px; font-weight: 600; color: var(--primary-blue); } .avatar-role { font-size: 14px; color: var(--dark-text); opacity: 0.7; margin-top: 5px; } .interaction-options { display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; width: 100%; margin-top: 10px; } .option-button { padding: 14px 22px; background-color: var(--light-teal); color: var(--dark-text); border: none; border-radius: 12px; font-size: 15px; font-weight: 500; cursor: pointer; transition: var(--transition); box-shadow: 0 4px 6px rgba(66, 133, 166, 0.1); flex: 1; min-width: 140px; max-width: 200px; text-align: center; display: flex; align-items: center; justify-content: center; gap: 8px; } .option-button i { font-size: 18px; } .option-button:hover { background-color: var(--teal); color: var(--light-text); transform: translateY(-2px); box-shadow: 0 7px 14px rgba(66, 133, 166, 0.2); } .chat-container { width: 100%; margin-top: 25px; display: none; transition: var(--transition); opacity: 0; transform: translateY(20px); } .chat-content { background-color: var(--light-green); border-radius: 16px; padding: 20px; margin-bottom: 15px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); } .chat-title { font-size: 16px; font-weight: 600; color: var(--primary-blue); margin-bottom: 10px; } .chat-message { font-size: 14px; line-height: 1.5; color: var(--dark-text); } .chat-input { display: flex; gap: 10px; width: 100%; } .chat-input input { flex: 1; padding: 12px 16px; border: 2px solid var(--light-teal); border-radius: 12px; font-size: 14px; outline: none; transition: var(--transition); } .chat-input input:focus { border-color: var(--teal); box-shadow: 0 0 0 3px rgba(94, 182, 184, 0.2); } .send-button { background-color: var(--primary-blue); color: white; border: none; border-radius: 12px; width: 45px; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .send-button:hover { background-color: var(--teal); transform: scale(1.05); } .info-panel { width: 100%; margin-top: 25px; display: none; transition: var(--transition); opacity: 0; transform: translateY(20px); } .info-content { background-color: var(--light-blue); border-radius: 16px; padding: 20px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05); } .info-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-top: 10px; } .info-item { display: flex; flex-direction: column; } .info-label { font-size: 12px; color: var(--primary-blue); font-weight: 600; margin-bottom: 4px; } .info-value { font-size: 14px; color: var(--dark-text); } .avatar-outer.focused { transform: scale(1.05); box-shadow: 0 8px 25px rgba(66, 133, 166, 0.25), 0 0 0 5px rgba(94, 182, 184, 0.15); } .avatar-outer.focused .pulse-ring { animation: pulse 2s infinite; } .avatar-outer.talking .avatar-mouth { animation: talk 1s infinite alternate; } @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 100% { transform: scale(1.2); opacity: 0; } } @keyframes talk { 0% { height: 5px; width: 30px; } 50% { height: 10px; width: 35px; } 100% { height: 6px; width: 28px; } } @keyframes blink { 0% { transform: scaleY(1); } 18% { transform: scaleY(1); } 20% { transform: scaleY(0.1); } 22% { transform: scaleY(1); } 100% { transform: scaleY(1); } } @media (max-width: 600px) { .container { width: 95%; padding: 30px 20px; } .portal-header h1 { font-size: 24px; } .interaction-options { flex-direction: column; align-items: center; } .option-button { width: 100%; max-width: 100%; } .info-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="pattern-overlay"></div> <div class="container"> <div class="portal-header"> <h1>WellPath Health Assistant</h1> <p>Your personal healthcare navigator, helping you access care with comfort and ease.</p> </div> <div class="avatar-container"> <div class="avatar-outer" id="avatar"> <div class="pulse-ring"></div> <div class="avatar-inner"> <div class="avatar-face"> <div class="avatar-eyes"> <div class="avatar-eye"> <div class="avatar-pupil"></div> </div> <div class="avatar-eye"> <div class="avatar-pupil"></div> </div> </div> <div class="avatar-mouth"></div> </div> </div> <div class="avatar-status"></div> </div> <div class="avatar-name">Claire</div> <div class="avatar-role">Care Navigator</div> </div> <div class="interaction-options"> <button class="option-button" id="chat-btn"> <i>๐ฌ</i> Start Chat </button> <button class="option-button" id="info-btn"> <i>โน๏ธ</i> My Care Info </button> <button class="option-button" id="appt-btn"> <i>๐ </i> Appointments </button> </div> <div class="chat-container" id="chat-container"> <div class="chat-content"> <div class="chat-title">Claire</div> <div class="chat-message">Hi there! I'm Claire, your personal health navigator. How can I assist you today? You can ask about scheduling appointments, medication reminders, or finding specialists nearby.</div> </div> <div class="chat-input"> <input type="text" placeholder="Type your question here..." id="chat-input"> <button class="send-button" id="send-btn">โค</button> </div> </div> <div class="info-panel" id="info-panel"> <div class="info-content"> <div class="chat-title">My Care Summary</div> <div class="info-grid"> <div class="info-item"> <div class="info-label">PRIMARY CARE</div> <div class="info-value">Dr. Sarah Chen</div> </div> <div class="info-item"> <div class="info-label">NEXT APPOINTMENT</div> <div class="info-value">Oct 18, 10:30 AM</div> </div> <div class="info-item"> <div class="info-label">PRESCRIPTION REFILL</div> <div class="info-value">2 medications due</div> </div> <div class="info-item"> <div class="info-label">RECENT LABS</div> <div class="info-value">Results available</div> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const avatar = document.getElementById('avatar'); const chatBtn = document.getElementById('chat-btn'); const infoBtn = document.getElementById('info-btn'); const apptBtn = document.getElementById('appt-btn'); const chatContainer = document.getElementById('chat-container'); const infoPanel = document.getElementById('info-panel'); const sendBtn = document.getElementById('send-btn'); const chatInput = document.getElementById('chat-input'); const chatContent = document.querySelector('.chat-content'); const avatarEyes = document.querySelectorAll('.avatar-eye'); const avatarMouth = document.querySelector('.avatar-mouth'); // Blinking animation function startBlinking() { avatarEyes.forEach(eye => { eye.style.animation = 'blink 4s infinite'; }); } startBlinking(); // Eye tracking document.addEventListener('mousemove', function(e) { const mouseX = e.clientX; const mouseY = e.clientY; avatarEyes.forEach(eye => { const pupil = eye.querySelector('.avatar-pupil'); const eyeRect = eye.getBoundingClientRect(); const eyeCenterX = eyeRect.left + eyeRect.width / 2; const eyeCenterY = eyeRect.top + eyeRect.height / 2; const angle = Math.atan2(mouseY - eyeCenterY, mouseX - eyeCenterX); const distance = Math.min(3, Math.sqrt(Math.pow(mouseX - eyeCenterX, 2) + Math.pow(mouseY - eyeCenterY, 2)) / 25); const pupilX = Math.cos(angle) * distance; const pupilY = Math.sin(angle) * distance; pupil.style.transform = `translate(${pupilX}px, ${pupilY}px)`; }); }); // Avatar focus state avatar.addEventListener('click', function() { this.classList.toggle('focused'); if (this.classList.contains('focused')) { this.classList.add('talking'); setTimeout(() => { this.classList.remove('talking'); }, 2000); } }); // Show chat function function showChat() { infoPanel.style.display = 'none'; infoPanel.style.opacity = '0'; infoPanel.style.transform = 'translateY(20px)'; chatContainer.style.display = 'block'; setTimeout(() => { chatContainer.style.opacity = '1'; chatContainer.style.transform = 'translateY(0)'; }, 50); avatar.classList.add('focused'); avatar.classList.add('talking'); setTimeout(() => { avatar.classList.remove('talking'); }, 2000); } // Show info function function showInfo() { chatContainer.style.display = 'none'; chatContainer.style.opacity = '0'; chatContainer.style.transform = 'translateY(20px)'; infoPanel.style.display = 'block'; setTimeout(() => { infoPanel.style.opacity = '1'; infoPanel.style.transform = 'translateY(0)'; }, 50); avatar.classList.add('focused'); setTimeout(() => { avatar.classList.remove('focused'); }, 2000); } // Button click handlers chatBtn.addEventListener('click', showChat); infoBtn.addEventListener('click', showInfo); apptBtn.addEventListener('click', function() { showChat(); setTimeout(() => { const newMessage = document.createElement('div'); newMessage.classList.add('chat-content'); newMessage.innerHTML = ` <div class="chat-title">Claire</div> <div class="chat-message">I see you have an upcoming appointment with Dr. Chen on October 18th at 10:30 AM. Would you like to reschedule or set a reminder?</div> `; chatContainer.insertBefore(newMessage, document.querySelector('.chat-input')); avatar.classList.add('talking'); setTimeout(() => { avatar.classList.remove('talking'); }, 2000); }, 500); }); // Send message function function sendMessage() { const message = chatInput.value.trim(); if (message) { // Add user message const userMessage = document.createElement('div'); userMessage.classList.add('chat-content'); userMessage.style.backgroundColor = 'var(--light-blue)'; userMessage.innerHTML = ` <div class="chat-title">You</div> <div class="chat-message">${message}</div> `; chatContainer.insertBefore(userMessage, document.querySelector('.chat-input')); chatInput.value = ''; // Simulate response setTimeout(() => { avatar.classList.add('talking'); setTimeout(() => { const responseMessage = document.createElement('div'); responseMessage.classList.add('chat-content'); let response = "I'm here to help with your healthcare needs. Could you please provide more details about what you're looking for?"; if (message.toLowerCase().includes('appointment') || message.toLowerCase().includes('schedule')) { response = "I'd be happy to help you schedule an appointment. We have openings with Dr. Chen this Thursday at 2:30 PM or Friday at 11:00 AM. Which would work better for you?"; } else if (message.toLowerCase().includes('medication') || message.toLowerCase().includes('prescription')) { response = "I see you have 2 medications due for refill: Lisinopril (10mg) and Atorvastatin (20mg). Would you like me to request these refills from your pharmacy now?"; } else if (message.toLowerCase().includes('test') || message.toLowerCase().includes('lab')) { response = "Your recent lab results from October 5th are available. All values are within normal range except for slightly elevated LDL cholesterol. Dr. Chen has added a note recommending dietary changes."; } responseMessage.innerHTML = ` <div class="chat-title">Claire</div> <div class="chat-message">${response}</div> `; chatContainer.insertBefore(responseMessage, document.querySelector('.chat-input')); avatar.classList.remove('talking'); }, 1500); }, 500); } } sendBtn.addEventListener('click', sendMessage); chatInput.addEventListener('keypress', function(e) { if (e.key === 'Enter') { sendMessage(); } }); // Initial animation setTimeout(() => { avatar.classList.add('focused'); avatar.classList.add('talking'); setTimeout(() => { avatar.classList.remove('talking'); avatar.classList.remove('focused'); }, 2000); }, 800); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Artist Portfolio Avatar</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Cormorant Garamond', serif; background-color: #f9f6f2; color: #333; width: 100%; height: 100%; overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; } .container { width: 100%; max-width: 700px; height: 700px; display: flex; flex-direction: column; align-items: center; padding: 20px; position: relative; } .avatar-container { position: relative; width: 280px; height: 280px; margin-top: 40px; transition: all 0.5s ease; } .avatar-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; background-size: cover; background-position: center; transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); filter: saturate(1.2); } .avatar-base { background-color: #e9d9c7; z-index: 1; } .avatar-layer-1 { background-color: #e4d2bc; clip-path: path('M140,0 C215,0 280,65 280,140 C280,215 215,280 140,280 C65,280 0,215 0,140 C0,65 65,0 140,0 Z'); z-index: 2; opacity: 0.85; } .avatar-layer-2 { background-color: #d1a88e; clip-path: path('M140,20 C205,20 260,75 260,140 C260,205 205,260 140,260 C75,260 20,205 20,140 C20,75 75,20 140,20 Z'); z-index: 3; opacity: 0.75; } .avatar-layer-3 { background-color: #b97c63; clip-path: path('M140,40 C195,40 240,85 240,140 C240,195 195,240 140,240 C85,240 40,195 40,140 C40,85 85,40 140,40 Z'); z-index: 4; opacity: 0.65; } .avatar-layer-4 { background-color: #8c5e50; clip-path: path('M140,60 C185,60 220,95 220,140 C220,185 185,220 140,220 C95,220 60,185 60,140 C60,95 95,60 140,60 Z'); z-index: 5; opacity: 0.55; } .avatar-layer-5 { background-color: #563c36; clip-path: path('M140,80 C175,80 200,105 200,140 C200,175 175,200 140,200 C105,200 80,175 80,140 C80,105 105,80 140,80 Z'); z-index: 6; opacity: 0.45; } .avatar-features { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 7; pointer-events: none; } .avatar-texture { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><filter id="noise"><feTurbulence type="fractalNoise" baseFrequency="0.65" numOctaves="3" stitchTiles="stitch"/><feColorMatrix type="saturate" values="0"/><feBlend in="SourceGraphic" mode="multiply"/></filter><rect width="100%" height="100%" filter="url(%23noise)" opacity="0.1"/></svg>'); mix-blend-mode: overlay; opacity: 0.5; z-index: 8; } .brushstroke { position: absolute; background-size: contain; background-repeat: no-repeat; transform-origin: center; filter: opacity(0.7); transition: all 0.6s ease-out; } .brushstroke-1 { width: 120px; height: 80px; top: -40px; left: 80px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 50"><path d="M5,25 Q30,5 50,25 T95,25" fill="none" stroke="%23d1a88e" stroke-width="12" stroke-linecap="round"/></svg>'); transform: rotate(-15deg) scale(1); } .brushstroke-2 { width: 150px; height: 100px; bottom: -35px; right: 50px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 50"><path d="M5,25 Q30,45 50,25 T95,25" fill="none" stroke="%238c5e50" stroke-width="14" stroke-linecap="round"/></svg>'); transform: rotate(20deg) scale(1); } .brushstroke-3 { width: 100px; height: 70px; bottom: 60px; left: -30px; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 50"><path d="M10,40 Q30,10 50,40 T90,40" fill="none" stroke="%23b97c63" stroke-width="10" stroke-linecap="round"/></svg>'); transform: rotate(-25deg) scale(1); } .avatar-container:hover .brushstroke-1 { transform: rotate(-5deg) scale(1.15); } .avatar-container:hover .brushstroke-2 { transform: rotate(10deg) scale(1.15); } .avatar-container:hover .brushstroke-3 { transform: rotate(-15deg) scale(1.15); } .customizer { margin-top: 60px; width: 100%; max-width: 500px; display: flex; flex-direction: column; gap: 25px; } .sliders { display: flex; flex-wrap: wrap; gap: 15px; justify-content: center; } .slider-control { display: flex; flex-direction: column; width: calc(50% - 15px); min-width: 200px; } label { font-size: 14px; margin-bottom: 8px; font-weight: 600; color: #563c36; } input[type="range"] { -webkit-appearance: none; width: 100%; height: 6px; background: #e4d2bc; border-radius: 5px; outline: none; } input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: #8c5e50; cursor: pointer; transition: all 0.2s ease; } input[type="range"]::-webkit-slider-thumb:hover { background: #563c36; transform: scale(1.1); } .palette { display: flex; justify-content: center; gap: 12px; margin-top: 10px; } .color-option { width: 30px; height: 30px; border-radius: 50%; cursor: pointer; transition: all 0.3s ease; border: 2px solid #f9f6f2; } .color-option:hover { transform: scale(1.15); } .color-option.active { border: 2px solid #333; transform: scale(1.1); } .color-1 { background-color: #d1a88e; } .color-2 { background-color: #a4c5c6; } .color-3 { background-color: #b987a7; } .color-4 { background-color: #a9c27f; } .color-5 { background-color: #e6b25b; } h1 { font-size: 32px; font-weight: 500; margin-bottom: 5px; color: #563c36; letter-spacing: 1px; } p { font-size: 16px; line-height: 1.5; text-align: center; max-width: 450px; color: #8c5e50; } .water-ripple { position: absolute; width: 300px; height: 300px; border-radius: 50%; background: transparent; border: 2px solid rgba(209, 168, 142, 0.5); transform: translate(-50%, -50%); pointer-events: none; opacity: 0; z-index: 9; } @keyframes ripple { 0% { width: 0; height: 0; opacity: 0.5; } 100% { width: 300px; height: 300px; opacity: 0; } } .signature { position: absolute; bottom: 20px; right: 30px; font-family: 'Caveat', cursive; font-size: 18px; color: #8c5e50; transform: rotate(-5deg); } @media (max-width: 600px) { .avatar-container { width: 220px; height: 220px; margin-top: 20px; } .customizer { margin-top: 40px; } .sliders { gap: 10px; } .slider-control { width: 100%; } h1 { font-size: 26px; } p { font-size: 14px; } } /* Watercolor paper texture overlay */ .paper-texture { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" viewBox="0 0 250 250"><filter id="paper"><feTurbulence type="fractalNoise" baseFrequency="0.04" numOctaves="5" stitchTiles="stitch"/><feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0"/></filter><rect width="100%" height="100%" filter="url(%23paper)"/></svg>'); pointer-events: none; z-index: 999; opacity: 0.2; mix-blend-mode: multiply; } </style> <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600&family=Caveat&display=swap" rel="stylesheet"> </head> <body> <div class="paper-texture"></div> <div class="container"> <h1>Watercolor Self-Portrait</h1> <p>A dynamic artistic representation that adapts to your aesthetic preferences. Customize colors and brush density to create a unique avatar for your portfolio.</p> <div class="avatar-container" id="avatarContainer"> <div class="avatar-layer avatar-base"></div> <div class="avatar-layer avatar-layer-1"></div> <div class="avatar-layer avatar-layer-2"></div> <div class="avatar-layer avatar-layer-3"></div> <div class="avatar-layer avatar-layer-4"></div> <div class="avatar-layer avatar-layer-5"></div> <div class="avatar-features" id="avatarFeatures"></div> <div class="avatar-texture"></div> <div class="brushstroke brushstroke-1"></div> <div class="brushstroke brushstroke-2"></div> <div class="brushstroke brushstroke-3"></div> </div> <div class="customizer"> <div class="sliders"> <div class="slider-control"> <label for="layerBlend">Watercolor Blend</label> <input type="range" id="layerBlend" min="0" max="100" value="70"> </div> <div class="slider-control"> <label for="brushDensity">Brush Stroke Density</label> <input type="range" id="brushDensity" min="0" max="100" value="50"> </div> <div class="slider-control"> <label for="colorTone">Color Tone</label> <input type="range" id="colorTone" min="0" max="100" value="60"> </div> <div class="slider-control"> <label for="textureOpacity">Texture Intensity</label> <input type="range" id="textureOpacity" min="0" max="100" value="50"> </div> </div> <div class="palette"> <div class="color-option color-1 active" data-color="#d1a88e"></div> <div class="color-option color-2" data-color="#a4c5c6"></div> <div class="color-option color-3" data-color="#b987a7"></div> <div class="color-option color-4" data-color="#a9c27f"></div> <div class="color-option color-5" data-color="#e6b25b"></div> </div> </div> <div class="signature">A. Artist</div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const avatarContainer = document.getElementById('avatarContainer'); const avatarLayers = document.querySelectorAll('.avatar-layer'); const colorOptions = document.querySelectorAll('.color-option'); const layerBlendSlider = document.getElementById('layerBlend'); const brushDensitySlider = document.getElementById('brushDensity'); const colorToneSlider = document.getElementById('colorTone'); const textureOpacitySlider = document.getElementById('textureOpacity'); const avatarTexture = document.querySelector('.avatar-texture'); const brushstrokes = document.querySelectorAll('.brushstroke'); const avatarFeatures = document.getElementById('avatarFeatures'); let activeColor = '#d1a88e'; let featureElements = []; // Generate random facial features function generateFeatures() { avatarFeatures.innerHTML = ''; featureElements = []; const density = brushDensitySlider.value / 100; const featureCount = Math.floor(5 + density * 15); for (let i = 0; i < featureCount; i++) { const feature = document.createElement('div'); feature.classList.add('feature'); const size = 10 + Math.random() * 30; const opacity = 0.1 + Math.random() * 0.4; const posX = 30 + Math.random() * 220; const posY = 30 + Math.random() * 220; const rotation = Math.random() * 360; feature.style.position = 'absolute'; feature.style.width = `${size}px`; feature.style.height = `${size}px`; feature.style.borderRadius = '50%'; feature.style.backgroundColor = activeColor; feature.style.opacity = opacity; feature.style.left = `${posX}px`; feature.style.top = `${posY}px`; feature.style.transform = `rotate(${rotation}deg)`; feature.style.filter = 'blur(3px)'; avatarFeatures.appendChild(feature); featureElements.push(feature); } } // Apply watercolor ripple effect function createRipple(event) { const rect = avatarContainer.getBoundingClientRect(); const x = event.clientX - rect.left; const y = event.clientY - rect.top; const ripple = document.createElement('div'); ripple.classList.add('water-ripple'); ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; ripple.style.animation = 'ripple 1.5s ease-out forwards'; avatarContainer.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 1500); } // Update avatar based on slider values function updateAvatar() { const blendValue = layerBlendSlider.value / 100; const colorTone = colorToneSlider.value / 100; const textureOpacity = textureOpacitySlider.value / 100; // Adjust layer opacities for watercolor blend effect avatarLayers.forEach((layer, index) => { if (index > 0) { const layerOpacity = 0.85 - (index * 0.1 * blendValue); layer.style.opacity = Math.max(0.1, layerOpacity); } }); // Adjust texture opacity avatarTexture.style.opacity = 0.2 + (textureOpacity * 0.6); // Adjust color saturation based on color tone brushstrokes.forEach(stroke => { stroke.style.filter = `opacity(${0.6 + (colorTone * 0.4)}) saturate(${0.8 + (colorTone * 0.8)})`; }); // Update feature elements featureElements.forEach(feature => { feature.style.backgroundColor = activeColor; feature.style.filter = `blur(${3 + (1 - colorTone) * 5}px)`; }); } // Mouse move effect on avatar avatarContainer.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = (e.clientX - rect.left) / rect.width - 0.5; const y = (e.clientY - rect.top) / rect.height - 0.5; avatarLayers.forEach((layer, index) => { if (index > 0) { const factor = (index + 1) * 10; layer.style.transform = `translateX(${x * factor}px) translateY(${y * factor}px)`; } }); brushstrokes.forEach((stroke, index) => { const factor = (index + 1) * 5; const currentTransform = stroke.style.transform.split(' ')[0] || ''; stroke.style.transform = `${currentTransform} translateX(${x * factor * -1}px) translateY(${y * factor * -1}px)`; }); }); avatarContainer.addEventListener('mouseleave', function() { avatarLayers.forEach(layer => { layer.style.transform = 'translateX(0) translateY(0)'; }); brushstrokes.forEach((stroke, index) => { const rotations = ['-15deg', '20deg', '-25deg']; stroke.style.transform = `rotate(${rotations[index]}) scale(1)`; }); }); // Color palette selection colorOptions.forEach(option => { option.addEventListener('click', function() { colorOptions.forEach(opt => opt.classList.remove('active')); this.classList.add('active'); activeColor = this.dataset.color; document.documentElement.style.setProperty('--primary-color', activeColor); // Update avatar layers colors avatarLayers.forEach((layer, index) => { if (index > 0) { const baseColor = activeColor; const r = parseInt(baseColor.slice(1, 3), 16); const g = parseInt(baseColor.slice(3, 5), 16); const b = parseInt(baseColor.slice(5, 7), 16); const darkenFactor = 1 - (index * 0.15); const newR = Math.floor(r * darkenFactor); const newG = Math.floor(g * darkenFactor); const newB = Math.floor(b * darkenFactor); const newColor = `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`; layer.style.backgroundColor = newColor; } }); // Update brushstroke colors brushstrokes.forEach((stroke, index) => { const svgUrl = createBrushSvg(activeColor, index); stroke.style.backgroundImage = `url('${svgUrl}')`; }); generateFeatures(); updateAvatar(); }); }); // Create SVG brushstrokes with specific color function createBrushSvg(color, index) { const pathData = [ 'M5,25 Q30,5 50,25 T95,25', 'M5,25 Q30,45 50,25 T95,25', 'M10,40 Q30,10 50,40 T90,40' ]; const strokeWidths = [12, 14, 10]; const hexColor = color.replace('#', '%23'); return `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 50"><path d="${pathData[index]}" fill="none" stroke="${hexColor}" stroke-width="${strokeWidths[index]}" stroke-linecap="round"/></svg>`; } // Ripple effect on click avatarContainer.addEventListener('click', createRipple); // Update on slider changes layerBlendSlider.addEventListener('input', updateAvatar); colorToneSlider.addEventListener('input', updateAvatar); textureOpacitySlider.addEventListener('input', updateAvatar); brushDensitySlider.addEventListener('input', function() { generateFeatures(); updateAvatar(); }); // Initial setup generateFeatures(); updateAvatar(); // Set initial brushstroke colors brushstrokes.forEach((stroke, index) => { const svgUrl = createBrushSvg(activeColor, index); stroke.style.backgroundImage = `url('${svgUrl}')`; }); }); </script> </body> </html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Moodvatar - Expressive Messaging Avatars</title> <style> :root { --primary-bg: #121a2d; --secondary-bg: #1e2742; --text-color: #ecf0ff; --accent-color: #7b42f6; --accent-glow: rgba(123, 66, 246, 0.3); --happy-color: #42f6b0; --sad-color: #4285f6; --busy-color: #f64242; --chill-color: #f6b042; --focus-color: #f642d1; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--primary-bg); color: var(--text-color); display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 700px; width: 100%; overflow-x: hidden; padding: 20px; } .container { max-width: 700px; width: 100%; display: flex; flex-direction: column; align-items: center; gap: 20px; } header { text-align: center; margin-bottom: 10px; } h1 { font-size: 2.2rem; font-weight: 700; margin-bottom: 8px; background: linear-gradient(45deg, var(--happy-color), var(--accent-color)); -webkit-background-clip: text; background-clip: text; color: transparent; } p { opacity: 0.9; line-height: 1.5; max-width: 600px; text-align: center; } .avatar-stage { display: flex; flex-direction: column; align-items: center; padding: 30px; background-color: var(--secondary-bg); border-radius: 20px; margin-bottom: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); width: 100%; max-width: 500px; position: relative; overflow: hidden; } .avatar-stage::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient( 45deg, transparent, transparent, rgba(123, 66, 246, 0.1), transparent, transparent ); transform: rotate(45deg); animation: glow 10s linear infinite; z-index: 0; } @keyframes glow { 0% { transform: rotate(45deg) translateX(-100%); } 100% { transform: rotate(45deg) translateX(100%); } } .avatar-container { position: relative; width: 200px; height: 200px; z-index: 1; } .avatar { width: 100%; height: 100%; border-radius: 50%; background-color: var(--secondary-bg); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); display: flex; justify-content: center; align-items: center; position: relative; overflow: hidden; transition: all 0.3s ease; } .avatar-face { width: 80%; height: 80%; border-radius: 50%; background-color: #2f3756; display: flex; flex-direction: column; justify-content: center; align-items: center; position: relative; overflow: hidden; } .avatar-eyes { display: flex; justify-content: space-around; width: 70%; position: relative; margin-bottom: 15px; } .avatar-eye { width: 20px; height: 20px; border-radius: 50%; background: var(--accent-color); position: relative; display: flex; justify-content: center; align-items: center; transition: all 0.3s ease; } .avatar-eye::after { content: ''; width: 8px; height: 8px; background: #fff; border-radius: 50%; position: absolute; } .avatar-mouth { width: 40px; height: 10px; background: var(--accent-color); border-radius: 10px; transition: all 0.3s ease; } .mood-ring { position: absolute; width: 100%; height: 100%; border-radius: 50%; box-shadow: 0 0 15px var(--accent-glow); z-index: -1; opacity: 0.8; background: conic-gradient( var(--happy-color) 0%, var(--sad-color) 20%, var(--busy-color) 40%, var(--chill-color) 60%, var(--focus-color) 80%, var(--happy-color) 100% ); animation: rotate 15s linear infinite; } @keyframes rotate { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } .status-badge { position: absolute; bottom: 10px; right: 10px; width: 40px; height: 40px; border-radius: 50%; background: var(--accent-color); display: flex; justify-content: center; align-items: center; font-size: 20px; box-shadow: 0 0 10px var(--accent-glow); z-index: 2; transition: all 0.3s ease; } .mood-controls { display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; width: 100%; margin-top: 20px; z-index: 1; } .mood-btn { padding: 12px 20px; border: none; border-radius: 30px; font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 8px; transition: all 0.3s ease; color: white; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); } .mood-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3); } .mood-btn:active { transform: translateY(1px); } .btn-happy { background-color: var(--happy-color); } .btn-sad { background-color: var(--sad-color); } .btn-busy { background-color: var(--busy-color); } .btn-chill { background-color: var(--chill-color); } .btn-focus { background-color: var(--focus-color); } .badge-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 15px; margin-top: 20px; z-index: 1; } .badge-btn { width: 50px; height: 50px; border-radius: 50%; border: 2px solid var(--secondary-bg); display: flex; justify-content: center; align-items: center; font-size: 20px; cursor: pointer; transition: all 0.3s ease; background-color: var(--primary-bg); color: white; } .badge-btn:hover { transform: scale(1.1); box-shadow: 0 0 15px var(--accent-glow); } .feature-section { display: flex; flex-direction: column; gap: 20px; width: 100%; margin-top: 20px; } .feature-card { background-color: var(--secondary-bg); padding: 20px; border-radius: 15px; display: flex; align-items: center; gap: 15px; transition: all 0.3s ease; cursor: pointer; } .feature-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); } .feature-icon { min-width: 50px; height: 50px; border-radius: 12px; display: flex; justify-content: center; align-items: center; font-size: 24px; background: var(--accent-color); box-shadow: 0 0 10px var(--accent-glow); } .feature-text { flex: 1; } .feature-text h3 { margin-bottom: 5px; font-size: 1.1rem; } .feature-text p { opacity: 0.8; font-size: 0.9rem; text-align: left; } /* Responsive styles */ @media (max-width: 600px) { h1 { font-size: 1.8rem; } .avatar-container { width: 150px; height: 150px; } .avatar-stage { padding: 20px; } .mood-btn { padding: 10px 15px; font-size: 0.9rem; } .badge-btn { width: 40px; height: 40px; font-size: 16px; } } /* Animation classes */ .happy-avatar .avatar-mouth { width: 50px; height: 20px; border-radius: 0 0 20px 20px; background: var(--happy-color); } .happy-avatar .avatar-eye { background: var(--happy-color); height: 15px; } .sad-avatar .avatar-mouth { width: 50px; height: 20px; border-radius: 20px 20px 0 0; background: var(--sad-color); transform: translateY(10px); } .sad-avatar .avatar-eye { background: var(--sad-color); transform: scaleY(0.8); } .busy-avatar .avatar-mouth { width: 30px; height: 5px; border-radius: 5px; background: var(--busy-color); } .busy-avatar .avatar-eye { background: var(--busy-color); animation: blink 2s infinite; } @keyframes blink { 0%, 95%, 100% { transform: scaleY(1); } 97% { transform: scaleY(0.1); } } .chill-avatar .avatar-mouth { width: 40px; height: 10px; border-radius: 10px; background: var(--chill-color); transform: translateY(2px); } .chill-avatar .avatar-eye { background: var(--chill-color); transform: scaleY(0.7); } .focus-avatar .avatar-mouth { width: 25px; height: 8px; border-radius: 5px; background: var(--focus-color); } .focus-avatar .avatar-eye { background: var(--focus-color); transform: scale(1.2); } /* Badge active state */ .badge-active { transform: scale(1.1); box-shadow: 0 0 15px var(--accent-glow); background: var(--accent-color); } /* Pulse animation for active status */ .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 var(--accent-glow); } 70% { box-shadow: 0 0 0 10px rgba(123, 66, 246, 0); } 100% { box-shadow: 0 0 0 0 rgba(123, 66, 246, 0); } } .tooltip { position: absolute; top: -40px; left: 50%; transform: translateX(-50%); background: var(--secondary-bg); padding: 8px 15px; border-radius: 20px; font-size: 14px; opacity: 0; pointer-events: none; transition: all 0.3s ease; white-space: nowrap; } .tooltip.show { opacity: 1; top: -50px; } .tooltip::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 10px; height: 10px; background: var(--secondary-bg); transform: rotate(45deg); } </style> </head> <body> <div class="container"> <header> <h1>Moodvatar</h1> <p>Express yourself without words. Choose your mood and status badge to let others know how you're feeling in chatsโwhether you're focused, chilling, or just too busy to reply right away.</p> </header> <div class="avatar-stage"> <div class="avatar-container"> <div class="mood-ring"></div> <div class="avatar"> <div class="avatar-face"> <div class="avatar-eyes"> <div class="avatar-eye"></div> <div class="avatar-eye"></div> </div> <div class="avatar-mouth"></div> </div> </div> <div class="status-badge pulse">๐</div> <div class="tooltip">Your current mood: Happy</div> </div> <div class="mood-controls"> <button class="mood-btn btn-happy" data-mood="happy">๐ Happy</button> <button class="mood-btn btn-sad" data-mood="sad">๐ Sad</button> <button class="mood-btn btn-busy" data-mood="busy">โฑ๏ธ Busy</button> <button class="mood-btn btn-chill" data-mood="chill">๐ Chill</button> <button class="mood-btn btn-focus" data-mood="focus">๐ง Focused</button> </div> <div class="badge-container"> <button class="badge-btn badge-active" data-badge="๐">๐</button> <button class="badge-btn" data-badge="๐ฑ">๐ฑ</button> <button class="badge-btn" data-badge="๐ฎ">๐ฎ</button> <button class="badge-btn" data-badge="๐ค">๐ค</button> <button class="badge-btn" data-badge="๐ง">๐ง</button> <button class="badge-btn" data-badge="๐">๐</button> </div> </div> <div class="feature-section"> <div class="feature-card"> <div class="feature-icon">๐ญ</div> <div class="feature-text"> <h3>Mood Reflection</h3> <p>Your avatar subtly changes expression to match your current vibe, helping friends understand your mood at a glance.</p> </div> </div> <div class="feature-card"> <div class="feature-icon">โก</div> <div class="feature-text"> <h3>Dynamic Status Badges</h3> <p>Add context to your availability with interactive status badges that glow when you're actively chatting.</p> </div> </div> <div class="feature-card"> <div class="feature-icon">โจ</div> <div class="feature-text"> <h3>Animated Mood Ring</h3> <p>The subtle mood ring animation reflects your emotional state, adding depth to your digital presence.</p> </div> </div> </div> </div> <script> // DOM elements const avatar = document.querySelector('.avatar'); const statusBadge = document.querySelector('.status-badge'); const tooltip = document.querySelector('.tooltip'); const moodButtons = document.querySelectorAll('.mood-btn'); const badgeButtons = document.querySelectorAll('.badge-btn'); // Current state let currentMood = 'happy'; let currentBadge = '๐'; // Update avatar based on mood function updateAvatar(mood) { // First remove all mood classes avatar.classList.remove('happy-avatar', 'sad-avatar', 'busy-avatar', 'chill-avatar', 'focus-avatar'); // Add the new mood class avatar.classList.add(`${mood}-avatar`); // Update tooltip text tooltip.textContent = `Your current mood: ${mood.charAt(0).toUpperCase() + mood.slice(1)}`; // Get color variable based on mood const moodColor = getComputedStyle(document.documentElement).getPropertyValue(`--${mood}-color`); // Update status badge glow color statusBadge.style.boxShadow = `0 0 10px ${moodColor}`; currentMood = mood; // Show tooltip temporarily tooltip.classList.add('show'); setTimeout(() => { tooltip.classList.remove('show'); }, 2000); } // Update badge function updateBadge(badge) { statusBadge.textContent = badge; currentBadge = badge; // Animate badge change statusBadge.classList.remove('pulse'); void statusBadge.offsetWidth; // Trigger reflow statusBadge.classList.add('pulse'); } // Event listeners for mood buttons moodButtons.forEach(button => { button.addEventListener('click', () => { const mood = button.dataset.mood; updateAvatar(mood); }); // Add hover effect button.addEventListener('mouseenter', () => { tooltip.textContent = `Change mood to: ${button.dataset.mood.charAt(0).toUpperCase() + button.dataset.mood.slice(1)}`; tooltip.classList.add('show'); }); button.addEventListener('mouseleave', () => { tooltip.classList.remove('show'); setTimeout(() => { tooltip.textContent = `Your current mood: ${currentMood.charAt(0).toUpperCase() + currentMood.slice(1)}`; }, 300); }); }); // Event listeners for badge buttons badgeButtons.forEach(button => { button.addEventListener('click', () => { // Remove active class from all badges badgeButtons.forEach(b => b.classList.remove('badge-active')); // Add active class to clicked badge button.classList.add('badge-active'); const badge = button.dataset.badge; updateBadge(badge); }); }); // Avatar container hover effect const avatarContainer = document.querySelector('.avatar-container'); avatarContainer.addEventListener('mouseenter', () => { tooltip.classList.add('show'); }); avatarContainer.addEventListener('mouseleave', () => { tooltip.classList.remove('show'); }); // Initialize with happy mood updateAvatar('happy'); // Easter egg - click on the face to make it do a spin animation avatar.addEventListener('click', () => { avatar.style.transform = 'rotate(360deg)'; setTimeout(() => { avatar.style.transform = 'rotate(0)'; }, 1000); }); // Feature cards interaction const featureCards = document.querySelectorAll('.feature-card'); featureCards.forEach(card => { card.addEventListener('click', () => { card.style.backgroundColor = 'var(--accent-color)'; setTimeout(() => { card.style.backgroundColor = ''; }, 500); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #ff4757; --secondary: #2ed573; --dark: #1e272e; --light: #f1f2f6; --accent: #ffa502; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 700px; width: 100%; max-width: 700px; margin: 0 auto; background-color: var(--light); overflow: hidden; } .container { width: 100%; height: 100%; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; } .avatar-container { width: 280px; height: 280px; position: relative; margin: 20px auto 40px; } .avatar-base { width: 100%; height: 100%; border-radius: 50%; background: var(--dark); position: relative; overflow: hidden; box-shadow: 0 8px 30px rgba(30, 39, 46, 0.2); transition: transform 0.3s ease-out; } .avatar-figure { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; position: relative; } .avatar-head { width: 100px; height: 100px; border-radius: 50%; background: var(--light); position: absolute; top: 50px; z-index: 3; } .avatar-body { width: 120px; height: 160px; border-radius: 60px; background: var(--light); position: absolute; top: 130px; z-index: 2; } .avatar-arm-left, .avatar-arm-right { width: 40px; height: 120px; background: var(--light); position: absolute; top: 150px; border-radius: 20px; z-index: 1; transform-origin: top center; } .avatar-arm-left { left: 65px; transform: rotate(25deg); } .avatar-arm-right { right: 65px; transform: rotate(-25deg); } .avatar-leg-left, .avatar-leg-right { width: 45px; height: 130px; background: var(--light); position: absolute; top: 270px; border-radius: 22px; z-index: 1; } .avatar-leg-left { left: 90px; } .avatar-leg-right { right: 90px; } .fitness-circles { position: absolute; width: 100%; height: 100%; border-radius: 50%; z-index: 4; pointer-events: none; } .circle { position: absolute; border-radius: 50%; opacity: 0; transform: scale(0); } .circle-1 { width: 140%; height: 140%; border: 6px solid var(--primary); top: -20%; left: -20%; animation: pulse 2s ease-in-out infinite; } .circle-2 { width: 160%; height: 160%; border: 4px solid var(--secondary); top: -30%; left: -30%; animation: pulse 2s ease-in-out 0.5s infinite; } .circle-3 { width: 180%; height: 180%; border: 3px solid var(--accent); top: -40%; left: -40%; animation: pulse 2s ease-in-out 1s infinite; } @keyframes pulse { 0% { transform: scale(0.3); opacity: 0.8; } 100% { transform: scale(1); opacity: 0; } } .avatar-stats { display: flex; flex-wrap: wrap; justify-content: space-between; width: 100%; max-width: 500px; margin-bottom: 30px; } .stat-box { width: calc(33.33% - 10px); padding: 15px; margin-bottom: 15px; background: white; border-radius: 12px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; cursor: pointer; position: relative; overflow: hidden; } .stat-box:hover { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); } .stat-box:before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 5px; background: linear-gradient(90deg, var(--primary), var(--secondary)); } .stat-number { font-size: 24px; font-weight: 700; color: var(--dark); display: block; margin-bottom: 5px; } .stat-label { font-size: 14px; color: #6c757d; display: block; } .avatar-actions { display: flex; flex-wrap: wrap; justify-content: center; width: 100%; max-width: 500px; } .action-btn { padding: 12px 20px; margin: 0 10px 10px; background: var(--primary); color: white; border: none; border-radius: 50px; font-weight: 600; font-size: 16px; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; z-index: 1; box-shadow: 0 4px 15px rgba(255, 71, 87, 0.3); } .action-btn:hover { transform: translateY(-3px); box-shadow: 0 8px 25px rgba(255, 71, 87, 0.4); } .action-btn:active { transform: translateY(1px); } .action-btn.secondary { background: var(--secondary); box-shadow: 0 4px 15px rgba(46, 213, 115, 0.3); } .action-btn.secondary:hover { box-shadow: 0 8px 25px rgba(46, 213, 115, 0.4); } .action-btn:after { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: 0; background: rgba(255, 255, 255, 0.2); transform: scale(0); transform-origin: center; border-radius: 50%; z-index: -1; transition: transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94); } .action-btn:active:after { transform: scale(2); } .avatar-pulse { animation: avatar-pulse 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.28); } @keyframes avatar-pulse { 0% { transform: scale(1); } 50% { transform: scale(1.1); } 100% { transform: scale(1); } } @media (max-width: 600px) { .avatar-container { width: 220px; height: 220px; margin-bottom: 30px; } .stat-box { width: calc(50% - 10px); } .action-btn { padding: 10px 16px; font-size: 14px; } } @media (max-width: 400px) { .avatar-container { width: 180px; height: 180px; } .avatar-head { width: 80px; height: 80px; top: 40px; } .avatar-body { width: 100px; height: 130px; top: 100px; } .avatar-arm-left, .avatar-arm-right { width: 30px; height: 100px; top: 120px; } .avatar-arm-left { left: 55px; } .avatar-arm-right { right: 55px; } .avatar-leg-left, .avatar-leg-right { width: 35px; height: 100px; top: 220px; } .avatar-leg-left { left: 70px; } .avatar-leg-right { right: 70px; } .stat-box { width: 100%; } } /* Motion Effects */ .avatar-exercising .avatar-arm-left { animation: arm-exercise-left 1s ease-in-out infinite alternate; } .avatar-exercising .avatar-arm-right { animation: arm-exercise-right 1s ease-in-out infinite alternate; } @keyframes arm-exercise-left { 0% { transform: rotate(25deg); } 100% { transform: rotate(-15deg); } } @keyframes arm-exercise-right { 0% { transform: rotate(-25deg); } 100% { transform: rotate(15deg); } } .heartbeat-effect { position: absolute; width: 40px; height: 40px; background: var(--primary); border-radius: 50%; opacity: 0; pointer-events: none; } @keyframes heartbeat { 0% { transform: scale(0); opacity: 0.7; } 50% { opacity: 0.3; } 100% { transform: scale(3); opacity: 0; } } </style> </head> <body> <div class="container"> <div class="avatar-container" id="avatarContainer"> <div class="avatar-base" id="avatarBase"> <div class="avatar-figure"> <div class="avatar-head"></div> <div class="avatar-body"></div> <div class="avatar-arm-left"></div> <div class="avatar-arm-right"></div> <div class="avatar-leg-left"></div> <div class="avatar-leg-right"></div> </div> <div class="fitness-circles"> <div class="circle circle-1"></div> <div class="circle circle-2"></div> <div class="circle circle-3"></div> </div> </div> </div> <div class="avatar-stats"> <div class="stat-box" data-stat="steps"> <span class="stat-number">12,843</span> <span class="stat-label">Daily Steps</span> </div> <div class="stat-box" data-stat="calories"> <span class="stat-number">684</span> <span class="stat-label">Calories Burned</span> </div> <div class="stat-box" data-stat="streak"> <span class="stat-number">14</span> <span class="stat-label">Day Streak</span> </div> <div class="stat-box" data-stat="workouts"> <span class="stat-number">6</span> <span class="stat-label">Workouts This Week</span> </div> <div class="stat-box" data-stat="time"> <span class="stat-number">45</span> <span class="stat-label">Min Active Today</span> </div> <div class="stat-box" data-stat="heart"> <span class="stat-number">72</span> <span class="stat-label">Resting HR (bpm)</span> </div> </div> <div class="avatar-actions"> <button class="action-btn" id="exerciseBtn">Start Workout</button> <button class="action-btn secondary" id="customizeBtn">Customize Avatar</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const avatarBase = document.getElementById('avatarBase'); const exerciseBtn = document.getElementById('exerciseBtn'); const customizeBtn = document.getElementById('customizeBtn'); const avatarContainer = document.getElementById('avatarContainer'); const statBoxes = document.querySelectorAll('.stat-box'); let isExercising = false; const colors = [ '#ff4757', // primary '#2ed573', // secondary '#ffa502', // accent '#5352ed', // blue '#ff6b81', // pink '#1e90ff', // dodger blue '#ff7f50', // coral '#20bf6b' // green ]; // Heartbeat effect on avatar tap avatarBase.addEventListener('click', function(e) { avatarBase.classList.add('avatar-pulse'); // Create heartbeat visual effect const heartbeat = document.createElement('div'); heartbeat.classList.add('heartbeat-effect'); // Position the heartbeat effect at click position relative to avatar const rect = avatarBase.getBoundingClientRect(); const x = e.clientX - rect.left - 20; // Centering the 40px effect const y = e.clientY - rect.top - 20; heartbeat.style.left = `${x}px`; heartbeat.style.top = `${y}px`; heartbeat.style.animation = 'heartbeat 0.8s ease-out forwards'; avatarBase.appendChild(heartbeat); // Remove the effect and class after animation setTimeout(() => { avatarBase.classList.remove('avatar-pulse'); avatarBase.removeChild(heartbeat); }, 800); }); // Toggle exercising animation exerciseBtn.addEventListener('click', function() { isExercising = !isExercising; if (isExercising) { exerciseBtn.textContent = 'End Workout'; avatarBase.classList.add('avatar-exercising'); // Activate pulse circles document.querySelectorAll('.circle').forEach(circle => { circle.style.opacity = '1'; }); } else { exerciseBtn.textContent = 'Start Workout'; avatarBase.classList.remove('avatar-exercising'); // Deactivate pulse circles document.querySelectorAll('.circle').forEach(circle => { circle.style.opacity = '0'; }); } // Button pulse effect addButtonRipple(exerciseBtn); }); // Customize avatar colors customizeBtn.addEventListener('click', function() { const randomColor = colors[Math.floor(Math.random() * colors.length)]; // Change avatar element colors document.querySelectorAll('.avatar-head, .avatar-body, .avatar-arm-left, .avatar-arm-right, .avatar-leg-left, .avatar-leg-right').forEach(el => { el.style.background = randomColor; }); // Button pulse effect addButtonRipple(customizeBtn); }); // Stat box interaction statBoxes.forEach(box => { box.addEventListener('click', function() { // Visual feedback this.style.transform = 'scale(0.95)'; // Update stats with small random change const statNumber = this.querySelector('.stat-number'); const currentValue = parseInt(statNumber.textContent.replace(/,/g, '')); // Different logic for different stat types const statType = this.getAttribute('data-stat'); let newValue; switch(statType) { case 'steps': newValue = currentValue + Math.floor(Math.random() * 200); statNumber.textContent = newValue.toLocaleString(); break; case 'calories': newValue = currentValue + Math.floor(Math.random() * 20); statNumber.textContent = newValue; break; case 'streak': // Streaks usually just increment by 1 newValue = currentValue + 1; statNumber.textContent = newValue; break; case 'workouts': // Workout count increments by 1 newValue = Math.min(currentValue + 1, 7); // Cap at 7 for a week statNumber.textContent = newValue; break; case 'time': newValue = currentValue + Math.floor(Math.random() * 5 + 1); statNumber.textContent = newValue; break; case 'heart': // Heart rate fluctuates up or down const change = Math.floor(Math.random() * 5) * (Math.random() > 0.5 ? 1 : -1); newValue = Math.max(60, Math.min(100, currentValue + change)); statNumber.textContent = newValue; break; } // Reset the transform after animation setTimeout(() => { this.style.transform = ''; }, 300); }); }); // Add ripple effect to buttons function addButtonRipple(button) { button.style.position = 'relative'; button.style.overflow = 'hidden'; const ripple = document.createElement('span'); ripple.style.position = 'absolute'; ripple.style.background = 'rgba(255, 255, 255, 0.3)'; ripple.style.borderRadius = '50%'; ripple.style.transform = 'scale(0)'; ripple.style.animation = 'ripple 0.6s linear'; ripple.style.pointerEvents = 'none'; const buttonRect = button.getBoundingClientRect(); const size = Math.max(buttonRect.width, buttonRect.height); ripple.style.width = ripple.style.height = `${size}px`; ripple.style.left = `${buttonRect.width / 2 - size / 2}px`; ripple.style.top = `${buttonRect.height / 2 - size / 2}px`; button.appendChild(ripple); setTimeout(() => { button.removeChild(ripple); }, 600); } // Add ripple animation const style = document.createElement('style'); style.textContent = ` @keyframes ripple { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(2); opacity: 0; } } `; document.head.appendChild(style); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Rhythm Pulse | Music Avatar Creator</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { width: 100%; height: 100%; background: #090418; color: #fff; display: flex; justify-content: center; align-items: center; overflow: hidden; } .container { width: 700px; height: 700px; display: flex; flex-direction: column; justify-content: center; align-items: center; position: relative; } .avatar-container { width: 300px; height: 300px; border-radius: 50%; position: relative; display: flex; justify-content: center; align-items: center; overflow: hidden; box-shadow: 0 0 30px rgba(149, 0, 255, 0.3); transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275); cursor: pointer; z-index: 10; } .avatar-container:hover { transform: scale(1.05); box-shadow: 0 0 50px rgba(149, 0, 255, 0.5); } .avatar { width: 100%; height: 100%; border-radius: 50%; background: radial-gradient(circle, #3a0ca3 0%, #7209b7 50%, #f72585 100%); position: relative; overflow: hidden; } .waveform { position: absolute; width: 100%; height: 100%; top: 0; left: 0; display: flex; flex-direction: column; justify-content: center; align-items: center; opacity: 0.7; } .wave { width: 100%; height: 2px; background: rgba(255, 255, 255, 0.2); margin: 2px 0; transform-origin: center; transform: scaleX(0.3); border-radius: 4px; transition: transform 0.2s; } .sound-icon { position: absolute; width: 60px; height: 60px; background: rgba(255, 255, 255, 0.9); border-radius: 50%; display: flex; justify-content: center; align-items: center; z-index: 2; } .sound-icon::before { content: ""; width: 0; height: 0; border-top: 15px solid transparent; border-bottom: 15px solid transparent; border-left: 25px solid #7209b7; transform: translateX(3px); } .pulse { position: absolute; width: 100%; height: 100%; border-radius: 50%; background: transparent; border: 2px solid rgba(255, 255, 255, 0.5); animation: pulse 2s infinite; z-index: 1; } @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 50% { transform: scale(1.1); opacity: 0.3; } 100% { transform: scale(0.95); opacity: 0.7; } } .audio-circles { position: absolute; width: 700px; height: 700px; display: flex; justify-content: center; align-items: center; } .circle { position: absolute; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.1); transition: all 0.5s ease; } .controls { margin-top: 30px; display: flex; flex-direction: column; align-items: center; z-index: 10; } .slider-container { display: flex; flex-direction: column; gap: 20px; margin: 25px 0; width: 300px; } .slider-group { display: flex; flex-direction: column; gap: 8px; } .slider-label { display: flex; justify-content: space-between; font-size: 14px; color: rgba(255, 255, 255, 0.7); } .slider { -webkit-appearance: none; width: 100%; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.1); outline: none; cursor: pointer; } .slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 50%; background: #f72585; cursor: pointer; transition: all 0.2s; } .slider::-webkit-slider-thumb:hover { transform: scale(1.2); background: #ff5caa; } .button { background: linear-gradient(135deg, #7209b7, #3a0ca3); color: white; border: none; padding: 12px 24px; border-radius: 30px; font-size: 16px; font-weight: 600; cursor: pointer; transition: all 0.3s; margin-top: 10px; box-shadow: 0 4px 15px rgba(114, 9, 183, 0.3); } .button:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(114, 9, 183, 0.4); } .title { font-size: 28px; font-weight: 700; margin-bottom: 10px; text-align: center; background: linear-gradient(to right, #f72585, #7209b7, #3a0ca3); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; position: relative; z-index: 10; } .subtitle { font-size: 16px; color: rgba(255, 255, 255, 0.7); text-align: center; max-width: 400px; margin-bottom: 30px; line-height: 1.5; position: relative; z-index: 10; } @media (max-width: 700px) { .container { width: 100%; padding: 20px; } .avatar-container { width: 200px; height: 200px; } .slider-container { width: 250px; } .title { font-size: 24px; } .subtitle { font-size: 14px; max-width: 300px; } } .frequency-bar { position: absolute; bottom: 0; left: 0; width: 100%; height: 50px; display: flex; justify-content: center; align-items: flex-end; padding: 0 20px; z-index: 9; } .bar { width: 5px; background: linear-gradient(to top, #f72585, transparent); border-radius: 3px 3px 0 0; margin: 0 2px; transition: height 0.2s ease; } </style> </head> <body> <div class="container"> <h1 class="title">Rhythm Pulse</h1> <p class="subtitle">Create a unique avatar that moves to your music's rhythm. Adjust the intensity and watch the waveforms dance.</p> <div class="audio-circles"> <div class="circle" style="width: 350px; height: 350px;"></div> <div class="circle" style="width: 400px; height: 400px;"></div> <div class="circle" style="width: 450px; height: 450px;"></div> <div class="circle" style="width: 500px; height: 500px;"></div> <div class="circle" style="width: 550px; height: 550px;"></div> </div> <div class="avatar-container" id="avatarContainer"> <div class="avatar" id="avatar"> <div class="waveform" id="waveform"></div> <div class="sound-icon"></div> <div class="pulse"></div> </div> </div> <div class="controls"> <div class="slider-container"> <div class="slider-group"> <div class="slider-label"> <span>Beat Intensity</span> <span id="beatValue">5</span> </div> <input type="range" min="1" max="10" value="5" class="slider" id="beatSlider"> </div> <div class="slider-group"> <div class="slider-label"> <span>Frequency Range</span> <span id="freqValue">6</span> </div> <input type="range" min="1" max="10" value="6" class="slider" id="freqSlider"> </div> </div> <button class="button" id="generateBtn">Generate Avatar</button> </div> <div class="frequency-bar" id="frequencyBar"></div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Generate waveform const waveform = document.getElementById('waveform'); const avatar = document.getElementById('avatar'); const avatarContainer = document.getElementById('avatarContainer'); const beatSlider = document.getElementById('beatSlider'); const freqSlider = document.getElementById('freqSlider'); const beatValue = document.getElementById('beatValue'); const freqValue = document.getElementById('freqValue'); const generateBtn = document.getElementById('generateBtn'); const frequencyBar = document.getElementById('frequencyBar'); const circles = document.querySelectorAll('.circle'); let isPlaying = false; let animationFrame; let wavesCount = 30; // Create initial waves function createWaves() { waveform.innerHTML = ''; for (let i = 0; i < wavesCount; i++) { const wave = document.createElement('div'); wave.className = 'wave'; waveform.appendChild(wave); } updateWaves(); } // Create frequency bars function createFrequencyBars() { frequencyBar.innerHTML = ''; const barCount = 40; for (let i = 0; i < barCount; i++) { const bar = document.createElement('div'); bar.className = 'bar'; bar.style.height = '0px'; frequencyBar.appendChild(bar); } } // Update waves animation function updateWaves() { const waves = document.querySelectorAll('.wave'); const beatIntensity = beatSlider.value / 10; waves.forEach((wave, index) => { const randomScale = 0.3 + Math.random() * beatIntensity; wave.style.transform = `scaleX(${randomScale})`; // Random color const hue = 280 + Math.random() * 60; wave.style.background = `hsla(${hue}, 90%, 70%, ${0.2 + beatIntensity * 0.5})`; }); // Update frequency bars const bars = document.querySelectorAll('.bar'); const freqRange = freqSlider.value; bars.forEach((bar) => { const randomHeight = Math.random() * freqRange * 4; bar.style.height = `${randomHeight}px`; }); // Make circles pulse with the beat circles.forEach((circle, index) => { const factor = 1 + (Math.sin(Date.now() / 1000 + index) * 0.05 * beatIntensity); circle.style.transform = `scale(${factor})`; // Random color based on frequency const hue = 280 + (index * 10) + (Math.random() * 20); circle.style.borderColor = `hsla(${hue}, 70%, 60%, ${0.05 + (index * 0.02)})`; }); if (isPlaying) { animationFrame = requestAnimationFrame(updateWaves); } } // Initialize createWaves(); createFrequencyBars(); // Event listeners beatSlider.addEventListener('input', function() { beatValue.textContent = this.value; updateWaves(); }); freqSlider.addEventListener('input', function() { freqValue.textContent = this.value; updateWaves(); }); avatarContainer.addEventListener('click', function() { isPlaying = !isPlaying; if (isPlaying) { avatarContainer.style.boxShadow = '0 0 40px rgba(247, 37, 133, 0.7)'; updateWaves(); } else { avatarContainer.style.boxShadow = '0 0 30px rgba(149, 0, 255, 0.3)'; cancelAnimationFrame(animationFrame); } }); generateBtn.addEventListener('click', function() { // Generate new colors const hue1 = Math.floor(Math.random() * 60) + 240; // Blue to purple range const hue2 = Math.floor(Math.random() * 60) + 280; // Purple to pink range const hue3 = Math.floor(Math.random() * 30) + 330; // Pink to red range avatar.style.background = `radial-gradient(circle, hsl(${hue1}, 90%, 35%) 0%, hsl(${hue2}, 85%, 40%) 50%, hsl(${hue3}, 90%, 55%) 100%)`; // Trigger animation isPlaying = true; avatarContainer.style.boxShadow = '0 0 40px rgba(247, 37, 133, 0.7)'; updateWaves(); // Visual feedback animation avatarContainer.style.transform = 'scale(1.1)'; setTimeout(() => { avatarContainer.style.transform = 'scale(1)'; }, 200); }); // Mouse move effect on avatar avatarContainer.addEventListener('mousemove', function(e) { const rect = this.getBoundingClientRect(); const x = e.clientX - rect.left - rect.width / 2; const y = e.clientY - rect.top - rect.height / 2; // Limit tilt to 10 degrees const tiltX = Math.max(Math.min(y / 10, 10), -10); const tiltY = Math.max(Math.min(-x / 10, 10), -10); avatar.style.transform = `perspective(1000px) rotateX(${tiltX}deg) rotateY(${tiltY}deg)`; }); avatarContainer.addEventListener('mouseleave', function() { avatar.style.transform = 'perspective(1000px) rotateX(0) rotateY(0)'; }); }); </script> </body> </html>