Back Home
TOC Loading..
Keyframes
References
  1. GSAP Docs
Github Repo
Webflow Cloneable

Using Functions as Property Values in GSAP (And Why You Probably Should)

In this article my goal is to explain the concept and uses cases as I would have liked to learn it.

The Basics: Function as a Property

In its most basic (and admittedly useless) form:

1gsap.to('.my-element', {
2  y: function() {
3    // Simply sets the value as 10. No different than just putting y: 10
4    return 10;
5  }
6});

Cool, right? Not really.

But it gets more useful when you realize what GSAP passes to these functions.

Each function gets three arguments:

  1. index — the element’s index in the animation target list
  2. target — the actual DOM element
  3. targets — the full array of all elements being animated

Going forward I'll refer to them as follows for the sake of clarity

  1. index
  2. currentElement
  3. allElements

Using functions like this lets you write context-aware animations that adapt to position, attributes, or even external data.

1gsap.to('.lots-of-elements', {
2  height: function(index) {
3    // In this example, each element will be 10px taller than the last
4    return index * 10;
5  }
6});

A Few Practical Examples

Some simple ideas to get you started:

1gsap.to('.lots-of-elements', {
2  height: function(index) {
3    // In this example, each element will be 10px taller than the last
4    return index * 10;
5  },
6  stagger: 0.1 // And a simple stagger to make it fancy
7});

1gsap.to('.myFirstElement, .mySecondElement', {
2  scale: function(index, currentElement, allElements) {
3    // Check which element this is (useful for needle in a haystack scenarios)
4    if (currentElement === allElements[1]) {
5      return 10;
6    } else {
7      return 0;
8    }
9  }
10});

This kind of logic is super handy when you're targeting multiple elements but need one to behave differently — without hardcoding selectors or rewriting the animation for each case.

Modularity and Ease Math

You can also define your logic outside the tween, and GSAP will still handle the parameters correctly. Here’s a modular approach using `gsap.utils.pipe` to build a value from multiple utility functions:

1let elements = document.querySelectorAll('.lots-of-elements');
2
3// Define a function that will take an index of an element 
4// and return a value weighted on an ease
5let heightFn = gsap.utils.pipe(
6  gsap.utils.normalize(0, elements.length - 1),
7  gsap.parseEase("power2.out"),
8  gsap.utils.mapRange(0, 1, 0, elements.length * 10)
9);
10
11gsap.to(elements, {
12  height: heightFn
13  // Notice how we don't need to put the (index), because by default
14  // GSAP will pass all 3 values through if they can be.
15  // This means we can write our code in more modular ways.
16});

This reads a bit like a functional playground: normalize the index, ease it out, and then map it to a new range. You don’t need to call the function yourself — GSAP will pass everything in behind the scenes. Which means you can build tiny, testable functions and still keep your tweens clean.

Attribute-Based Values

Another use case is pulling values directly from HTML attributes. This lets you keep logic in the markup — useful when clients (or teammates) want some control without editing JS files:

1gsap.from('.element', {
2  y: function(index, currentElement) {
3    // Dynamic attribute-powered values
4    return currentElement.getAttribute('data-gsap-y') || 0;
5  }
6});

This one's especially handy in Webflow sites, where dynamic fields can inject values into attributes.

Arrow functions?

Notice how I'm always declaring the function anonymously.

1y: function() {}

Rather than an arrow function

1y: ()=>{}

This is because arrow functions don't have access to the 'this' keyword. So you wont be able to reference the current tween. I also just think it's cleaner to be a bit more verbose especially in the Webflow world where a lot of developers are inexperienced with writing any javascript at all

Final Thoughts

There’s something really satisfying about using functions like this. It’s one of those techniques that makes your animation logic cleaner, more flexible, and easier to reason about — especially when projects scale or switch hands.

If you do decide to go ahead with it, **comment your code clearly**. It’s deceptively powerful and extremely easy to forget _why_ something’s been written the way it has.

For me, it’s replaced a lot of conditional logic and manual iteration in timelines.

Writings

Managing UI State in Webflow with JavaScript

A concise introduction to front-end reactivity, showing why data should control the UI and how to create and watch reactive variables using Vue’s reactivity system, with practical examples.

Using HonoJS with your reverse proxy

Hono.js replaces messy if/else chains with clean, readable routing to build a reverse proxy that scales

Reverse Proxy First Steps

In the next ~30 minutes, you'll have two different sites running under one URL.

Webflow Reverse Proxy Overview: What It Is, Why It Matters, and When to Use It

Reverse proxies are the gateway drug to Webflow Enterprise. Almost every enterprise project I’ve been involved in has implemented it in some form.

Building a Webflow to Algolia Sync with Cloudflare Workers

Build an automated sync between Webflow's CMS and Algolia's search service using Cloudflare Workers.

Using Videos Effectively in Webflow (Without Losing Your Mind)

If you’ve ever used Webflow’s native background video component and thought “damn, that looks rough” I'm here for you.

Webflow + Cloudflare reverse proxy. Why and How

As more companies move to Webflow and demand for Webflow Enterprise grows, you’ll see more teams leaning on reverse proxies to solve some of Webflow’s infrastructure limitations.

How (and why) to add keyboard shortcuts to your Webflow site

A small keyboard shortcut can make a marketing site feel faster, more intentional, and “app-like” with almost no extra design or development

Useful GSAP utilities

A practical, code-heavy dive into GSAP’s utility functions—keyframes, pipe, clamp, normalize, and interpolate—and why they’re so much more than just shortcuts for animation math.

Organising JavaScript in Webflow: Exploring Scalable Patterns

Exploring ways to keep JavaScript modular and maintainable in Webflow — from Slater to GitHub to a custom window.functions pattern. A look at what’s worked (and what hasn’t) while building more scalable websites.

Building a Scroll-Based Image Sequencer with GSAP

An exploration in building a scroll-driven image sequence animation using GSAP and HTML5 canvas. Using Avif file compression with the Avif CLI, hosting strategies (Webflow vs AWS), GSAP and the quirks of working with canvas.