Jump to content
Search Community

Sometime the reverse of my timeline doesn't reverse variables in set()

coolfarmer test
Moderator Tag

Recommended Posts

Hi guys!

 

I'm currently using GSAP to zoom a section of a SVG map. Every region on my map have 2 instances (using <use> from SVG). So when I click a region the second instance pass from a visibility:hidden to a visible state. And when I reverse the timeline it go back from visible to hidden.

 

The problem is that after a few view zoom/unzoom, the visibility stay on a visible state... It can happen randomly between 2-7 zooms.

I really don't understand that behavior. I think the bug happen fastly if I click quickly. I have a ton of security like a var "isTweening" with a "onReverseComplete" but the samething happen.

 

Here is my timeline code (inside a Vue Component)

if (!this.isTweening) {
    this.isTweening = true;

    if (this.tl != null) {
        console.log('Using existing TL');
        return this.tl;
    }

    const details = this.$parent.$parent.$refs[this.$props.code + '-details'].$el;
    this.tl = gsap.timeline({onReverseComplete: this.onReverseComplete});
    this.tl
        .set(details, {
            visibility: "visible",
            transformOrigin: "50% 50%"
        })
        .to(details, 0.7, {
            scale: 2.8,
            x: this.positionElementToCenter(details).x,
            y: this.positionElementToCenter(details).y,
            ease: "Power2.easeInOut"
        });

    this.tl.pause();

    return this.tl;
}

This timeline is play() when I click on a region and reverse() when I click on the zoomed region.

Any idea why GSAP can't reverse the property visibility 100% of time?

 

After 3 hours on this problem, I need help haha.
Sorry for my english it's not my main language.

 

Thanks!

 

Link to comment
Share on other sites

  Ok I think I have the solution!! 😱

I only had to transfer the 2 css properties (visibility and transformOrigin) from set() to to() and now it work perfectly even if I spam the event.

this.tl
        .to(details, 0.7, {
            visibility: "visible",  
            transformOrigin: "50% 50%"            
            scale: 2.8,
            x: this.positionElementToCenter(details).x,
            y: this.positionElementToCenter(details).y,
            ease: "Power2.easeInOut"
        });
  • Like 1
Link to comment
Share on other sites

Hey coolfarmer.

 

A few things:

  • Try using the latest GSAP beta because we recently fixed an issue where .set()s at the start of a timeline were not being used: https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js
  • In general it's best to use .isActive() to judge the state of a tween or timeline. So if this function is supposed to act like a toggle, something like this may work:
    if (this.tl != null) {
      console.log('Using existing TL');
    } else {
      // Setup timeline here
      // this.tl = gsap.timeline({paused: true, ...
    }
    
    // Toggle the direction of the timeline
    if (!this.tl.isActive()) {
      this.tl.reversed() ? this.tl.play() : this.tl.reverse();
    }

     

  • Your ease is invalid. We recommend using the condensed string form: "power2". Alternatively you can use the object form (not in eases): Power2.easeInOut

It's hard to say for sure what the problem is given we can't see things for ourselves.

 

Some related threads that may help you:

 

  • Like 1
Link to comment
Share on other sites

Yeah it's a bit long to extract the code from my component and transform them into css/html for codepen, but here we go:

See the Pen ExVEdOB by coolfarmer (@coolfarmer) on CodePen



And yeah..., the problem don't come from Gsap because it run pretty smoothly on all browser on codepen.

Well, thanks again for all the tips avd have a nice day!

Link to comment
Share on other sites

Hum yeah, like I said it's pretty long to extract all the logic from my components (VueJS).

I can assure you that my calculations are done one time only and the code on codepen is only for demo purpose. And I don't use addEventListener wit Vue, it's more like "@click" and "$emit"  to play with event between childs and parent.

 

Thanks for your time!

Link to comment
Share on other sites

You don't have to parse the viewbox. Just do it like this.

 

const viewBox = svg.viewBox.baseVal;

// now you can grab values like
const x = viewBox.x;
const y = viewBox.y;
const width = viewBox.width;
const height = viewBox.height;

 

Your demo seemed choppy on my computer at fullscreen. Maybe get rid of the <use> elements. <use> elements are stupid slow.

 

And maybe put stuff that is gets animated into separate <svg> elements so it doesn't have to redraw the entire svg when you animate it.

 

Also, text is slow to animate.

 

Firefox might be smoother because it can hardware accelerates some SVG operations. Chrome doesn't.

 

 

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