Jump to content
Search Community

3D Carousel with text description - double click bug

wisertech test
Moderator Tag

Go to solution Solved by GreenSock,

Recommended Posts

Hi everyone,

 

I built a 3D carousel component and am using it to display a law firm's practice areas on mobile. The interactive section I had previously built with GSAP Flip didn't fit on smaller devices. The carousel is great because it works with a variable number of items, and increasing the count doesn't require much additional width to fit the carousel. The practice areas are a dynamic collection, manageable by admins signed into the website, so this was essential. 

 

Everything is working as intended except for one minor bug.

 

When clicking the previous or next button (or icon buttons) rapidly, the text that begins animating to the left fails to complete. It resets to the position it was in before, causing the absolute text boxes to overlap. This only happens if the carousel begins spinning again before the previous rotation finishes. The problem has to be somewhere here:

 

spinToItem(item){
    let angle = -item.positionAngle;
    gsap.to(this.carouselRoot, {rotationY:angle + '_short', duration:1, ease:'power4.out'});
    gsap.to(this.currentItem.textElement, {autoAlpha:0, xPercent:-100, duration:0.5, ease: 'power4.out'});
    gsap.fromTo(item.textElement, {autoAlpha:0, xPercent:100}, {autoAlpha:1, xPercent: 0, duration: 1, ease: 'power4.out'});

    this.currentItem = item;
    this.nextItem = this.arrayOfItems[(this.currentItem.position + 1) % this.arrayOfItems.length];
    this.previousItem = this.arrayOfItems.slice((this.currentItem.position - 1) % this.arrayOfItems.length)[0];
}

 

When spinToItem() is immediately called a second time, is currentItem being set to the target item causing the problem? Would it fix it if I updated currentItem and nextItem in an onComplete callback? 

 

Why does this happen?
 

See the Pen KKLaxWJ by wisertech (@wisertech) on CodePen

Link to comment
Share on other sites

  • Solution

I think it's a logic issue in your code related to the fact that you're allowing overlapping/competing tweens to occur on the same elements. You're animating the autoAlpha with a duration of 0.5 in one direction, and a duration of 1 in another, and you aren't doing any overwriting, thus you're allowing the tweens to fight with each other. The easiest solution is probably to just set overwrite: "auto". 

 

See the Pen xxNgMMz?editors=0010 by GreenSock (@GreenSock) on CodePen

Link to comment
Share on other sites

Wow, what an easy fix! FYI,  overwrite: 'auto' only needed to be added to this tween.

 gsap.to(this.currentItem.textElement, {autoAlpha:0, xPercent:-100, duration:0.5, ease: 'power4.out'});

Let me make sure I understand what happened:

 

You said, "I think it's a logic issue in your code related to the fact that you're allowing overlapping/competing tweens to occur on the same elements"

  • this.currentItem.textElement is different from item.textElement,  at least before this.currentItem is set to item in the following line.  Am I correct that setting currentItem to item is what causes the competing tweens to target the same element?  
    • 1.   button is clicked and spinToItem is called
    • 2.  currentItem's text animation (leaves container towards the left) begins at the same time as item's (enters container from the right)
    • 3.  currentItem is set equal to item while the animations are still going
    • 4.  button is clicked again before the animations complete
    • 5.  currentItem, which is equal to the last iteration's item, is given competing instructions to animate before it finishes its previous animation, thus causing the overlap on the same element.
  • Finally, (and this is the part I am least sure about) adding overwrite: auto instructs step 5 to kill any active animations of the same element's properties. Because autoAlpha and xPercent are the only properties being animated in both tweens, overwrite: auto behaves the same as overwrite: true would, and kills the active tween, thus letting step 5 accurately animate the item to its desired location, offscreen and hidden.

Sorry for all the detail. I always try to understand the exact cause of any bug I fix to prevent future occurrences! I appreciate your help and quick response. 

 

Thanks for sharing! I like it. I would love to add draggable functionality and inertia to the component. I have quite a few other components that I regularly use on websites that would benefit from this, especially for mobile.  

 

Oh wow, I just looked and realized that draggable is publicly available. I will check out its docs.

Link to comment
Share on other sites

Yep, it seems like you understood properly, at least for the most part. But...

 

overwrite: "auto" will ONLY find individual properties that are already being tweened in competing tweens, and isolate just those (killing them in the competing tween) whereas overwrite: true will find ANY active tween of the same target (doesn't care about individual properties) and kill the whole thing. So "auto" is more targeted. 

 

Usually people don't run into the problem because they use the same durations for everything, thus the problem is sorta invisible. For example, if you start tweening opacity from 0 to 1 over the course of 1 second...and then 0.5 seconds later you start ANOTHER tween that animates opacity from 1 to 0, since that starts later, it renders last, thus you never see the effects of the first tween. So the first tween might set opacity to 0.3 on one tick, but the other (later) tween sets opacity to 0.7 on the same tick thus you never actually see opacity at 0.3. 

 

But imagine if you start tweening opacity from 0 to 1 over the course of 1 second and then 0.2 seconds later, you start another tween that animates opacity from 1 to 0, but it only lasts 0.5 seconds. When that one ends, the first one is STILL GOING for another 0.3 seconds! So you'd see the 2nd one finish rendering with opacity at 0 but on the very next tick you'd see the original tween (which is 0.7 seconds into its 1-second long duration) continuing on! Opacity would suddenly jump from 0 to like 0.7 (assuming a linear ease) and animate up to 1. 

 

Make sense? 

  • 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...