Jump to content
Search Community

Separated (global) gsap instances

playworksleep test
Moderator Tag

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

I have the following situation: a phaser gameworld (many tweens) where i use gsap (2.0 es6). And a surrounding page with some small interactive elements (also using gsap, but not so many tweens/timelines, about 10-15). I would like to be able to pause everything in the game and keep the animation in the page active.

 

Is it possible to create 2 different gsap (global) instances? So I can pause just the game instance.

That seems the cleanest approach.

 

Other approaches i tried, but failed so far:

 

- exportroot (no use, cause i get all tweens, also thje one in the page scope)

- attach the tweens in the game to a global timeline, use this as a sort of proxy/container, but gives unexpected behaviour and also the code becomes less readable

 

Currently i'm even considering using another animation framework for the in page animation, so I can still use the global pause resume for the game,

this is off course pretty lame...;)

What would be the best approach?

 

Link to comment
Share on other sites

Welcome to the forums!

 

Several approaches come to mind...

 

1) Simply use getTweensOf() to get the animations you need.

I imagine you know the targets of the tweens that you need, so just feed those in...

var animations = TweenLite.getTweensOf([obj1, obj2, obj3]); 
//now you can do whatever you want with those - pause() them, timeScale(), or whatever.

 

2) Populate a discrete timeline instance

var game = new TimelineLite({smoothChildTiming:true});
var ui = new TimelineLite({smoothChildTiming:true});

//now just tween accordingly, and if you want things to start "now", use rawTime()...
game.to(obj, 1, {...}, game.rawTime());
ui.to(obj2, 1, {...}, ui.rawTime());

 

If you feel like the code is getting redundant or long-winded, you could even write some functions to make it more concise...

 

var gameTL = new TimelineLite({smoothChildTiming:true}),
    game = {
        to: function(target, duration, vars) {
            return gameTL.to(target, duration, vars, gameTL.rawTime());
        },
        from: function(target, duration, vars) {
            return gameTL.from(target, duration, vars, gameTL.rawTime());
        },
        fromTo: function(target, duration, fromVars, toVars) {
            return gameTL.fromTo(target, duration, fromVars, toVars, gameTL.rawTime());
        }
    },
    uiTL = new TimelineLite({smoothChildTiming:true}),
    ui = {
        to: function(target, duration, vars) {
            return uiTL.to(target, duration, vars, uiTL.rawTime());
        },
        from: function(target, duration, vars) {
            return uiTL.from(target, duration, vars, uiTL.rawTime());
        },
        fromTo: function(target, duration, fromVars, toVars) {
            return uiTL.fromTo(target, duration, fromVars, toVars, uiTL.rawTime());
        }
    };

//now you can just write animations using "game" or "ui" instead of TweenLite or TweenMax:
game.to(...);
game.from(...);
ui.to(...);
ui.from(...);
...


Then, just control them independently like game.pause() or ui.pause(). 

 

3) Use the "data" property to segregate things

 

You can flag any tween using the data property like:

TweenMax.to(... {data:"game"});
TweenMax.to(... {data:"ui"});

//now get them and do whatever you want with them: 
var gameTweens = getByData("game");

function getByData(data) {
    var animations = TweenMax.getAllTweens(),
        i = animations.length,
        results = [];
    while (--i > -1) {
        if (animations[i].vars.data === data) {
            results.push(animations[i]);
        }
    }
    return results;
}

 

Does that help? 

 

There are probably even more ways to do this, but hopefully this gets you going in the right direction :)

  • Like 4
Link to comment
Share on other sites

Really helpfull! I was already at this exact moment working with the getAllTweens  method and segregating the tweens by targets with the game property, but the data approach is cleaner. Thnx! I'll provide feedback after solving mu use-case.

  • Like 2
Link to comment
Share on other sites

Ok, for now i implemented option 3 and only mark the several 'ui' tweens with a data property, works very smooth.

 

I might refactor my code to option 2 which seems a bit cleaner to me. Before dropping my questio nheere this was the approach I took, but not aware of the 'smoothChildTiming' which is crucial to prevent stange behaviour.

Thnx again! 

  • Like 2
Link to comment
Share on other sites

  • 1 year later...

I'm re-opening this thread I'm afraid ;) 

Is there a simple way to get actual separated global instances of gsap ? 
Same use-case..   Having a game I need to pause, and the rest of the website to still run.

Using different instances would make the code really more simpler in order to pause all the tweens in an instance.

Link to comment
Share on other sites

Not really.

I'd be looking for : 
 

let gsapinstance0 = ????
let gsapinstance1 = ????

// gsapInstance0 != gsapInstance1 == true

gsapInstance0.to / from / etc..
gsapInstance1.to / from / etc..


gsapInstance0.ticker.fps(0)

Trying to get multiple instances of gsap where, for example, changing fps ticker  does not affect the other instance.
I understand the use of timeline etc.. for this, but those are global properties.



 

Link to comment
Share on other sites

I think those are great, but are not what I'd be looking for there.

- getTweensOf is a bit local when you get   + 100 files containing 100 tweens. Bit hard to select them into all thoses classes.

- A timeline wont work, cause tweens are created / killed / removed / added  on the fly

- Data property might work, but it needs to be added and implemented in every tweens. In a 100 files project that is not really convenient. Unless writing a wrapper around gsap to aggregate, but it causes too much writing where I think it could be much simpler.

Having an instance of gsap ( without relying on a timeline ) could really help to set different global options to each of them
 

getTweensOf
Link to comment
Share on other sites

15 minutes ago, samsy said:

Data property might work, but it needs to be added and implemented in every tweens. In a 100 files project that is not really convenient.

Wouldn't you need to change gsap to gsapInstance0 and gsapInstance1 for every tween even if you could have two instances running on a page? Adding a data property instead seems like an equivalent amount of work to me.

 

Maybe @GreenSock can provide additional input since he is more familiar with the internals of GSAP.

Link to comment
Share on other sites

Quote

Adding a data property instead seems like an equivalent amount of work to me.



Not really, 
Creating those two instances of gsap into singletons classes ( one for UI let say and one for your Game ), helps you to import the gsap instance you want straight into the file that needs it

 

import gsap from 'uigsap'

or

import gsap from 'gamegsap'


Are definitely less of a work than adding a data property to each tween. For that example, the actual naming would stay the same, we are still using 'gsap.whatever' but the instance required is a different one and would not require to write specific data for each tween.

 

Link to comment
Share on other sites

I can't think of a clean way to import multiple GSAP instances and somehow force them to be completely independent. I don't think anyone has ever wanted to do this before (or at least nobody has mentioned it to us before that I can recall). We already provide ways to build out things separately in timelines, and you can set autoRemoveChildren:true on your timeline if you want animations to pop off automatically when they're done. Plus there's an exportRoot() method for taking all the stuff on the root and wrapping it in a timeline at any given time which is great for situations where you've got a bunch of animations going in the background that you want to stop/slow while brining in a modal window with regular-speed animations or whatever. So it sure seems like the tools are all there for you - it's just a matter of tapping into them appropriately. 

Link to comment
Share on other sites

Quote

Sure. Use an iframe.


Using an Iframe is definitely not an option. It add perfs issues, and a ton of complexity.

Adding tweens to a global timeline on the fly, removing them, pausing them, timescaling them etc.. leads to bugs.
 

That is definitely an advanced use-case. But if I'd like my game to stop running while displaying some UI MENU in top of it, I usually use the FPS ticker as RAF, and set the FPS ticker to 0 ( suspend all tween, suspend all delayed call etc.. ).  That is pretty handy, that is just a one-line instruction to pause the entire game.

But because the UI is also using GSAP to animate things, the whole game is suspended then. 

I'm not working on that UI part though, but sharing a same gsap instance in this case really leads to problem as multiple developers are working on different parts of the project. We just cannot set independant global gsap settings / framerate etc..


I guess we'll just switch to another animation library ! 

Many thanks

Link to comment
Share on other sites

49 minutes ago, samsy said:

Using an Iframe is definitely not an option. It add perfs issues, and a ton of complexity.

 

Hm. Citation needed. 😉

 

Then try importing 2 different modules. Proof of concept using actual es-modules.

 

See the Pen 0fe540125c7f1acba6efaab618cedebb by osublake (@osublake) on CodePen

 

 

57 minutes ago, samsy said:

I guess we'll just switch to another animation library ! 

 

Real question. Do you know of any animation libraries that can do that?

  • Like 3
Link to comment
Share on other sites

22 hours ago, samsy said:

Not really, 
Creating those two instances of gsap into singletons classes ( one for UI let say and one for your Game ), helps you to import the gsap instance you want straight into the file that needs it

 


import gsap from 'uigsap'

or

import gsap from 'gamegsap'

 

 

gsap will be scoped to the import, so its like singletons.

 

So try this.

import { gsap } from "gsap";
import { gsap as gsap2 } from "./somewhereElse/gsap/index.js";

 

import { gsap } from "gsap" will actually become something like this.

import { gsap } from "./node_modules/gsap/index.js";

 

And as long as that url is different from the gsap2 url, then it should work like a separate instance.

 

 

  • Like 2
Link to comment
Share on other sites

9 hours ago, samsy said:

Adding tweens to a global timeline on the fly, removing them, pausing them, timescaling them etc.. leads to bugs.

I didn't understand that comment. Did you know that you can set autoRemoveChildren: true and smoothChildTiming: true to a timeline and it'll act very much like the root timeline? You don't have to keep manually removing animations. I wonder if you've tried this at all. 

 

9 hours ago, samsy said:

That is definitely an advanced use-case. But if I'd like my game to stop running while displaying some UI MENU in top of it, I usually use the FPS ticker as RAF, and set the FPS ticker to 0 ( suspend all tween, suspend all delayed call etc.. ).  That is pretty handy, that is just a one-line instruction to pause the entire game.

This sounds a lot like what I mentioned earlier with exportRoot(). Are you familiar with that? Is there some reason that wouldn't work for you? 

 

9 hours ago, samsy said:

But because the UI is also using GSAP to animate things, the whole game is suspended then. 

Nope, not if you do it in either of the ways I described above. If I understand your description properly, I've done EXACTLY what you're talking about with exportRoot() and it worked great. Super easy. 

 

9 hours ago, samsy said:

I guess we'll just switch to another animation library ! 

No problem. But like Blake, I'm super curious what you'd switch to and why. GSAP isn't for everyone, but I think you may have a really hard time finding something that comes even close to the feature set which is fine if you're doing simple stuff but it sounds like you're more of an advanced user. In my experience, folks like you tend to demand a lot from their animation tools and it gets REALLY frustrating/stifling when you write a bunch of code that depends on a less robust tool that seems fine initially and then you need something more advanced and you're...well...out of luck. We really try to craft our tools to serve the unique needs of high-end professionals. I'm relatively confident there's already a solution you could use in GSAP (especially with with Blake mentioned above), but if not, I'm still very curious about what library you'd be switching to for something like that. 

 

Happy tweening!

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