Skip to content

Anime.js Callbacks and Events — Complete Guide

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you'll learn about Anime.js callbacks and events. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

Anime.js callbacks let you hook into animation lifecycle events: when it starts, updates each frame, completes, and loops, giving you precise control over side effects during animations.

What You'll Learn

By the end of this tutorial, you'll use begin, complete, update, loopBegin, loopComplete, and changeBegin callbacks to trigger code at specific animation moments.

Why It Matters

Callbacks connect animations to the rest of your application. Start a sound when an animation begins, update a progress bar each frame, or navigate to a new page when the animation completes.

Real-World Use

Durga Antivirus Pro uses the update callback during the scanning animation to update the real-time progress percentage. The complete callback triggers the scan results report to slide in.

Where This Fits in Your Learning Path

flowchart LR
    A["Timeline & Controls"] --> B["**Easing & Callbacks**"]
    B --> C["SVG & Morph"]
    C --> D["Scroll & Performance"]
    D --> E["Advanced Anime.js"]
    style B fill:#f97316,stroke:#c2410c,color:#fff
    style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
    style E fill:#22c55e,stroke:#16a34a,color:#fff

begin Callback

Fires once when the animation starts playing, after any initial delay.

anime({
  targets: '.box',
  translateX: 300,
  duration: 1000,
  begin: function(anim) {
    console.log('Animation started at', anim.currentTime)
    document.querySelector('.status').textContent = 'Animating...'
  }
})

Expected output: The console logs the start time and the status text updates immediately when the animation begins.

complete Callback

Fires once when the animation finishes playing all iterations.

anime({
  targets: '.box',
  translateX: 300,
  duration: 1000,
  complete: function(anim) {
    console.log('Animation completed at', anim.currentTime)
    document.querySelector('.status').textContent = 'Done!'
  }
})

Expected output: The console logs the completion time and the status updates after the box finishes moving.

update Callback

Fires on every frame during the animation, giving you the current progress.

anime({
  targets: '.box',
  translateX: 300,
  duration: 2000,
  update: function(anim) {
    const progress = Math.round(anim.progress)
    document.querySelector('.progress').textContent = progress + '%'
  }
})

Expected output: The progress percentage updates smoothly from 0% to 100% over 2 seconds.

loopBegin and loopComplete

Fire at the start and end of each loop iteration.

anime({
  targets: '.box',
  scale: 1.5,
  duration: 500,
  loop: 3,
  direction: 'alternate',
  loopBegin: function(anim) {
    console.log('Loop iteration', anim.currentIteration, 'started')
  },
  loopComplete: function(anim) {
    console.log('Loop iteration', anim.currentIteration, 'completed')
  }
})

Expected output: The console logs the start and end of each of the 3 loop iterations.

changeBegin and changeComplete

Fire when the animation's current value changes direction or completes a change.

anime({
  targets: '.box',
  translateX: [0, 200, 100],
  duration: 2000,
  changeBegin: function(anim) {
    console.log('Value began changing at', anim.currentTime)
  },
  changeComplete: function(anim) {
    console.log('Value finished changing at', anim.currentTime)
  }
})

Expected output: The callbacks fire as the box moves from 0 to 200, then from 200 to 100.

Using Callbacks with Timelines

Timelines also support the same callbacks, firing for the entire sequence.

const tl = anime.timeline({
  duration: 600,
  update: function(anim) {
    console.log('Timeline progress:', Math.round(anim.progress) + '%')
  },
  complete: function() {
    console.log('Entire timeline done')
  }
})

tl.add({ targets: '.a', translateX: 100 })
tl.add({ targets: '.b', translateX: 100 })
tl.add({ targets: '.c', translateX: 100 })

Expected output: The update callback fires for the entire timeline, not per step. Progress goes from 0 to 100% across all three segments.

Common Mistakes

1. Using callbacks for heavy DOM operations every frame

