DEV Community

Divine
Divine

Posted on

Hello dev

<!DOCTYPE html>




Dragon Dog Animation
<br> body {<br> margin: 0;<br> background: #111;<br> display: flex;<br> flex-direction: column;<br> align-items: center;<br> justify-content: center;<br> min-height: 100vh;<br> color: #fff;<br> font-family: sans-serif;<br> }<br> canvas {<br> border: 2px solid #333;<br> background: #222;<br> border-radius: 8px;<br> }<br> button {<br> margin-top: 15px;<br> padding: 10px 20px;<br> font-size: 16px;<br> cursor: pointer;<br> border: none;<br> background-color: #ff5722;<br> color: white;<br> border-radius: 4px;<br> }<br>


Start Animation & Sound

<br> const canvas = document.getElementById(&#39;canvas&#39;);<br> const ctx = canvas.getContext(&#39;2d&#39;);</p> <div class="highlight"><pre class="highlight plaintext"><code>// Web Audio Context setup let audioCtx; function initAudio() { if (!audioCtx) { audioCtx = new (window.AudioContext || window.webkitAudioContext)(); } } // Audio Synthesizers function playBark() { initAudio(); const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = 'sawtooth'; osc.frequency.setValueAtTime(300, audioCtx.currentTime); osc.frequency.exponentialRampToValueAtTime(120, audioCtx.currentTime + 0.15); gain.gain.setValueAtTime(0.3, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.15); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 0.15); } function playFireSound() { initAudio(); const bufferSize = audioCtx.sampleRate * 1.5; const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate); const output = buffer.getChannelData(0); for (let i = 0; i &lt; bufferSize; i++) { output[i] = Math.random() * 2 - 1; // White noise } const whiteNoise = audioCtx.createBufferSource(); whiteNoise.buffer = buffer; const filter = audioCtx.createBiquadFilter(); filter.type = 'lowpass'; filter.frequency.setValueAtTime(800, audioCtx.currentTime); const gain = audioCtx.createGain(); gain.gain.setValueAtTime(0.4, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 1.5); whiteNoise.connect(filter); filter.connect(gain); gain.connect(audioCtx.destination); whiteNoise.start(); } function playWhooshSound() { initAudio(); const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); osc.type = 'sine'; osc.frequency.setValueAtTime(150, audioCtx.currentTime); osc.frequency.exponentialRampToValueAtTime(400, audioCtx.currentTime + 0.8); gain.gain.setValueAtTime(0.2, audioCtx.currentTime); gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.8); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(); osc.stop(audioCtx.currentTime + 0.8); } // Animation State Variables let state = 'SLEEPING'; // SLEEPING, WAKE, FIRE, WINGS, FLYING let dogX = 150, dogY = 280; let wingSize = 0; let particles = []; let eyeOpen = false; function drawDog() { ctx.save(); ctx.translate(dogX, dogY); // Tail ctx.strokeStyle = '#d7ccc8'; ctx.lineWidth = 6; ctx.beginPath(); ctx.moveTo(-35, -5); ctx.quadraticCurveTo(-50, -20, -45, -35); ctx.stroke(); // Dog Body ctx.fillStyle = '#8d6e63'; ctx.beginPath(); ctx.ellipse(0, 0, 40, 25, 0, 0, Math.PI * 2); ctx.fill(); // Dog Head ctx.beginPath(); ctx.arc(35, -20, 20, 0, Math.PI * 2); ctx.fill(); // Dog Snout ctx.beginPath(); ctx.ellipse(50, -15, 10, 8, 0, 0, Math.PI * 2); ctx.fill(); // Dog Nose ctx.fillStyle = '#3e2723'; ctx.beginPath(); ctx.arc(58, -17, 3, 0, Math.PI * 2); ctx.fill(); // Dog Ears ctx.beginPath(); ctx.ellipse(25, -35, 6, 14, Math.PI / 6, 0, Math.PI * 2); ctx.fill(); // Dog Eyes ctx.fillStyle = '#000'; if (eyeOpen) { ctx.beginPath(); ctx.arc(40, -23, 3, 0, Math.PI * 2); ctx.fill(); } else { ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(37, -23); ctx.lineTo(43, -23); ctx.stroke(); } // Wings (If growing or grown) if (wingSize &gt; 0) { ctx.fillStyle = '#b71c1c'; // Left Wing ctx.beginPath(); ctx.moveTo(-10, -15); ctx.quadraticCurveTo(-10 - wingSize, -15 - wingSize, -30 - wingSize, -5 - wingSize); ctx.quadraticCurveTo(-15, -5, -10, -15); ctx.fill(); // Right Wing ctx.beginPath(); ctx.moveTo(0, -15); ctx.quadraticCurveTo(0 + wingSize / 2, -15 - wingSize, -20 + wingSize, -5 - wingSize); ctx.quadraticCurveTo(-5, -5, 0, -15); ctx.fill(); } ctx.restore(); } function createFireParticle() { particles.push({ x: dogX + 58, y: dogY - 17, vx: 4 + Math.random() * 4, vy: (Math.random() - 0.5) * 3, size: 10 + Math.random() * 10, life: 1, color: `hsl(${Math.random() * 40}, 100%, 50%)` }); } function updateParticles() { for (let i = particles.length - 1; i &gt;= 0; i--) { let p = particles[i]; p.x += p.vx; p.y += p.vy; p.life -= 0.03; p.size *= 0.95; ctx.fillStyle = p.color; ctx.globalAlpha = Math.max(0, p.life); ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fill(); ctx.globalAlpha = 1.0; if (p.life &lt;= 0) particles.splice(i, 1); } } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); // Floor ctx.fillStyle = '#333'; ctx.fillRect(0, 310, canvas.width, 90); drawDog(); updateParticles(); // State Handling if (state === 'FIRE') { createFireParticle(); } else if (state === 'WINGS') { if (wingSize &lt; 45) wingSize += 0.8; } else if (state === 'FLYING') { dogX += 2; dogY -= 2; } requestAnimationFrame(animate); } function startSequence() { // Reset state = 'SLEEPING'; dogX = 150; dogY = 280; wingSize = 0; eyeOpen = false; // Timeline Sequence setTimeout(() =&gt; { state = 'WAKE'; eyeOpen = true; playBark(); }, 1000); setTimeout(() =&gt; { state = 'FIRE'; playFireSound(); }, 2000); setTimeout(() =&gt; { state = 'WINGS'; }, 3800); setTimeout(() =&gt; { state = 'FLYING'; playWhooshSound(); }, 5000); } // Start loop animate(); </code></pre></div> <p>

Top comments (0)