Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
jesper.landberg

FLIP with GSAP?

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Hello @jesper.landberg

 

All the F.L.I.P. technique does at its very core, is per-calculate the expensive tweening values up front.

 

In GSAP you can do the same thing by using the progress() method before you play() the tween or timeline.

 

https://greensock.com/docs/TimelineMax/progress

 

Move the virtual playhead to the end of progress(1), then move it back to the start progress(0) before playing so GSAP can pre-record / pre-calculate the values.

 

tl.progress(1).progress(0);

.

So for example here we have a simple animation of a box :

 

// creates a timeline in a paused state
var tl = new TimelineMax({paused:true});
// create tween for the timeline
tl.to(".box", 2, {x: 50, y: 50});
// move virtual playhead to the end of the timeline,  progress(1)
// and then move it back to the start of the timeline, progress(0)
// so GSAP can pre-record / pre-calculate the values
tl.progress(1).progress(1);
// then play your timeline as normal
tl.play();

 

As you can see GSAP makes the F.L.I.P. technique very easy with one line of code.

 

Happy Tweening! :)

  • Like 3
Link to comment
Share on other sites

I had a horrible time getting my point across in that thread. Please don't make me do it again.

 

Changing the progress of a GSAP animation has nothing to do with the FLIP technique. A FLIP animation should always look the same. We are animating to an identity matrix. That's because we are already in the end state. There's a big difference between transitioning to a new state, and transitioning from a previous state. The underlying values are different, which makes a FLIP animation very hard to break.

 

TweenMax.to(element, 1, {
  x: 0,
  y: 0,
  scale: 1
})

 

Please look at the many posts I've made about animating Flexbox. I may not have used the term "FLIP", but it's still doing the same thing.

 

 

  • Like 4
Link to comment
Share on other sites

FLIP is a simple and not a complicated concept. The FLIP technique is all about pre-calculating the values up front. So you dont have to do all the expensive precalculations on each frame so you can achieve 60fps. GSAP does all that for you in the beginning.

 

Its all about getting it SILKY SMOOTH.. No Jank!

 

Paul Lewis's definition of FLIP

 

Quote

What we’re trying and do is to turn animations on their head (flip, see? Gosh darnit, I’m so funneh) and, instead of animating “straight ahead” and potentially doing expensive calculations on every single frame we precalculate the animation dynamically and let it play out cheaply.

 

Its all about getting that 60fps.. the buttery goodness. But precalculating is not the only thing you need, it doesn't guarantee 60fps. You still need all the correct CSS properties to play nice cross browser. This way you achieve 60fps and have it be the same cross browser :)

  • Like 1
Link to comment
Share on other sites

You are taking that definition completely out of context and applying it to some trick that Jack showed you. Yes, I know about that progress trick. That is not the flip technique.

 

Can somebody else please verify what I'm saying? I'm really losing my mind having to re-explain this all over again.

  • Like 1
Link to comment
Share on other sites

Why did Paul Lewis make a GSAP helper for FLIP?

https://github.com/googlearchive/flipjs/blob/master/src/gsap.js

 

And why does this code code look very close to what I posted above?
 

if (this.updateTransform_) {
  Object.assign(options, {
    scaleX: 1,
    scaleY: 1,
    x: 0,
    y: 0});
}

 


FLIP animations are not new to me. I have been doing them for several years, and I realize that at face value they might look like a regular animation, but they aren't. Look at those Flexbox animations I linked to. There is simply no other way to do them other than with a FLIP-like animation technique.

 

 

  • Like 2
Link to comment
Share on other sites

Its not a trick, its just about precalculating values to get 60fps. I'm not taking it out of context. I am talking that exactly from his  post. This whole CSS thing is not new to me.  He's updated the article since but its pretty much the same when he first introduced it. Its just a model to follow, which GSAP already does the precalculation for you. Even thw point of his article ws to get smooth animation with no jank.

 

In my opinion FLIP is great if your not using CSS transitions and the Web Animation API. It taps into those CSS transition events. Its still doing that expensive cost within that 100ms. But with GSAP you can take that FLIP model like you have done, but GSAP is still doing the expensive calculatoons for you up front.

 

Great codepens and I understand what you mean? But your missing my point, and taking it out of context ( pull hair now ;) ). We are both talking about different aspects of FLIP. Your talking about one part of FLIP with Invert. I am talking about the whole of all parts. which is to precaluate to get smooth 60fps. :)

 

 

Link to comment
Share on other sites

I can't do this anymore. I'm done.

 

 

  • Like 1
Link to comment
Share on other sites

I still love ya Blake :)

  • Like 2
Link to comment
Share on other sites

Well I still love ya too. That's why I said I'm done... with this thread, not with GSAP. I don't want to get into an argument and say something that I can't take back.

  • Like 1
Link to comment
Share on other sites

And yes, I do understand the point you were making about precaluclating values for better performance. I would never argue that that is a bad thing.

 

I was talking about the actual inverting of an animation, which is what @jesper.landberg was probably asking about because that is what it looks like he is trying to do in this post. That is very similar to the video animation I did in the post that @Sahil linked to.

 

 

  • Like 4
Link to comment
Share on other sites

Oh I see.. I understand your understanding, that makes sense. We were both talking about different munchkins varieties in the same Dunkin Donuts box.  I was focusing too much on trying to get 60 (fps) munchkins in my mouth at once as fast as I can. :blink: 

  • Like 3
Link to comment
Share on other sites

4 hours ago, OSUblake said:

Can somebody else please verify what I'm saying? I'm really losing my mind having to re-explain this all over again.

 