The update callback fires 60 times per second. Heavy DOM operations cause frame drops. Keep update callbacks lightweight.

2. Expecting begin to fire before the initial delay

begin fires after the delay, not immediately on creation. Use a separate function call before anime() if you need pre-delay logic.

3. Mixing begin and complete with loop

begin fires once for the entire animation (including loops). loopBegin fires per iteration. Use the right one for your use case.

4. Forgetting that 'this' inside callbacks refers to the animation

Inside callback functions, 'this' is the anime animation instance. Use arrow functions if you need the outer scope.

5. Not checking anim.progress for partial updates

The update callback fires on every frame. Compare anim.progress or anim.currentTime with previous values to avoid redundant work.

Practice Questions

  1. Which callback fires 60 times per second? The update callback fires on every animation frame.

  2. How is loopBegin different from begin? begin fires once when the entire animation starts. loopBegin fires at the start of each loop iteration.

  3. What information does the anim parameter contain? The anim object has properties like currentTime, progress, currentIteration, and reversed.

  4. Can callbacks access the animation's target elements? Yes. Use anim.animatables to access the animated objects and their properties.

  5. Do timeline callbacks cover the entire sequence? Yes. The timeline's update callback reports progress across the entire sequence, not individual steps.

Challenge

Build a progress bar that fills from 0 to 100%. The update callback writes the percentage to a display. The complete callback changes the bar color to green and logs "Loading complete!".

FAQ

Can I remove a callback after creation?

No. Callbacks are set at creation. To change behavior, create a new animation or use a conditional inside the callback.

Do callbacks fire if the animation is paused or seeked?

begin fires when .play() is called. update fires on seek. complete may not fire if the animation is paused before finishing.

Can I use async/await with callbacks?

Wrap the animation in a Promise and resolve in the complete callback for async/await compatibility.

How many callbacks can I have per event?

One per event type. To run multiple functions, call them all from a single callback.

Do callbacks work with all easing functions?

Yes. Callbacks are independent of easing. They fire based on time progression, not the easing curve.


Mini Project

Build a multi-step progress indicator. Each step in a 4-step Process animates sequentially. Use complete callbacks on each step to highlight the next step in the UI. Use a final complete callback to show a congratulations message.

const steps = document.querySelectorAll('.step')
const status = document.querySelector('.status')

const tl = anime.timeline({
  easing: 'easeOutQuad',
  duration: 400
})

steps.forEach((step, i) => {
  tl.add({
    targets: step,
    scale: [1, 1.3, 1],
    backgroundColor: ['#e0e0e0', '#4ecdc4'],
    complete: function() {
      status.textContent = 'Step ' + (i + 1) + ' completed'
    }
  })
})

tl.add({
  targets: '.done-banner',
  translateY: [20, 0],
  opacity: [0, 1],
  complete: function() {
    status.textContent = 'All steps done!'
    status.style.color = '#4ecdc4'
  }
})
<div style="display:flex;gap:10px;justify-content:center">
  <div class="step" style="width:40px;height:40px;background:#e0e0e0;border-radius:50%"></div>
  <div class="step" style="width:40px;height:40px;background:#e0e0e0;border-radius:50%"></div>
  <div class="step" style="width:40px;height:40px;background:#e0e0e0;border-radius:50%"></div>
  <div class="step" style="width:40px;height:40px;background:#e0e0e0;border-radius:50%"></div>
</div>
<p class="status">Waiting to start...</p>
<p class="done-banner" style="opacity:0;color:#4ecdc4;font-weight:bold">All Steps Complete!</p>
<button onclick="tl.restart()">Restart</button>

What's Next

Move into SVG and scroll animations:

Tutorial What You'll Learn
SVG and Motion Paths Animate SVG elements along motion paths
Easing Functions Deep dive into all easing functions and custom curves

Related topics: requestAnimationFrame and frame timing, event-driven programming.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro