Skip to content

GSAP Callbacks — Events and Lifecycle Hooks

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about GSAP Callbacks. We cover key concepts, practical examples, and best practices to help you master this topic.

GSAP callbacks fire at specific points in an animation's lifecycle, enabling code execution on start, during updates, on completion, and on reverse completion.

What You'll Learn

By the end of this guide, you will use onStart for initialization, onComplete for cleanup, onUpdate for progress tracking, onReverseComplete for reverse end, pass callback parameters, and debug animation timing.

Basic Callbacks

gsap.to('.box', {
    x: 300,
    duration: 1,
    onStart: function() {
        console.log('Animation started');
    },
    onComplete: function() {
        console.log('Animation completed');
    },
    onUpdate: function() {
        console.log('Progress:', this.progress());
    }
});

Callbacks with Parameters

gsap.to('.box', {
    x: 300,
    duration: 1,
    onStart: myStartFunction,
    onStartParams: ['param1', 42],
    onComplete: myCompleteFunction,
    onCompleteParams: ['${this.targets()}']
});

function myStartFunction(p1, p2) {
    console.log('Start:', p1, p2);
}

function myCompleteFunction() {
    console.log('Done:', arguments);
}

Callback Scope

gsap.to('.box', {
    x: 300,
    duration: 1,
    callbackScope: document.getElementById('box'),
    onComplete: function() {
        this.style.backgroundColor = '#ff6b35';
    }
});

onReverseComplete

gsap.to('.box', {
    x: 300,
    duration: 1,
    onReverseComplete: function() {
        console.log('Reversed to start');
    }
});

Common Mistakes

1. Using Arrow Functions for Callbacks

Arrow functions do not have their own this. Use regular functions to access the tween via this.

2. Not Using onStartParams

Callback functions receive no arguments by default. Use onStartParams to pass data.

3. Heavy Operations in onUpdate

onUpdate fires every frame (60fps). Avoid DOM queries or heavy calculations here.

4. Forgetting callbackScope

When using this inside a callback, set callbackScope to the desired context.

5. Callbacks Not Firing on Reverse

onComplete does not fire when reversing past the beginning. Use onReverseComplete for that.

Practice Questions

Q1: How often does onUpdate fire? A: Every frame (approximately 60fps) during the animation.

Q2: How do you pass arguments to a callback? A: Use onStartParams, onUpdateParams, and onCompleteParams arrays.

Q3: What does this refer to inside a callback? A: The tween instance by default, or the callbackScope object if set.

Q4: How do you get the current progress in onUpdate? A: Call this.progress() inside the callback (for regular functions).

Q5: What callback fires when reverse reaches the start? A: onReverseComplete.

Challenge: Build an animation with a progress bar that updates in onUpdate. Add play, pause, and reverse buttons that log the current animation state.

FAQ

Do callbacks fire if the animation is killed?

onComplete does not fire on kill. Use an onKill callback property instead.

Can callbacks be added after creation?

No. Callbacks must be set in the tween vars. Use eventCallback method to add later.

What is the order of callbacks?

onStart, onUpdate (repeated), onComplete or onReverseComplete.

Can callbacks be removed?

Set the callback to null: tween.eventCallback('onComplete', null).

Do callbacks work in timelines?

Yes. Timelines support the same callbacks on child tweens.

Try It Yourself

Build an animation with progress logging.

<!DOCTYPE html>
<html>
<head>
    <title>GSAP Callbacks Demo</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12/gsap.min.js"></script>
    <style>
        .box { width: 80px; height: 80px; background: #4ecdc4; border-radius: 8px; }
        #log { background: #f5f5f5; padding: 10px; border-radius: 6px; font-size: 12px; max-height: 150px; overflow-y: auto; margin-top: 10px; }
        #progress-bar { height: 6px; background: #eee; border-radius: 3px; margin-top: 10px; overflow: hidden; }
        #progress-fill { height: 100%; width: 0%; background: #ff6b35; border-radius: 3px; }
    </style>
</head>
<body style="font-family:sans-serif;padding:20px;">
<h2>Callback Demo</h2>
<button onclick="playAnim()">Play</button>
<button onclick="reverseAnim()">Reverse</button>
<div class="box" id="box" style="position:relative;"></div>
<div id="progress-bar"><div id="progress-fill"></div></div>
<div id="log">Log output...</div>
<script>
var tween;

function playAnim() {
    tween = gsap.to('#box', {
        x: 400,
        duration: 2,
        ease: 'power2.out',
        onStart: function() { log('Started'); },
        onComplete: function() { log('Completed'); },
        onReverseComplete: function() { log('Reversed to start'); },
        onUpdate: function() {
            var p = Math.round(this.progress() * 100);
            document.getElementById('progress-fill').style.width = p + '%';
        }
    });
}

function reverseAnim() {
    if (tween) tween.reverse();
}

function log(msg) {
    var el = document.getElementById('log');
    el.innerHTML += '<br>' + msg;
    el.scrollTop = el.scrollHeight;
}
</script>
</body>
</html>

What's Next

Control timelines.

Timeline Controls — Timeline control and sequencing. MotionPath — Motion path plugin.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro