| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Pokemon Sprite Expression Animator</title> |
| <style> |
| * { |
| margin: 0; |
| padding: 0; |
| box-sizing: border-box; |
| } |
| |
| body { |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| min-height: 100vh; |
| padding: 20px; |
| } |
| |
| .container { |
| max-width: 1400px; |
| margin: 0 auto; |
| background: rgba(255, 255, 255, 0.95); |
| border-radius: 20px; |
| padding: 30px; |
| box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); |
| } |
| |
| h1 { |
| text-align: center; |
| color: #333; |
| font-size: 2.5em; |
| margin-bottom: 10px; |
| text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); |
| } |
| |
| .subtitle { |
| text-align: center; |
| color: #666; |
| margin-bottom: 30px; |
| font-size: 1.1em; |
| } |
| |
| .upload-section { |
| background: linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%); |
| padding: 25px; |
| border-radius: 15px; |
| margin-bottom: 30px; |
| text-align: center; |
| border: 3px dashed #ff6b35; |
| } |
| |
| .file-input { |
| margin: 15px 0; |
| } |
| |
| .file-input input[type="file"] { |
| display: none; |
| } |
| |
| .file-label { |
| display: inline-block; |
| padding: 12px 25px; |
| background: #ff6b35; |
| color: white; |
| border-radius: 25px; |
| cursor: pointer; |
| transition: all 0.3s ease; |
| font-weight: bold; |
| } |
| |
| .file-label:hover { |
| background: #e55a2b; |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(229, 90, 43, 0.3); |
| } |
| |
| .animation-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); |
| gap: 25px; |
| margin-top: 30px; |
| } |
| |
| .animation-card { |
| background: white; |
| border-radius: 15px; |
| padding: 20px; |
| text-align: center; |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); |
| transition: all 0.3s ease; |
| border: 2px solid transparent; |
| } |
| |
| .animation-card:hover { |
| transform: translateY(-5px); |
| box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15); |
| border-color: #667eea; |
| } |
| |
| .animation-title { |
| font-size: 1.2em; |
| color: #333; |
| margin-bottom: 15px; |
| font-weight: bold; |
| } |
| |
| .sprite-container { |
| width: 120px; |
| height: 120px; |
| margin: 0 auto 20px; |
| background: #f0f0f0; |
| border-radius: 10px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| overflow: visible; |
| border: 2px solid #ddd; |
| position: relative; |
| } |
| |
| .sprite { |
| max-width: 100%; |
| max-height: 100%; |
| image-rendering: pixelated; |
| } |
| |
| .demo-sprite { |
| width: 80px; |
| height: 80px; |
| background: linear-gradient(45deg, #ff6b6b, #4ecdc4); |
| border-radius: 50%; |
| position: relative; |
| } |
| |
| .demo-sprite::before { |
| content: '🎮'; |
| position: absolute; |
| top: 50%; |
| left: 50%; |
| transform: translate(-50%, -50%); |
| font-size: 2em; |
| } |
| |
| .apply-btn { |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| color: white; |
| border: none; |
| padding: 10px 20px; |
| border-radius: 25px; |
| cursor: pointer; |
| font-weight: bold; |
| transition: all 0.3s ease; |
| width: 100%; |
| } |
| |
| .apply-btn:hover { |
| transform: translateY(-2px); |
| box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3); |
| } |
| |
| .apply-btn:disabled { |
| background: #ccc; |
| cursor: not-allowed; |
| transform: none; |
| box-shadow: none; |
| } |
| |
| |
| .idle-bounce { |
| animation: idleBounce 2s ease-in-out infinite; |
| } |
| |
| .happy-bounce { |
| animation: happyBounce 0.6s ease-in-out infinite; |
| } |
| |
| .excited-shake { |
| animation: excitedShake 0.5s ease-in-out infinite; |
| } |
| |
| .sad-droop { |
| animation: sadDroop 3s ease-in-out infinite; |
| } |
| |
| .angry-shake { |
| animation: angryShake 0.3s ease-in-out infinite; |
| } |
| |
| .confused-tilt { |
| animation: confusedTilt 2s ease-in-out infinite; |
| } |
| |
| .sleepy-sway { |
| animation: sleepySway 4s ease-in-out infinite; |
| } |
| |
| .alert-pulse { |
| animation: alertPulse 1s ease-in-out infinite; |
| } |
| |
| .hurt-flash { |
| animation: hurtFlash 0.8s ease-in-out infinite; |
| } |
| |
| .victory-spin { |
| animation: victorySpin 1.5s ease-in-out infinite; |
| } |
| |
| .charging-glow { |
| animation: chargingGlow 1.2s ease-in-out infinite; |
| } |
| |
| .dizzy-wobble { |
| animation: dizzyWobble 1s ease-in-out infinite; |
| } |
| |
| .attack-lunge { |
| animation: attackLunge 1.5s ease-in-out infinite; |
| } |
| |
| .defend-crouch { |
| animation: defendCrouch 2s ease-in-out infinite; |
| } |
| |
| .love-hearts { |
| animation: loveHearts 2s ease-in-out infinite; |
| } |
| |
| .fear-tremble { |
| animation: fearTremble 0.4s ease-in-out infinite; |
| } |
| |
| .evolving-glow { |
| animation: evolvingGlow 2s ease-in-out infinite; |
| } |
| |
| .fainting-fall { |
| animation: faintingFall 3s ease-in-out infinite; |
| } |
| |
| .turn-left { |
| animation: turnLeft 2s ease-in-out infinite; |
| } |
| |
| .turn-right { |
| animation: turnRight 2s ease-in-out infinite; |
| } |
| |
| .look-around { |
| animation: lookAround 4s ease-in-out infinite; |
| } |
| |
| .confetti-effect { |
| animation: confettiSpin 2s ease-in-out infinite; |
| } |
| |
| .hearts-float { |
| animation: heartsFloat 3s ease-in-out infinite; |
| } |
| |
| .lightning-strike { |
| animation: lightningStrike 1.5s ease-in-out infinite; |
| } |
| |
| .sparkle-magic { |
| animation: sparkleMagic 2s ease-in-out infinite; |
| } |
| |
| .fire-burst { |
| animation: fireBurst 1.8s ease-in-out infinite; |
| } |
| |
| .ice-crystals { |
| animation: iceCrystals 2.5s ease-in-out infinite; |
| } |
| |
| .poison-bubbles { |
| animation: poisonBubbles 3s ease-in-out infinite; |
| } |
| |
| .healing-aura { |
| animation: healingAura 2.8s ease-in-out infinite; |
| } |
| |
| |
| .particles { |
| position: absolute; |
| top: 0; |
| left: 0; |
| width: 100%; |
| height: 100%; |
| pointer-events: none; |
| overflow: visible; |
| } |
| |
| .particle { |
| position: absolute; |
| border-radius: 50%; |
| } |
| |
| .confetti-particle { |
| width: 6px; |
| height: 6px; |
| animation: confettifall 2s linear infinite; |
| } |
| |
| .heart-particle { |
| width: 12px; |
| height: 12px; |
| animation: heartFloat 3s ease-in-out infinite; |
| color: #ff69b4; |
| } |
| |
| .heart-particle::before { |
| content: '💖'; |
| font-size: 12px; |
| } |
| |
| .lightning-particle { |
| width: 2px; |
| height: 20px; |
| background: linear-gradient(to bottom, #ffff00, #4169e1); |
| animation: lightningFlash 0.3s ease-in-out infinite; |
| border-radius: 1px; |
| } |
| |
| .sparkle-particle { |
| width: 4px; |
| height: 4px; |
| background: #ffd700; |
| animation: sparkleShine 1.5s ease-in-out infinite; |
| box-shadow: 0 0 6px #ffd700; |
| } |
| |
| .fire-particle { |
| width: 8px; |
| height: 8px; |
| background: radial-gradient(circle, #ff4500, #ff8c00); |
| animation: fireRise 1.8s ease-out infinite; |
| } |
| |
| .ice-particle { |
| width: 6px; |
| height: 6px; |
| background: linear-gradient(45deg, #00bfff, #87ceeb); |
| animation: iceFall 2.5s linear infinite; |
| transform: rotate(45deg); |
| } |
| |
| .poison-particle { |
| width: 10px; |
| height: 10px; |
| background: radial-gradient(circle, #9932cc, #8b008b); |
| animation: poisonBubble 3s ease-in-out infinite; |
| } |
| |
| .heal-particle { |
| width: 5px; |
| height: 5px; |
| background: radial-gradient(circle, #32cd32, #90ee90); |
| animation: healFloat 2.8s ease-in-out infinite; |
| box-shadow: 0 0 8px #32cd32; |
| } |
| |
| |
| @keyframes idleBounce { |
| 0%, 100% { transform: translateY(0px); } |
| 50% { transform: translateY(-8px); } |
| } |
| |
| @keyframes happyBounce { |
| 0%, 100% { transform: translateY(0px) scale(1); } |
| 50% { transform: translateY(-15px) scale(1.1); } |
| } |
| |
| @keyframes excitedShake { |
| 0%, 100% { transform: translateX(0px); } |
| 25% { transform: translateX(-5px) rotate(-2deg); } |
| 75% { transform: translateX(5px) rotate(2deg); } |
| } |
| |
| @keyframes sadDroop { |
| 0%, 100% { transform: translateY(0px) scaleY(1); } |
| 50% { transform: translateY(10px) scaleY(0.9); } |
| } |
| |
| @keyframes angryShake { |
| 0%, 100% { transform: translateX(0px); } |
| 10%, 30%, 50%, 70%, 90% { transform: translateX(-3px); } |
| 20%, 40%, 60%, 80% { transform: translateX(3px); } |
| } |
| |
| @keyframes confusedTilt { |
| 0%, 100% { transform: rotate(0deg); } |
| 25% { transform: rotate(-10deg); } |
| 75% { transform: rotate(10deg); } |
| } |
| |
| @keyframes sleepySway { |
| 0%, 100% { transform: rotate(0deg) translateY(0px); } |
| 25% { transform: rotate(-5deg) translateY(5px); } |
| 75% { transform: rotate(5deg) translateY(5px); } |
| } |
| |
| @keyframes alertPulse { |
| 0%, 100% { transform: scale(1); } |
| 50% { transform: scale(1.15); } |
| } |
| |
| @keyframes hurtFlash { |
| 0%, 100% { opacity: 1; filter: brightness(1); } |
| 50% { opacity: 0.7; filter: brightness(1.5) hue-rotate(0deg); } |
| } |
| |
| @keyframes victorySpin { |
| 0% { transform: rotate(0deg) scale(1); } |
| 50% { transform: rotate(180deg) scale(1.2); } |
| 100% { transform: rotate(360deg) scale(1); } |
| } |
| |
| @keyframes chargingGlow { |
| 0%, 100% { filter: brightness(1) saturate(1); transform: scale(1); } |
| 50% { filter: brightness(1.3) saturate(1.5); transform: scale(1.05); } |
| } |
| |
| @keyframes dizzyWobble { |
| 0%, 100% { transform: rotate(0deg); } |
| 25% { transform: rotate(-15deg) translateX(-5px); } |
| 50% { transform: rotate(0deg) translateX(0px); } |
| 75% { transform: rotate(15deg) translateX(5px); } |
| } |
| |
| @keyframes attackLunge { |
| 0%, 100% { transform: translateX(0px) scaleX(1); } |
| 30% { transform: translateX(-10px) scaleX(0.9); } |
| 60% { transform: translateX(15px) scaleX(1.1); } |
| } |
| |
| @keyframes defendCrouch { |
| 0%, 100% { transform: scaleY(1) translateY(0px); } |
| 50% { transform: scaleY(0.8) translateY(10px); } |
| } |
| |
| @keyframes loveHearts { |
| 0%, 100% { transform: scale(1); filter: hue-rotate(0deg); } |
| 50% { transform: scale(1.1); filter: hue-rotate(20deg); } |
| } |
| |
| @keyframes fearTremble { |
| 0%, 100% { transform: translateX(0px) translateY(0px); } |
| 10%, 30%, 50%, 70%, 90% { transform: translateX(-2px) translateY(-1px); } |
| 20%, 40%, 60%, 80% { transform: translateX(2px) translateY(1px); } |
| } |
| |
| @keyframes evolvingGlow { |
| 0%, 100% { |
| filter: brightness(1) contrast(1); |
| transform: scale(1); |
| } |
| 50% { |
| filter: brightness(1.5) contrast(1.2); |
| transform: scale(1.1); |
| } |
| } |
| |
| @keyframes faintingFall { |
| 0%, 70% { transform: rotate(0deg) translateY(0px); opacity: 1; } |
| 100% { transform: rotate(90deg) translateY(20px); opacity: 0.3; } |
| } |
| |
| |
| @keyframes turnLeft { |
| 0%, 100% { transform: scaleX(1); } |
| 50% { transform: scaleX(-1); } |
| } |
| |
| @keyframes turnRight { |
| 0%, 100% { transform: scaleX(-1); } |
| 50% { transform: scaleX(1); } |
| } |
| |
| @keyframes lookAround { |
| 0%, 100% { transform: scaleX(1); } |
| 25% { transform: scaleX(-1); } |
| 50% { transform: scaleX(1); } |
| 75% { transform: scaleX(-1); } |
| } |
| |
| |
| @keyframes confettiSpin { |
| 0%, 100% { transform: translateY(0px) rotate(0deg) scale(1); } |
| 50% { transform: translateY(-10px) rotate(180deg) scale(1.1); } |
| } |
| |
| @keyframes heartsFloat { |
| 0%, 100% { transform: translateY(0px) scale(1); } |
| 50% { transform: translateY(-8px) scale(1.05); } |
| } |
| |
| @keyframes lightningStrike { |
| 0%, 90%, 100% { filter: brightness(1) contrast(1); } |
| 10%, 20%, 30% { filter: brightness(2) contrast(1.5) hue-rotate(60deg); } |
| } |
| |
| @keyframes sparkleMagic { |
| 0%, 100% { transform: rotate(0deg) scale(1); filter: brightness(1); } |
| 50% { transform: rotate(180deg) scale(1.1); filter: brightness(1.3); } |
| } |
| |
| @keyframes fireBurst { |
| 0%, 100% { transform: scale(1); filter: hue-rotate(0deg) brightness(1); } |
| 50% { transform: scale(1.1); filter: hue-rotate(30deg) brightness(1.2); } |
| } |
| |
| @keyframes iceCrystals { |
| 0%, 100% { transform: rotate(0deg) scale(1); filter: brightness(1) saturate(1); } |
| 50% { transform: rotate(180deg) scale(1.05); filter: brightness(1.2) saturate(1.3); } |
| } |
| |
| @keyframes poisonBubbles { |
| 0%, 100% { transform: translateY(0px) scale(1); filter: hue-rotate(0deg); } |
| 50% { transform: translateY(-5px) scale(1.03); filter: hue-rotate(30deg); } |
| } |
| |
| @keyframes healingAura { |
| 0%, 100% { transform: scale(1); filter: brightness(1) saturate(1); } |
| 50% { transform: scale(1.05); filter: brightness(1.2) saturate(1.4); } |
| } |
| |
| |
| @keyframes confettifall { |
| 0% { |
| transform: translateY(-20px) rotate(0deg); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(140px) rotate(360deg); |
| opacity: 0; |
| } |
| } |
| |
| @keyframes heartFloat { |
| 0% { |
| transform: translateY(20px) scale(0.5); |
| opacity: 0; |
| } |
| 50% { |
| opacity: 1; |
| transform: translateY(-10px) scale(1); |
| } |
| 100% { |
| transform: translateY(-40px) scale(0.8); |
| opacity: 0; |
| } |
| } |
| |
| @keyframes lightningFlash { |
| 0%, 100% { opacity: 0; } |
| 50% { opacity: 1; } |
| } |
| |
| @keyframes sparkleShine { |
| 0%, 100% { |
| transform: scale(0.5) rotate(0deg); |
| opacity: 0.5; |
| } |
| 50% { |
| transform: scale(1.2) rotate(180deg); |
| opacity: 1; |
| } |
| } |
| |
| @keyframes fireRise { |
| 0% { |
| transform: translateY(20px) scale(1); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(-30px) scale(0.3); |
| opacity: 0; |
| } |
| } |
| |
| @keyframes iceFall { |
| 0% { |
| transform: translateY(-20px) rotate(45deg) scale(1); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(140px) rotate(405deg) scale(0.5); |
| opacity: 0; |
| } |
| } |
| |
| @keyframes poisonBubble { |
| 0% { |
| transform: translateY(20px) scale(0.5); |
| opacity: 0.7; |
| } |
| 50% { |
| transform: translateY(0px) scale(1); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(-20px) scale(0.3); |
| opacity: 0; |
| } |
| } |
| |
| @keyframes healFloat { |
| 0% { |
| transform: translateY(10px) scale(0.5); |
| opacity: 0.5; |
| } |
| 50% { |
| transform: translateY(-5px) scale(1); |
| opacity: 1; |
| } |
| 100% { |
| transform: translateY(-20px) scale(0.7); |
| opacity: 0; |
| } |
| } |
| |
| .description { |
| font-size: 0.9em; |
| color: #666; |
| margin-bottom: 15px; |
| line-height: 1.4; |
| } |
| |
| .controls { |
| display: flex; |
| gap: 10px; |
| margin-top: 15px; |
| } |
| |
| .speed-control { |
| flex: 1; |
| } |
| |
| .speed-control select { |
| width: 100%; |
| padding: 5px; |
| border: 1px solid #ddd; |
| border-radius: 5px; |
| } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <h1>🎮 Pokemon Sprite Expression Animator</h1> |
| <p class="subtitle">Upload your sprite and test various Pokemon-style animations</p> |
| |
| <div class="upload-section"> |
| <h3>Upload Your Sprite</h3> |
| <div class="file-input"> |
| <label for="sprite-upload" class="file-label">Choose Sprite Image</label> |
| <input type="file" id="sprite-upload" accept="image/*"> |
| </div> |
| <p>Supports PNG, JPG, GIF - Best results with square sprites (64x64 to 256x256px)</p> |
| </div> |
|
|
| <div class="animation-grid" id="animationGrid"> |
| |
| </div> |
| </div> |
|
|
| <script> |
| const animations = [ |
| { |
| name: 'Idle Bounce', |
| class: 'idle-bounce', |
| description: 'Gentle up-down bounce for idle state' |
| }, |
| { |
| name: 'Happy Bounce', |
| class: 'happy-bounce', |
| description: 'Excited bouncing with slight scaling' |
| }, |
| { |
| name: 'Excited Shake', |
| class: 'excited-shake', |
| description: 'Side-to-side shake with rotation' |
| }, |
| { |
| name: 'Sad Droop', |
| class: 'sad-droop', |
| description: 'Slow drooping motion with vertical squash' |
| }, |
| { |
| name: 'Angry Shake', |
| class: 'angry-shake', |
| description: 'Rapid horizontal shaking' |
| }, |
| { |
| name: 'Confused Tilt', |
| class: 'confused-tilt', |
| description: 'Side-to-side head tilting motion' |
| }, |
| { |
| name: 'Sleepy Sway', |
| class: 'sleepy-sway', |
| description: 'Slow swaying with slight rotation' |
| }, |
| { |
| name: 'Alert Pulse', |
| class: 'alert-pulse', |
| description: 'Quick scaling pulse for attention' |
| }, |
| { |
| name: 'Hurt Flash', |
| class: 'hurt-flash', |
| description: 'Opacity and brightness flashing' |
| }, |
| { |
| name: 'Victory Spin', |
| class: 'victory-spin', |
| description: 'Full rotation with scaling' |
| }, |
| { |
| name: 'Charging Glow', |
| class: 'charging-glow', |
| description: 'Brightness and saturation increase' |
| }, |
| { |
| name: 'Dizzy Wobble', |
| class: 'dizzy-wobble', |
| description: 'Unsteady wobbling motion' |
| }, |
| { |
| name: 'Attack Lunge', |
| class: 'attack-lunge', |
| description: 'Forward lunge motion with stretch' |
| }, |
| { |
| name: 'Defend Crouch', |
| class: 'defend-crouch', |
| description: 'Defensive crouching animation' |
| }, |
| { |
| name: 'Love Hearts', |
| class: 'love-hearts', |
| description: 'Gentle scaling with color shift' |
| }, |
| { |
| name: 'Fear Tremble', |
| class: 'fear-tremble', |
| description: 'Rapid small trembling motion' |
| }, |
| { |
| name: 'Evolving Glow', |
| class: 'evolving-glow', |
| description: 'Mystical glowing evolution effect' |
| }, |
| { |
| name: 'Fainting Fall', |
| class: 'fainting-fall', |
| description: 'Rotation and fade for fainting' |
| }, |
| { |
| name: 'Turn Left', |
| class: 'turn-left', |
| description: 'Smooth horizontal flip to face left' |
| }, |
| { |
| name: 'Turn Right', |
| class: 'turn-right', |
| description: 'Smooth horizontal flip to face right' |
| }, |
| { |
| name: 'Look Around', |
| class: 'look-around', |
| description: 'Turn left and right alternately' |
| }, |
| { |
| name: 'Confetti Celebration', |
| class: 'confetti-effect', |
| description: 'Victory with colorful confetti particles', |
| hasParticles: true |
| }, |
| { |
| name: 'Love Hearts Float', |
| class: 'hearts-float', |
| description: 'Floating heart particles around sprite', |
| hasParticles: true |
| }, |
| { |
| name: 'Lightning Strike', |
| class: 'lightning-strike', |
| description: 'Electric attack with lightning effects', |
| hasParticles: true |
| }, |
| { |
| name: 'Sparkle Magic', |
| class: 'sparkle-magic', |
| description: 'Magical sparkles surrounding sprite', |
| hasParticles: true |
| }, |
| { |
| name: 'Fire Burst', |
| class: 'fire-burst', |
| description: 'Fire attack with flame particles', |
| hasParticles: true |
| }, |
| { |
| name: 'Ice Crystals', |
| class: 'ice-crystals', |
| description: 'Ice attack with crystal particles', |
| hasParticles: true |
| }, |
| { |
| name: 'Poison Bubbles', |
| class: 'poison-bubbles', |
| description: 'Toxic bubbles floating around', |
| hasParticles: true |
| }, |
| { |
| name: 'Healing Aura', |
| class: 'healing-aura', |
| description: 'Gentle healing particles', |
| hasParticles: true |
| } |
| ]; |
| |
| let uploadedImage = null; |
| |
| function createAnimationCard(animation) { |
| const particleHTML = animation.hasParticles ? '<div class="particles" id="particles-' + animation.class + '"></div>' : ''; |
| |
| return ` |
| <div class="animation-card"> |
| <div class="animation-title">${animation.name}</div> |
| <div class="sprite-container"> |
| ${uploadedImage |
| ? `<img src="${uploadedImage}" class="sprite ${animation.class}" alt="Animated sprite">` |
| : `<div class="demo-sprite ${animation.class}"></div>` |
| } |
| ${particleHTML} |
| </div> |
| <div class="description">${animation.description}</div> |
| <div class="controls"> |
| <div class="speed-control"> |
| <select onchange="changeSpeed(this, '${animation.class}')"> |
| <option value="0.5">2x Speed</option> |
| <option value="1" selected>Normal</option> |
| <option value="1.5">0.75x Speed</option> |
| <option value="2">0.5x Speed</option> |
| </select> |
| </div> |
| </div> |
| <button class="apply-btn" onclick="copyCSS('${animation.class}')"> |
| Copy CSS |
| </button> |
| </div> |
| `; |
| } |
| |
| function renderAnimations() { |
| const grid = document.getElementById('animationGrid'); |
| grid.innerHTML = animations.map(createAnimationCard).join(''); |
| |
| |
| animations.forEach(animation => { |
| if (animation.hasParticles) { |
| initializeParticles(animation.class); |
| } |
| }); |
| } |
| |
| function initializeParticles(animationClass) { |
| const particleContainer = document.getElementById(`particles-${animationClass}`); |
| if (!particleContainer) return; |
| |
| |
| particleContainer.innerHTML = ''; |
| |
| const particleConfigs = { |
| 'confetti-effect': { |
| count: 8, |
| type: 'confetti', |
| colors: ['#ff6b6b', '#4ecdc4', '#45b7d1', '#96ceb4', '#ffeaa7', '#dda0dd'] |
| }, |
| 'hearts-float': { |
| count: 6, |
| type: 'heart' |
| }, |
| 'lightning-strike': { |
| count: 5, |
| type: 'lightning' |
| }, |
| 'sparkle-magic': { |
| count: 12, |
| type: 'sparkle' |
| }, |
| 'fire-burst': { |
| count: 8, |
| type: 'fire' |
| }, |
| 'ice-crystals': { |
| count: 10, |
| type: 'ice' |
| }, |
| 'poison-bubbles': { |
| count: 6, |
| type: 'poison' |
| }, |
| 'healing-aura': { |
| count: 8, |
| type: 'heal' |
| } |
| }; |
| |
| const config = particleConfigs[animationClass]; |
| if (!config) return; |
| |
| for (let i = 0; i < config.count; i++) { |
| const particle = document.createElement('div'); |
| particle.className = `particle ${config.type}-particle`; |
| |
| |
| const angle = (360 / config.count) * i + Math.random() * 45; |
| const radius = 40 + Math.random() * 20; |
| const x = 50 + Math.cos(angle * Math.PI / 180) * radius; |
| const y = 50 + Math.sin(angle * Math.PI / 180) * radius; |
| |
| particle.style.left = x + '%'; |
| particle.style.top = y + '%'; |
| |
| |
| particle.style.animationDelay = Math.random() * 2 + 's'; |
| |
| |
| if (config.type === 'confetti' && config.colors) { |
| particle.style.backgroundColor = config.colors[Math.floor(Math.random() * config.colors.length)]; |
| } |
| |
| particleContainer.appendChild(particle); |
| } |
| } |
| |
| function changeSpeed(select, animationClass) { |
| const multiplier = parseFloat(select.value); |
| const elements = document.querySelectorAll(`.${animationClass}`); |
| elements.forEach(el => { |
| el.style.animationDuration = `${getOriginalDuration(animationClass) * multiplier}s`; |
| }); |
| } |
| |
| function getOriginalDuration(animationClass) { |
| const durations = { |
| 'idle-bounce': 2, |
| 'happy-bounce': 0.6, |
| 'excited-shake': 0.5, |
| 'sad-droop': 3, |
| 'angry-shake': 0.3, |
| 'confused-tilt': 2, |
| 'sleepy-sway': 4, |
| 'alert-pulse': 1, |
| 'hurt-flash': 0.8, |
| 'victory-spin': 1.5, |
| 'charging-glow': 1.2, |
| 'dizzy-wobble': 1, |
| 'attack-lunge': 1.5, |
| 'defend-crouch': 2, |
| 'love-hearts': 2, |
| 'fear-tremble': 0.4, |
| 'evolving-glow': 2, |
| 'fainting-fall': 3, |
| 'turn-left': 2, |
| 'turn-right': 2, |
| 'look-around': 4, |
| 'confetti-effect': 2, |
| 'hearts-float': 3, |
| 'lightning-strike': 1.5, |
| 'sparkle-magic': 2, |
| 'fire-burst': 1.8, |
| 'ice-crystals': 2.5, |
| 'poison-bubbles': 3, |
| 'healing-aura': 2.8 |
| }; |
| return durations[animationClass] || 1; |
| } |
| |
| function copyCSS(animationClass) { |
| const cssMap = { |
| 'idle-bounce': `.idle-bounce { |
| animation: idleBounce 2s ease-in-out infinite; |
| } |
| |
| @keyframes idleBounce { |
| 0%, 100% { transform: translateY(0px); } |
| 50% { transform: translateY(-8px); } |
| }`, |
| 'happy-bounce': `.happy-bounce { |
| animation: happyBounce 0.6s ease-in-out infinite; |
| } |
| |
| @keyframes happyBounce { |
| 0%, 100% { transform: translateY(0px) scale(1); } |
| 50% { transform: translateY(-15px) scale(1.1); } |
| }`, |
| 'excited-shake': `.excited-shake { |
| animation: excitedShake 0.5s ease-in-out infinite; |
| } |
| |
| @keyframes excitedShake { |
| 0%, 100% { transform: translateX(0px); } |
| 25% { transform: translateX(-5px) rotate(-2deg); } |
| 75% { transform: translateX(5px) rotate(2deg); } |
| }`, |
| 'sad-droop': `.sad-droop { |
| animation: sadDroop 3s ease-in-out infinite; |
| } |
| |
| @keyframes sadDroop { |
| 0%, 100% { transform: translateY(0px) scaleY(1); } |
| 50% { transform: translateY(10px) scaleY(0.9); } |
| }`, |
| 'angry-shake': `.angry-shake { |
| animation: angryShake 0.3s ease-in-out infinite; |
| } |
| |
| @keyframes angryShake { |
| 0%, 100% { transform: translateX(0px); } |
| 10%, 30%, 50%, 70%, 90% { transform: translateX(-3px); } |
| 20%, 40%, 60%, 80% { transform: translateX(3px); } |
| }`, |
| 'confused-tilt': `.confused-tilt { |
| animation: confusedTilt 2s ease-in-out infinite; |
| } |
| |
| @keyframes confusedTilt { |
| 0%, 100% { transform: rotate(0deg); } |
| 25% { transform: rotate(-10deg); } |
| 75% { transform: rotate(10deg); } |
| }`, |
| 'sleepy-sway': `.sleepy-sway { |
| animation: sleepySway 4s ease-in-out infinite; |
| } |
| |
| @keyframes sleepySway { |
| 0%, 100% { transform: rotate(0deg) translateY(0px); } |
| 25% { transform: rotate(-5deg) translateY(5px); } |
| 75% { transform: rotate(5deg) translateY(5px); } |
| }`, |
| 'alert-pulse': `.alert-pulse { |
| animation: alertPulse 1s ease-in-out infinite; |
| } |
| |
| @keyframes alertPulse { |
| 0%, 100% { transform: scale(1); } |
| 50% { transform: scale(1.15); } |
| }`, |
| 'hurt-flash': `.hurt-flash { |
| animation: hurtFlash 0.8s ease-in-out infinite; |
| } |
| |
| @keyframes hurtFlash { |
| 0%, 100% { opacity: 1; filter: brightness(1); } |
| 50% { opacity: 0.7; filter: brightness(1.5); } |
| }`, |
| 'victory-spin': `.victory-spin { |
| animation: victorySpin 1.5s ease-in-out infinite; |
| } |
| |
| @keyframes victorySpin { |
| 0% { transform: rotate(0deg) scale(1); } |
| 50% { transform: rotate(180deg) scale(1.2); } |
| 100% { transform: rotate(360deg) scale(1); } |
| }`, |
| 'charging-glow': `.charging-glow { |
| animation: chargingGlow 1.2s ease-in-out infinite; |
| } |
| |
| @keyframes chargingGlow { |
| 0%, 100% { filter: brightness(1) saturate(1); transform: scale(1); } |
| 50% { filter: brightness(1.3) saturate(1.5); transform: scale(1.05); } |
| }`, |
| 'dizzy-wobble': `.dizzy-wobble { |
| animation: dizzyWobble 1s ease-in-out infinite; |
| } |
| |
| @keyframes dizzyWobble { |
| 0%, 100% { transform: rotate(0deg); } |
| 25% { transform: rotate(-15deg) translateX(-5px); } |
| 50% { transform: rotate(0deg) translateX(0px); } |
| 75% { transform: rotate(15deg) translateX(5px); } |
| }`, |
| 'attack-lunge': `.attack-lunge { |
| animation: attackLunge 1.5s ease-in-out infinite; |
| } |
| |
| @keyframes attackLunge { |
| 0%, 100% { transform: translateX(0px) scaleX(1); } |
| 30% { transform: translateX(-10px) scaleX(0.9); } |
| 60% { transform: translateX(15px) scaleX(1.1); } |
| }`, |
| 'defend-crouch': `.defend-crouch { |
| animation: defendCrouch 2s ease-in-out infinite; |
| } |
| |
| @keyframes defendCrouch { |
| 0%, 100% { transform: scaleY(1) translateY(0px); } |
| 50% { transform: scaleY(0.8) translateY(10px); } |
| }`, |
| 'love-hearts': `.love-hearts { |
| animation: loveHearts 2s ease-in-out infinite; |
| } |
| |
| @keyframes loveHearts { |
| 0%, 100% { transform: scale(1); filter: hue-rotate(0deg); } |
| 50% { transform: scale(1.1); filter: hue-rotate(20deg); } |
| }`, |
| 'fear-tremble': `.fear-tremble { |
| animation: fearTremble 0.4s ease-in-out infinite; |
| } |
| |
| @keyframes fearTremble { |
| 0%, 100% { transform: translateX(0px) translateY(0px); } |
| 10%, 30%, 50%, 70%, 90% { transform: translateX(-2px) translateY(-1px); } |
| 20%, 40%, 60%, 80% { transform: translateX(2px) translateY(1px); } |
| }`, |
| 'evolving-glow': `.evolving-glow { |
| animation: evolvingGlow 2s ease-in-out infinite; |
| } |
| |
| @keyframes evolvingGlow { |
| 0%, 100% { |
| filter: brightness(1) contrast(1); |
| transform: scale(1); |
| } |
| 50% { |
| filter: brightness(1.5) contrast(1.2); |
| transform: scale(1.1); |
| } |
| }`, |
| 'fainting-fall': `.fainting-fall { |
| animation: faintingFall 3s ease-in-out infinite; |
| } |
| |
| @keyframes faintingFall { |
| 0%, 70% { transform: rotate(0deg) translateY(0px); opacity: 1; } |
| 100% { transform: rotate(90deg) translateY(20px); opacity: 0.3; } |
| }` |
| }; |
| |
| const css = cssMap[animationClass]; |
| if (css) { |
| navigator.clipboard.writeText(css).then(() => { |
| alert('CSS copied to clipboard!'); |
| }).catch(() => { |
| const textArea = document.createElement('textarea'); |
| textArea.value = css; |
| document.body.appendChild(textArea); |
| textArea.select(); |
| document.execCommand('copy'); |
| document.body.removeChild(textArea); |
| alert('CSS copied to clipboard!'); |
| }); |
| } |
| } |
| |
| |
| document.getElementById('sprite-upload').addEventListener('change', function(e) { |
| const file = e.target.files[0]; |
| if (file) { |
| const reader = new FileReader(); |
| reader.onload = function(e) { |
| uploadedImage = e.target.result; |
| renderAnimations(); |
| }; |
| reader.readAsDataURL(file); |
| } |
| }); |
| |
| |
| renderAnimations(); |
| </script> |
| </body> |
| </html> |