Sorry I was late to the party. Sounds like you guys worked it out though, right? And yeah, my understanding of FLIP is that it's different than the progress(1).play(0) thing (which just forces the recording of all the initial values immediately). FLIP is for when you're animating to a state that has a totally different document flow (jockeying things around in the DOM), thus you're taking its new position in the document flow and making it APPEAR (only via the animation) as though it's coming from where it used to be (old document flow). Correct me if I'm off base here. 

 

And Jonathan, I think it's smart to do the pre-calculating thing in many cases (sounds like Blake is totally on board with that too). 

  • Like 3
Link to comment
Share on other sites

Yes, I think we worked it out. 

 

Sometimes it's very hard to see the point of a FLIP animation, and it shouldn't be used for every animation. It's really only useful for when the DOM has changed, and you don't know what the end values are. 

 

Once you figure out what the end values are, you could do a regular .to() tween, but if the DOM changes during the animation, then it might jump at the end.

TweenLite.to(element, 1, {
  x: 300,
  y: 200,
  scale: 2
});

 

The invert step helps fix that problem, so you end up with an animation that looks more like this.

TweenLite.fromTo(element, 1, {
  x: -300,
  y: -200,
  scale: 0.5
}, {
  x: 0,
  y: 0,
  scale: 1
});

 

  • Like 5
Link to comment
Share on other sites

4 hours ago, OSUblake said:

And yes, I do understand the point you were making about precaluclating values for better performance. I would never argue that that is a bad thing.

 

I was talking about the actual inverting of an animation, which is what @jesper.landberg was probably asking about because that is what it looks like he is trying to do in this post. That is very similar to the video animation I did in the post that @Sahil linked to.

 

 


Thanks for all the answers, I think I have a better understanding of FLIP now=)

Btw, FLIP or not in your opinion @OSUblake but is the trick that Johanthan is mentioning a good way to help to smoothen up things when there are heavy or many concurrent animations going on?

Link to comment
Share on other sites

13 minutes ago, jesper.landberg said:

Btw, FLIP or not in your opinion @OSUblake but is the trick that Johanthan is mentioning a good way to help to smoothen up things when there are heavy or many concurrent animations going on?

 

The progress trick can help out with the start of animation. There can be a little stutter the first time you play an animation. It usually only happens with long or complicated timelines, but if you have a bunch of animations going on at the same time, then the stutter is likely to be more noticeable. So it can help out, but at the same time, doing the progress trick can cause a stutter if you do it when there are a lot of animations going on. You kind of just have to play around and see.

 

  • Like 2
Link to comment
Share on other sites

I'm glad to see Blake and Jonathan still love each other and all is right in the world again. Each time you guys mentioned FLIP, all I could think of was this scene from The IT Crowd.

 

 

 

  • Like 2
  • Haha 2
Link to comment
Share on other sites

@jesper.landberg .. When I use that progress trick i don't count on it for smooth 60fps, it just helps with initial cost up front. In my above replies, I also mention that it depends on getting all the correct CSS properties to play nice cross browser, so it is just one cog in the wheel.  With browsers like webkit browsers like Chrome, Safari, and MS Edge constantly changing how CSS properties render, its not written in stone. Sometimes you have to do the opposite to get smoothness, so it is like Blake said you will have to play around and see. :)

  • Like 3
Link to comment
Share on other sites

  • 1 year later...

I haven't used it, but isn't that what https://github.com/googlearchive/flipjs does? There are instructions there for using it with GSAP. 

 

Per your request, though, I whipped together a flip() helper function that might be more of what you're looking for. Here's a simple codepen that takes 7 <div> elements and re-parents them into a different container (right half of screen), then animates them there using FLIP. 

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

 

Here's the function: 

/* 
This is the function that does all the magic. Copy this to your project. Pass in the elements (selector text 
or NodeList or array), then a function/callback that actually makes your DOM changes, and optionally a vars 
object that contains any of the following properties to customize the transition:

 - duration [Number] - duration (in seconds) of each animation
 - stagger [Number | Object | Function] - amount to stagger the starting time of each animation. You may use advanceds staggers too (see https://codepen.io/GreenSock/pen/jdawKx)
 - ease [Ease] - controls the easing of the animation. Like Power2.easeInOut, or Elastic.easeOut, etc.
 - onComplete [Function] - a callback function that should be called when all the animation has completed.
 - delay [Number] - time (in seconds) that should elapse before any of the animations begin. 

This function will return a TimelineLite containing all the animations. 
*/
function flip(elements, changeFunc, vars) {
  if (typeof(elements) === "string") {
    elements = document.querySelectorAll(elements);
  }
  vars = vars || {};
  var bounds = [],
      tl = new TimelineLite({onComplete:vars.onComplete, delay:vars.delay || 0}),
      duration = vars.duration || 1,
      copy = {cycle:vars.cycle || {}},
      i, b, p;
  for (i = 0; i < elements.length; i++) {
    bounds[i] = elements[i].getBoundingClientRect();
  }
  changeFunc();
  for (p in vars) {
    if (p !== "duration" && p !== "onComplete" && p !== "delay") {
      copy[p] = vars[p];
    }
  }
  copy.cycle.x = function(i, element) {
    return "-=" + (element.getBoundingClientRect().left - bounds[i].left);
  };
  copy.cycle.y = function(i, element) {
    return "-=" + (element.getBoundingClientRect().top - bounds[i].top);
  }
  tl.staggerFrom(elements, vars.duration || 1, copy);
  return tl;
}

 

Is that what you were looking for? 

  • Like 5
Link to comment
Share on other sites

I love how Jack is always "whipping together" these amazing little helper functions.

 

It's kinda like:

 

AlmG7j8.jpg

 

Yeah, now I've got Devo stuck in my head too. 

 

 

You may now all suffer this earworm with me. You're welcome. ;)

 

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