Jump to content
Search Community

animate element base on their index

Kelimino test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hello everyone,

 

How do you animate element base on their index ?

 

I have a div parent ".lottie" with list of lotties child inside. I try to animate them following their index, each time i trigger another element of an array of div".skill".

Trigger A.1 > animate 1 of ".lottie" ... then

Trigger A.2 > animate 2 of ".lottie" ... then

Trigger A.3 > animate 3 of ".lottie"... 

Etc...

 

I used a "add" function() in a gsap timeline, with (for, forEach, stagger) but i can't have the expected result. In the code below, all the lottie appear at once, where i'll like them to appear in a successive order.

 

Does anyone have a clue on this function ? or is there a similar topic ?

 

Thanks in advance

Have a good Day

Kellig

 

    const lotties = document.querySelectorAll(".lottie");
    gsap.utils.toArray(".skill").forEach(el => {
      let SkillAnim = gsap.timeline({
        scrollTrigger: {
          trigger: el,
          start: "top 80%",
          end: "bottom center",
          toggleActions: "play none none reset"
        }
      });
      SkillAnim.from(el, { autoAlpha: 0, y: 20 })
        .to(el, { autoAlpha: 1, y: 0 })
        .add(() => {
          for (let index = 0; index < lotties.length; index++) {
            gsap.to(
              lotties,
              1,
              {
                x: 0,
                autoAlpha: 1,
                stagger: function(index, target) {
                  return target[index++] * 0.1;
                }
              },
              1
            );
          }
        });
    });

 

Link to comment
Share on other sites

  • Solution

Sure, it should be totally possible to do that, but it's hard for me to visualize your setup exactly. It would be really, really, REALLY helpful if you could provide a minimal demo so we can see it in context. For example, I'm not sure what ".skill" or ".lottie" refer to.

 

I assume that maybe you meant something more like this: 

const lotties = document.querySelectorAll(".lottie");
gsap.utils.toArray(".skill").forEach((el, i) => {
  let SkillAnim = gsap.timeline({
    scrollTrigger: {
      trigger: el,
      start: "top 80%",
      end: "bottom center",
      toggleActions: "play none none reset"
    }
  });
  SkillAnim.from(el, { autoAlpha: 0, y: 20 })
    .to(el, { autoAlpha: 1, y: 0 })
    .to(lotties[i], {x: 0, autoAlpha: 1, duration: 1});
});

Happy tweening!

  • Like 1
Link to comment
Share on other sites

Oh Thanks a lot Jack,

 

Your solution is very clear and seems simple, it make sens. I still  need to learn more on parameter such as index, element, target, etc...

I will practice more with this setup. Next time, if i am getting stuck for hours, i will do a codePen. 

 

Thanks again, have a nice Day

Kellig

 

  • Like 1
Link to comment
Share on other sites

Sorry, i have one more question, i feel bad because i should be able to deal on my own but spent all afternoon on this one (for, forEach, el, i, target...).

 

In the code below, almost the same as above, i fire a function with scrollTrigger " onEnter" but only the last animation of the list play. I wish i could fire the function playLottie() everytime it's trigger "... I dont know how to use the Index, target, or el on this case and if i should use .call, . add function instead.

 

Again, many thanks for your help.

Kellig

 

    const lotties = document.querySelectorAll(".lottie");
    gsap.utils.toArray(".skill").forEach((el, i) => {
      let SkillAnim = gsap.timeline({
        scrollTrigger: {
          trigger: el,
          start: "top 70%",
          toggleActions: "play none none reset",
          onEnter: this.playLottie
        }
      });
      SkillAnim.from(el, { autoAlpha: 0, y: 20 })
        .to(el, { autoAlpha: 1, y: 0 })
        .to(
          lotties[i],
          {
            right: "-10%",
            autoAlpha: 1,
            duration: 1
          },
          "<"
        );
    });

 

Link to comment
Share on other sites

Hi, thank ou for your time and answer. I  tried this one aready but only the last of the list play. 

 

Here, are the various function that i tried: 

 

//scrollTrigger
onEnter: () => this.playLottie(i)

//scrollTrigger
OnComplete: this.playLottie

//In Timeline
.to(lotties[i],{onComplete: () => {this.playLottie(i);})

//In Timeline
.call(() => {this.playLottie(lotties[i]);})

or

.call((i) => {this.playLottie})

//In timeline
.call(() => (for(let i = 0, i < lotties.lenght, i++){
  this.playLottie(i);
}

 

Link to comment
Share on other sites

Here is the code, with controller, relative to Lottie:

 

In vue, i call the function ' this.playLottie' from 'methods'

 

methods: {
    handleAnimation: function(anim) {
      this.anim = anim;
    },
    playLottie: function() {
      this.anim.play(0);
    },
    stopLottie: function() {
      this.anim.stop();
    }
  }

 

 

Link to comment
Share on other sites

18 minutes ago, OSUblake said:

Where does anim from? According to that code there is only 1 lottie animation, correct?

 

A demo would go a long way and save us both time.

I have many lottie, like the example above.

 

'anim' is the argument from the 'method' function and each lottie in the DOm is like that

:options have the path, controller (loop, autoplay..) 

<lottie
:options="lotties.ui"
@animCreated="handleAnimation"
/>
Link to comment
Share on other sites

Here is part of my code:

//In template:
<lottie
          :options="lotties.da"
          class="lottie bg-white absolute top-1/2 -right-full transform -translate-x-1/2 -translate-y-1/2 rotate-3 rounded shadow p-10 opacity-0"
          @animCreated="handleAnimation"
/>

// In DATA: as object
lotties:{
       ux: {
          class: "ux",
          animationData: ux.default,
          loop: true,
          autoplay: false
       },
}

// In mounted:  scrollTrigger

    const lotties = document.querySelectorAll(".lottie");
    gsap.utils.toArray(".skill").forEach((el, i) => {
      let SkillAnim = gsap.timeline({
        scrollTrigger: {
          trigger: el,
          start: "top 70%",
          toggleActions: "play none none reset",
          onEnter: () => this.playLottie(i)
        }
      });
      SkillAnim.from(el, { autoAlpha: 0, y: 20 })
        .to(el, { autoAlpha: 1, y: 0 })
        .to(
          lotties[i],
          {
            right: "-10%",
            autoAlpha: 1,
            duration: 1
          },
          "<"
        )
    });

//In methods:

    handleAnimation: function(anim) {
      this.anim = anim;
    },
    playLottie: function() {
      this.anim.play();
    },
    stopLottie: function() {
      this.anim.stop();
    }

 

Link to comment
Share on other sites

20 minutes ago, OSUblake said:

Is there more than 1 <lottie> component? If so there needs to be an array if you're trying to play each one individually.

Yes, there are several lotties component like in the Codepen. Thanks a lot for your time and code example. I will try to understand and see how i can implement.

 

Thanks a lot

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...