How to stagger a timeline and apply it to multiple elements?

I have the following setup:

  • A list (UL) with an unknown number of list-items (LI)
  • Each list-item has a custom bullet

Here is the animation I would like to achieve creating:
For each list-item:

  1. First show the bullet
  2. Then show the text using a split-text animation showing each letter individually
  3. Once the bullet + text of a list-item is visible: animate the next list-item

For the animation I would like to use a single timeline, so it is easy to adjust the animation.
On the timeline I would like to add an animation for the bullet and an animation for the text.

I have looked into callbacks like onComplete, and enabling advanced settings like “Trigger Selector > As Array” and “Trigger Selector > Handle triggers separately”.
The first does not seem to be supported?
The latter two I do not really understand and cannot find any documentation for.

Any pointers on how to set this up efficiently are much appreciated!

Could you share the markup of your ul so I can tinker with it on my end? :slight_smile:
Are the custom bullets done via css or are you using a separate element like an svg icon or something?

Hi @manc, I could not find a way to do this with the animation-editor so I ended up creating the animation in Javascript. You can see the end result in the hero of https://crossmodel.io/

If you can find a solution just using the editor, I would be curious to learn how.

Here is the main part of the code I used:

/* Get each list item (LI) */
        document.querySelectorAll(".list-item").forEach((el) => {
            gsap.set(el, { visibility: "visible" });
            el.style.setProperty("--opacity", 0);
            el.style.setProperty("--scale", 0);

/* Get the text inside the LI */
            const textElement = el.querySelector(".list-item__text");
            
            const split = new SplitText(textElement, { type: "chars" });
            const chars = split.chars;

/* Create a timeline for this list-item */
            const tl = gsap.timeline();

/* Animate bullet */
            tl.to(el, {
                duration: 0.5,
                ease: "back.out",
                "--opacity": 1,
                "--scale": 1,
            });
/* Animate text */
            tl.from(chars, {
                opacity: 0,
                duration: 0.2,
                stagger: 0.02,
                ease: "power2.out",
            });

/* Add the animation for this list-item to the master timeline */
            masterTimeline.add(tl, ">-25%");
        });