Lesson 35: Creating Animation

Master JavaScript animation techniques - learn to create smooth animations using timers, requestAnimationFrame, and canvas with interactive examples.

35.1 Animation Fundamentals

JavaScript animations create the illusion of motion by changing element properties over time. This is achieved using timers that repeatedly update visual elements.

Key concepts:
  • setInterval(): Executes code repeatedly at fixed intervals
  • setTimeout(): Executes code once after a delay
  • requestAnimationFrame(): Modern method optimized for animations
  • Frame rate control: Balancing smoothness and performance
  • Canvas element: For complex graphics and animations
// Basic animation with setInterval
const element = document.getElementById('animated-element');
let position = 0;

function moveElement() {
  position += 2;
  element.style.left = position + 'px';
  
  // Stop when element reaches 300px
  if (position >= 300) {
    clearInterval(animationInterval);
  }
}

const animationInterval = setInterval(moveElement, 16); // ~60fps

Example 35.1: Moving Box Animation

Basic animation using setInterval:

35.2 requestAnimationFrame

The modern approach for smooth animations. It's optimized for the browser's rendering cycle and pauses when the tab is inactive.

// Animation with requestAnimationFrame
let position = 0;
let animationId;

function animate() {
  position += 2;
  element.style.left = position + 'px';
  
  if (position < 300) {
    animationId = requestAnimationFrame(animate);
  }
}

// Start animation
animationId = requestAnimationFrame(animate);

// Stop animation
cancelAnimationFrame(animationId);

Example 35.2: Smooth Bouncing Ball

Using requestAnimationFrame for smoother animation:

0.5

35.3 Canvas Animations

The Canvas API provides powerful tools for creating complex animations and games.

// Particle system with canvas
const canvas = document.getElementById('particleCanvas');
const ctx = canvas.getContext('2d');

class Particle {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.size = Math.random() * 5 + 1;
    this.speedX = Math.random() * 3 - 1.5;
    this.speedY = Math.random() * 3 - 1.5;
  }
  
  update() {
    this.x += this.speedX;
    this.y += this.speedY;
    if (this.size > 0.2) this.size -= 0.1;
  }
  
  draw() {
    ctx.fillStyle = `hsl(${Math.random() * 360}, 50%, 50%)`;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
    ctx.fill();
  }
}

const particles = [];

function createParticles(x, y) {
  for (let i = 0; i < 5; i++) {
    particles.push(new Particle(x, y));
  }
}

function animateParticles() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  particles.forEach((particle, index) => {
    particle.update();
    particle.draw();
    
    if (particle.size <= 0.2) {
      particles.splice(index, 1);
    }
  });
  
  requestAnimationFrame(animateParticles);
}

animateParticles();

Example 35.3: Interactive Particle System

Click on the canvas to create colorful particles:

35.4 Animation Performance

Optimize animations for smooth performance across devices:

Performance tips:
  • Use requestAnimationFrame instead of setInterval
  • Limit DOM manipulations - batch changes when possible
  • Use CSS transforms for smooth motion (GPU accelerated)
  • Reduce the number of animated elements
  • Use canvas for complex animations instead of DOM
  • Throttle or debounce event handlers

Example 35.4: Performance Comparison

Compare setInterval vs requestAnimationFrame:

setInterval Animation

FPS: --

requestAnimationFrame

FPS: --

35.5 Easing Functions

Easing functions create more natural animations by varying the rate of change over time.

// Common easing functions
function linear(t) { return t; }
function easeInQuad(t) { return t * t; }
function easeOutQuad(t) { return t * (2 - t); }
function easeInOutQuad(t) { 
  return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; 
}

// Applying easing to animation
function animateWithEasing(duration, easingFn) {
  const start = performance.now();
  
  function animate(time) {
    const elapsed = time - start;
    const progress = Math.min(elapsed / duration, 1);
    const easedProgress = easingFn(progress);
    
    // Update position based on eased progress
    element.style.left = (easedProgress * 300) + 'px';
    
    if (progress < 1) {
      requestAnimationFrame(animate);
    }
  }
  
  requestAnimationFrame(animate);
}

Example 35.5: Easing Function Explorer

Compare different easing functions: